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

bregex.c (445850B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * COS Queue Management
      8  * Purpose: Regex API for flow tracking
      9  */
     10 #include <shared/bsl.h>
     11 
     12 #include <sal/core/libc.h>
     13 #include <soc/defs.h>
     14 #if defined(BCM_TRIUMPH3_SUPPORT)
     15 
     16 #if defined(INCLUDE_REGEX)
     17 #include <soc/drv.h>
     18 #include <soc/scache.h>
     19 #include <soc/profile_mem.h>
     20 
     21 #include <soc/triumph3.h>
     22 #include <bcm_int/esw/firebolt.h>
     23 #include <bcm_int/esw/triumph3.h>
     24 #include <bcm/error.h>
     25 #include <bcm/bregex.h>
     26 #include <bcm_int/regex_api.h>
     27 #include <bcm_int/esw/mbcm.h>
     28 #include <bcm_int/esw/policer.h>
     29 
     30 #include <bcm_int/esw_dispatch.h>
     31 #include <bcm_int/common/multicast.h>
     32 
     33 #include <bcm_int/esw/multicast.h>
     34 #include <bcm_int/esw/flex_ctr.h>
     35 #include <bcm_int/esw/bregex.h>
     36 #include <bcm_int/esw/fb4regex.h>
     37 
     38 #ifdef BCM_WARM_BOOT_SUPPORT
     39 #include <bcm_int/esw/switch.h>
     40 #endif /* BCM_WARM_BOOT_SUPPORT */
     41 
     42 #define BCM_TR3_MAX_ENGINE                  32
     43 #define BCM_TR3_MAX_MATCH_MEM               4
     44 #define BCM_TR3_MAX_NUM_MATCH               256
     45 #define BCM_TR3_MAX_SLOTS                   512
     46 #define BCM_TR3_MAX_TILES                   8
     47 
     48 #define BCM_TR3_LINE_BYTE_SIZE              32
     49 #define BCM_TR3_NUM_RV_PER_LINE             8
     50 #define BCM_TR3_RV_STATE_SIZE               (BCM_TR3_LINE_BYTE_SIZE / BCM_TR3_NUM_RV_PER_LINE)
     51 
     52 /* Maximum number of flow */
     53 #define BCM_TR3_MAX_FLOWS   8192
     54 #define BCM_TR3_IN_USE_MASK          0x00003FFF
     55 #define BCM_TR3_IN_USE_MASK_SIZE     14
     56 #define BCM_TR3_MAX_IN_USE_MASK      0x0FFFC000
     57 #define BCM_TR3_MAX_IN_USE_MASK_SIZE 14
     58 
     59 /* maximum payload depth */
     60 #define BCM_TR3_MAX_PAYLOAD_DEPTH   16383
     61 
     62 /* maximum packets to SME */
     63 #define BCM_TR3_MAX_PKT_TO_SME   15
     64 
     65 #define BCM_REGEX_ENG2MATCH_MEMIDX(u,e)    ((e)/8)
     66 
     67 #define BCM_REGEX_NUM_SLOT_PER_CPS 16
     68 
     69 #define BCM_TR3_SPECIAL_SLOT 0x2012
     70 
     71 typedef struct _bcm_regex_cps_obj_s {
     72     uint32    flags;
     73     int             foff;
     74     int             alloc_map[BCM_REGEX_NUM_SLOT_PER_CPS];
     75     int             refcnt[BCM_REGEX_NUM_SLOT_PER_CPS];
     76     int             from_line;
     77     int             req_lsz;
     78 } _bcm_regex_cps_obj_t;
     79 
     80 #define BCM_REGEX_CPS_F_ALLOC     1
     81 
     82 #define BCM_REGEX_CPS_ALLOCED(pc) ((pc)->flags & BCM_REGEX_CPS_F_ALLOC)
     83 
     84 #define BCM_REGEX_CPS_SET_ALLOCED(pc) (pc)->flags |= BCM_REGEX_CPS_F_ALLOC
     85 
     86 #define BCM_REGEX_CPS_FREE_ALLOCED(pc) (pc)->flags &= ~BCM_REGEX_CPS_F_ALLOC
     87 
     88 #define BCM_TR3_MAX_SIG_ID  1024
     89 
     90 #define BCM_TR3_SIG_ID_MAP_BSZ   ((1024+31)/32)
     91 
     92 #define BCM_TR3_POLICER_NUM     256
     93 
     94 STATIC int _bcm_tr3_free_cps(int unit, _bcm_regex_cps_obj_t *pcps);
     95 
     96 typedef struct _bcm_regex_engine_obj_s {
     97     int                     hw_idx;
     98     uint32            flags;
     99     int                     total_lsz;  
    100     /* HW mapping */
    101     int                     tile;
    102     int                     from_line;
    103     int                     req_lsz;
    104     _bcm_regex_cps_obj_t    cps;
    105 } _bcm_regex_engine_obj_t;
    106 
    107 #define BCM_TR3_REGEX_ENGINE_ALLOC          0x01
    108 #define BCM_REGEX_ENGINE_ALLOCATED(eng) \
    109                         ((eng)->flags & BCM_TR3_REGEX_ENGINE_ALLOC)
    110 
    111 #define BCM_REGEX_ENGINE_SET_ALLOCATED(eng) \
    112                          (eng)->flags |= BCM_TR3_REGEX_ENGINE_ALLOC
    113 
    114 #define BCM_REGEX_ENGINE_SET_UNALLOCATED(eng) \
    115                          (eng)->flags &= ~BCM_TR3_REGEX_ENGINE_ALLOC
    116 
    117 typedef struct _bcm_regex_lengine_s {
    118     bcm_regex_engine_t      id;
    119     uint32                  flags;
    120     bcm_regex_engine_config_t config;
    121     _bcm_regex_engine_obj_t *physical_engine;
    122 } _bcm_regex_lengine_t;
    123 
    124 typedef int (*reset_engine)(int unit, int engine_idx);
    125 typedef int (*enable_engine)(int unit, _bcm_regex_engine_obj_t *pengine);
    126 typedef int (*get_engine_info)(int unit, int engine_idx, 
    127                                             _bcm_regex_engine_obj_t *e);
    128 typedef int (*disable_engine)(int unit, int engine_idx);
    129 typedef uint32 (*l2pf)(int line, int off);
    130 
    131 typedef struct bcm_regex_desc_s {
    132     int                 num_tiles;
    133     int                 num_engine_per_tile;
    134     int                 num_match_mem;
    135     int                 line_sz;
    136     uint32              flags;
    137     reset_engine        reset_engine;
    138     get_engine_info     get_engine_info;
    139     enable_engine       enable_engine;
    140     disable_engine      disable_engine;
    141 } bcm_regex_desc_t;
    142 
    143 #define BCM_REGEX_RESET_ENGINE(d, u, e) (d)->info->reset_engine((u), (e))
    144 
    145 #define BCM_REGEX_GET_ENGINE_INFO(d, u, pe, po) \
    146                                     (d)->info->get_engine_info((u), (pe), (po))
    147 
    148 #define BCM_REGEX_ENABLE_ENGINE(d, u, pe) (d)->info->enable_engine((u), (pe))
    149 #define BCM_REGEX_DISABLE_ENGINE(d, u, e) (d)->info->disable_engine((u), (e))
    150 
    151 #define BCM_TR3_MATCH_BMAP_BSZ  ((BCM_TR3_MAX_NUM_MATCH+31)/32)
    152 
    153 #define BCM_REGEX_DB_BUCKET_MAX 32
    154 
    155 STATIC int _bcm_tr3_alloc_regex_engine(int unit, int clsz, int extra_lsz,
    156                             _bcm_regex_engine_obj_t **ppeng, int intile);
    157 
    158 struct bcm_regexdb_entry_s;
    159 
    160 typedef struct _bcm_tr3_regex_device_info_s {
    161     int max_engines;
    162 
    163     bcm_regex_desc_t *info;
    164 
    165     _bcm_regex_engine_obj_t physical_engines[BCM_TR3_MAX_ENGINE];
    166 
    167     /* logical engines table */
    168     _bcm_regex_lengine_t engines[BCM_TR3_MAX_ENGINE];
    169 
    170     uint32      match_alloc_bmap[BCM_TR3_MAX_MATCH_MEM][BCM_TR3_MATCH_BMAP_BSZ];
    171 
    172     struct bcm_regexdb_entry_s *l[BCM_REGEX_DB_BUCKET_MAX];
    173 
    174     sal_mutex_t regex_mutex;
    175 
    176     uint32      sigid[BCM_TR3_SIG_ID_MAP_BSZ];    
    177 
    178     bcm_stat_flex_pool_attribute_t flex_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
    179 
    180     uint32      policer_bmp[BCM_TR3_POLICER_NUM/sizeof(uint32)];
    181     bcm_policer_config_t policer_cfg[BCM_TR3_POLICER_NUM];
    182 
    183     _regex_policy_t **policies;
    184     int               num_policies;
    185 } _bcm_tr3_regex_device_info_t;
    186 
    187 #define _BCM_TR3_FLEX_CTR_POOL_VALID(p) (((p) == -1) ? 0 : 1)
    188 
    189 static _bcm_tr3_regex_device_info_t *_bcm_tr3_regex_info[BCM_MAX_NUM_UNITS];
    190 
    191 static soc_profile_mem_t *_bcm_tr3_ft_policy_profile[BCM_MAX_NUM_UNITS];
    192 
    193 #define REGEX_INFO(u) _bcm_tr3_regex_info[(u)]
    194 
    195 #define BCM_TR3_NUM_ENGINE(d)   ((d)->max_engines)
    196 
    197 #define BCM_TR3_LOGICAL_ENGINE(d,leid)  \
    198   ((leid) >= BCM_TR3_NUM_ENGINE((d))) ? NULL : &(d)->engines[(leid)]
    199 
    200 #define BCM_TR3_PHYSICAL_ENGINE(d,peid) \
    201   ((peid) >= (BCM_TR3_NUM_ENGINE((d)))) ? NULL : &(d)->physical_engines[(peid)]
    202 
    203 #define BCM_TR3_ENGINE_PER_TILE(d)  ((d)->info->num_engine_per_tile)
    204 
    205 #define BCM_TR3_ENGINE_TILE(d,peid) \
    206   ((peid) >= (BCM_TR3_NUM_ENGINE((d)))) ? 0 : ((peid) / BCM_TR3_ENGINE_PER_TILE(d))
    207 
    208 #define BCM_TR3_CPS_INFO(d,peid)    &((d)->physical_engines[(peid)].cps)
    209 
    210 #define BCM_TR3_MATCH_BMAP_PTR(u,d,peid)    \
    211             (d)->match_alloc_bmap[BCM_REGEX_ENG2MATCH_MEMIDX((u),(peid))]
    212 
    213 typedef struct bcm_regexdb_entry_s {
    214     int         sigid;
    215     int         engid;
    216     int         match_id;
    217     uint16      match_index;
    218     int         provides;
    219     int         requires;
    220     short int   match_set_id;
    221     short int   match_chk_id;
    222     struct bcm_regexdb_entry_s *next;
    223 } _bcm_regexdb_entry_t;
    224 
    225 typedef struct _bcm_tr3_regex_data_s {
    226     int                     unit;
    227     uint32                  flags;
    228     int                     compile_size;
    229     /* HW engine information */
    230     _bcm_regex_engine_obj_t *hw_eng;
    231     bcm_regex_match_t       *matches;
    232     int                     num_match;
    233     int                     *match_set_ids;
    234     int                     *match_check_ids;
    235     int                     *sig_ids;
    236     int                     *hw_match_idx;
    237 
    238     /* temp information to compile to HW */
    239     int                     last_state;
    240     uint32                  last_flags;
    241     uint8                   cmap[REGEX_MAX_CHARACTER_CLASS_BYTES];
    242     soc_mem_t               mem;
    243     axp_sm_state_table_mem0_entry_t line;
    244    
    245     uint16                  *per_state_data;
    246     uint16                  wr_off;
    247     uint16                  line_off;
    248     int                     line_dirty;
    249 } _bcm_tr3_regex_data_t;
    250 
    251 typedef struct _bcm_regex_resource_s {
    252     _bcm_regex_engine_obj_t *pres;
    253     int     eng_idx;
    254     int     lsize;
    255 } _bcm_regex_resource_t;
    256 
    257 STATIC int
    258 _bcm_regex_sort_resources_by_size(int unit,
    259                                   _bcm_regex_resource_t *res, int num_res);
    260 
    261 STATIC int
    262 _bcm_regex_sort_resources_by_offset(int unit, 
    263                                   _bcm_regex_resource_t *res, int num_res);
    264 
    265 typedef struct _bcm_regex_tile_s {
    266     int valid;
    267     int freep;
    268     int avail;
    269     int oidx[BCM_TR3_MAX_ENGINE]; 
    270     int num_o;
    271     axp_sm_match_table_mem0_entry_t *match_mem;
    272 } _bcm_regex_tile_t;
    273 
    274 STATIC int
    275 _bcm_tr3_arrange_resources_in_tiles(int unit, _bcm_regex_resource_t *res, 
    276                                     int num_res, int to_tiles, int to_tilee,
    277                                     _bcm_regex_tile_t *_tr3tile, int num_tile);
    278 
    279 STATIC int
    280 _bcm_tr3_rearrange_engines_in_hw(int unit, _bcm_regex_resource_t *res, 
    281                            int num_res, int to_tiles, int to_tilee, 
    282                            _bcm_regex_tile_t *_tr3tile);
    283 
    284 STATIC int
    285 _bcm_tr3_regex_alloc_set_ids(int unit, int *match_set_ids, bcm_regex_match_t *matches,
    286                             int count, int pengine_hwidx);
    287 
    288 STATIC int
    289 _bcm_regexdb_handle_setid_avail(int unit, int avail, int engid,
    290                                 int provides, int setid);
    291 
    292 STATIC int _regex_tr3_policy_index_min_get(int unit);
    293 STATIC int _regex_tr3_policy_index_max_get(int unit);
    294 STATIC int _regex_tr3_policy_action_support_check(int                 unit,
    295                                                   bcm_field_action_t  action);
    296 STATIC int _regex_tr3_policy_action_conflict_check(int                unit,
    297                                                    bcm_field_action_t action1,
    298                                                    bcm_field_action_t action);
    299 STATIC int _regex_tr3_policy_action_params_check(int                     unit,
    300                                                  _regex_policy_t        *p_ent,
    301                                                  _regex_policy_action_t *pa);
    302 STATIC int _regex_tr3_policy_install(int unit, _regex_policy_t *p_ent);
    303 STATIC int _regex_tr3_policy_remove(int unit, _regex_policy_t *p_ent);
    304 STATIC int _regex_tr3_policer_install(int unit, _field_policer_t *f_pl);
    305 STATIC int _regex_tr3_policy_redirect_profile_alloc(int unit, _regex_policy_t *p_ent,
    306                                                     _regex_policy_action_t *pa);
    307 STATIC int _regex_tr3_policy_redirect_profile_ref_count_get(int unit, int index, int *ref_count);
    308 STATIC int _regex_tr3_policy_redirect_profile_delete(int unit, int index);
    309 
    310 STATIC _bcm_esw_regex_functions_t _regex_tr3_functions =
    311 {
    312     _regex_tr3_policy_index_min_get,
    313     _regex_tr3_policy_index_max_get,
    314     _regex_tr3_policy_action_support_check,
    315     _regex_tr3_policy_action_conflict_check,
    316     _regex_tr3_policy_action_params_check,
    317     _regex_tr3_policy_install,
    318     _regex_tr3_policy_remove,
    319     _regex_tr3_policer_install,
    320     _regex_tr3_policy_redirect_profile_alloc,
    321     _regex_tr3_policy_redirect_profile_delete,
    322     _regex_tr3_policy_redirect_profile_ref_count_get,
    323 };
    324 
    325 STATIC int _regex_tr3_policer_action_set(int              unit,
    326                                          _regex_policy_t *p_ent,
    327                                          uint32          *policy_buf);
    328 
    329 STATIC int _bcm_tr3_alloc_sigid(int unit, bcm_regex_match_t *match)
    330 {
    331     _bcm_tr3_regex_device_info_t *device;
    332     int     i, j;
    333 
    334     device = REGEX_INFO(unit);
    335 
    336     for (i=0; i<BCM_TR3_SIG_ID_MAP_BSZ; i++) {
    337         if (device->sigid[i] == 0) {
    338             continue;
    339         }
    340         for (j = 0; j < 32; j++) {
    341             if (device->sigid[i] & (1 << j)) {
    342                 device->sigid[i] &= ~(1 << j);
    343                 return ((i*32) + j);
    344             }
    345         }
    346     }
    347     return -1;
    348 }
    349 
    350 STATIC int
    351 _bcm_tr3_free_sigid(int unit, int sigid)
    352 {
    353     _bcm_tr3_regex_device_info_t *device;
    354 
    355     if ((sigid < 0) || (sigid >= BCM_TR3_MAX_SIG_ID)) {
    356         return BCM_E_PARAM;
    357     }
    358 
    359     device = REGEX_INFO(unit);
    360     device->sigid[sigid/32] |= 1 << (sigid % 32);
    361     return BCM_E_NONE;
    362 }
    363 
    364 typedef struct _bcm_regexdb_cb_ua_s {
    365     int avail;
    366     int setid;
    367 } _bcm_regexdb_cb_ua_t;
    368 
    369 /* locking */
    370 STATIC int _bcm_tr3_regex_lock (int unit)
    371 {
    372     _bcm_tr3_regex_device_info_t *device;
    373 
    374     if ((device = REGEX_INFO(unit)) == NULL) {
    375         return BCM_E_INIT;
    376     }
    377     
    378     sal_mutex_take(device->regex_mutex, sal_mutex_FOREVER);
    379     return BCM_E_NONE; 
    380 }
    381 
    382 STATIC void _bcm_tr3_regex_unlock(int unit)
    383 {
    384     _bcm_tr3_regex_device_info_t *device;
    385 
    386     device = REGEX_INFO(unit);
    387     sal_mutex_give(device->regex_mutex);
    388 }
    389 
    390 #define BCM_REGEX_LOCK(u) _bcm_tr3_regex_lock((u))
    391 
    392 #define BCM_REGEX_UNLOCK(u) _bcm_tr3_regex_unlock((u))
    393 
    394 
    395 /********** db *******/
    396 
    397 #define BCM_REGEX_DB_MATCH_BUCKET(matchidx) \
    398                             ((matchidx) % BCM_REGEX_DB_BUCKET_MAX)
    399 
    400 #define BCM_REGEXDB_MATCH_SIG_ID            0x1
    401 #define BCM_REGEXDB_MATCH_ENGINE_ID         0x2
    402 #define BCM_REGEXDB_MATCH_MATCH_ID          0x4
    403 #define BCM_REGEXDB_MATCH_PROVIDES          0x10
    404 #define BCM_REGEXDB_MATCH_REQUIRES          0x20
    405 
    406 STATIC _bcm_regexdb_entry_t**
    407 _bcm_regexdb_find(int unit, uint32 match_flags, _bcm_regexdb_entry_t *a)
    408 {
    409     _bcm_tr3_regex_device_info_t *device;
    410     _bcm_regexdb_entry_t **p, **res =  NULL;
    411     int i, from, to, found = 0;
    412     uint32 tmpf = match_flags;
    413 
    414     if ((match_flags & BCM_REGEXDB_MATCH_SIG_ID)) {
    415         from = to = BCM_REGEX_DB_MATCH_BUCKET(a->sigid);
    416     } else {
    417         from = 0;
    418         to = BCM_REGEX_DB_BUCKET_MAX - 1;
    419     }
    420 
    421     device = REGEX_INFO(unit);
    422 
    423     for (i = from; !found && (i <= to); i++) {
    424         p = &device->l[i];
    425         while (*p) {
    426             tmpf = match_flags;
    427             if ((match_flags & BCM_REGEXDB_MATCH_SIG_ID) &&
    428                 (a->sigid == (*p)->sigid)) {
    429                 tmpf &= ~BCM_REGEXDB_MATCH_SIG_ID;
    430             }
    431             if ((match_flags & BCM_REGEXDB_MATCH_ENGINE_ID) &&
    432                 (a->engid == (*p)->engid)) {
    433                 tmpf &= ~BCM_REGEXDB_MATCH_ENGINE_ID;
    434             }
    435         #if 0
    436             if ((match_flags & BCM_REGEXDB_MATCH_MATCH_INDEX) &&
    437                 (a->match_index == (*p)->match_index)) {
    438                 tmpf &= ~BCM_REGEXDB_MATCH_MATCH_INDEX;
    439             }
    440         #endif
    441             if ((match_flags & BCM_REGEXDB_MATCH_MATCH_ID) &&
    442                 (a->match_id == (*p)->match_id)) {
    443                 tmpf &= ~BCM_REGEXDB_MATCH_MATCH_ID;
    444             }
    445             if ((match_flags & BCM_REGEXDB_MATCH_PROVIDES) &&
    446                 (a->provides == (*p)->provides)) {
    447                 tmpf &= ~BCM_REGEXDB_MATCH_PROVIDES;
    448             }
    449             if ((match_flags & BCM_REGEXDB_MATCH_REQUIRES) &&
    450                 (a->requires == (*p)->requires)) {
    451                 tmpf &= ~BCM_REGEXDB_MATCH_REQUIRES;
    452             }
    453 
    454             /* match */
    455             if (tmpf == 0) {
    456                 found = 1;
    457                 res = p;
    458                 break;
    459             }
    460             p = &((*p)->next);
    461         }
    462     }
    463 
    464     return found ? res : NULL;
    465 }
    466 
    467 typedef int (*regexdb_traverse)(int unit, _bcm_regexdb_entry_t *e, void *ua);
    468 
    469 STATIC int
    470 _bcm_regexdb_traverse(int unit, uint32 match_flags, _bcm_regexdb_entry_t *a,
    471                       regexdb_traverse cbf, void *ua)
    472 {
    473     _bcm_tr3_regex_device_info_t *device;
    474     _bcm_regexdb_entry_t **p;
    475     int i, from, to, skip;
    476 
    477     if ((match_flags & BCM_REGEXDB_MATCH_SIG_ID)) {
    478         from = to = BCM_REGEX_DB_MATCH_BUCKET(a->sigid);
    479     } else {
    480         from = 0;
    481         to = BCM_REGEX_DB_BUCKET_MAX - 1;
    482     }
    483     
    484     device = REGEX_INFO(unit);
    485 
    486     for (i = from; i <= to; i++) {
    487         p = &device->l[i];
    488         while (*p) {
    489             skip = 0;
    490             if (!skip && (match_flags & BCM_REGEXDB_MATCH_SIG_ID) &&
    491                 (a->sigid != (*p)->sigid)) {
    492                 skip = 1;
    493             }
    494             if (!skip && (match_flags & BCM_REGEXDB_MATCH_ENGINE_ID) &&
    495                 (a->engid != (*p)->engid)) {
    496                 skip = 1;
    497             }
    498             #if 0
    499             if (!skip && (match_flags & BCM_REGEXDB_MATCH_MATCH_INDEX) &&
    500                 (a->match_index != (*p)->match_index)) {
    501                 skip = 1;
    502             }
    503             #endif
    504             if (!skip && (match_flags & BCM_REGEXDB_MATCH_MATCH_ID) &&
    505                 (a->match_id != (*p)->match_id)) {
    506                 skip = 1;
    507             }
    508             if (!skip && (match_flags & BCM_REGEXDB_MATCH_PROVIDES) &&
    509                 (a->provides != (*p)->provides)) {
    510                 skip = 1;
    511             }
    512             if (!skip && (match_flags & BCM_REGEXDB_MATCH_REQUIRES) &&
    513                 (a->requires != (*p)->requires)) {
    514                 skip = 1;
    515             }
    516 
    517             /* match */
    518             if (!skip) {
    519                 cbf(unit, *p, ua);
    520             }
    521             p = &((*p)->next);
    522         }    
    523     }
    524     return BCM_E_NONE;
    525 }
    526 
    527 STATIC int
    528 _bcm_regexdb_delete_cmn(int unit, uint32 match_flags, _bcm_regexdb_entry_t *a)
    529 {
    530     _bcm_tr3_regex_device_info_t *device;
    531     _bcm_regexdb_entry_t **p, *pn;
    532     int i, from, to, del, num_del = 0;
    533 
    534     if ((match_flags & BCM_REGEXDB_MATCH_SIG_ID)) {
    535         from = to = BCM_REGEX_DB_MATCH_BUCKET(a->match_index);
    536     } else {
    537         from = 0;
    538         to = BCM_REGEX_DB_BUCKET_MAX - 1;
    539     }
    540     
    541     device = REGEX_INFO(unit);
    542 
    543     for (i = from; i <= to; i++) {
    544         p = &device->l[i];
    545         while (*p) {
    546             del = 1;
    547             if (del && (match_flags & BCM_REGEXDB_MATCH_SIG_ID) &&
    548                 (a->sigid != (*p)->sigid)) {
    549                 del = 0;
    550             }
    551             if (del && (match_flags & BCM_REGEXDB_MATCH_ENGINE_ID) &&
    552                 (a->engid != (*p)->engid)) {
    553                 del = 0;
    554             }
    555             #if 0
    556             if ((match_flags & BCM_REGEXDB_MATCH_MATCH_INDEX) &&
    557                 (a->match_index != (*p)->match_index)) {
    558                 del = 0;
    559             }
    560             #endif
    561             if (del && (match_flags & BCM_REGEXDB_MATCH_MATCH_ID) &&
    562                 (a->match_id != (*p)->match_id)) {
    563                 del = 0;
    564             }
    565             if (del & (match_flags & BCM_REGEXDB_MATCH_PROVIDES) &&
    566                 (a->provides != (*p)->provides)) {
    567                 del = 0;
    568             }
    569             if (del && (match_flags & BCM_REGEXDB_MATCH_REQUIRES) &&
    570                 (a->requires != (*p)->requires)) {
    571                 del = 0;
    572             }
    573 
    574             if (del) {
    575                 pn = *p;
    576                 *p = pn->next;
    577                 sal_free(pn);
    578                 num_del++;
    579             } else {
    580                 p = &((*p)->next);
    581             }
    582         }    
    583     }
    584     return !num_del;
    585 }
    586 
    587 /*
    588  * Mark all the match entries that wre in pending state because on
    589  * unavailability of setid, to enable state.
    590  */
    591 STATIC int
    592 _bcm_regexdb_setid_avail_cb(int unit, _bcm_regexdb_entry_t *en, void *vua) 
    593 {
    594     soc_mem_t mem;
    595     axp_sm_match_table_mem0_entry_t match_entry;
    596     _bcm_regexdb_cb_ua_t *ua = (_bcm_regexdb_cb_ua_t*) vua;
    597 
    598     mem = AXP_SM_MATCH_TABLE_MEM0m + BCM_REGEX_ENG2MATCH_MEMIDX(unit,en->engid);
    599 
    600     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
    601                           MEM_BLOCK_ALL, en->match_index, &match_entry));
    602     if (soc_mem_field32_get(unit, mem, &match_entry, MATCH_ENTRY_VALIDf) == 0) {
    603         return BCM_E_NONE;
    604     }
    605     if (ua->avail) {
    606         soc_mem_field32_set(unit, mem, 
    607                         &match_entry, CHECK_CROSS_SIG_FLAG_IS_SETf, 1);
    608         soc_mem_field32_set(unit, mem, 
    609                         &match_entry, CHECK_CROSS_SIG_FLAG_INDEXf, ua->setid);
    610     } else {
    611         soc_mem_field32_set(unit, mem, 
    612                         &match_entry, CHECK_CROSS_SIG_FLAG_IS_SETf, 0);
    613         en->match_chk_id = BCM_TR3_SPECIAL_SLOT;
    614     }
    615     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 
    616                               MEM_BLOCK_ALL, en->match_index, &match_entry));
    617     return BCM_E_NONE;
    618 }
    619 
    620 STATIC int
    621 _bcm_regexdb_handle_setid_avail(int unit, int avail, int engid,
    622                                 int provides, int setid)
    623 {
    624     _bcm_regexdb_entry_t en;
    625     _bcm_regexdb_cb_ua_t ua;
    626 
    627     en.requires = provides;
    628     ua.avail = avail;
    629     ua.setid = setid;
    630 
    631     return _bcm_regexdb_traverse(unit, BCM_REGEXDB_MATCH_REQUIRES, 
    632                                  &en, _bcm_regexdb_setid_avail_cb, (void*) &ua);
    633 }
    634 
    635 STATIC int
    636 _bcm_regexdb_engine_unavail_cb(int unit, _bcm_regexdb_entry_t *en, void *vua) 
    637 { 
    638     _bcm_tr3_regex_device_info_t *device;
    639     axp_sm_match_table_mem0_entry_t match_entry;
    640     soc_mem_t mem;
    641     uint32 *alloc_bmap;
    642 
    643     device = REGEX_INFO(unit);
    644 
    645     if (en->match_set_id >= 0) {
    646         _bcm_regexdb_handle_setid_avail(unit, 0, en->engid, 
    647                                         en->provides, en->match_set_id);
    648     }
    649 
    650     /* delete the match index */
    651     mem = AXP_SM_MATCH_TABLE_MEM0m + BCM_REGEX_ENG2MATCH_MEMIDX(unit,en->engid);
    652 
    653     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
    654                           MEM_BLOCK_ALL, en->match_index, &match_entry));
    655     soc_mem_field32_set(unit, mem, &match_entry, MATCH_ENTRY_VALIDf, 0);
    656     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 
    657                               MEM_BLOCK_ALL, en->match_index, &match_entry));
    658 
    659     /* clear the alloc bitmap */
    660     alloc_bmap = BCM_TR3_MATCH_BMAP_PTR(unit,device, en->engid);
    661 
    662     alloc_bmap[en->match_index/32] &= ~(1 << (en->match_index % 32));
    663 
    664     _bcm_tr3_free_sigid(unit, en->sigid);
    665 
    666     return BCM_E_NONE;
    667 }
    668 
    669 STATIC int
    670 bcm_regexdb_find_chkid_for_requires(int unit, int requires, int *slot)
    671 {
    672     _bcm_tr3_regex_device_info_t *device;
    673     _bcm_regex_cps_obj_t *pcps;
    674     int i, j;
    675 
    676     device = REGEX_INFO(unit);
    677     for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
    678         pcps = BCM_TR3_CPS_INFO(device, i);
    679         if (!BCM_REGEX_CPS_ALLOCED(pcps)) {
    680             continue;
    681         }
    682 
    683         for (j=0; j<BCM_REGEX_NUM_SLOT_PER_CPS; j++) {
    684             if (pcps->alloc_map[j] == requires) {
    685                 *slot = pcps->foff + j;
    686                 return BCM_E_NONE;
    687             }
    688         }
    689     }
    690     return BCM_E_NOT_FOUND;
    691 }
    692 
    693 STATIC _bcm_regexdb_entry_t*
    694 bcm_regexdb_find_match_entry_by_sig_id(int unit, int sigid)
    695 {
    696     _bcm_regexdb_entry_t e, **ppe;
    697     e.sigid = sigid;
    698     ppe = _bcm_regexdb_find(unit, BCM_REGEXDB_MATCH_SIG_ID, &e);
    699     return ppe ? *ppe : NULL;
    700 }
    701 
    702 STATIC _bcm_regexdb_entry_t*
    703 bcm_regexdb_find_match_entry_by_match_id(int unit, int match_id)
    704 {
    705     _bcm_regexdb_entry_t e, **ppe;
    706     e.match_id = match_id;
    707     ppe = _bcm_regexdb_find(unit, BCM_REGEXDB_MATCH_MATCH_ID, &e);
    708     return ppe ? *ppe : NULL;
    709 }
    710 
    711 #if 0
    712 STATIC int
    713 bcm_regexdb_delete_by_match_id(int unit, int match_id)
    714 {
    715     _bcm_regexdb_entry_t en;
    716     en.match_id = match_id;
    717 
    718     return _bcm_regexdb_delete_cmn(unit, BCM_REGEXDB_MATCH_MATCH_ID, &en);
    719 }
    720 #endif
    721 
    722 STATIC int
    723 bcm_regexdb_delete_by_engine_id(int unit, int engid)
    724 {
    725     _bcm_regexdb_entry_t en;
    726     en.engid = engid;
    727     return _bcm_regexdb_delete_cmn(unit, BCM_REGEXDB_MATCH_ENGINE_ID, &en);
    728 }
    729 
    730 STATIC int
    731 bcm_regexdb_add_entry(int unit, int match_idx, int eng_idx, 
    732                       int match_id, int sigid, int provides, int requires,
    733                       int match_set_id, int match_chk_id)
    734 {
    735     _bcm_regexdb_entry_t *en, **ppen;
    736     _bcm_tr3_regex_device_info_t *device;
    737 
    738     en = bcm_regexdb_find_match_entry_by_match_id(unit, match_id);
    739     if (en) {
    740         return BCM_E_EXISTS;
    741     }
    742 
    743     en = sal_alloc(sizeof(_bcm_regexdb_entry_t), "regx_db-entry");
    744     en->sigid = sigid;
    745     en->match_index = match_idx;
    746     en->match_id = match_id;
    747     en->provides = provides;
    748     en->requires = requires;
    749     en->match_set_id = match_set_id;
    750     en->match_chk_id = match_chk_id;
    751     en->engid = eng_idx;
    752     en->next = NULL;
    753 
    754     device = REGEX_INFO(unit);
    755 
    756     ppen = &device->l[BCM_REGEX_DB_MATCH_BUCKET(sigid)];
    757     while(*ppen) {
    758         ppen = &(*ppen)->next;
    759     }
    760 
    761     LOG_INFO(BSL_LS_BCM_REGEX,
    762              (BSL_META_U(unit,
    763                          "signature %d added (match_index=%d engid=%d provides=%d \
    764                          requires=%d match_set_id=%d match_chk_id=%d)\n"),
    765               sigid, match_idx, eng_idx, provides, requires, match_set_id, match_chk_id));
    766 
    767     *ppen = en;
    768     return 0;
    769 }
    770 
    771 /*
    772  * Compare the objects.
    773  */
    774 STATIC int _bcm_regex_object_cmp_size(void*a, void*b)
    775 {
    776     _bcm_regex_resource_t *oa, *ob;
    777 
    778     oa = (_bcm_regex_resource_t*)a;
    779     ob = (_bcm_regex_resource_t*)b;
    780 
    781     return ob->pres->total_lsz - oa->pres->total_lsz;
    782 }
    783 
    784 STATIC int _bcm_regex_object_cmp_offset(void*a, void*b)
    785 {
    786     _bcm_regex_resource_t *oa, *ob;
    787     _bcm_regex_engine_obj_t *eng_a, *eng_b;
    788 
    789     oa = (_bcm_regex_resource_t*)a;
    790     ob = (_bcm_regex_resource_t*)b;
    791 
    792     eng_a = (_bcm_regex_engine_obj_t*)oa->pres;
    793     eng_b = (_bcm_regex_engine_obj_t*)ob->pres;
    794 
    795     if (eng_a->tile != eng_b->tile) {
    796         /* if not in same tile, return a big bumber */
    797         return (eng_a->tile - eng_b->tile)*0x072011;
    798     }
    799 
    800     return eng_a->from_line - eng_b->from_line;
    801 }
    802 
    803 STATIC int
    804 _bcm_regex_sort_resources_by_size(int unit,
    805                                   _bcm_regex_resource_t *res, int num_res)
    806 {
    807     _shr_sort(res, num_res, sizeof(_bcm_regex_resource_t), 
    808                         _bcm_regex_object_cmp_size);
    809     return BCM_E_NONE;
    810 }
    811 
    812 STATIC int
    813 _bcm_regex_sort_resources_by_offset(int unit, 
    814                                   _bcm_regex_resource_t *res, int num_res)
    815 {
    816     _shr_sort(res, num_res, sizeof(_bcm_regex_resource_t), 
    817                         _bcm_regex_object_cmp_offset);
    818     return BCM_E_NONE;
    819 }
    820 
    821 STATIC int
    822 _bcm_tr3_make_resource_objs(int unit, _bcm_regex_resource_t **ppres,
    823                                     int *pnum_res, int tiles, int tilee)
    824 {
    825     _bcm_tr3_regex_device_info_t *device;
    826     int i, j, nept, count;
    827     _bcm_regex_resource_t *pres;
    828     _bcm_regex_engine_obj_t *pengine = NULL;
    829     
    830     *ppres = NULL;
    831     *pnum_res = 0;
    832 
    833     device = REGEX_INFO(unit);
    834 
    835     nept = BCM_TR3_ENGINE_PER_TILE(device);
    836 
    837     for (count=0, i=tiles; i<=tilee; i++) {
    838         for (j=0; j<nept; j++) {
    839             pengine = BCM_TR3_PHYSICAL_ENGINE(device, (i*nept) + j);
    840             if (!BCM_REGEX_ENGINE_ALLOCATED(pengine)) {
    841                 continue;
    842             }
    843             count++;
    844         }
    845     }
    846 
    847     if (count == 0) {
    848         return BCM_E_NONE;
    849     }
    850     
    851     pres = sal_alloc(sizeof(_bcm_regex_resource_t)*count, "res_objs");
    852     
    853     for (count=0, i=tiles; i<=tilee; i++) {
    854         for (j=0; j<nept; j++) {
    855             pengine = BCM_TR3_PHYSICAL_ENGINE(device, (i*nept) + j);
    856             if (!BCM_REGEX_ENGINE_ALLOCATED(pengine)) {
    857                 continue;
    858             }
    859             pres[count].pres = pengine;
    860             pres[count].eng_idx = pengine->hw_idx;
    861             pres[count].lsize = pengine->total_lsz;
    862             count++;
    863         }
    864     }
    865 
    866     *pnum_res = count;
    867     *ppres = pres;
    868 
    869     return BCM_E_NONE;
    870 }
    871 
    872 STATIC int
    873 _bcm_tr3_free_resource_objs(int unit, _bcm_regex_resource_t **ppres, 
    874                             int *num_res)
    875 {
    876     if (*ppres) {
    877         sal_free(*ppres);
    878         *ppres = NULL;
    879         *num_res = 0;
    880     }
    881     return BCM_E_NONE;
    882 }
    883 
    884 STATIC int _encode_max_flow(int max_flow)
    885 {
    886     int enc;
    887 
    888     if (max_flow <= 1024) {
    889         enc = 0;
    890     } else if (max_flow <= 2048) {
    891         enc = 1;
    892     } else if (max_flow <= 4096) {
    893         enc = 2;
    894     } else if (max_flow <= 8192) {
    895         enc = 3;
    896     } else {
    897         enc = -1;
    898     }
    899     return enc;
    900 }
    901 
    902 STATIC int _decode_max_flow(int hw_enc)
    903 {
    904     int max_flow;
    905 
    906     if (hw_enc == 0) {
    907         max_flow = 1024;
    908     } else if (hw_enc == 1) {
    909         max_flow = 2048;
    910     } else if (hw_enc == 2) {
    911         max_flow = 4096;
    912     } else if (hw_enc == 3) {
    913         max_flow = 8192;
    914     } else {
    915         max_flow = -1;
    916     }
    917     return max_flow;
    918 }
    919 
    920 static int is_printable(unsigned char c)
    921 {
    922     const unsigned int printable_bmap[] = {
    923         0x00000000,
    924         0xffffffff,
    925         0xffffffff,
    926         0x7fffffff,
    927         0x00000000,
    928         0x00000000,
    929         0x00000000,
    930         0x00000000
    931     };
    932 
    933     if (printable_bmap[c/32] & (1 << (c % 32))) {
    934         return 1;
    935     }
    936     return 0;
    937 }
    938 
    939 typedef enum _bcm_tr3_ctr_mode_e {
    940     _CTR_MODE_NONE  = 0,
    941     _CTR_MODE_PER_LEG,
    942     _CTR_MODE_BOTH_LEG
    943 } _bcm_tr3_ctr_mode_t;
    944 
    945 STATIC int
    946 _bcm_tr3_ctr_mode_set(int unit, _bcm_tr3_ctr_mode_t mode)
    947 {
    948     uint32 regval, fval;
    949 
    950     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit, &regval));
    951     switch (mode) {
    952         case _CTR_MODE_NONE:
    953             fval = 0;
    954         break;
    955         case _CTR_MODE_BOTH_LEG:
    956             fval = 1;
    957         break;
    958         case _CTR_MODE_PER_LEG:
    959             fval = 2;
    960         break;
    961         default:
    962             return BCM_E_PARAM;
    963     }
    964 
    965     soc_reg_field_set(unit, FT_CONFIGr, &regval, CNT_MODEf, fval);
    966     SOC_IF_ERROR_RETURN(WRITE_FT_CONFIGr(unit, regval));
    967     
    968     return BCM_E_NONE;
    969 }
    970 
    971 STATIC 
    972 _bcm_tr3_ctr_mode_t _bcm_tr3_ctr_mode_get(int unit)
    973 {
    974     uint32 regval, fval;
    975 
    976     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit, &regval));
    977     fval = soc_reg_field_get(unit, FT_CONFIGr, regval, CNT_MODEf);
    978     
    979     switch (fval) {
    980         case 1:
    981             return _CTR_MODE_BOTH_LEG;
    982         case 2:
    983             return _CTR_MODE_PER_LEG;
    984         default:
    985         case 0:
    986             return _CTR_MODE_NONE;
    987     }
    988 }
    989 
    990 STATIC int _bcm_tr3_flex_ctr_pool_id_unmap(int unit, int pool_id)
    991 {
    992     _bcm_tr3_regex_device_info_t *device;
    993     int i;
    994     int rv;
    995 
    996     if ((device = REGEX_INFO(unit)) == NULL) {
    997         return BCM_E_INIT;
    998     }
    999     for (i = bcmStatFlexDirectionEgress; i >= bcmStatFlexDirectionIngress; i--) {
   1000         device->flex_pools[i].pool_id = pool_id;
   1001         if (!_BCM_TR3_FLEX_CTR_POOL_VALID(device->flex_pools[i].pool_id)) {
   1002             continue;
   1003         }
   1004         device->flex_pools[i].flags = BCM_FLEX_DEALLOCATE_POOL;
   1005         device->flex_pools[i].flags |= (i == bcmStatFlexDirectionIngress ?
   1006                                              BCM_FLEX_INGRESS_POOL : 
   1007                                              BCM_FLEX_EGRESS_POOL);
   1008         rv = _bcm_esw_stat_flex_pool_operation(unit, &device->flex_pools[i]);
   1009         if (rv != 0) {
   1010             LOG_INFO(BSL_LS_BCM_REGEX,
   1011                     (BSL_META_U(unit,
   1012                                 "unmap: _bcm_esw_stat_flex_pool_operation failed: i = %d, id = %d, flags = 0x%04x, size = %d\n"),
   1013                      i, device->flex_pools[i].pool_id,
   1014                      device->flex_pools[i].flags,
   1015                      device->flex_pools[i].pool_size));
   1016             return rv;
   1017         } else {
   1018             LOG_INFO(BSL_LS_BCM_REGEX,
   1019                     (BSL_META_U(unit,
   1020                                 "unmap: _bcm_esw_stat_flex_pool_operation succeeded: i = %d, id = %d, flags = 0x%04x, size = %d\n"),
   1021                      i, device->flex_pools[i].pool_id,
   1022                      device->flex_pools[i].flags,
   1023                      device->flex_pools[i].pool_size));
   1024         }
   1025         device->flex_pools[i].pool_id = -1;
   1026     }
   1027     return BCM_E_NONE;
   1028 }
   1029 
   1030 STATIC int _bcm_tr3_flex_ctr_pool_map(int unit, _bcm_tr3_ctr_mode_t mode, int max_flows)
   1031 {
   1032     _bcm_tr3_regex_device_info_t *device;
   1033     int dir;
   1034     int rgn, poff, poolr;
   1035     uint64 fval;
   1036     uint64 regval;
   1037     int rv;
   1038     soc_field_t poolfTR3[] = { FWD_00f, FWD_01f, FWD_10f, FWD_11f,
   1039                             REV_00f,  REV_01f, REV_10f, REV_11f };
   1040     soc_field_t poolfH4[] = { FWD_000f, FWD_001f, FWD_010f, FWD_011f, FWD_100f, FWD_101f, FWD_110f, FWD_111f,
   1041                             REV_000f, REV_001f, REV_010f, REV_011f, REV_100f, REV_101f, REV_110f, REV_111f };
   1042     uint64 reg_update_per_dir[] = { 0,1,2,3,0,0,0,0,4,5,6,7,0,0,0,0 };    
   1043     uint64 reg_update_shared[] = { 0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7 };    
   1044     int poolf_size;
   1045 
   1046     if (SOC_IS_HELIX4(unit)) {
   1047         poolf_size = sizeof(poolfH4)/sizeof(poolfH4[0]);
   1048     }
   1049     else {
   1050         poolf_size = sizeof(poolfTR3)/sizeof(poolfTR3[0]);
   1051     }
   1052 
   1053     if ((device = REGEX_INFO(unit)) == NULL) {
   1054         return BCM_E_INIT;
   1055     }
   1056 
   1057     if (mode == _CTR_MODE_NONE) {
   1058         return BCM_E_NONE;
   1059     }
   1060 
   1061 
   1062     /* Alloc pools */
   1063 
   1064     /*
   1065     Note that stat direction can be ingress or egress depending on the flow
   1066     direction.  However, flow tracker stats are always on the ingress side,
   1067     no matter whether the flow is coming from the client or the server.  So
   1068     the size of the pool used will always be the size of an ingress pool.
   1069 
   1070     Since Triumph3 and Helix4 support 8192 entries in a flex_ingress_pool,
   1071     device->flex_pools is only ever of size two, so there will be only
   1072     two pools available for the FT stats, and the second one will only be
   1073     used when traffic must be counted separately for each direction.
   1074     */
   1075     poolr = max_flows/ (SOC_INFO(unit).size_flex_ingress_pool);
   1076     poolr += (max_flows % (SOC_INFO(unit).size_flex_ingress_pool)) ? 1 : 0;
   1077 
   1078     if(poolr > SOC_INFO(unit).num_flex_ingress_pools) {
   1079         return BCM_E_RESOURCE;
   1080     }
   1081 
   1082     for (dir = bcmStatFlexDirectionIngress; dir <=
   1083           ((mode == _CTR_MODE_PER_LEG) ? bcmStatFlexDirectionEgress :
   1084            bcmStatFlexDirectionIngress); dir++) {
   1085         for( rgn =0; rgn < poolr; rgn++) {
   1086             device->flex_pools[dir].flags = BCM_FLEX_ALLOCATE_POOL;
   1087             device->flex_pools[dir].pool_size =
   1088                 (dir == bcmStatFlexDirectionIngress ?
   1089                          SOC_INFO(unit).size_flex_ingress_pool:
   1090                          SOC_INFO(unit).size_flex_egress_pool);
   1091             device->flex_pools[dir].flags |= (dir == bcmStatFlexDirectionIngress ?
   1092                     BCM_FLEX_INGRESS_POOL : 
   1093                     BCM_FLEX_EGRESS_POOL);
   1094             if (SOC_IS_HELIX4(unit)) {
   1095                 if(mode == _CTR_MODE_PER_LEG) {
   1096                     device->flex_pools[dir].pool_id = reg_update_per_dir[rgn + dir*8];
   1097                 } else {
   1098                     device->flex_pools[dir].pool_id = reg_update_shared[rgn + dir*8];
   1099                 }
   1100             } else {
   1101                 device->flex_pools[dir].pool_id = dir;
   1102             }
   1103             rv = _bcm_esw_stat_flex_pool_operation(unit, &device->flex_pools[dir]);
   1104             if (rv != 0) {
   1105                 LOG_INFO(BSL_LS_BCM_REGEX,
   1106                         (BSL_META_U(unit,
   1107                                     "map: _bcm_esw_stat_flex_pool_operation failed: dir = %d, id = %d, flags = 0x%04x, size = %d\n"),
   1108                          dir, device->flex_pools[dir].pool_id,
   1109                          device->flex_pools[dir].flags,
   1110                          device->flex_pools[dir].pool_size));
   1111                 /*Clean up*/
   1112                 if(device->flex_pools[dir].pool_id == 0) {
   1113                     device->flex_pools[dir].pool_id = -1;
   1114                     return rv;
   1115                 }
   1116                 for(rgn = device->flex_pools[dir].pool_id - 1; rgn >= 0; rgn--) {
   1117                     _bcm_tr3_flex_ctr_pool_id_unmap(unit,rgn); 
   1118                 }
   1119                 return rv;
   1120             } else {
   1121                 LOG_INFO(BSL_LS_BCM_REGEX,
   1122                         (BSL_META_U(unit,
   1123                                     "map: _bcm_esw_stat_flex_pool_operation succeeded: dir = %d, id = %d, flags = 0x%04x, size = %d\n"),
   1124                          dir, device->flex_pools[dir].pool_id,
   1125                          device->flex_pools[dir].flags,
   1126                          device->flex_pools[dir].pool_size));
   1127             }
   1128         }
   1129     }
   1130 
   1131     SOC_IF_ERROR_RETURN(READ_FT_CTR_POOLr(unit, &regval));
   1132     /*
   1133     Assign 2 pools of 8K entries for counting traffic in separate directions,
   1134     and just 1 pool of 8K entries for counting bidirectional traffic.
   1135     */
   1136     if (SOC_IS_HELIX4(unit)) {
   1137         for (rgn = 0; rgn < poolf_size; rgn++) {
   1138              if (mode == _CTR_MODE_PER_LEG) {
   1139                  soc_reg64_field_set(unit, FT_CTR_POOLr, &regval, poolfH4[rgn], reg_update_per_dir[rgn]);
   1140              } else  {
   1141                  soc_reg64_field_set(unit, FT_CTR_POOLr, &regval, poolfH4[rgn], reg_update_shared[rgn]);
   1142              }
   1143         }
   1144     } else {
   1145         for (rgn = 0; rgn < poolf_size; rgn++) {
   1146             poff = (mode == _CTR_MODE_PER_LEG) ? rgn/(poolf_size/2) : 0;
   1147             COMPILER_64_SET(fval, 0, device->flex_pools[poff].pool_id);
   1148             soc_reg64_field_set(unit, FT_CTR_POOLr, &regval, poolfTR3[rgn], fval);
   1149         }
   1150     }
   1151     SOC_IF_ERROR_RETURN(WRITE_FT_CTR_POOLr(unit, regval));
   1152 
   1153     return BCM_E_NONE;
   1154 }
   1155 
   1156 STATIC int _bcm_tr3_flex_ctr_pool_unmap(int unit)
   1157 {
   1158     _bcm_tr3_regex_device_info_t *device;
   1159     int i;
   1160     int rv, max_flows, poolr, rgn;
   1161     uint64 reg_update_shared[] = { 0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7 };
   1162 
   1163     if ((device = REGEX_INFO(unit)) == NULL) {
   1164         return BCM_E_INIT;
   1165     }
   1166 
   1167     max_flows = BCM_TR3_MAX_FLOWS;
   1168     poolr = max_flows/ (SOC_INFO(unit).size_flex_ingress_pool);
   1169     poolr += (max_flows % (SOC_INFO(unit).size_flex_ingress_pool)) ? 1 : 0;
   1170 
   1171     if(poolr > SOC_INFO(unit).num_flex_ingress_pools){
   1172         return BCM_E_RESOURCE;
   1173     }
   1174     for (i = bcmStatFlexDirectionIngress; 
   1175             i <= bcmStatFlexDirectionEgress ; i++) {
   1176         for(rgn =0; rgn < poolr; rgn++) {
   1177             device->flex_pools[i].pool_id = reg_update_shared[rgn + i*8]; 
   1178             if (!_BCM_TR3_FLEX_CTR_POOL_VALID(device->flex_pools[i].pool_id)) {
   1179                 continue;
   1180             }
   1181             device->flex_pools[i].flags = BCM_FLEX_DEALLOCATE_POOL;
   1182             device->flex_pools[i].flags |= (i == bcmStatFlexDirectionIngress ?
   1183                     BCM_FLEX_INGRESS_POOL : 
   1184                     BCM_FLEX_EGRESS_POOL);
   1185             rv = _bcm_esw_stat_flex_pool_operation(unit, &device->flex_pools[i]);
   1186 
   1187             if (rv != 0) {
   1188                 LOG_INFO(BSL_LS_BCM_REGEX,
   1189                         (BSL_META_U(unit,
   1190                                     "unmap: _bcm_esw_stat_flex_pool_operation failed: i = %d, id = %d, flags = 0x%04x, size = %d\n"),
   1191                          i, device->flex_pools[i].pool_id,
   1192                          device->flex_pools[i].flags,
   1193                          device->flex_pools[i].pool_size));
   1194             }
   1195             else
   1196             {
   1197                 LOG_INFO(BSL_LS_BCM_REGEX,
   1198                         (BSL_META_U(unit,
   1199                                     "unmap: _bcm_esw_stat_flex_pool_operation succeeded: i = %d, id = %d, flags = 0x%04x, size = %d\n"),
   1200                          i, device->flex_pools[i].pool_id,
   1201                          device->flex_pools[i].flags,
   1202                          device->flex_pools[i].pool_size));
   1203             }
   1204         }
   1205     }
   1206     device->flex_pools[bcmStatFlexDirectionIngress].pool_id = -1;
   1207     device->flex_pools[bcmStatFlexDirectionEgress].pool_id = -1;
   1208     return BCM_E_NONE;
   1209 }
   1210 
   1211 int 
   1212 _bcm_tr3_regex_dump_axp(int unit)
   1213 {
   1214     uint32 regval;
   1215 
   1216     LOG_CLI((BSL_META_U(unit,
   1217                         "Regex AXP status register values:\n")));
   1218     SOC_IF_ERROR_RETURN
   1219         (READ_AXP_SM_SIGNATURE_MATCH_ACTIVE_STATUS1r(unit, &regval));
   1220     LOG_CLI((BSL_META_U(unit,
   1221                         " AXP_SM_SIGNATURE_MATCH_ACTIVE_STATUS1 = 0x%08x\n"), regval));
   1222     SOC_IF_ERROR_RETURN
   1223         (READ_AXP_SM_SIGNATURE_MATCH_ACTIVE_STATUS0r(unit, &regval));
   1224     LOG_CLI((BSL_META_U(unit,
   1225                         " AXP_SM_SIGNATURE_MATCH_ACTIVE_STATUS0 = 0x%08x\n\n"), regval));
   1226     LOG_CLI((BSL_META_U(unit,
   1227                         "Regex AXP counter register values:\n")));
   1228     SOC_IF_ERROR_RETURN(READ_AXP_SM_PACKETS_RECEIVED_COUNTERr(unit, &regval));
   1229     LOG_CLI((BSL_META_U(unit,
   1230                         " AXP_SM_PACKETS_RECEIVED_COUNTER       = 0x%08x\n"), regval));
   1231     SOC_IF_ERROR_RETURN(READ_AXP_SM_PACKETS_SENT_COUNTERr(unit, &regval));
   1232     LOG_CLI((BSL_META_U(unit,
   1233                         " AXP_SM_PACKETS_SENT_COUNTER           = 0x%08x\n"), regval));
   1234     SOC_IF_ERROR_RETURN(READ_AXP_SM_PACKETS_DROPPED_COUNTERr(unit, &regval));
   1235     LOG_CLI((BSL_META_U(unit,
   1236                         " AXP_SM_PACKETS_DROPPED_COUNTER        = 0x%08x\n"), regval));
   1237     SOC_IF_ERROR_RETURN(READ_AXP_SM_BYTES_MATCHED_COUNTERr(unit, &regval));
   1238     LOG_CLI((BSL_META_U(unit,
   1239                         " AXP_SM_BYTES_MATCHED_COUNTER          = 0x%08x\n"), regval));
   1240     SOC_IF_ERROR_RETURN(READ_AXP_SM_MATCHED_FLOWS_COUNTERr(unit, &regval));
   1241     LOG_CLI((BSL_META_U(unit,
   1242                         " AXP_SM_MATCHED_FLOWS_COUNTER          = 0x%08x\n"), regval));
   1243     SOC_IF_ERROR_RETURN(READ_AXP_SM_UNMATCHED_FLOWS_COUNTERr(unit, &regval));
   1244     LOG_CLI((BSL_META_U(unit,
   1245                         " AXP_SM_UNMATCHED_FLOWS_COUNTER        = 0x%08x\n"), regval));
   1246     SOC_IF_ERROR_RETURN(READ_AXP_SM_TOTAL_MATCH_COUNTERr(unit, &regval));
   1247     LOG_CLI((BSL_META_U(unit,
   1248                         " AXP_SM_TOTAL_MATCH_COUNTER            = 0x%08x\n"), regval));
   1249     SOC_IF_ERROR_RETURN
   1250         (READ_AXP_SM_TOTAL_CROSS_SIG_FLAGS_COUNTERr(unit, &regval));
   1251     LOG_CLI((BSL_META_U(unit,
   1252                         " AXP_SM_TOTAL_CROSS_SIG_FLAGS_COUNTER  = 0x%08x\n"), regval));
   1253     SOC_IF_ERROR_RETURN(READ_AXP_SM_FRAGMENTS_RECEIVED_COUNTERr(unit, &regval));
   1254     LOG_CLI((BSL_META_U(unit,
   1255                         " AXP_SM_FRAGMENTS_RECEIVED_COUNTER     = 0x%08x\n"), regval));
   1256     SOC_IF_ERROR_RETURN(READ_AXP_SM_IN_PACKET_ERROR_COUNTERr(unit, &regval));
   1257     LOG_CLI((BSL_META_U(unit,
   1258                         " AXP_SM_IN_PACKET_ERROR_COUNTER        = 0x%08x\n"), regval));
   1259     SOC_IF_ERROR_RETURN(READ_AXP_SM_FLOW_TRACKER_ERROR_COUNTERr(unit, &regval));
   1260     LOG_CLI((BSL_META_U(unit,
   1261                         " AXP_SM_FLOW_TRACKER_ERROR_COUNTER     = 0x%08x\n"), regval));
   1262     SOC_IF_ERROR_RETURN
   1263         (READ_AXP_SM_PACKET_LENGTH_ERROR_COUNTERr(unit, &regval));
   1264     LOG_CLI((BSL_META_U(unit,
   1265                         " AXP_SM_PACKET_LENGTH_ERROR_COUNTER    = 0x%08x\n"), regval));
   1266     SOC_IF_ERROR_RETURN(READ_AXP_SM_L4_CHECKSUM_ERROR_COUNTERr(unit, &regval));
   1267     LOG_CLI((BSL_META_U(unit,
   1268                         " AXP_SM_L4_CHECKSUM_ERROR_COUNTER      = 0x%08x\n"), regval));
   1269     SOC_IF_ERROR_RETURN
   1270         (READ_AXP_SM_FLOW_DONE_PACKET_DROP_COUNTERr(unit, &regval));
   1271     LOG_CLI((BSL_META_U(unit,
   1272                         " AXP_SM_FLOW_DONE_PACKET_DROP_COUNTER  = 0x%08x\n"), regval));
   1273     SOC_IF_ERROR_RETURN
   1274         (READ_AXP_SM_FLOW_TIMESTAMP_ERROR_COUNTERr(unit, &regval));
   1275     LOG_CLI((BSL_META_U(unit,
   1276                         " AXP_SM_FLOW_TIMESTAMP_ERROR_COUNTER   = 0x%08x\n"), regval));
   1277     SOC_IF_ERROR_RETURN
   1278         (READ_AXP_SM_FLOW_PACKET_NUM_ERROR_COUNTERr(unit, &regval));
   1279     LOG_CLI((BSL_META_U(unit,
   1280                         " AXP_SM_FLOW_PACKET_NUM_ERROR_COUNTER  = 0x%08x\n"), regval));
   1281     SOC_IF_ERROR_RETURN(READ_AXP_SM_ECC_ERROR_COUNTERr(unit, &regval));
   1282     LOG_CLI((BSL_META_U(unit,
   1283                         " AXP_SM_ECC_ERROR_COUNTER              = 0x%08x\n"), regval));
   1284 
   1285     return BCM_E_NONE;
   1286 }
   1287 
   1288 int
   1289 _bcm_tr3_regex_config_set(int unit, bcm_regex_config_t *config)
   1290 {
   1291     int max_flows, payload_depth, inspect_num_pkt, rv;
   1292     _bcm_tr3_regex_device_info_t *device;
   1293     _bcm_tr3_ctr_mode_t ctr_mode;
   1294     uint32 field_val;
   1295     uint32 regval;
   1296 
   1297     if ((device = REGEX_INFO(unit)) == NULL) {
   1298         return BCM_E_INIT;
   1299     }
   1300 
   1301     if (!config) {
   1302         return BCM_E_PARAM;
   1303     }
   1304 
   1305     /*
   1306     Set mode for REGEX usage
   1307     */
   1308 
   1309     if (config->flags & BCM_REGEX_USE_POLICY_ID) {
   1310         device->info->flags |= BCM_REGEX_USE_POLICY_ID;
   1311     }
   1312     else {
   1313         device->info->flags &= ~BCM_REGEX_USE_POLICY_ID;
   1314     }
   1315 
   1316 
   1317     /*
   1318      * Adjust encodings.
   1319      */
   1320     max_flows = ((config->max_flows < 0) || 
   1321                  (_encode_max_flow(config->max_flows) == -1)) ? 
   1322                 BCM_TR3_MAX_FLOWS : config->max_flows;
   1323 
   1324     if (config->flags & BCM_REGEX_PER_DIRECTION_COUNTER_ENABLE) {
   1325         if (config->max_flows < 0) {
   1326             max_flows = BCM_TR3_MAX_FLOWS/2;
   1327         } else {
   1328             if (max_flows > (BCM_TR3_MAX_FLOWS/2)) {
   1329                 return BCM_E_RESOURCE;
   1330             } 
   1331         } 
   1332     }
   1333 
   1334     payload_depth = (config->payload_depth <= 0) ?
   1335                 BCM_TR3_MAX_PAYLOAD_DEPTH : config->payload_depth;
   1336 
   1337     inspect_num_pkt = (config->inspect_num_pkt <= 0) ?
   1338                 BCM_TR3_MAX_PKT_TO_SME : config->inspect_num_pkt;
   1339 
   1340     /* validate params */
   1341     if ((config->max_flows > BCM_TR3_MAX_FLOWS) ||
   1342         (config->payload_depth > BCM_TR3_MAX_PAYLOAD_DEPTH) ||
   1343         (config->inspect_num_pkt > BCM_TR3_MAX_PKT_TO_SME)) {
   1344         return BCM_E_PARAM;
   1345     }
   1346 
   1347     /* set MACSA/DA */
   1348     if (config->flags & BCM_REGEX_CONFIG_ENABLE) {
   1349         field_val = (config->dst_mac[0] << 8) |    /* MAC-DA[47:40] */
   1350                     (config->dst_mac[1]);          /* MAC-DA[39:32] */
   1351         SOC_IF_ERROR_RETURN(READ_FT_RESULT_DA_MSr(unit, &regval));
   1352         soc_reg_field_set(unit, FT_RESULT_DA_MSr, &regval, DAf, field_val);
   1353         SOC_IF_ERROR_RETURN(WRITE_FT_RESULT_DA_MSr(unit, regval));
   1354 
   1355         field_val = (config->dst_mac[2] << 24) |    /* MAC-DA[31:24] */
   1356                     (config->dst_mac[3] << 16) |    /* MAC-DA[23:16] */
   1357                     (config->dst_mac[4] << 8) |     /* MAC-DA[15:8] */
   1358                     (config->dst_mac[5]);           /* MAC-DA[7:0] */
   1359 
   1360         regval = 0;
   1361         soc_reg_field_set(unit, FT_RESULT_DA_LSr, &regval, DAf, field_val);
   1362         SOC_IF_ERROR_RETURN(WRITE_FT_RESULT_DA_LSr(unit, regval));
   1363 
   1364         regval = 0;
   1365         field_val = (config->dst_mac[0] << 24) |    /* MAC-DA[47:40] */
   1366                     (config->dst_mac[1] << 16) |    /* MAC-DA[39:32] */
   1367                     (config->dst_mac[2] << 8) |     /* MAC-DA[31:24] */
   1368                     (config->dst_mac[3]);           /* MAC-DA[23:16] */
   1369         soc_reg_field_set(unit, AXP_SM_REPORT_PACKET_CONTROL0r, &regval, 
   1370                             UPPER_MACDAf, field_val);
   1371         SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REPORT_PACKET_CONTROL0r(unit, regval));
   1372 
   1373         regval = 0;
   1374         field_val = (config->dst_mac[4] << 8) | (config->dst_mac[5]);
   1375         soc_reg_field_set(unit, AXP_SM_REPORT_PACKET_CONTROL1r, &regval, 
   1376                             LOWER_MACDAf, field_val);
   1377         field_val = (config->src_mac[0] << 8) | (config->src_mac[1]);
   1378         soc_reg_field_set(unit, AXP_SM_REPORT_PACKET_CONTROL1r, &regval, 
   1379                             UPPER_MACSAf, field_val);
   1380         SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REPORT_PACKET_CONTROL1r(unit, regval));
   1381 
   1382         regval = 0;
   1383         field_val = ((config->src_mac[2] <<24) | 
   1384                      (config->src_mac[3] << 16) |
   1385                      (config->src_mac[4] << 8) |
   1386                      (config->src_mac[5]));
   1387         soc_reg_field_set(unit, AXP_SM_REPORT_PACKET_CONTROL2r, &regval, 
   1388                             LOWER_MACSAf, field_val);
   1389         SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REPORT_PACKET_CONTROL2r(unit, regval));
   1390 
   1391         regval = 0;
   1392         soc_reg_field_set(unit, FT_RESULT_LENGTH_TYPEr, &regval, ENABLEf, 1);
   1393         soc_reg_field_set(unit, FT_RESULT_LENGTH_TYPEr, &regval, 
   1394                           LENGTH_TYPEf, config->ethertype);
   1395         SOC_IF_ERROR_RETURN(WRITE_FT_RESULT_LENGTH_TYPEr(unit, regval));
   1396 
   1397         regval = 0;
   1398         soc_reg_field_set(unit, AXP_SM_REPORT_PACKET_CONTROL3r, &regval, 
   1399                           VLANf, 1);
   1400         soc_reg_field_set(unit, AXP_SM_REPORT_PACKET_CONTROL3r, &regval, 
   1401                           ETHER_TYPEf, config->ethertype);
   1402         SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REPORT_PACKET_CONTROL3r(unit, regval));
   1403     }
   1404 
   1405     /* Set Reports */
   1406     SOC_IF_ERROR_RETURN(READ_FT_EVENT_CONFIGr(unit, &regval));
   1407     if (config->flags & BCM_REGEX_CONFIG_ENABLE) {
   1408         soc_reg_field_set(unit, FT_EVENT_CONFIGr, &regval, NEW_FLOWf, 
   1409                           ((config->report_flags & (BCM_REGEX_REPORT_NEW | BCM_REGEX_REPORT_ALL)) ? 1 : 0));
   1410         soc_reg_field_set(unit, FT_EVENT_CONFIGr, &regval, RESf,
   1411                           ((config->report_flags & (BCM_REGEX_REPORT_MATCHED | BCM_REGEX_REPORT_ALL)) ? 1 : 0));
   1412         soc_reg_field_set(unit, FT_EVENT_CONFIGr, &regval, RETIREDf,
   1413                           ((config->report_flags & (BCM_REGEX_REPORT_END | BCM_REGEX_REPORT_ALL)) ? 1 : 0));
   1414     } else {
   1415         soc_reg_field_set(unit, FT_EVENT_CONFIGr, &regval, NEW_FLOWf, 0);
   1416         soc_reg_field_set(unit, FT_EVENT_CONFIGr, &regval, RESf, 0);
   1417         soc_reg_field_set(unit, FT_EVENT_CONFIGr, &regval, RETIREDf, 0);
   1418     }
   1419     SOC_IF_ERROR_RETURN(WRITE_FT_EVENT_CONFIGr(unit, regval));
   1420    
   1421     SOC_IF_ERROR_RETURN(READ_FT_AGE_CONTROLr(unit,&regval));
   1422     if (config->flags & BCM_REGEX_CONFIG_AGING) {
   1423         soc_reg_field_set(unit, FT_AGE_CONTROLr, &regval, AGE_ENABLEf, 
   1424                     ((config->inactivity_timeout_usec >= 0) ? 1 : 0));
   1425     }
   1426     else {
   1427         soc_reg_field_set(unit, FT_AGE_CONTROLr, &regval, AGE_ENABLEf, 0);
   1428     }
   1429     soc_reg_field_set(unit, FT_AGE_CONTROLr, &regval, INDEXf, 0);
   1430     SOC_IF_ERROR_RETURN(WRITE_FT_AGE_CONTROLr(unit, regval));
   1431 
   1432     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit,&regval));
   1433     soc_reg_field_set(unit, FT_CONFIGr, &regval, MAX_BYTESf, 
   1434                                                      payload_depth);
   1435     soc_reg_field_set(unit, FT_CONFIGr, &regval, MAX_PKTSf, 
   1436                                                     inspect_num_pkt);
   1437     soc_reg_field_set(unit, FT_CONFIGr, &regval, TABLE_SIZEf, 
   1438                                         _encode_max_flow(max_flows));
   1439     /*
   1440      * Initializing INT_SME_ENABLEf to 0 so that the flow tracker does
   1441      * not direct packets to Signature Matching block even before any 
   1442      * signatures are configured.
   1443      */
   1444     soc_reg_field_set(unit, FT_CONFIGr, &regval, INT_SME_ENABLEf, 0);
   1445     soc_reg_field_set(unit, FT_CONFIGr, &regval, EXT_SME_ENABLEf, 0);
   1446 
   1447     soc_reg_field_set(unit, FT_CONFIGr, &regval, FT_DISABLEf, 
   1448                 (config->flags & BCM_REGEX_CONFIG_ENABLE) ? 0 : 1);
   1449 
   1450     soc_reg_field_set(unit, FT_CONFIGr, &regval, TCP_END_DETECTf, 
   1451           (config->flags & BCM_REGEX_CONFIG_TCP_SESSION_DETECT) ? 1 : 0);
   1452 
   1453     soc_reg_field_set(unit, FT_CONFIGr, &regval, NORMALIZEf, 1);
   1454 
   1455     soc_reg_field_set(unit, FT_CONFIGr, &regval, IPV4_CREATE_ENf,
   1456                     (config->flags & BCM_REGEX_CONFIG_IP4) ? 1 : 0);
   1457 
   1458     soc_reg_field_set(unit, FT_CONFIGr, &regval, IPV6_CREATE_ENf,
   1459                         (config->flags & BCM_REGEX_CONFIG_IP6) ? 1 : 0);
   1460 
   1461     SOC_IF_ERROR_RETURN(WRITE_FT_CONFIGr(unit,regval));
   1462 
   1463     field_val = (config->flags & BCM_REGEX_CONFIG_ENABLE) ? 1 : 0;
   1464     SOC_IF_ERROR_RETURN(
   1465                 READ_AXP_SM_SIGNATURE_MATCH_CONTROLr(unit, &regval));
   1466     soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1467                                              &regval, ENABLEf, field_val);
   1468     soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1469                                                 &regval, RESETf, 0);
   1470     if (field_val) {
   1471         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1472                           &regval, STATE_TABLE_ACCESS_LIMIT_ENABLEf, 1);
   1473         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1474                          &regval, DROP_ON_L4_CHECKSUM_ERROR_ENABLEf, 1);
   1475         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1476                        &regval, DROP_ON_PACKET_LENGTH_ERROR_ENABLEf, 0);
   1477         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1478                       &regval, DROP_ON_FLOW_TIMESTAMP_ERROR_ENABLEf, 1);
   1479         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1480                                 &regval, MAX_BYTE_INSPECTED_ENABLEf, 1);
   1481         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1482                                 &regval, MAX_BYTE_INSPECTEDf, payload_depth);
   1483         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1484                         &regval, DROP_ON_FLOW_PKT_NUM_ERROR_ENABLEf, 1);
   1485         soc_reg_field_set(unit, AXP_SM_SIGNATURE_MATCH_CONTROLr, 
   1486                       &regval, DROP_ON_FLOW_TABLE_ECC_ERROR_ENABLEf, 0);
   1487     }
   1488     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_SIGNATURE_MATCH_CONTROLr(unit, 
   1489                                                             regval));
   1490 
   1491     SOC_IF_ERROR_RETURN(READ_AUX_ARB_CONTROL_2r(unit, &regval));
   1492     soc_reg_field_set(unit, AUX_ARB_CONTROL_2r, &regval, 
   1493                             FT_REFRESH_ENABLEf, field_val);
   1494     SOC_IF_ERROR_RETURN(WRITE_AUX_ARB_CONTROL_2r(unit, regval));
   1495 
   1496 
   1497     ctr_mode = _bcm_tr3_ctr_mode_get(unit);
   1498     LOG_INFO(BSL_LS_BCM_REGEX,
   1499              (BSL_META_U(unit,
   1500                          "Counter mode = %d, config flags = 0x%x\n"),
   1501               ctr_mode, config->flags));
   1502     if (config->flags & (BCM_REGEX_COUNTER_ENABLE | 
   1503                          BCM_REGEX_PER_DIRECTION_COUNTER_ENABLE)) {
   1504         /*
   1505         if ((ctr_mode != _CTR_MODE_NONE) &&
   1506             (((config->flags & BCM_REGEX_PER_DIRECTION_COUNTER_ENABLE) &&
   1507               (ctr_mode != _CTR_MODE_PER_LEG)) || 
   1508              (ctr_mode != _CTR_MODE_BOTH_LEG))) {
   1509             */
   1510         if (ctr_mode != _CTR_MODE_NONE) {
   1511             LOG_INFO(BSL_LS_BCM_REGEX,
   1512                      (BSL_META_U(unit,
   1513                                  "Setting counter mode to none and unmapping\n")));
   1514             _bcm_tr3_ctr_mode_set(unit, _CTR_MODE_NONE);
   1515             _bcm_tr3_flex_ctr_pool_unmap(unit);
   1516         }
   1517         ctr_mode = (config->flags & BCM_REGEX_PER_DIRECTION_COUNTER_ENABLE) ? 
   1518                                     _CTR_MODE_PER_LEG : _CTR_MODE_BOTH_LEG;
   1519         LOG_INFO(BSL_LS_BCM_REGEX,
   1520                  (BSL_META_U(unit,
   1521                              "Counter mode = %d, setting and mapping flex counters\n"),
   1522                   ctr_mode));
   1523         rv = _bcm_tr3_flex_ctr_pool_map(unit, ctr_mode, max_flows);
   1524         if(rv != BCM_E_NONE)
   1525             return rv;
   1526         _bcm_tr3_ctr_mode_set(unit, ctr_mode);
   1527     } else {
   1528         /* free up the pools */
   1529         LOG_INFO(BSL_LS_BCM_REGEX,
   1530                  (BSL_META_U(unit,
   1531                              "No counters enabled, setting counter mode to none and unmapping\n")));
   1532         _bcm_tr3_ctr_mode_set(unit, _CTR_MODE_NONE);
   1533         _bcm_tr3_flex_ctr_pool_unmap(unit);
   1534     }
   1535 
   1536     return BCM_E_NONE;
   1537 }
   1538 
   1539 int 
   1540 _bcm_tr3_regex_config_get(int unit, bcm_regex_config_t *config)
   1541 {
   1542     _bcm_tr3_ctr_mode_t ctr_mode;
   1543     uint32 field_val;
   1544     uint32 regval;
   1545     _bcm_tr3_regex_device_info_t *device;
   1546 
   1547     if (!config) {
   1548         return BCM_E_PARAM;
   1549     }
   1550 
   1551     if ((device = REGEX_INFO(unit)) == NULL) {
   1552         return BCM_E_INIT;
   1553     }
   1554 
   1555     /* Set Reports */
   1556     SOC_IF_ERROR_RETURN(READ_FT_EVENT_CONFIGr(unit, &regval));
   1557     if (soc_reg_field_get(unit, FT_EVENT_CONFIGr, regval, NEW_FLOWf)) {
   1558         config->report_flags |= BCM_REGEX_REPORT_NEW;
   1559     }
   1560     if (soc_reg_field_get(unit, FT_EVENT_CONFIGr, regval, RESf)) {
   1561         config->report_flags |= BCM_REGEX_REPORT_MATCHED;
   1562     }
   1563     if (soc_reg_field_get(unit, FT_EVENT_CONFIGr, regval, RETIREDf)) {
   1564         config->report_flags |= BCM_REGEX_REPORT_END;
   1565     }
   1566     
   1567 
   1568     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit,&regval));
   1569     config->payload_depth = 
   1570             soc_reg_field_get(unit, FT_CONFIGr, regval, MAX_BYTESf);
   1571     config->inspect_num_pkt = 
   1572             soc_reg_field_get(unit, FT_CONFIGr, regval, MAX_PKTSf);
   1573     config->max_flows = _decode_max_flow(soc_reg_field_get(unit, 
   1574                                         FT_CONFIGr, regval, TABLE_SIZEf));
   1575 
   1576     config->flags = 0;
   1577     if (soc_reg_field_get(unit, FT_CONFIGr, regval, FT_DISABLEf) == 0) {
   1578         config->flags |= BCM_REGEX_CONFIG_ENABLE;
   1579     }
   1580 
   1581     if (soc_reg_field_get(unit, FT_CONFIGr, regval, TCP_END_DETECTf)) {
   1582         config->flags |= BCM_REGEX_CONFIG_TCP_SESSION_DETECT;
   1583     }
   1584 
   1585     if (soc_reg_field_get(unit, FT_CONFIGr, regval, IPV4_CREATE_ENf)) {
   1586         config->flags |= BCM_REGEX_CONFIG_IP4;
   1587     }
   1588 
   1589     if (soc_reg_field_get(unit, FT_CONFIGr, regval, IPV6_CREATE_ENf)) {
   1590         config->flags |= BCM_REGEX_CONFIG_IP6;
   1591     }
   1592 
   1593     /* get MACSA/DA */
   1594     SOC_IF_ERROR_RETURN(READ_AXP_SM_REPORT_PACKET_CONTROL0r(unit, &regval));
   1595     field_val = soc_reg_field_get(unit, AXP_SM_REPORT_PACKET_CONTROL0r, 
   1596                                     regval, UPPER_MACDAf);
   1597     config->dst_mac[0] = ((field_val >> 24) & 0xff);
   1598     config->dst_mac[1] = ((field_val >> 16) & 0xff);
   1599     config->dst_mac[2] = ((field_val >> 8) & 0xff);
   1600     config->dst_mac[3] = (field_val & 0xff);
   1601 
   1602     SOC_IF_ERROR_RETURN(READ_AXP_SM_REPORT_PACKET_CONTROL2r(unit, &regval));
   1603     field_val = soc_reg_field_get(unit, AXP_SM_REPORT_PACKET_CONTROL2r, 
   1604                                   regval, LOWER_MACSAf);
   1605     config->src_mac[2] = ((field_val >> 24) & 0xff);
   1606     config->src_mac[3] = ((field_val >> 16) & 0xff);
   1607     config->src_mac[4] = ((field_val >> 8) & 0xff);
   1608     config->src_mac[5] = (field_val & 0xff);
   1609 
   1610     SOC_IF_ERROR_RETURN(READ_AXP_SM_REPORT_PACKET_CONTROL1r(unit, &regval));
   1611     field_val = soc_reg_field_get(unit, AXP_SM_REPORT_PACKET_CONTROL1r, regval, 
   1612                                   UPPER_MACSAf);
   1613     config->src_mac[0] = ((field_val >> 8) & 0xff);
   1614     config->src_mac[1] = (field_val & 0xff);
   1615 
   1616     field_val = soc_reg_field_get(unit, AXP_SM_REPORT_PACKET_CONTROL1r, 
   1617                                  regval, LOWER_MACDAf);
   1618     config->dst_mac[4] = ((field_val >> 8) & 0xff);
   1619     config->dst_mac[5] = (field_val & 0xff);
   1620 
   1621     SOC_IF_ERROR_RETURN(READ_FT_RESULT_LENGTH_TYPEr(unit, &regval));
   1622     config->ethertype = soc_reg_field_get(unit, 
   1623                      FT_RESULT_LENGTH_TYPEr, regval, LENGTH_TYPEf);
   1624 
   1625     ctr_mode = _bcm_tr3_ctr_mode_get(unit);
   1626     if (ctr_mode == _CTR_MODE_PER_LEG) {
   1627         config->flags |= BCM_REGEX_PER_DIRECTION_COUNTER_ENABLE;
   1628     } else if (ctr_mode == _CTR_MODE_BOTH_LEG) {
   1629         config->flags |= BCM_REGEX_COUNTER_ENABLE;
   1630     }
   1631 
   1632     /*
   1633     Get REGEX usage mode
   1634     */
   1635 
   1636     if (device->info->flags & BCM_REGEX_USE_POLICY_ID) {
   1637         config->flags |= BCM_REGEX_USE_POLICY_ID;
   1638     }
   1639 
   1640     return BCM_E_NONE;
   1641 }
   1642 
   1643 int _bcm_tr3_regex_exclude_delete_all(int unit)
   1644 {
   1645     int rv;
   1646 
   1647     BCM_REGEX_LOCK(unit);
   1648     rv = soc_mem_clear(unit, FT_L4PORTm, COPYNO_ALL, TRUE);
   1649     BCM_REGEX_UNLOCK(unit);
   1650     return rv;
   1651 }
   1652 
   1653 #define BCM_TR3_PROTOCOL_TCP        6
   1654 #define BCM_TR3_PROTOCOL_UDP        17
   1655 
   1656 STATIC
   1657 int _bcm_tr3_valid_protocol(int unit, uint16 protocol)
   1658 {
   1659     if ((protocol == BCM_TR3_PROTOCOL_TCP) || 
   1660         (protocol == BCM_TR3_PROTOCOL_UDP)) {
   1661         return BCM_E_NONE;
   1662     }
   1663     return BCM_E_UNAVAIL;
   1664 }
   1665 
   1666 #define BCM_TR3_EXCLUDE_OP_INSERT   0
   1667 #define BCM_TR3_EXCLUDE_OP_DELETE   1
   1668 
   1669 #define BCM_TR3_NUM_PROCOL          2
   1670 
   1671 #define BCM_TR3_MAX_EXCLUDE_RANGE   8
   1672 
   1673 typedef struct _bcm_tr3_l4_range_s {
   1674     uint16 start;
   1675     uint16 end;
   1676     int    tcp;
   1677     int    any;
   1678 } _bcm_tr3_l4_range_t;
   1679 
   1680 STATIC int
   1681 _bcm_tr3_regex_sort_ranges(void *a, void *b)
   1682 {
   1683     _bcm_tr3_l4_range_t *ia, *ib;
   1684     ia = (_bcm_tr3_l4_range_t*) a;
   1685     ib = (_bcm_tr3_l4_range_t*) b;
   1686     return ia->start - ib->start; 
   1687 }
   1688 
   1689 #define _TR3_REGEX_E_RANGE(s,t,a,b)     \
   1690             ((s))->tcp = (t);             \
   1691             ((s))->any = 0;               \
   1692             ((s))->start = (a);           \
   1693             ((s))->end = (b);
   1694 
   1695 #define _TR3_REGEX_E_RANGE_START(r)     (r)->start
   1696 #define _TR3_REGEX_E_RANGE_END(r)     (r)->end
   1697 #define _TR3_REGEX_E_RANGE_PROTOCOL(r)     (r)->tcp
   1698                 
   1699 
   1700 STATIC int
   1701 _bcm_tr3_merge_ranges(_bcm_tr3_l4_range_t *range, int *count)
   1702 {
   1703     int in_cnt = *count, i, j, o_cnt = in_cnt, pr1, pr2;
   1704 
   1705     _shr_sort(range, in_cnt, sizeof(_bcm_tr3_l4_range_t), 
   1706                              _bcm_tr3_regex_sort_ranges);
   1707 
   1708     for (i = 0; i < o_cnt - 1;) {
   1709         pr1 = _TR3_REGEX_E_RANGE_PROTOCOL(&range[i]);
   1710         pr2 = _TR3_REGEX_E_RANGE_PROTOCOL(&range[i + 1]);
   1711 
   1712         if ((_TR3_REGEX_E_RANGE_START(&range[i]) == 
   1713                             _TR3_REGEX_E_RANGE_START(&range[i+1])) &&
   1714             (_TR3_REGEX_E_RANGE_END(&range[i]) == 
   1715                             _TR3_REGEX_E_RANGE_END(&range[i+1]))) {
   1716             if (pr1 != pr2) {
   1717                 range[i].any = 1;
   1718             }
   1719 
   1720             o_cnt -= 1;
   1721             for (j = i+1; j < o_cnt; j++) {
   1722                 range[j] = range[j+1];
   1723             }
   1724         } else if (pr1 != pr2) {
   1725             i++;
   1726             continue;
   1727         } else if (_TR3_REGEX_E_RANGE_END(&range[i]) >= 
   1728                             _TR3_REGEX_E_RANGE_START(&range[i+1])) {
   1729             if (_TR3_REGEX_E_RANGE_END(&range[i+1]) > 
   1730                             _TR3_REGEX_E_RANGE_END(&range[i])) {
   1731                 _TR3_REGEX_E_RANGE(&range[i],
   1732                                    _TR3_REGEX_E_RANGE_PROTOCOL(&range[i]),
   1733                                    _TR3_REGEX_E_RANGE_START(&range[i]),
   1734                                    _TR3_REGEX_E_RANGE_END(&range[i+1]));
   1735             } else {
   1736                 _TR3_REGEX_E_RANGE(&range[i],
   1737                                    _TR3_REGEX_E_RANGE_PROTOCOL(&range[i]),
   1738                                    _TR3_REGEX_E_RANGE_START(&range[i]),
   1739                                    _TR3_REGEX_E_RANGE_END(&range[i]));
   1740             }
   1741 
   1742             o_cnt -= 1;
   1743             for (j = i+1; j < o_cnt; j++) {
   1744                 range[j] = range[j+1];
   1745             }
   1746         } else {
   1747             i++;
   1748         }
   1749     }
   1750     *count = o_cnt;
   1751     return 0;
   1752 }
   1753 
   1754 STATIC
   1755 int _bcm_tr3_exclude_op(int unit, int op, int tcp,
   1756                         uint16 l4start, uint16 l4end)
   1757 {
   1758     _bcm_tr3_l4_range_t *tcomp, *ucomp, *fcomp, *prange;
   1759     uint16 this_start, this_end, num_te;
   1760     int     rv = BCM_E_NONE, *pnum;
   1761     int     i, j, tcpi=0, udpi = 0, num_entry=0;
   1762     ft_l4port_entry_t   ftl4m;
   1763 
   1764     num_entry = soc_mem_index_count(unit, FT_L4PORTm);
   1765     num_te = (num_entry * 2) + 1;
   1766     tcomp = sal_alloc(sizeof(_bcm_tr3_l4_range_t) * num_te, "sortee");
   1767     ucomp = sal_alloc(sizeof(_bcm_tr3_l4_range_t) * num_te, "sorteeu");
   1768     fcomp = sal_alloc(sizeof(_bcm_tr3_l4_range_t) * 2 * num_te, "sorteef");
   1769 
   1770     /* read all the entries so that we can rebalnace the entries ie
   1771      * merge/split based on ranges. */
   1772     for (i=0; i < num_entry; i++) {
   1773         if (READ_FT_L4PORTm(unit, MEM_BLOCK_ANY, i, &ftl4m)) {
   1774             goto done;
   1775         }
   1776 
   1777         if (soc_mem_field32_get(unit, FT_L4PORTm, &ftl4m, VALIDf) == 0) {
   1778             break;
   1779         }
   1780         
   1781         this_start = soc_mem_field32_get(unit, FT_L4PORTm, 
   1782                                          &ftl4m, L4_PORT_LOWERf);
   1783         this_end = soc_mem_field32_get(unit, FT_L4PORTm, 
   1784                                          &ftl4m, L4_PORT_UPPERf);
   1785 
   1786         if (soc_mem_field32_get(unit, FT_L4PORTm, &ftl4m, TCPf)) {
   1787             _TR3_REGEX_E_RANGE(&tcomp[tcpi], 1, this_start, this_end);
   1788             tcpi++;
   1789         }
   1790         if (soc_mem_field32_get(unit, FT_L4PORTm, &ftl4m, UDPf)) {
   1791             _TR3_REGEX_E_RANGE(&ucomp[udpi], 0, this_start, this_end);
   1792             udpi++;
   1793         }
   1794     }
   1795 
   1796     if (tcp) {
   1797         prange = tcomp;
   1798         pnum = &tcpi;
   1799     } else {
   1800         prange = ucomp;
   1801         pnum = &udpi;
   1802     }
   1803 
   1804     if (op == BCM_TR3_EXCLUDE_OP_INSERT) {
   1805         /* insert the new range at the end */
   1806         _TR3_REGEX_E_RANGE(&prange[*pnum], tcp, l4start, l4end);
   1807         *pnum += 1;
   1808     }
   1809 
   1810     _bcm_tr3_merge_ranges(tcomp, &tcpi);
   1811     _bcm_tr3_merge_ranges(ucomp, &udpi);
   1812 
   1813 
   1814     if (op == BCM_TR3_EXCLUDE_OP_DELETE) {
   1815         for (i = 0; i < *pnum; i++) {
   1816             if ((l4start <= _TR3_REGEX_E_RANGE_START(&prange[i])) &&
   1817                 (l4end >= _TR3_REGEX_E_RANGE_START(&prange[i]))) {
   1818                 for (j = i+1; j < *pnum; j++) {
   1819                     prange[j - 1] = prange[j];
   1820                 }
   1821                 *pnum -= 1;
   1822                 i -= 1;
   1823             } else if ((l4start > _TR3_REGEX_E_RANGE_START(&prange[i])) &&
   1824                        (l4end >= _TR3_REGEX_E_RANGE_END(&prange[i]))) {
   1825                 _TR3_REGEX_E_RANGE(&prange[i], tcp, 
   1826                     _TR3_REGEX_E_RANGE_START(&prange[i]), l4start - 1);
   1827             } else if ((l4end >= _TR3_REGEX_E_RANGE_START(&prange[i])) &&
   1828                        (l4end < _TR3_REGEX_E_RANGE_END(&prange[i]))) {
   1829                 _TR3_REGEX_E_RANGE(&prange[i], tcp, l4end + 1,
   1830                                     _TR3_REGEX_E_RANGE_END(&prange[i]));
   1831             } else if ((l4start > _TR3_REGEX_E_RANGE_START(&prange[i])) &&
   1832                        (l4end < _TR3_REGEX_E_RANGE_END(&prange[i]))) {
   1833                 /* make space */
   1834                 for (j = *pnum - 1; j > i; j--) {
   1835                     prange[j+1] = prange[j];
   1836                 }
   1837                 _TR3_REGEX_E_RANGE(&prange[i+1], tcp, l4end + 1, 
   1838                                 _TR3_REGEX_E_RANGE_END(&prange[i]));
   1839                 _TR3_REGEX_E_RANGE(&prange[i], tcp, 
   1840                         _TR3_REGEX_E_RANGE_START(&prange[i]), l4start - 1);
   1841 
   1842                 *pnum += 1;
   1843                 i += 1;
   1844             }
   1845         }
   1846     }
   1847 
   1848     /* merge tcp and  udp entries */
   1849 
   1850     if ((tcpi + udpi) == 0) {
   1851         rv = _bcm_tr3_regex_exclude_delete_all(unit);
   1852         goto done;
   1853     }
   1854 
   1855     j = 0;
   1856     for (i = 0; i < tcpi; i++) {
   1857         fcomp[j++] = tcomp[i];
   1858     }
   1859 
   1860     for (i = 0; i < udpi; i++) {
   1861         fcomp[j++] = ucomp[i];
   1862     }
   1863     
   1864     _bcm_tr3_merge_ranges(fcomp, &j);
   1865     if (j > num_entry) {
   1866         return BCM_E_RESOURCE;
   1867     }
   1868 
   1869     for (i = 0; i < j; i++) {
   1870         sal_memset(&ftl4m, 0, sizeof(ft_l4port_entry_t));
   1871         soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, VALIDf, 1);
   1872         soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, 
   1873                L4_PORT_LOWERf, _TR3_REGEX_E_RANGE_START(&fcomp[i]));
   1874         soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, 
   1875                L4_PORT_UPPERf, _TR3_REGEX_E_RANGE_END(&fcomp[i]));
   1876 
   1877         if (fcomp[i].any == 1) {
   1878             soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, TCPf, 1);
   1879             soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, UDPf, 1);
   1880         } else if (_TR3_REGEX_E_RANGE_PROTOCOL(&fcomp[i])) {
   1881             soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, TCPf, 1);
   1882         } else {
   1883             soc_mem_field32_set(unit, FT_L4PORTm, &ftl4m, UDPf, 1);
   1884         }
   1885         rv = WRITE_FT_L4PORTm(unit, MEM_BLOCK_ANY, i, &ftl4m);
   1886         if (BCM_FAILURE(rv)) {
   1887             goto done;
   1888         }
   1889     }
   1890 
   1891     for (; i < num_entry; i++) {
   1892         sal_memset(&ftl4m, 0, sizeof(ft_l4port_entry_t));
   1893         rv = WRITE_FT_L4PORTm(unit, MEM_BLOCK_ANY, i, &ftl4m);
   1894         if (BCM_FAILURE(rv)) {
   1895             goto done;
   1896         }
   1897     }
   1898 
   1899 done:
   1900     sal_free(tcomp);
   1901     sal_free(ucomp);
   1902     sal_free(fcomp);
   1903 
   1904     return rv;
   1905 }
   1906 
   1907 int _bcm_tr3_regex_exclude_add(int unit, uint8 protocol, 
   1908                               uint16 l4_start, uint16 l4_end)
   1909 {
   1910     int rv;
   1911     if (_bcm_tr3_valid_protocol(unit, protocol)) {
   1912         return BCM_E_PARAM;
   1913     }
   1914     
   1915     BCM_REGEX_LOCK(unit);
   1916     rv = _bcm_tr3_exclude_op(unit, BCM_TR3_EXCLUDE_OP_INSERT, 
   1917                         (protocol == BCM_TR3_PROTOCOL_TCP) ? 1 : 0,
   1918                         l4_start, l4_end);
   1919     BCM_REGEX_UNLOCK(unit);
   1920     return rv;
   1921 }
   1922 
   1923 int _bcm_tr3_regex_exclude_delete(int unit, uint8 protocol, 
   1924                               uint16 l4_start, uint16 l4_end)
   1925 {
   1926     int rv;
   1927 
   1928     if (_bcm_tr3_valid_protocol(unit, protocol)) {
   1929         return BCM_E_PARAM;
   1930     }
   1931     
   1932     BCM_REGEX_LOCK(unit);
   1933     rv = _bcm_tr3_exclude_op(unit, BCM_TR3_EXCLUDE_OP_DELETE, 
   1934                         (protocol == BCM_TR3_PROTOCOL_TCP) ? 1 : 0,
   1935                         l4_start, l4_end);
   1936     BCM_REGEX_UNLOCK(unit);
   1937     return rv;
   1938 }
   1939 
   1940 int _bcm_tr3_regex_exclude_get(int unit, int array_size, uint8 *protocol, 
   1941                         uint16 *l4low, uint16 *l4high, int *array_count)
   1942 {
   1943     int i, valid, nume = 0;
   1944     uint16  this_start, this_end;
   1945     ft_l4port_entry_t   ftl4m;
   1946 
   1947     *array_count = 0;
   1948 
   1949     BCM_REGEX_LOCK(unit);
   1950     for (i=0; (i < soc_mem_index_count(unit, FT_L4PORTm)) && 
   1951                                   (nume < array_size); i++) {
   1952         SOC_IF_ERROR_RETURN(READ_FT_L4PORTm(unit, MEM_BLOCK_ANY, i, &ftl4m));
   1953         valid = soc_mem_field32_get(unit, FT_L4PORTm, &ftl4m, VALIDf);
   1954         if (!valid) {
   1955             continue;
   1956         }
   1957         
   1958         this_start = soc_mem_field32_get(unit, FT_L4PORTm, 
   1959                                          &ftl4m, L4_PORT_LOWERf);
   1960         this_end = soc_mem_field32_get(unit, FT_L4PORTm, 
   1961                                          &ftl4m, L4_PORT_UPPERf);
   1962 
   1963         if (soc_mem_field32_get(unit, FT_L4PORTm, &ftl4m, TCPf)) {
   1964             l4low[nume] = this_start;
   1965             l4high[nume] = this_end;
   1966             protocol[nume] = BCM_TR3_PROTOCOL_TCP;
   1967             nume++;
   1968             if (nume == array_size) {
   1969                 break;
   1970             }
   1971         }
   1972         if (soc_mem_field32_get(unit, FT_L4PORTm, &ftl4m, UDPf)) {
   1973             l4low[nume] = this_start;
   1974             l4high[nume] = this_end;
   1975             protocol[nume] = BCM_TR3_PROTOCOL_UDP;
   1976             nume++;
   1977             if (nume == array_size) {
   1978                 break;
   1979             }
   1980         }
   1981     }
   1982 
   1983     BCM_REGEX_UNLOCK(unit);
   1984 
   1985     *array_count = nume;
   1986     return BCM_E_NONE;
   1987 }
   1988 
   1989 /* remap tables */
   1990 static uint8 *cmap_lower_tbl = NULL;
   1991 
   1992 /* tr3 engine */
   1993 STATIC int _bcm_tr3_engine_reset(int unit, int eng_idx)
   1994 {
   1995     uint32  regval;
   1996 
   1997     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, &regval));
   1998 
   1999     /* reset the regex engines and clear out the state memories. */
   2000     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, 
   2001                       &regval, REGEX_RESETf, 1);
   2002     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, 
   2003                       &regval, REGEX_ENABLEf, 0);
   2004     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, regval));
   2005     return BCM_E_NONE;
   2006 }
   2007 
   2008 /* CHECK : this just returns start of dfa , change name */
   2009 STATIC int _bcm_tr3_get_engine_info(int unit, int eng_idx, 
   2010                                     _bcm_regex_engine_obj_t *pinfo)
   2011 {
   2012     uint32  regval;
   2013 
   2014     pinfo->flags = 0;
   2015     pinfo->req_lsz = 0;
   2016     pinfo->from_line = -1;
   2017 
   2018     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, &regval));
   2019     if (soc_reg_field_get(unit, AXP_SM_REGEX_CONTROL0r, regval, REGEX_ENABLEf)) {
   2020         pinfo->flags = BCM_TR3_REGEX_ENGINE_ALLOC;
   2021         /* read the regex code pointers */
   2022         SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL1r(unit, eng_idx, &regval));
   2023         pinfo->from_line = soc_reg_field_get(unit, AXP_SM_REGEX_CONTROL1r, 
   2024                                              regval, REGEX_START_PTR0f);
   2025     }
   2026     return BCM_E_NONE;
   2027 }
   2028 
   2029 #define BCM_REGEX_SM_LINE2_OFFSET(l) ((l) * BCM_TR3_NUM_RV_PER_LINE)
   2030 
   2031 STATIC int 
   2032 _bcm_tr3_engine_enable(int unit, _bcm_regex_engine_obj_t *pengine)
   2033 {
   2034     uint32  regval, regval1, start_addr;
   2035     int     eng_idx;
   2036 
   2037     eng_idx = pengine->hw_idx;
   2038 
   2039     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, &regval));
   2040     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval, REGEX_RESETf, 0);
   2041     if (soc_reg_field_get(unit, AXP_SM_REGEX_CONTROL0r, regval, REGEX_ENABLEf)) {
   2042     
   2043         soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval, REGEX_ENABLEf, 0);
   2044         SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, regval));
   2045     }
   2046 
   2047     /* program the regex program/state offsets. */
   2048     start_addr = BCM_REGEX_SM_LINE2_OFFSET(pengine->from_line);
   2049     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL1r(unit, eng_idx, &regval1));
   2050     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL1r, &regval1, REGEX_START_PTR0f,
   2051                       start_addr);
   2052     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL1r, &regval1, REGEX_START_PTR1f,
   2053                       start_addr);
   2054     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL1r(unit, eng_idx, regval1));
   2055 
   2056     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL2r(unit, eng_idx, &regval1));
   2057     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL2r, &regval1, REGEX_START_PTR3f,
   2058                       start_addr);
   2059     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL2r, &regval1, REGEX_START_PTR2f,
   2060                       start_addr);
   2061     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL2r(unit, eng_idx, regval1));
   2062 
   2063     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL3r(unit, eng_idx, &regval1));
   2064     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL3r, &regval1, REGEX_START_PTR4f,
   2065                       start_addr);
   2066     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL3r, &regval1, REGEX_START_PTR5f,
   2067                       start_addr);
   2068     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL3r(unit, eng_idx, regval1));
   2069 
   2070     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL4r(unit, eng_idx, &regval1));
   2071     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL4r, &regval1, REGEX_START_PTR7f,
   2072                       start_addr);
   2073     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL4r, &regval1, REGEX_START_PTR6f,
   2074                       start_addr);
   2075     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL4r(unit, eng_idx, regval1));
   2076 
   2077     /* enable the engine */
   2078     if (BCM_REGEX_CPS_ALLOCED(&pengine->cps)) {
   2079         start_addr = BCM_REGEX_SM_LINE2_OFFSET(pengine->cps.from_line);
   2080         soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval, 
   2081                             CONTEXT_BASE_PTRf, start_addr);
   2082     } else {
   2083         soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval, 
   2084                             CONTEXT_BASE_PTRf, 0);
   2085     }
   2086     
   2087     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval, REGEX_ENABLEf, 1);
   2088     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, regval));
   2089     return BCM_E_NONE;
   2090 }
   2091 
   2092 STATIC int _bcm_tr3_engine_disable(int unit, int eng_idx)
   2093 {
   2094     uint32  regval;
   2095 
   2096     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, &regval));
   2097     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval, REGEX_ENABLEf, 0);
   2098     SOC_IF_ERROR_RETURN(WRITE_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, regval));
   2099     return BCM_E_NONE;
   2100 }
   2101 
   2102 static bcm_regex_desc_t tr3_regex_info = { 8, 
   2103                                            4, 
   2104                                            4,
   2105                                            32,
   2106                                            0x0,
   2107                                            _bcm_tr3_engine_reset, 
   2108                                            _bcm_tr3_get_engine_info,
   2109                                            _bcm_tr3_engine_enable,
   2110                                            _bcm_tr3_engine_disable,
   2111                                          };
   2112 
   2113 #define BCM_REGEX_ENGINE_ID(u,i)  (((u)<<16) | (i))
   2114 #define BCM_REGEX_ENGINE_INDEX_FROM_ID(u,id)  ((id) & 0xffff)
   2115 
   2116 STATIC int
   2117 _bcm_tr3_find_engine(int unit, bcm_regex_engine_t engid,
   2118                         _bcm_regex_lengine_t** plengine)
   2119 {
   2120     int idx;
   2121     _bcm_tr3_regex_device_info_t *device;
   2122     _bcm_regex_lengine_t *lengine = NULL;
   2123     
   2124     device = REGEX_INFO(unit);
   2125 
   2126     if (!device) {
   2127         return BCM_E_UNAVAIL;
   2128     }
   2129 
   2130     idx = BCM_REGEX_ENGINE_INDEX_FROM_ID(unit, engid);
   2131 
   2132     if (idx >= BCM_TR3_NUM_ENGINE(device)) {
   2133         return BCM_E_PARAM;
   2134     }
   2135 
   2136     lengine = BCM_TR3_LOGICAL_ENGINE(device, idx);
   2137     if (!BCM_REGEX_ENGINE_ALLOCATED(lengine)) {
   2138         return BCM_E_NOT_FOUND;
   2139     }
   2140     *plengine = lengine;
   2141     return BCM_E_NONE;
   2142 }
   2143 
   2144 int 
   2145 _bcm_tr3_regex_engine_create(int unit, bcm_regex_engine_config_t *config, 
   2146                             bcm_regex_engine_t *engid)
   2147 {
   2148     int i;
   2149     _bcm_regex_lengine_t *lengine = NULL, *tmp;
   2150     _bcm_tr3_regex_device_info_t *device;
   2151    
   2152     device = REGEX_INFO(unit);
   2153     if (!device) {
   2154         return BCM_E_INIT;
   2155     }
   2156     
   2157     BCM_REGEX_LOCK(unit);
   2158     /* 
   2159      * When only Engine 0 is enabled the CSF table will not be enabled
   2160      * causing failure in chaining. Enabling from engine 1 and
   2161      * Engine 0 enabled at last
   2162      */  
   2163     for (i = 1; i < BCM_TR3_NUM_ENGINE(device); i++) {
   2164         tmp = BCM_TR3_LOGICAL_ENGINE(device, i);
   2165         if (BCM_REGEX_ENGINE_ALLOCATED(tmp)) {
   2166             continue;
   2167         }
   2168         BCM_REGEX_ENGINE_SET_ALLOCATED(tmp);
   2169         sal_memcpy(&tmp->config, config, sizeof(bcm_regex_engine_config_t));
   2170         lengine = tmp;
   2171         break;
   2172     }
   2173     if (i == BCM_TR3_NUM_ENGINE(device)) {
   2174         tmp = BCM_TR3_LOGICAL_ENGINE(device, 0);
   2175         if (!(BCM_REGEX_ENGINE_ALLOCATED(tmp))) {
   2176             BCM_REGEX_ENGINE_SET_ALLOCATED(tmp);
   2177             sal_memcpy(&tmp->config, config, sizeof(bcm_regex_engine_config_t));
   2178             lengine = tmp;
   2179         }
   2180     }
   2181     BCM_REGEX_UNLOCK(unit);
   2182     if (lengine) {
   2183         *engid = lengine->id;
   2184     }
   2185     return (lengine) ? BCM_E_NONE : BCM_E_RESOURCE;
   2186 }
   2187 
   2188 STATIC int
   2189 _bcm_tr3_regex_hw_engine_detach(int unit, _bcm_regex_engine_obj_t *pengine)
   2190 {
   2191     int num_alloc = 0, rv = BCM_E_NONE, i;
   2192     uint32 regval;
   2193     _bcm_regex_cps_obj_t *pcps;
   2194     _bcm_tr3_regex_device_info_t *device;
   2195     _bcm_regex_engine_obj_t *temp_pengine = NULL;
   2196 #if 0
   2197     _bcm_regexdb_cb_ua_t ua;
   2198 #endif
   2199     _bcm_regexdb_entry_t en;
   2200 
   2201     LOG_INFO(BSL_LS_BCM_REGEX,
   2202              (BSL_META_U(unit,
   2203                          "resetting engine..")));
   2204 
   2205     device = REGEX_INFO(unit);
   2206     if (!pengine || !BCM_REGEX_ENGINE_ALLOCATED(pengine)) {
   2207         return BCM_E_NONE;
   2208     }
   2209 
   2210     for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
   2211         temp_pengine = BCM_TR3_PHYSICAL_ENGINE(device, i);
   2212         if (BCM_REGEX_ENGINE_ALLOCATED(temp_pengine)) {
   2213             num_alloc++;
   2214         }
   2215     }
   2216 
   2217     if (num_alloc == 1) {
   2218         /*
   2219          * Detaching the last engine. INT_SME_ENABLEf is set to 0 here 
   2220          * so that the flow tracker does not direct packets to
   2221          * Signature Matching block
   2222          */
   2223         SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit,&regval));
   2224         soc_reg_field_set(unit, FT_CONFIGr, &regval, INT_SME_ENABLEf, 0);
   2225         SOC_IF_ERROR_RETURN(WRITE_FT_CONFIGr(unit,regval));
   2226     }
   2227 
   2228 
   2229     rv = BCM_REGEX_DISABLE_ENGINE(device, unit, pengine->hw_idx);
   2230 
   2231     if (SOC_FAILURE(rv)) {
   2232         if (num_alloc == 1) {
   2233             /*
   2234              * Detaching the last engine failed. INT_SME_ENABLEf is set
   2235              * back to 1 to let flow tracker direct packets to SME
   2236              */
   2237             SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit,&regval));
   2238             soc_reg_field_set(unit, FT_CONFIGr, &regval, INT_SME_ENABLEf, 1);
   2239             SOC_IF_ERROR_RETURN(WRITE_FT_CONFIGr(unit,regval));
   2240         }
   2241         return rv;
   2242     }
   2243 
   2244     /*
   2245      * unavail any check slots which depend on signatures in this engine.
   2246      */
   2247 #if 0
   2248     ua.avail = 0;
   2249     ua.setid = BCM_TR3_SPECIAL_SLOT;
   2250 #endif
   2251     en.engid = pengine->hw_idx;
   2252     _bcm_regexdb_traverse(unit, BCM_REGEXDB_MATCH_ENGINE_ID, &en, 
   2253                            _bcm_regexdb_engine_unavail_cb, NULL);
   2254 
   2255     bcm_regexdb_delete_by_engine_id(unit, pengine->hw_idx);
   2256 
   2257     pcps = BCM_TR3_CPS_INFO(device, pengine->hw_idx);
   2258     _bcm_tr3_free_cps(unit, pcps);
   2259 
   2260     BCM_REGEX_ENGINE_SET_UNALLOCATED(pengine);
   2261     pengine->from_line = -1;
   2262     pengine->flags = 0;
   2263     pengine->req_lsz = 0;
   2264 
   2265     return BCM_E_NONE;
   2266 }
   2267 
   2268 int 
   2269 _bcm_tr3_regex_engine_destroy(int unit, bcm_regex_engine_t engid)
   2270 {
   2271     int     idx, rv = BCM_E_NONE;
   2272     _bcm_tr3_regex_device_info_t *device;
   2273     _bcm_regex_lengine_t *lengine = NULL;
   2274     _bcm_regex_engine_obj_t *pengine = NULL;
   2275 
   2276     device = REGEX_INFO(unit);
   2277 
   2278     if (!device) {
   2279         return BCM_E_UNAVAIL;
   2280     }
   2281 
   2282     BCM_REGEX_LOCK(unit);
   2283 
   2284     idx = BCM_REGEX_ENGINE_INDEX_FROM_ID(unit, engid);
   2285     lengine = BCM_TR3_LOGICAL_ENGINE(device, idx);
   2286     if (!lengine) {
   2287         return BCM_E_PARAM;
   2288     }
   2289 
   2290     if (!BCM_REGEX_ENGINE_ALLOCATED(lengine)) {
   2291         BCM_REGEX_UNLOCK(unit);
   2292         return BCM_E_PARAM;
   2293     }
   2294     pengine = lengine->physical_engine;
   2295 
   2296     /*
   2297      * Disable the HW dfa engine and detach from logical engine 
   2298  */
   2299     rv = _bcm_tr3_regex_hw_engine_detach(unit, pengine);
   2300     if (SOC_FAILURE(rv)) {
   2301         BCM_REGEX_UNLOCK(unit);
   2302         return rv;
   2303     }
   2304     lengine->physical_engine = NULL;
   2305 
   2306     BCM_REGEX_ENGINE_SET_UNALLOCATED(lengine);
   2307     lengine->physical_engine = NULL;
   2308 
   2309     return rv;
   2310 }
   2311 
   2312 int 
   2313 _bcm_tr3_regex_engine_traverse(int unit, bcm_regex_engine_traverse_cb cb, 
   2314                                 void *user_data)
   2315 {
   2316     _bcm_tr3_regex_device_info_t *device;
   2317     bcm_regex_engine_config_t     config;
   2318     _bcm_regex_lengine_t *lengine = NULL;
   2319     int i, rv = BCM_E_NONE, eng_idx;
   2320     uint32  regval, fval;
   2321 
   2322     if ((device = REGEX_INFO(unit)) == NULL) {
   2323         return BCM_E_INIT;
   2324     }
   2325 
   2326     BCM_REGEX_LOCK(unit);
   2327 
   2328     for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
   2329         sal_memset(&config, 0, sizeof(config));
   2330         lengine = BCM_TR3_LOGICAL_ENGINE(device, i);
   2331         if (!BCM_REGEX_ENGINE_ALLOCATED(lengine)) {
   2332             continue;
   2333         }
   2334 
   2335         /* continue if no physical engine attached. */
   2336         if (lengine->physical_engine == NULL) {
   2337             rv = cb(unit, lengine->id, &config, user_data);
   2338 #ifdef BCM_CB_ABORT_ON_ERR
   2339             if (rv) {
   2340                 break;
   2341             }
   2342 #endif
   2343             continue;
   2344         }
   2345         
   2346 
   2347         /* read the config from HW */
   2348         eng_idx = lengine->physical_engine->hw_idx;
   2349         rv = READ_AXP_SM_REGEX_CONTROL0r(unit, eng_idx, &regval);
   2350         if (SOC_FAILURE(rv)) {
   2351             goto fail;
   2352         }
   2353         fval = soc_reg_field_get(unit, AXP_SM_REGEX_CONTROL0r,
   2354                                     regval, CONTEXT_STORAGE_MODEf);
   2355         if (fval == 1) {
   2356             config.flags |= BCM_REGEX_ENGINE_CONFIG_MULTI_PACKET;
   2357         }
   2358         rv = cb(unit, lengine->id, &config, user_data);
   2359 #ifdef BCM_CB_ABORT_ON_ERR
   2360         if (rv) {
   2361             break;
   2362         }
   2363 #endif
   2364     }
   2365 
   2366 fail:
   2367     BCM_REGEX_UNLOCK(unit);
   2368     return rv;
   2369 }
   2370 
   2371 int 
   2372 _bcm_tr3_regex_engine_get(int unit, bcm_regex_engine_t engid, 
   2373                             bcm_regex_engine_config_t *config)
   2374 {
   2375     _bcm_regex_lengine_t *lengine = NULL;
   2376     uint32  regval, fval;
   2377 
   2378     SOC_IF_ERROR_RETURN(_bcm_tr3_find_engine(unit, engid, &lengine));
   2379 
   2380     sal_memcpy(config, &lengine->config, sizeof(bcm_regex_engine_config_t));
   2381 
   2382     if (lengine->physical_engine) {
   2383         /* read the config from HW */
   2384         SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, 
   2385                                 lengine->physical_engine->hw_idx, &regval));
   2386         fval = soc_reg_field_get(unit, AXP_SM_REGEX_CONTROL0r,
   2387                                  regval, CONTEXT_STORAGE_MODEf);
   2388         if (fval == 1) {
   2389             config->flags |= BCM_REGEX_ENGINE_CONFIG_MULTI_PACKET;
   2390         }
   2391     }
   2392     return BCM_E_NONE;
   2393 }
   2394 
   2395 STATIC soc_mem_t
   2396 _bcm_tr3_get_axp_sm_memory(int unit, int tile)
   2397 {
   2398     soc_mem_t mem = -1;
   2399 
   2400     switch (tile) {
   2401         case 0: mem = AXP_SM_STATE_TABLE_MEM0m; break;
   2402         case 1: mem = AXP_SM_STATE_TABLE_MEM1m; break;
   2403         case 2: mem = AXP_SM_STATE_TABLE_MEM2m; break;
   2404         case 3: mem = AXP_SM_STATE_TABLE_MEM3m; break;
   2405         case 4: mem = AXP_SM_STATE_TABLE_MEM4m; break;
   2406         case 5: mem = AXP_SM_STATE_TABLE_MEM5m; break;
   2407         case 6: mem = AXP_SM_STATE_TABLE_MEM6m; break;
   2408         case 7: mem = AXP_SM_STATE_TABLE_MEM7m; break;
   2409         default: break;
   2410     }
   2411     return mem;
   2412 }
   2413 
   2414 /* CHECK */
   2415 #define BCM_TR3_ADD_TRANSITION_TO_STATE(t,s,c)    \
   2416             (t)[(s)] = (((t)[(s)] & 0xc000) | (((t)[(s)] & 0x3fff) + (c)))
   2417 
   2418 #define BCM_TR3_SET_STATE_TRANSITION_OFFSET(t,s,o)    \
   2419             (t)[(s)] = (((t)[(s)] & 0xc000) | ((o) & 0x3fff))
   2420 
   2421 #define BCM_TR3_NUM_STATE_TRANSITION(t,s)   ((t)[(s)] & 0x3fff)
   2422 
   2423 #define BCM_TR3_NUM_STATE_OFFSET(t,s)   ((t)[(s)] & 0x3fff)
   2424 
   2425 #define BCM_TR3_STATE_OFFSET(t,s)   ((t)[(s)] & 0x3fff)
   2426 
   2427 #define BCM_TR3_DFA_STATE_F_FINAL   0x1
   2428 #define BCM_TR3_SET_STATE_FLAGS(t,s,f)    \
   2429             (t)[(s)] = ((t)[(s)] & 0x3fff) | (((f) & 3) << 14)
   2430 
   2431 #define BCM_TR3_GET_STATE_FLAGS(t,s,f)  (((t)[(s)] >> 14) & 3)
   2432 
   2433 #define _BCM_TR3_SET_DEFAULT_POLICY 0x01
   2434 
   2435 extern int _regex_policers_hw_alloc(int unit, _regex_policy_t *p_ent);
   2436 
   2437 STATIC int
   2438 _bcm_tr3_install_action_policy(int unit, bcm_regex_match_t *match, 
   2439                             uint32 flags, int *policy_index)
   2440 {
   2441     int rv;
   2442     uint32 hw_index;
   2443     ft_policy_entry_t policy;
   2444     void *entries[1];
   2445     _regex_policy_t policy_ent;
   2446     _field_policer_t *f_pl;
   2447     _field_entry_policer_t *f_ent_pl;
   2448 
   2449     sal_memset(&policy, 0, sizeof(ft_policy_entry_t));
   2450 
   2451     if (match->action_flags & BCM_REGEX_MATCH_ACTION_DROP) {
   2452         soc_mem_field32_set(unit, FT_POLICYm, &policy, R_DROPf, 1);
   2453         soc_mem_field32_set(unit, FT_POLICYm, &policy, Y_DROPf, 1);
   2454         soc_mem_field32_set(unit, FT_POLICYm, &policy, G_DROPf, 1);
   2455     }
   2456 
   2457     if (match->action_flags & BCM_REGEX_MATCH_ACTION_COPY_TO_CPU) {
   2458         soc_mem_field32_set(unit, FT_POLICYm, &policy, R_COPY_TO_CPUf, 1);
   2459         soc_mem_field32_set(unit, FT_POLICYm, &policy, Y_COPY_TO_CPUf, 1);
   2460         soc_mem_field32_set(unit, FT_POLICYm, &policy, G_COPY_TO_CPUf, 1);
   2461     }
   2462 
   2463     if (match->action_flags & BCM_REGEX_MATCH_ACTION_INT_PRI) {
   2464         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2465                             R_COS_INT_PRIf, match->new_int_pri);
   2466         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2467                             Y_COS_INT_PRIf, match->new_int_pri);
   2468         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2469                             G_COS_INT_PRIf, match->new_int_pri);
   2470     }
   2471 
   2472     if (match->action_flags & BCM_REGEX_MATCH_ACTION_DSCP) {
   2473         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2474                                     R_NEW_DSCPf, match->new_dscp);
   2475         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2476                                     Y_NEW_DSCPf, match->new_dscp);
   2477         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2478                                     G_NEW_DSCP_TOSf, match->new_dscp);
   2479     }
   2480 
   2481     if (match->action_flags & BCM_REGEX_MATCH_ACTION_PKT_PRI) {
   2482         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2483                                     G_NEW_PKT_PRIf, match->new_pkt_pri);
   2484         soc_mem_field32_set(unit, FT_POLICYm, &policy, G_CHANGE_PKT_PRIf, 1);
   2485         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2486                                     Y_NEW_PKT_PRIf, match->new_pkt_pri);
   2487         soc_mem_field32_set(unit, FT_POLICYm, &policy, Y_CHANGE_PKT_PRIf, 1);
   2488         soc_mem_field32_set(unit, FT_POLICYm, &policy, 
   2489                                     R_NEW_PKT_PRIf, match->new_pkt_pri);
   2490         soc_mem_field32_set(unit, FT_POLICYm, &policy, R_CHANGE_PKT_PRIf, 1);
   2491     }
   2492 
   2493     if (match->policer_id > 0) {
   2494         /* Create a dummy policy entry which is needed for the policer APIs below. */
   2495         memset(&policy_ent, 0, sizeof(policy_ent));
   2496         f_ent_pl = &policy_ent.policer[0];
   2497         f_ent_pl->pid = match->policer_id;
   2498         rv = _bcm_regex_policer_get(unit, f_ent_pl->pid, &f_pl);
   2499         BCM_IF_ERROR_RETURN(rv);
   2500         f_ent_pl->flags = f_pl->hw_flags;
   2501         /* Normally this flag will be set when the policer is attached to a policy. */
   2502         f_ent_pl->flags |= _FP_POLICER_VALID;
   2503         /* Calculate the HW index and install the policer in the meter table. */
   2504         _regex_policers_hw_alloc(unit, &policy_ent);
   2505         BCM_IF_ERROR_RETURN(rv);
   2506         /* Update the policy memory with the policer info. */
   2507         rv = _regex_tr3_policer_action_set(unit, &policy_ent, policy.entry_data);
   2508         BCM_IF_ERROR_RETURN(rv);
   2509     }
   2510 
   2511     if (flags & _BCM_TR3_SET_DEFAULT_POLICY) {
   2512         rv = soc_mem_write(unit, FT_POLICYm, MEM_BLOCK_ALL, 0, &policy);
   2513     } else {
   2514         entries[0] = &policy;
   2515         rv = soc_profile_mem_add(unit, _bcm_tr3_ft_policy_profile[unit], entries,
   2516                                  1, &hw_index);
   2517         if (!rv) {
   2518             *policy_index = hw_index;
   2519         }
   2520     }
   2521     return rv;
   2522 }
   2523 
   2524 STATIC int
   2525 _bcm_tr3_set_match_action(int unit, int eng_idx, bcm_regex_match_t *match, 
   2526                           int *match_idx, int match_set_id, int match_chk_id, int sigid)
   2527 {
   2528     uint32 *alloc_bmap, fval;
   2529     _bcm_tr3_regex_device_info_t *device;
   2530     int     i, j, idx, policy_index = -1, rv = BCM_E_NONE;
   2531     axp_sm_match_table_mem0_entry_t match_entry;
   2532     int     defer_enable = 0;
   2533     ft_age_profile_entry_t ftpm;
   2534     int     age_profile = -1, ticks, max_index, anc_end = 0, ptlen;
   2535     soc_mem_t mem;
   2536 
   2537     device = REGEX_INFO(unit);
   2538 
   2539     ptlen = sal_strlen(match->pattern);
   2540     if (ptlen && (match->pattern[ptlen - 1] == '$') &&
   2541         ((ptlen > 1) ? (match->pattern[ptlen - 2] != '\\') : 1)) {
   2542         anc_end = 1;
   2543     }
   2544 
   2545     /*
   2546      * defer enabling the entry if check slot is not determined yet,
   2547      * either the corresponding setid signature is not programmed.
   2548      */
   2549      if (match_chk_id == BCM_TR3_SPECIAL_SLOT) {
   2550         defer_enable = 1;
   2551      }
   2552 
   2553     /*
   2554      * Alloc action index entry.
   2555      */
   2556     if ((match->action_flags & BCM_REGEX_MATCH_ACTION_IGNORE) == 0) {
   2557         if (device->info->flags & BCM_REGEX_USE_POLICY_ID) {
   2558             /*
   2559             TBD: Check that the policy_id actually exists and is installed
   2560             (getting the hardware ID would be sufficient, similar to what
   2561             is already returned by _bcm_tr3_install_action_policy().  If
   2562             not, return BCM_E_PARAM
   2563             */
   2564         }
   2565         else {
   2566         SOC_IF_ERROR_RETURN(_bcm_tr3_install_action_policy(unit, match, 0,
   2567                                                         &policy_index));
   2568         }
   2569         /* if the flow is just ignore type, program the entry and enable
   2570          * it now even if check slot is pernding */
   2571          defer_enable = 0;
   2572     }
   2573 
   2574     alloc_bmap = BCM_TR3_MATCH_BMAP_PTR(unit, device, eng_idx);
   2575     mem = AXP_SM_MATCH_TABLE_MEM0m + BCM_REGEX_ENG2MATCH_MEMIDX(unit,eng_idx);
   2576     idx = -1;
   2577     for (i = 0; i < BCM_TR3_MATCH_BMAP_BSZ; i++) {
   2578         if (alloc_bmap[i] == 0xffffffff) {
   2579             continue;
   2580         }
   2581         for (j = 0; j < 32; j++) {
   2582             if (alloc_bmap[i] & (1 << j)) {
   2583                 continue;
   2584             }
   2585             idx = (i*32) + j;
   2586             break;
   2587         }
   2588         break;
   2589     }
   2590 
   2591     if (idx < 0) {
   2592         rv = BCM_E_NOT_FOUND;
   2593         goto fail;
   2594     }
   2595 
   2596     /* mark the entry as alloced */
   2597     alloc_bmap[idx/32] |= (1 << (idx % 32));
   2598 
   2599     sal_memset(&match_entry, 0, sizeof(match_entry));
   2600 
   2601     soc_mem_field32_set(unit, mem, &match_entry, CHECK_LAST_BYTE_ANCHORf, anc_end);
   2602 
   2603     soc_mem_field32_set(unit, mem, &match_entry, REPORT_SIGNATURE_IDf, sigid);
   2604 
   2605     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PROTOCOLf, 3);
   2606 
   2607     if (match->action_flags & BCM_REGEX_MATCH_ACTION_IGNORE) {
   2608         soc_mem_field32_set(unit, mem, &match_entry, REPORT_KEEP_FLOWf, 0);
   2609         soc_mem_field32_set(unit, mem, &match_entry, MATCH_REPORT_LEVELf, 2);
   2610     } else {
   2611         soc_mem_field32_set(unit, mem, &match_entry, MATCH_REPORT_LEVELf, 3);
   2612         soc_mem_field32_set(unit, mem, &match_entry, REPORT_KEEP_FLOWf, 1);
   2613         soc_mem_field32_set(unit, mem, &match_entry, REPORT_APPLY_ACTIONf, 1);
   2614         if ((device->info->flags & BCM_REGEX_USE_POLICY_ID) == 0) {
   2615         soc_mem_field32_set(unit, mem, &match_entry, REPORT_ACTION_INDEXf, 
   2616                                                                 policy_index);
   2617     }
   2618         else
   2619         {
   2620             soc_mem_field32_set(unit, mem, &match_entry, REPORT_ACTION_INDEXf,
   2621                                                                     match->policy_id);
   2622         }
   2623     }
   2624 
   2625     if (match_set_id >= 0) {
   2626         soc_mem_field32_set(unit, mem, 
   2627                           &match_entry, MATCH_CROSS_SIG_FLAG_SETf, 1);
   2628         soc_mem_field32_set(unit, mem, 
   2629                         &match_entry, MATCH_CROSS_SIG_FLAG_INDEXf, match_set_id);
   2630         soc_mem_field32_set(unit, mem, &match_entry, MATCH_REPORT_LEVELf, 0);
   2631     }
   2632 
   2633     if ((match_chk_id >= 0) && (match_chk_id != BCM_TR3_SPECIAL_SLOT)) {
   2634         soc_mem_field32_set(unit, mem, 
   2635                             &match_entry, CHECK_CROSS_SIG_FLAG_IS_SETf, 1);
   2636 
   2637         soc_mem_field32_set(unit, mem, 
   2638                             &match_entry, CHECK_CROSS_SIG_FLAG_INDEXf, match_chk_id);
   2639     }
   2640 
   2641     if (match->action_flags & BCM_REGEX_MATCH_ACTION_NOTIFY_HEADER_ONLY) {
   2642         soc_mem_field32_set(unit, mem, &match_entry, REPORT_PACKET_HEADER_ONLYf, 1);
   2643     }
   2644 
   2645     if (match->action_flags & BCM_REGEX_MATCH_ACTION_NOTIFY_COPY_TO_CPU) {
   2646         soc_mem_field32_set(unit, mem, &match_entry, REPORT_COPY_TO_CPUf, 1);
   2647     }
   2648 
   2649     if (match->payload_length_min > 0) {
   2650         soc_mem_field32_set(unit, mem, &match_entry, 
   2651                             CHECK_L4_PAYLOAD_LENGTH_MINf, 
   2652                             (match->payload_length_min & 0x3fff));
   2653     } else {
   2654         soc_mem_field32_set(unit, mem, &match_entry, 
   2655                             CHECK_L4_PAYLOAD_LENGTH_MINf, 0);
   2656     }
   2657 
   2658     if (match->payload_length_max >= 0) {
   2659         soc_mem_field32_set(unit, mem, &match_entry, 
   2660                             CHECK_L4_PAYLOAD_LENGTH_MAXf, 
   2661                             (match->payload_length_max & 0x3fff));
   2662     } else {
   2663         soc_mem_field32_set(unit, mem, &match_entry, 
   2664                             CHECK_L4_PAYLOAD_LENGTH_MAXf, 0x3fff);
   2665     }
   2666 
   2667     if (match->flags & BCM_REGEX_MATCH_PKT_SEQUENCE) {
   2668         soc_mem_field32_set(unit, mem, &match_entry, CHECK_CONTIGUOUS_FLOWf, 1);
   2669     } else {
   2670         soc_mem_field32_set(unit, mem, &match_entry, CHECK_CONTIGUOUS_FLOWf, 0);
   2671     }
   2672 
   2673     fval = 3;
   2674     if (match->flags & (BCM_REGEX_MATCH_TO_SERVER | BCM_REGEX_MATCH_TO_CLIENT)) {
   2675         fval = (match->flags & (BCM_REGEX_MATCH_TO_SERVER | BCM_REGEX_MATCH_TO_CLIENT));
   2676     }
   2677     soc_mem_field32_set(unit, mem, &match_entry, CHECK_PKT_DIRECTIONf, fval);
   2678 
   2679     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_MAXf, 0xffff);
   2680     if (match->flags & BCM_REGEX_MATCH_L4_SRC_PORT) {
   2681         soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_MINf, 
   2682                                                         match->l4_src_port_low);
   2683         soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_MAXf, 
   2684                                                         match->l4_src_port_high);
   2685     } 
   2686     if (match->flags & BCM_REGEX_MATCH_L4_DST_PORT) {
   2687         soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_MINf, 
   2688                                                         match->l4_dst_port_low);
   2689         soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_MAXf, 
   2690                                                         match->l4_dst_port_high);
   2691     }
   2692     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_VALUEf, 0xffff);
   2693     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_MASKf, 0);
   2694     if ((match->flags & BCM_REGEX_MATCH_L4_DST_PORT) && 
   2695         (match->flags & BCM_REGEX_MATCH_L4_SRC_PORT)) {
   2696         fval = 3;
   2697     } else if (match->flags & BCM_REGEX_MATCH_L4_DST_PORT) {
   2698         fval = 2;
   2699     } else if (match->flags & BCM_REGEX_MATCH_L4_SRC_PORT) {
   2700         fval = 1;
   2701     } else { 
   2702         fval = 3;
   2703     }
   2704     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PORT_SELECTf, fval);
   2705 
   2706     fval = (match->flags & BCM_REGEX_MATCH_MULTI_FLOW) ? 1 : 0;
   2707     soc_mem_field32_set(unit, mem, &match_entry, REPORT_HTTP_PERSISTENTf, fval);
   2708 
   2709     soc_mem_field32_set(unit, mem, &match_entry, REPORT_INACTIVITY_INDEXf, 0);
   2710 
   2711     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PAYLOAD_LENGTH_MAXf, 
   2712                                                                         0x3fff);
   2713 
   2714     soc_mem_field32_set(unit, mem, &match_entry, CHECK_L4_PAYLOAD_LENGTH_MINf, 0);
   2715 
   2716     soc_mem_field32_set(unit, mem, &match_entry, MATCH_PRIORITYf, match->priority);
   2717     soc_mem_field32_set(unit, mem, &match_entry, CHECK_FIRST_PACKETf, 
   2718                                                 (match->sequence ? 0 : 1));
   2719 
   2720     soc_mem_field32_set(unit, mem, &match_entry, MATCH_ENTRY_VALIDf, 
   2721                                                             !defer_enable);
   2722    
   2723     if (match->inactivity_timeout_usec >= 0)  {
   2724         ticks = match->inactivity_timeout_usec/_REGEX_SESSION_AGE_PROFILE_TICKS_US;
   2725         max_index = soc_mem_index_max(unit, FT_AGE_PROFILEm);
   2726         for (i = max_index; i >= 0; i--) {
   2727             SOC_IF_ERROR_RETURN(READ_FT_AGE_PROFILEm(unit, MEM_BLOCK_ALL,
   2728                                                         i, &ftpm));
   2729             if (ticks >= soc_mem_field32_get(unit, 
   2730                                     FT_AGE_PROFILEm, &ftpm, TIMEOUTf)) {
   2731                 age_profile = (i == max_index) ? i : i + 1;
   2732                 break;
   2733             }
   2734         }
   2735     }
   2736     if (age_profile == -1) {
   2737         age_profile = soc_mem_index_max(unit, FT_AGE_PROFILEm);
   2738     }
   2739    
   2740     soc_mem_field32_set(unit, mem, &match_entry, 
   2741                                     REPORT_INACTIVITY_INDEXf, age_profile);
   2742 
   2743     *match_idx = idx;
   2744 
   2745     SOC_IF_ERROR_RETURN(
   2746             soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &match_entry));
   2747 
   2748     /* add to db */
   2749     LOG_INFO(BSL_LS_BCM_REGEX,
   2750              (BSL_META_U(unit,
   2751                          "Add entry to DB, sig=%d match=%d p=%d r=%d ms=%d mc=%d\n"),
   2752               sigid, match->match_id, match->provides, 
   2753               match->requires, match_set_id, match_chk_id));
   2754     BCM_IF_ERROR_RETURN(bcm_regexdb_add_entry(unit, idx, eng_idx, match->match_id, 
   2755                     sigid, match->provides, match->requires, match_set_id, match_chk_id));
   2756 
   2757     return BCM_E_NONE;
   2758 
   2759 fail:
   2760     return rv;
   2761 }
   2762 
   2763 /*
   2764 cmap is used to keep track of all character classes used for
   2765 transitions.  If all 0-255 characters are used in a transition,
   2766 then no final "default" transition is necessary
   2767 */
   2768 
   2769 STATIC void _regex_cmap_init(_bcm_tr3_regex_data_t *cd)
   2770 {
   2771     memset(cd->cmap, 0, sizeof(cd->cmap));
   2772 }
   2773 
   2774 STATIC void _regex_cmap_add(_bcm_tr3_regex_data_t *cd, int from_c, int to_c)
   2775 {
   2776     int i;
   2777 
   2778     for (i = from_c; i <= to_c; i++) {
   2779         cd->cmap[i / BYTES2BITS(1)] |= 1 << (i % BYTES2BITS(1));
   2780     }
   2781 }
   2782 
   2783 STATIC int _regex_cmap_is_full(_bcm_tr3_regex_data_t *cd)
   2784 {
   2785     int i;
   2786 
   2787     /* Check to see if there are transitions for all characters */
   2788     for (i = 0; i < sizeof(cd->cmap); i++) {
   2789         if (cd->cmap[i] != 0xff) {
   2790             return 0;
   2791         }
   2792     }
   2793 
   2794     return 1;
   2795 }
   2796 
   2797 STATIC regex_cb_error_t 
   2798 _bcm_regex_dfa_cb_calc_size(uint32 flags, int match_idx, int in_state, 
   2799                            int from_c, int to_c, int to_state, 
   2800                            int num_dfa_state, void *user_data)
   2801 {
   2802     _bcm_tr3_regex_data_t *cd = (_bcm_tr3_regex_data_t*)user_data;
   2803 
   2804     if (flags & DFA_TRAVERSE_START) {
   2805         cd->compile_size = 0;
   2806         cd->last_state = 0;
   2807         cd->last_flags = 0;
   2808         _regex_cmap_init(cd);
   2809         return REGEX_CB_OK;
   2810     }
   2811 
   2812     if (flags & DFA_TRAVERSE_END) {
   2813         return REGEX_CB_OK;
   2814     }
   2815 
   2816     /* if last state is not same as this state, insert goto IDLE state if necessary*/
   2817     if (cd->last_state != in_state) {
   2818         /*
   2819         LOG_INFO(BSL_LS_BCM_REGEX,
   2820                  (BSL_META("State %s %d:\n"),
   2821                   (match_idx>=0)? "[FINAL]" : ""),
   2822                   in_state));
   2823         */
   2824         /*
   2825         If last state is not same as this state, insert goto IDLE state
   2826         for non-final states, and only if all characters don't already
   2827         have a transition
   2828         */
   2829         if ((cd->last_flags & DFA_STATE_FINAL) == 0) {
   2830             if (0 == _regex_cmap_is_full(cd)) {
   2831         cd->compile_size++;
   2832     }
   2833         }
   2834         _regex_cmap_init(cd);
   2835     }
   2836 
   2837     /*
   2838     if (to_state >= 0)
   2839     {
   2840         LOG_INFO(BSL_LS_BCM_REGEX,
   2841                  (BSL_META("\t %d -> %d [%d-%d];\n"),
   2842                   in_state, to_state, from_c, to_c));
   2843     }
   2844     */
   2845     cd->compile_size++;
   2846     cd->last_state = in_state;
   2847     cd->last_flags = flags;
   2848     _regex_cmap_add(cd, from_c, to_c);
   2849     return REGEX_CB_OK;
   2850 }
   2851 
   2852 STATIC int
   2853 _bcm_tr3_regex_rv_fields_get(int unit, int eoff, soc_field_t *minf,
   2854                              soc_field_t *maxf, soc_field_t *matchf,
   2855                              soc_field_t *ptrf)
   2856 {
   2857     *minf = RV_MIN0f + eoff;
   2858     *maxf = RV_MAX0f + eoff;
   2859     *matchf = RV_MATCHID0f + eoff;
   2860     *ptrf = RV_PTR0f + eoff;
   2861     return 0;
   2862 }
   2863 
   2864 STATIC int
   2865 _bcm_tr3_regex_rv_set(int unit, soc_mem_t mem,
   2866                       axp_sm_state_table_mem0_entry_t *line,
   2867                       uint8 fromc, uint8 toc, int eoff,
   2868                       uint32 jump_off, int match_index)
   2869 {
   2870     soc_field_t minf, maxf, matchf, ptrf;
   2871 
   2872     _bcm_tr3_regex_rv_fields_get(unit, eoff, &minf, &maxf, &matchf, &ptrf);
   2873     
   2874     soc_mem_field32_set(unit, mem, line, minf, fromc);
   2875     soc_mem_field32_set(unit, mem, line, maxf, toc);
   2876     if (match_index >= 0) {
   2877         soc_mem_field32_set(unit, mem, line, matchf, match_index);
   2878     } else {
   2879         soc_mem_field32_set(unit, mem, line, ptrf, jump_off);
   2880     }
   2881     return 0;
   2882 }
   2883 
   2884 STATIC int
   2885 _bcm_tr3_regex_rv_get(int unit, soc_mem_t mem,
   2886                       axp_sm_state_table_mem0_entry_t *line,
   2887                       uint8 *fromc, uint8 *toc, int eoff,
   2888                       uint32 *jump_off, int *match_index)
   2889 {
   2890     soc_field_t minf, maxf, matchf, ptrf;
   2891 
   2892     _bcm_tr3_regex_rv_fields_get(unit, eoff, &minf, &maxf, &matchf, &ptrf);
   2893     
   2894     *match_index = -1;
   2895     *jump_off = 0xffff;
   2896     *fromc = soc_mem_field32_get(unit, mem, line, minf);
   2897     *toc = soc_mem_field32_get(unit, mem, line, maxf);
   2898     if ((*fromc == 255) && ((*toc == 1) || (*toc == 2))) {
   2899         *match_index = soc_mem_field32_get(unit, mem, line, matchf);
   2900     } else {
   2901         *jump_off = soc_mem_field32_get(unit, mem, line, ptrf);
   2902     }
   2903     return 0;
   2904 }
   2905 
   2906 STATIC regex_cb_error_t 
   2907 _bcm_tr3_regex_compiler_preprocess_cb(uint32 flags, int match_idx, 
   2908                             int in_state, int from_c, int to_c, int to_state, 
   2909                            int num_dfa_state, void *user_data)
   2910 {
   2911     _bcm_tr3_regex_data_t *cd = (_bcm_tr3_regex_data_t*)user_data;
   2912     int insert_fail = 0, i, offset, size, num_state;
   2913 
   2914     if (flags & DFA_TRAVERSE_START) {
   2915         cd->last_state = 0;
   2916         cd->last_flags = 0;
   2917         _regex_cmap_init(cd);
   2918         return REGEX_CB_OK;
   2919     } else if (flags & DFA_TRAVERSE_END) {
   2920         /* adjust the per state table data to make generate the
   2921          * offset table. */
   2922         offset = BCM_TR3_NUM_STATE_TRANSITION(cd->per_state_data, 0);
   2923         BCM_TR3_SET_STATE_TRANSITION_OFFSET(cd->per_state_data,0,0);
   2924         for (i=1; i<num_dfa_state; i++) {
   2925             num_state = BCM_TR3_NUM_STATE_TRANSITION(cd->per_state_data, i);
   2926             BCM_TR3_SET_STATE_TRANSITION_OFFSET(cd->per_state_data,i,offset);
   2927             offset += num_state;
   2928         }
   2929         return REGEX_CB_OK;
   2930     }
   2931 
   2932     /*
   2933     If last state is not same as this state, insert goto IDLE state
   2934     for non-final states, and only if all characters don't already
   2935     have a transition
   2936     */
   2937     if (cd->last_state != in_state) {
   2938         if ((cd->last_flags & DFA_STATE_FINAL) == 0) {
   2939             if (0 == _regex_cmap_is_full(cd)) {
   2940         insert_fail = 1;
   2941     }
   2942         }
   2943         _regex_cmap_init(cd);
   2944     }
   2945 
   2946     if (cd->per_state_data == NULL) {
   2947         size = sizeof(cd->per_state_data[0]) * num_dfa_state;
   2948         cd->per_state_data = sal_alloc(size, "dfa_state_tbl");
   2949         sal_memset(cd->per_state_data, 0, size);
   2950     }
   2951     if (insert_fail) {
   2952         BCM_TR3_ADD_TRANSITION_TO_STATE(cd->per_state_data, cd->last_state,1);
   2953     }
   2954     BCM_TR3_ADD_TRANSITION_TO_STATE(cd->per_state_data, in_state, 1);
   2955     if (flags & DFA_STATE_FINAL) {
   2956         BCM_TR3_SET_STATE_FLAGS(cd->per_state_data, 
   2957                                 in_state, BCM_TR3_DFA_STATE_F_FINAL);
   2958     }
   2959     cd->last_state = in_state;
   2960     cd->last_flags = flags;
   2961     _regex_cmap_add(cd, from_c, to_c);
   2962     return REGEX_CB_OK;
   2963 }
   2964 
   2965 STATIC regex_cb_error_t 
   2966 _bcm_tr3_regex_compiler_install_cb(uint32 flags, int match_idx, int in_state, 
   2967                            int from_c, int to_c, int to_state, 
   2968                            int num_dfa_state, void *user_data)
   2969 {
   2970     _bcm_tr3_regex_data_t *cd = (_bcm_tr3_regex_data_t*)user_data;
   2971     int insert_fail = 0, i, j, unit, jf, hw_match_idx;
   2972     int match_set_id, match_chk_id, sigid;
   2973     uint16      ptr;
   2974 
   2975     unit = cd->unit;
   2976     
   2977     if (flags & DFA_TRAVERSE_START) {
   2978         cd->last_state = 0;
   2979         cd->last_flags = 0;
   2980         _regex_cmap_init(cd);
   2981         cd->line_dirty = 0;
   2982         cd->wr_off = 0;
   2983         cd->line_off = cd->hw_eng->from_line;
   2984         cd->hw_match_idx = sal_alloc(sizeof(int)*cd->num_match, "hw_match_idx");
   2985         for (i=0; i<cd->num_match; i++) {
   2986             cd->hw_match_idx[i] = -1;
   2987         }
   2988         cd->mem = _bcm_tr3_get_axp_sm_memory(unit, cd->hw_eng->tile);
   2989         if (cd->mem < 0) {
   2990             return REGEX_CB_ABORT;
   2991         }
   2992         _regex_cmap_init(cd);
   2993         return REGEX_CB_OK;
   2994     } else if (flags & DFA_TRAVERSE_END) {
   2995         if (cd->line_dirty) {
   2996             /* fill rest of the line with fail statements */
   2997             for (i=cd->wr_off; i<BCM_TR3_NUM_RV_PER_LINE; i++) {
   2998                 _bcm_tr3_regex_rv_set(unit, cd->mem, &cd->line, 0, 
   2999                                         255, i, 0xffff, -1);
   3000             }
   3001 	    soc_mem_write(unit, cd->mem, MEM_BLOCK_ALL, cd->line_off, &cd->line);
   3002         }
   3003         if (cd->per_state_data) {
   3004             sal_free(cd->per_state_data);
   3005             cd->per_state_data = NULL;
   3006         }
   3007         if (cd->hw_match_idx) {
   3008             sal_free(cd->hw_match_idx);
   3009             cd->hw_match_idx = NULL;
   3010         }
   3011         return REGEX_CB_OK;
   3012     }
   3013 
   3014     /*
   3015     If last state is not same as this state, insert goto IDLE state
   3016     for non-final states, and only if all characters don't already
   3017     have a transition
   3018     */
   3019     if (cd->last_state != in_state) {
   3020         if ((cd->last_flags & DFA_STATE_FINAL) == 0) {
   3021             if (0 == _regex_cmap_is_full(cd)) {
   3022         insert_fail = 1;
   3023     }
   3024         }
   3025         _regex_cmap_init(cd);
   3026     }
   3027 
   3028     /* INSTALL */
   3029     jf = 2 | (insert_fail ? 1 : 0);
   3030     for (j=0; j<2; j++) {
   3031         if ((jf & (1 << j)) == 0) {
   3032             continue;
   3033         }
   3034 
   3035         if ((cd->wr_off % BCM_TR3_NUM_RV_PER_LINE) == 0) {
   3036             if (cd->line_dirty) {
   3037                 soc_mem_write(unit, cd->mem, 
   3038                                 MEM_BLOCK_ALL, cd->line_off, &cd->line);
   3039                 cd->line_off++;
   3040                 cd->line_dirty = 0;
   3041             }
   3042             sal_memset(&cd->line, 0, sizeof(axp_sm_state_table_mem0_entry_t));
   3043             soc_mem_field32_set(unit, cd->mem, &cd->line, STATE_DATA_TYPEf, 1);
   3044             cd->wr_off = 0;
   3045         }
   3046 
   3047         if (j == 1) {
   3048             /* encode an rv entry */
   3049             if (match_idx >= 0) {
   3050                 /*
   3051                 Note that the following code will be run multiple times for a FINAL
   3052                 state that has transitions.  To avoid installing multiple 255/2
   3053                 RVs, FINAL states should have all transitions removed first
   3054                 */
   3055                 match_set_id = cd->match_set_ids ? cd->match_set_ids[match_idx] : -1;
   3056                 match_chk_id = cd->match_check_ids ? cd->match_check_ids[match_idx] : -1;
   3057                 sigid = cd->sig_ids[match_idx];
   3058                 hw_match_idx = cd->hw_match_idx[match_idx];
   3059                 if (hw_match_idx == -1) {
   3060                     if (_bcm_tr3_set_match_action(unit, cd->hw_eng->hw_idx, 
   3061                                               &cd->matches[match_idx], 
   3062                                               &hw_match_idx, 
   3063                                               match_set_id, match_chk_id, sigid)) {
   3064                         LOG_INFO(BSL_LS_BCM_REGEX,
   3065                                  (BSL_META("error\n")));
   3066                         return REGEX_CB_ABORT;
   3067                     }
   3068                     cd->hw_match_idx[match_idx] = hw_match_idx;
   3069                 }
   3070 
   3071                 _bcm_tr3_regex_rv_set(unit, cd->mem, &cd->line, 255, 2, 
   3072                                       cd->wr_off, 0, hw_match_idx);
   3073 
   3074             } else {
   3075                 ptr = (cd->hw_eng->from_line * BCM_TR3_NUM_RV_PER_LINE) +
   3076                         BCM_TR3_STATE_OFFSET(cd->per_state_data, to_state);
   3077                 _bcm_tr3_regex_rv_set(unit, cd->mem, &cd->line, from_c, 
   3078                                         to_c, cd->wr_off, ptr, -1);
   3079             }
   3080         } else {
   3081             _bcm_tr3_regex_rv_set(unit, cd->mem, &cd->line, 0, 
   3082                                         255, cd->wr_off, 0xffff, -1);
   3083         }
   3084         cd->line_dirty = 1;
   3085         cd->wr_off++;
   3086     }
   3087     cd->last_state = in_state;
   3088     cd->last_flags = flags;
   3089     _regex_cmap_add(cd, from_c, to_c);
   3090     return REGEX_CB_OK;
   3091 }
   3092 
   3093 /* Note: the caller should allocate enough state line to read the dfa */
   3094 STATIC int
   3095 _bcm_tr3_regex_read_hw_dfa(int unit, _bcm_regex_engine_obj_t *pengine,
   3096                            axp_sm_state_table_mem0_entry_t *pmem)
   3097 {
   3098     int    i;
   3099     int    rv;
   3100     uint32 entry[SOC_MAX_MEM_WORDS];
   3101     soc_mem_t mem;
   3102 
   3103     mem = _bcm_tr3_get_axp_sm_memory(unit, pengine->tile);
   3104 
   3105     for (i = pengine->from_line; i < pengine->from_line + pengine->req_lsz; i++) {
   3106         rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, i, entry);
   3107         if (rv < 0) {
   3108             LOG_ERROR(BSL_LS_BCM_REGEX,
   3109                       (BSL_META_U(unit,
   3110                                   "Read ERROR: table %s[%d]: %s\n"),
   3111                        SOC_MEM_UFNAME(unit, mem),
   3112                        i, soc_errmsg(i)));
   3113             break;
   3114         }
   3115         memcpy(pmem[i - pengine->from_line].entry_data, entry, sizeof(pmem[0].entry_data));
   3116     }
   3117 
   3118     return BCM_E_NONE;
   3119 }
   3120 
   3121 /*
   3122  * Rearrange the engines and optimize the use of tile resources,
   3123  * so that all the states in the tiles are utilized to fullest.
   3124  */
   3125 STATIC int
   3126 _bcm_tr3_rearrage_engines(int unit)
   3127 {
   3128     _bcm_tr3_regex_device_info_t *device;
   3129     _bcm_regex_resource_t *res;
   3130     int rv = BCM_E_NONE;
   3131     int tiles, tilee, num_res;
   3132     _bcm_regex_tile_t  tmp_tiles[BCM_TR3_MAX_TILES];
   3133 
   3134     device = REGEX_INFO(unit);
   3135 
   3136     tiles = 0;
   3137     tilee = device->info->num_tiles - 1;
   3138 
   3139     _bcm_tr3_make_resource_objs(unit, &res, &num_res, tiles, tilee);
   3140 
   3141     if (num_res == 0) {
   3142         goto done;
   3143     }
   3144 
   3145     _bcm_regex_sort_resources_by_size(unit, res, num_res);
   3146 
   3147     _bcm_tr3_arrange_resources_in_tiles(unit, res, num_res, tiles, tilee,
   3148                                             tmp_tiles, BCM_TR3_MAX_TILES);
   3149 
   3150     rv = _bcm_tr3_rearrange_engines_in_hw(unit, res, num_res, 
   3151                                                tiles, tilee, tmp_tiles);
   3152 done:
   3153     return rv;
   3154 }
   3155 
   3156 STATIC int _bcm_tr3_get_tile_line_size(int unit)
   3157 {
   3158     return soc_mem_index_count(unit, AXP_SM_STATE_TABLE_MEM0m);
   3159 }
   3160 
   3161 STATIC int _bcm_tr3_get_cps_line_size(int unit)
   3162 {
   3163     uint32  regval, fval, cslsize;
   3164 
   3165     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit,&regval));
   3166     fval = soc_reg_field_get(unit, FT_CONFIGr, regval, TABLE_SIZEf);
   3167     cslsize = (_decode_max_flow(fval) * 2)/BCM_TR3_LINE_BYTE_SIZE;
   3168     return cslsize;
   3169 }
   3170 
   3171 STATIC int
   3172 _bcm_tr3_calc_dfa_memsize(int unit, char **re, uint32 *re_flags, 
   3173                           int num_pattern, uint32 flags, 
   3174                          int *hw_states, void **ppdfa)
   3175 {
   3176     _bcm_tr3_regex_data_t cdata;
   3177     void    *pdfa;
   3178     int                    rv;
   3179 
   3180     rv = bcm_regex_compile(re, re_flags, num_pattern, 0, &pdfa);
   3181     if (rv < 0) {
   3182         switch (rv) {
   3183             case REGEX_ERROR_INVALID_CLASS:
   3184                 LOG_WARN(BSL_LS_BCM_REGEX,
   3185                          (BSL_META_U(unit,
   3186                                      "Regex: Invalid class.\n")));
   3187                 break;
   3188             case REGEX_ERROR_EXPANSION_FAIL:
   3189                 LOG_WARN(BSL_LS_BCM_REGEX,
   3190                          (BSL_META_U(unit,
   3191                                      "Regex: Expansion failed.\n")));
   3192                 break;
   3193             case REGEX_ERROR_NO_POST:
   3194                 LOG_WARN(BSL_LS_BCM_REGEX,
   3195                          (BSL_META_U(unit,
   3196                                      "Regex: No post.\n")));
   3197                 break;
   3198             case REGEX_ERROR_NO_DFA:
   3199                 LOG_WARN(BSL_LS_BCM_REGEX,
   3200                          (BSL_META_U(unit,
   3201                                      "Regex: No DFA.\n")));
   3202                 break;
   3203             case REGEX_ERROR_NO_NFA:
   3204                 LOG_WARN(BSL_LS_BCM_REGEX,
   3205                          (BSL_META_U(unit,
   3206                                      "Regex: No NFA.\n")));
   3207                 break;
   3208             case REGEX_ERROR_NO_MEMORY:
   3209                 LOG_WARN(BSL_LS_BCM_REGEX,
   3210                          (BSL_META_U(unit,
   3211                                      "Regex: No memory.\n")));
   3212                 break;
   3213             default:
   3214                 LOG_WARN(BSL_LS_BCM_REGEX,
   3215                          (BSL_META_U(unit,
   3216                                      "Regex: Error.\n")));
   3217                 break;
   3218         }
   3219         return BCM_E_FAIL;
   3220     }
   3221 
   3222     sal_memset(&cdata, 0, sizeof(_bcm_tr3_regex_data_t));
   3223     cdata.unit = unit;
   3224 
   3225     if (bcm_regex_dfa_traverse(pdfa, 
   3226                                 _bcm_regex_dfa_cb_calc_size, &cdata)) {
   3227         return BCM_E_INTERNAL;
   3228     }
   3229 
   3230     LOG_INFO(BSL_LS_BCM_REGEX,
   3231              (BSL_META_U(unit,
   3232                          "DFA num hw_states/transitions = %d, %d lines\n"),
   3233               cdata.compile_size,
   3234               cdata.compile_size/BCM_TR3_NUM_RV_PER_LINE +
   3235               (((cdata.compile_size/BCM_TR3_NUM_RV_PER_LINE) % BCM_TR3_NUM_RV_PER_LINE) ? 1 : 0)));
   3236 
   3237     *hw_states = cdata.compile_size;
   3238     if (ppdfa != NULL) {
   3239        *ppdfa = pdfa;
   3240     } else {
   3241         bcm_regex_dfa_free(pdfa);    
   3242     }
   3243     return BCM_E_NONE;
   3244 }
   3245 
   3246 int _bcm_tr3_get_engine_size_info(int unit, int engine_id,
   3247                                   bcm_regex_engine_info_t *engine_info)
   3248 {
   3249     uint32  regval;
   3250     _bcm_regex_lengine_t *ltmp = NULL;
   3251     _bcm_regex_engine_obj_t *ptmp = NULL;
   3252     _bcm_tr3_regex_device_info_t *device;
   3253     int i, in_use, tile;
   3254     int max_tile_free = 0, tile_free_size[BCM_TR3_MAX_TILES];
   3255     int tile_eng[BCM_TR3_MAX_TILES] = {0};
   3256 
   3257     device = REGEX_INFO(unit);
   3258 
   3259     if (engine_id == BCM_REGEX_ENGINE_ALL) {
   3260         engine_info->size = _bcm_tr3_get_tile_line_size(unit) * BCM_TR3_MAX_TILES * BCM_TR3_LINE_BYTE_SIZE;
   3261         in_use = 0;
   3262 
   3263         for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
   3264             ltmp = BCM_TR3_LOGICAL_ENGINE(device, i);
   3265             if (ltmp == NULL) {
   3266                 LOG_INFO(BSL_LS_BCM_REGEX,
   3267                          (BSL_META_U(unit,
   3268                                      "i = %d, logical engine NULL\n"),
   3269                           i));
   3270                 continue;
   3271             }
   3272             if (!BCM_REGEX_ENGINE_ALLOCATED(ltmp)) {
   3273                 continue;
   3274             }
   3275             ptmp = ltmp->physical_engine;
   3276             if (ptmp == NULL) {
   3277                 LOG_INFO(BSL_LS_BCM_REGEX,
   3278                          (BSL_META_U(unit,
   3279                                      "i = %d, Engine id %d : physical engine NULL\n"),
   3280                           i, ltmp->id));
   3281                 continue;
   3282             }
   3283             in_use += ptmp->total_lsz;
   3284         }
   3285 
   3286         engine_info->free_size = ((_bcm_tr3_get_tile_line_size(unit) * BCM_TR3_MAX_TILES) - in_use)
   3287                                     * BCM_TR3_LINE_BYTE_SIZE;
   3288     }
   3289     else
   3290     {
   3291         if (engine_id < 0 || engine_id >= BCM_TR3_MAX_ENGINE) {
   3292             LOG_INFO(BSL_LS_BCM_REGEX,
   3293                      (BSL_META_U(unit,
   3294                                  "engine_id = %d, INVALID\n"),
   3295                       engine_id));
   3296             return BCM_E_PARAM;
   3297         }
   3298 
   3299         if (_bcm_tr3_find_engine(unit, engine_id, &ltmp) ||
   3300             ((ptmp = ltmp->physical_engine) == NULL)) {
   3301             LOG_INFO(BSL_LS_BCM_REGEX,
   3302                      (BSL_META_U(unit,
   3303                                  "engine_id = %d, Engine logical id %d : physical engine NULL\n"),
   3304                       engine_id, ltmp->id));
   3305 
   3306             /*
   3307             Search for tile with largest free size available
   3308             */
   3309 
   3310             for (i = 0; i < BCM_TR3_MAX_TILES; i++) {
   3311                 tile_free_size[i] = _bcm_tr3_get_tile_line_size(unit) * BCM_TR3_LINE_BYTE_SIZE;
   3312             }
   3313 
   3314             for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
   3315                 ltmp = BCM_TR3_LOGICAL_ENGINE(device, i);
   3316                 if (ltmp == NULL) {
   3317                     continue;
   3318                 }
   3319                 if (!BCM_REGEX_ENGINE_ALLOCATED(ltmp)) {
   3320                     continue;
   3321                 }
   3322                 ptmp = ltmp->physical_engine;
   3323                 if (ptmp == NULL) {
   3324                     LOG_INFO(BSL_LS_BCM_REGEX,
   3325                              (BSL_META_U(unit,
   3326                                          "i = %d, Engine id %d, pid NULL\n"),
   3327                               i, ltmp->id));
   3328                     continue;
   3329                 }
   3330                 tile = BCM_TR3_ENGINE_TILE(device, ptmp->hw_idx);
   3331                 tile_free_size[tile] -= (ptmp->total_lsz*BCM_TR3_LINE_BYTE_SIZE);
   3332                 tile_eng[tile]++;
   3333             }
   3334 
   3335             for (i = 0; i < BCM_TR3_MAX_TILES; i++) {
   3336                 if ((tile_free_size[i] > max_tile_free) &&
   3337                     tile_eng[i] < BCM_TR3_ENGINE_PER_TILE(device)) {
   3338                     max_tile_free = tile_free_size[i];
   3339                 }
   3340             }
   3341 
   3342             engine_info->size = _bcm_tr3_get_tile_line_size(unit) * BCM_TR3_LINE_BYTE_SIZE;
   3343             engine_info->free_size = max_tile_free;
   3344             LOG_CLI((BSL_META_U(unit,
   3345                                 "Engine %d not allocated, max size in tile would be engine size:\n"),
   3346                      engine_id));
   3347             return BCM_E_NONE;
   3348         }
   3349 
   3350         SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, ptmp->hw_idx, &regval));
   3351 
   3352         if (!soc_reg_field_get(unit, AXP_SM_REGEX_CONTROL0r, regval, REGEX_ENABLEf)) {
   3353             return BCM_E_NONE;
   3354         }
   3355 
   3356         engine_info->size = _bcm_tr3_get_tile_line_size(unit) * BCM_TR3_LINE_BYTE_SIZE;
   3357         in_use = 0;
   3358         tile = BCM_TR3_ENGINE_TILE(device, ptmp->hw_idx);
   3359 
   3360         for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
   3361             ltmp = BCM_TR3_LOGICAL_ENGINE(device, i);
   3362             if (!BCM_REGEX_ENGINE_ALLOCATED(ltmp)) {
   3363                 continue;
   3364             }
   3365             ptmp = ltmp->physical_engine;
   3366             if (ptmp == NULL) {
   3367                 LOG_INFO(BSL_LS_BCM_REGEX,
   3368                          (BSL_META_U(unit,
   3369                                      "i = %d, Engine id %d, pid NULL\n"),
   3370                           i, ltmp->id));
   3371                 continue;
   3372             }
   3373             if (ptmp->tile != tile) {
   3374                 continue;
   3375             }
   3376             LOG_INFO(BSL_LS_BCM_REGEX,
   3377                      (BSL_META_U(unit,
   3378                                  "i = %d, Engine id %d, pid %d : tile %d, size %d\n"),
   3379                       i,
   3380                       ltmp->id, ptmp->hw_idx, ptmp->tile, ptmp->req_lsz * BCM_TR3_LINE_BYTE_SIZE));
   3381             in_use += ptmp->total_lsz;
   3382         }
   3383 
   3384         engine_info->free_size = (_bcm_tr3_get_tile_line_size(unit) - in_use)
   3385                                     * BCM_TR3_LINE_BYTE_SIZE;
   3386     }
   3387 
   3388     return BCM_E_NONE;
   3389 }
   3390         
   3391 STATIC int
   3392 _bcm_tr3_set_remap_table(int unit, int hw_idx, uint8 *cmap_tbl)
   3393 {
   3394     int i;
   3395     soc_mem_t remap_mem = AXP_SM_CHAR_REMAP0m + hw_idx;
   3396     axp_sm_char_remap0_entry_t remap_en;
   3397     uint32  regval;
   3398    
   3399     if (cmap_tbl) {
   3400         for (i=0; i<256; i+=4) {
   3401             soc_mem_field32_set(unit, remap_mem, &remap_en, 
   3402                               REMAP_VAL0f, *(cmap_tbl+i));
   3403             soc_mem_field32_set(unit, remap_mem, &remap_en, 
   3404                               REMAP_VAL1f, *(cmap_tbl + i+1));
   3405             soc_mem_field32_set(unit, remap_mem, &remap_en, 
   3406                               REMAP_VAL2f, *(cmap_tbl + i+2));
   3407             soc_mem_field32_set(unit, remap_mem, &remap_en, 
   3408                               REMAP_VAL3f, *(cmap_tbl + i+3));
   3409             soc_mem_write(unit, remap_mem, MEM_BLOCK_ALL, i/4, &remap_en);
   3410         }
   3411     }
   3412     SOC_IF_ERROR_RETURN(READ_AXP_SM_REGEX_CONTROL0r(unit, hw_idx, &regval));
   3413     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, 
   3414                                   &regval, CHAR_REMAP_ENABLEf, cmap_tbl?1:0);
   3415     SOC_IF_ERROR_RETURN(
   3416                     WRITE_AXP_SM_REGEX_CONTROL0r(unit, hw_idx, regval));
   3417     return 0;
   3418 }
   3419 
   3420 STATIC int
   3421 _bcm_tr3_install_dfa(int unit, void *dfa, bcm_regex_match_t *matches,
   3422                      int *match_set_ids, int *match_check_ids, int *sig_ids,
   3423                      int count, _bcm_regex_engine_obj_t* pengine)
   3424 {
   3425     _bcm_tr3_regex_data_t user_data;
   3426 
   3427     /* Install is done in 2 stages, first stage, preprocess stage
   3428      * calculate the enteries required per state including any fail states.
   3429      * this will create a map :
   3430      *  stateA-> num_hw_state, offset in state_table
   3431      *  stateB-> num_hw_state, offset in state_table
   3432      *  using this its easy to generate the jump pointers to next state.
   3433      */
   3434 
   3435     LOG_INFO(BSL_LS_BCM_REGEX,
   3436              (BSL_META_U(unit,
   3437                          "installing DFA\n")));
   3438     /*
   3439      * Traverse al the DFA with flags preprocess */
   3440     sal_memset(&user_data, 0, sizeof(user_data));
   3441     user_data.matches = matches;
   3442     user_data.num_match = count;
   3443     user_data.match_set_ids = match_set_ids;
   3444     user_data.match_check_ids = match_check_ids;
   3445     user_data.sig_ids = sig_ids;
   3446     user_data.unit = unit;
   3447     user_data.hw_eng = pengine;
   3448 
   3449     LOG_INFO(BSL_LS_BCM_REGEX,
   3450              (BSL_META_U(unit,
   3451                          "preprocessing ..")));
   3452     if (bcm_regex_dfa_traverse(dfa, _bcm_tr3_regex_compiler_preprocess_cb,
   3453                                     &user_data)) {
   3454         LOG_INFO(BSL_LS_BCM_REGEX,
   3455                  (BSL_META_U(unit,
   3456                              "Error\n")));
   3457         return BCM_E_INTERNAL;
   3458     }
   3459 
   3460     /* traverse again and install it */
   3461     LOG_INFO(BSL_LS_BCM_REGEX,
   3462              (BSL_META_U(unit,
   3463                          "HW Install ..")));
   3464     if (bcm_regex_dfa_traverse(dfa, _bcm_tr3_regex_compiler_install_cb,
   3465                                     &user_data)) {
   3466         LOG_INFO(BSL_LS_BCM_REGEX,
   3467                  (BSL_META_U(unit,
   3468                              "Error\n")));
   3469         return BCM_E_INTERNAL;
   3470     }
   3471 
   3472     return BCM_E_NONE;
   3473 }
   3474 
   3475 STATIC int
   3476 _bcm_tr3_disable_tile(int unit, int tile)
   3477 {
   3478     _bcm_tr3_regex_device_info_t *device;
   3479     int e, eng_idx;
   3480     
   3481     device = REGEX_INFO(unit);
   3482     for (e = 0; e < BCM_TR3_ENGINE_PER_TILE(device); e++) {
   3483         eng_idx = (tile*BCM_TR3_ENGINE_PER_TILE(device)) + e;
   3484         BCM_REGEX_DISABLE_ENGINE(device, unit, eng_idx);
   3485     }
   3486 
   3487     return 0;
   3488 }
   3489 
   3490 STATIC int
   3491 _bcm_tr3_enable_tile(int unit, int tile)
   3492 {
   3493     _bcm_tr3_regex_device_info_t *device;
   3494     _bcm_regex_engine_obj_t      *pengine;
   3495     int e, eng_idx;
   3496     
   3497     device = REGEX_INFO(unit);
   3498     for (e = 0; e < BCM_TR3_ENGINE_PER_TILE(device); e++) {
   3499         eng_idx = (tile*BCM_TR3_ENGINE_PER_TILE(device)) + e;
   3500         pengine = BCM_TR3_PHYSICAL_ENGINE(device, eng_idx); 
   3501         if (!BCM_REGEX_ENGINE_ALLOCATED(pengine)) {
   3502             continue;
   3503         }
   3504         BCM_REGEX_ENABLE_ENGINE(device, unit, pengine);
   3505     }
   3506 
   3507     return 0;
   3508 }
   3509 
   3510 STATIC int 
   3511 _bcm_tr3_init_cps_block(int unit, _bcm_regex_cps_obj_t *pcps)
   3512 {
   3513     int     i;
   3514 
   3515     for (i = 0; i < BCM_REGEX_NUM_SLOT_PER_CPS; i++) {
   3516         pcps->alloc_map[i] = -1;
   3517         pcps->refcnt[i] = 0;
   3518     }
   3519     return BCM_E_NONE;
   3520 }
   3521 
   3522 STATIC int _bcm_tr3_free_cps(int unit, _bcm_regex_cps_obj_t *pcps)
   3523 {
   3524     int i;
   3525 
   3526     for (i = 0; i < BCM_REGEX_NUM_SLOT_PER_CPS; i++) {
   3527         pcps->alloc_map[i] = -1;
   3528         pcps->refcnt[i] = 0;
   3529     }
   3530     return BCM_E_NONE;
   3531 }
   3532 
   3533 STATIC int
   3534 _bcm_regex_alloc_one_cps_slot(int unit, int linkid, 
   3535                               _bcm_regex_cps_obj_t *pcps, int *slot)
   3536 {
   3537     int j;
   3538 
   3539     if (linkid < 0) {
   3540         return BCM_E_PARAM;
   3541     }
   3542 
   3543     for (j=0; j<BCM_REGEX_NUM_SLOT_PER_CPS; j++) {
   3544         if (pcps->alloc_map[j] == linkid) {
   3545             *slot = pcps->foff + j;
   3546             pcps->alloc_map[j] = linkid;
   3547             pcps->refcnt[j]++;
   3548             return BCM_E_NONE;
   3549         }
   3550     }
   3551 
   3552     for (j=0; j<BCM_REGEX_NUM_SLOT_PER_CPS; j++) {
   3553         if (pcps->alloc_map[j] == -1) {
   3554             *slot = pcps->foff + j;
   3555             pcps->alloc_map[j] = linkid;
   3556             pcps->refcnt[j] = 1;
   3557             return BCM_E_NONE;
   3558         }
   3559     }
   3560 
   3561     return BCM_E_RESOURCE;
   3562 }
   3563 
   3564 STATIC int
   3565 _bcm_regex_free_one_cps_slot(int unit, _bcm_regex_cps_obj_t *pcps, int slot)
   3566 {
   3567     int b, idx;
   3568     
   3569     b = (slot/BCM_REGEX_NUM_SLOT_PER_CPS)*BCM_REGEX_NUM_SLOT_PER_CPS;
   3570     if (pcps->foff != b) {
   3571         return BCM_E_PARAM;
   3572     }
   3573    
   3574     idx = slot % BCM_REGEX_NUM_SLOT_PER_CPS;
   3575     if (pcps->refcnt[idx]) {
   3576         pcps->refcnt[idx]--;
   3577         if (pcps->refcnt[idx] == 0) {
   3578             pcps->alloc_map[idx] = -1;
   3579         }
   3580     }
   3581     
   3582     return BCM_E_RESOURCE;
   3583 }
   3584 
   3585 STATIC int
   3586 _bcm_tr3_regex_alloc_set_ids(int unit, int *match_set_ids, bcm_regex_match_t *matches,
   3587                             int count, int pengine_hwidx)
   3588 {
   3589     _bcm_tr3_regex_device_info_t *device;
   3590     _bcm_regex_cps_obj_t *pcps;
   3591     int si, rv = BCM_E_NONE;
   3592 
   3593     device = REGEX_INFO(unit);
   3594     pcps = BCM_TR3_CPS_INFO(device, pengine_hwidx);
   3595 
   3596     for (si = 0; si < count; si++) {
   3597         if (matches[si].provides < 0) { /* setids */
   3598             match_set_ids[si] = -1;
   3599             continue;
   3600         }
   3601 
   3602         /* Multiple signature might set the same flag, in which case 
   3603          * reuse the flag, ie 
   3604          * S{a} -> sets f1
   3605          * S{b} -> sets f1
   3606          * S{c} -> checks for f1, something similar to 
   3607          * match = (S{a} || S{bb}) && S{c}
   3608          */
   3609         rv = _bcm_regex_alloc_one_cps_slot(unit, matches[si].provides,
   3610                                                 pcps, &match_set_ids[si]);
   3611         if (rv) {
   3612             break;
   3613         }
   3614     }
   3615 
   3616     if (rv) {
   3617         for (si = 0; si < count; si++) {
   3618             if (match_set_ids[si] == -1) {
   3619                 continue;
   3620             }
   3621             _bcm_regex_free_one_cps_slot(unit, pcps, match_set_ids[si]);
   3622         }
   3623         _bcm_tr3_free_cps(unit, pcps);
   3624     }
   3625     return rv;
   3626 }
   3627 
   3628 STATIC int
   3629 _bcm_tr3_regex_alloc_check_ids(int unit, int *match_check_ids, bcm_regex_match_t *matches,
   3630                             int count, int pengine_hwidx, int defer)
   3631 {
   3632     int rv = BCM_E_NONE, i;
   3633 
   3634     for (i = 0; i < count; i++) {
   3635         if (matches[i].requires < 0) { /* chkids */
   3636             match_check_ids[i] = -1;
   3637             continue;
   3638         }
   3639         rv = bcm_regexdb_find_chkid_for_requires(unit, 
   3640                                         matches[i].requires, &match_check_ids[i]);
   3641         if (rv) {
   3642             if (defer) {
   3643                 match_check_ids[i] = BCM_TR3_SPECIAL_SLOT;
   3644             } else {
   3645                 return BCM_E_RESOURCE;
   3646             }
   3647         }
   3648     }
   3649     return BCM_E_NONE;
   3650 }
   3651 
   3652 STATIC int
   3653 _bcm_tr3_attach_hw_engine(int unit, _bcm_regex_lengine_t *lengine,
   3654                           int req_lsz, int *match_set_ids, int *match_check_ids,
   3655                           bcm_regex_match_t *matches, int *sigids, 
   3656                           int count)
   3657 {
   3658     int rv = BCM_E_NONE, try, engidx, i;
   3659     bcm_regex_engine_config_t config;
   3660     _bcm_regex_engine_obj_t *pengine = NULL;
   3661     int  extra_lsz = 0;
   3662 
   3663     engidx = BCM_REGEX_ENGINE_INDEX_FROM_ID(unit, lengine->id);
   3664 
   3665     /*
   3666      * Cannot do both multipacket and cross packet mode 
   3667      */
   3668     SOC_IF_ERROR_RETURN(_bcm_tr3_regex_engine_get(unit, engidx, &config));
   3669     if ((config.flags & BCM_REGEX_ENGINE_CONFIG_MULTI_PACKET) && 
   3670         (match_set_ids || match_check_ids)) {
   3671         LOG_INFO(BSL_LS_BCM_REGEX,
   3672                  (BSL_META_U(unit,
   3673                              "Can't use multi-packet with chaining\n")));
   3674         return BCM_E_CONFIG;
   3675     }
   3676 
   3677     if ((config.flags & BCM_REGEX_ENGINE_CONFIG_MULTI_PACKET) || match_set_ids ||
   3678          match_check_ids) {
   3679         extra_lsz = _bcm_tr3_get_cps_line_size(unit);
   3680     }
   3681     
   3682     for(pengine=NULL, try=0; (try<2) && !pengine; try++) {
   3683         rv = _bcm_tr3_alloc_regex_engine(unit, req_lsz, extra_lsz, &pengine, -1);
   3684         if (rv && (try == 0)) {
   3685             /* first try and alloc failed, try to rearrange engines
   3686              * across tiles and optimize resources to see if we can still
   3687              * fit things.
   3688              */
   3689             LOG_INFO(BSL_LS_BCM_REGEX,
   3690                      (BSL_META_U(unit,
   3691                                  "Alloc of regex engine failed.. rearrange engines\n")));
   3692             rv = _bcm_tr3_rearrage_engines(unit);
   3693             if (rv) {
   3694                 LOG_INFO(BSL_LS_BCM_REGEX,
   3695                          (BSL_META_U(unit,
   3696                                      "rearrange engines failed.\n")));
   3697                 goto fail;
   3698             }
   3699         }
   3700     }
   3701 
   3702     /* allocate signature IDs, this is internal ID for a pattern and maps
   3703      * 1 to 1 to match_id provided by the application. The reason for the
   3704      * remapping is , internal signature ID space is limited whereas 
   3705      * application can pick arbitary values for the match-id.
   3706      */
   3707     for (i = 0; i < count; i++) {
   3708         sigids[i] = _bcm_tr3_alloc_sigid(unit, &matches[i]);
   3709     }
   3710 
   3711     /*
   3712      * Allocate set slots if required 
   3713      */
   3714     if (match_set_ids) {
   3715         rv = _bcm_tr3_regex_alloc_set_ids(unit, match_set_ids,
   3716                                            matches, count, pengine->hw_idx);
   3717         if (rv) {
   3718             LOG_INFO(BSL_LS_BCM_REGEX,
   3719                      (BSL_META_U(unit,
   3720                                  "Alloc of set_ids failed\n")));
   3721             goto fail;
   3722         }
   3723     }
   3724 
   3725     /*
   3726      * allocate check slots if required 
   3727      */
   3728     if (match_check_ids) {
   3729         rv = _bcm_tr3_regex_alloc_check_ids(unit, match_check_ids,
   3730                                             matches, count, pengine->hw_idx, 1);
   3731         if (rv) {
   3732             LOG_INFO(BSL_LS_BCM_REGEX,
   3733                      (BSL_META_U(unit,
   3734                                  "Alloc of check_ids failed\n")));
   3735             goto fail;
   3736         }
   3737     }
   3738 
   3739     lengine->physical_engine = pengine;
   3740 
   3741     return BCM_E_NONE;
   3742     
   3743 fail:
   3744 
   3745     if (pengine) {
   3746         _bcm_tr3_regex_hw_engine_detach(unit, pengine);
   3747     }
   3748 
   3749     return rv;
   3750 }
   3751 
   3752 int
   3753 _bcm_tr3_regex_match_check(int unit, bcm_regex_match_t *matches,
   3754                            int count, int *metric)
   3755 {
   3756     char **res;
   3757     uint32   *res_flags;
   3758     int     i, hw_states, ncs = 0, nncs = 0, rv = BCM_E_NONE;
   3759     int need_check_ids = 0, need_set_ids = 0, extra_lsz=0;
   3760 
   3761     if ((count <= 0) || (!matches) || (!metric))  {
   3762         return BCM_E_PARAM;
   3763     }
   3764 
   3765     res = sal_alloc(count * sizeof(char*), "tmp_regex_patterns");
   3766     res_flags = sal_alloc(count * sizeof(uint32), "tmp_regex_ptr");
   3767 
   3768     for (i=0; i<count; i++) {
   3769         res[i] = matches[i].pattern;
   3770         res_flags[i] = 0;
   3771         if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3772             nncs++;
   3773         } else {
   3774             ncs++;
   3775         }
   3776         if (matches[i].provides > 0) {
   3777             need_set_ids += 1;
   3778         }
   3779         if (matches[i].requires > 0) {
   3780             need_check_ids += 1;
   3781         }
   3782     }
   3783 
   3784 #if 1
   3785     if (ncs && nncs) {
   3786         for (i = 0; i < count; i++) {
   3787             if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3788                 res_flags[i] = BCM_TR3_REGEX_CFLAG_EXPAND_LCUC;
   3789             }
   3790         }
   3791     }
   3792 #else
   3793     if (nncs) {
   3794         for (i = 0; i < count; i++) {
   3795             if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3796                 res_flags[i] = BCM_TR3_REGEX_CFLAG_EXPAND_LCUC;
   3797             }
   3798         }
   3799     }
   3800 #endif
   3801 
   3802     if (!ncs && nncs) {
   3803         for (i = 0; i < count; i++) {
   3804             if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3805                 res_flags[i] = BCM_TR3_REGEX_CFLAG_EXPAND_LC;
   3806             }
   3807         }
   3808     }
   3809     
   3810     BCM_REGEX_LOCK(unit);
   3811 
   3812     rv = _bcm_tr3_calc_dfa_memsize(unit, res, res_flags, count, 
   3813                                     0, &hw_states, NULL);
   3814     if (!rv && (hw_states >= 0)) {
   3815         *metric = ((hw_states / BCM_TR3_NUM_RV_PER_LINE) +
   3816             (((hw_states % BCM_TR3_NUM_RV_PER_LINE) == 0) ? 0 : 1)) *
   3817             BCM_TR3_LINE_BYTE_SIZE;
   3818     }
   3819     if(need_set_ids || need_check_ids) {
   3820         /*Extra lsz for saving CSF*/
   3821         extra_lsz = _bcm_tr3_get_cps_line_size(unit);
   3822         *metric += (extra_lsz*BCM_TR3_LINE_BYTE_SIZE);
   3823     }
   3824 
   3825     BCM_REGEX_UNLOCK(unit);
   3826 
   3827     sal_free(res);
   3828     sal_free(res_flags);
   3829     return rv;
   3830 }
   3831 
   3832 int
   3833 _bcm_tr3_regex_match_set(int unit, bcm_regex_engine_t engid, 
   3834                          bcm_regex_match_t *matches, int count)
   3835 {
   3836     char                         **res        = NULL;
   3837     uint32                        *res_flags  = NULL;
   3838     uint32                         cflags     = 0, regval, fval;
   3839     void    *dfa = NULL;
   3840     int  i, hw_states, *cps_match_set_ids=NULL, *cps_match_check_ids = NULL;
   3841     int  ncs = 0;                       /* number of case sensitive signatures */
   3842     int  nncs = 0;                      /* number of non-case sensitive signatures */
   3843     int  rv = SOC_E_NONE, req_lsz, need_set_ids = 0, need_check_ids = 0;
   3844     _bcm_tr3_regex_device_info_t  *device;
   3845     _bcm_regex_lengine_t          *lengine    = NULL;
   3846     _bcm_regex_engine_obj_t       *pengine    = NULL;
   3847     int                           *sig_ids    = NULL;
   3848     int                            tot_length = 0;
   3849 
   3850     if (!(device = REGEX_INFO(unit))) {
   3851         return BCM_E_INIT;
   3852         LOG_INFO(BSL_LS_BCM_REGEX,
   3853                  (BSL_META_U(unit,
   3854                              "unit %d, device not initialized\n"),
   3855                   unit));
   3856     }
   3857 
   3858     if ((engid == -1) && (count > 0)) {
   3859         return _bcm_tr3_install_action_policy(unit, &matches[0], 
   3860                                      _BCM_TR3_SET_DEFAULT_POLICY, NULL);
   3861     }
   3862 
   3863     /* Ensure that at least one regex has non-zero length. Otherwise, no DFA can be
   3864      * generated. Making the check here so that the engine is not disturbed if invalid
   3865      * parameters are supplied. Note that it is valid to supply a count of zero which
   3866      * means to delete the engine. */
   3867     if (count > 0) {
   3868         for (i = 0; i < count; i++) {
   3869             if (NULL != matches[i].pattern) {
   3870                 tot_length += strlen(matches[i].pattern);
   3871             }
   3872         }
   3873         if (tot_length <= 0) {
   3874             return BCM_E_PARAM;
   3875         }
   3876     }
   3877 
   3878     rv = _bcm_tr3_find_engine(unit, engid, &lengine);
   3879     if (rv) {
   3880         LOG_INFO(BSL_LS_BCM_REGEX,
   3881                  (BSL_META_U(unit,
   3882                              "can't find engine %d\n"),
   3883                   engid));
   3884         return BCM_E_PARAM;
   3885     }
   3886    
   3887     BCM_REGEX_LOCK(unit);
   3888 
   3889     /* if engine already has patterns, delete them */
   3890     pengine = lengine->physical_engine;
   3891     rv = _bcm_tr3_regex_hw_engine_detach(unit, pengine);
   3892     if (rv) {
   3893         LOG_INFO(BSL_LS_BCM_REGEX,
   3894                  (BSL_META_U(unit,
   3895                              "can't detach hw_engine %d, rv %d\n"),
   3896                   engid, rv));
   3897         goto fail;
   3898     }
   3899     lengine->physical_engine = NULL;
   3900 
   3901     if (count <= 0) {
   3902         BCM_REGEX_UNLOCK(unit);
   3903         LOG_INFO(BSL_LS_BCM_REGEX,
   3904                  (BSL_META_U(unit,
   3905                              "no patterns to install\n")));
   3906         return BCM_E_NONE;
   3907     }
   3908 
   3909     res = sal_alloc(count * sizeof(char*), "tmp_regex_ptr");
   3910     res_flags = sal_alloc(count * sizeof(uint32), "tmp_regex_ptr");
   3911     sig_ids = sal_alloc(count * sizeof(int), "tmp_sigids");
   3912 
   3913     /* iterate over all the patterns and see if we can enable
   3914      * case insensitive feature in HW vs in software by doing [xX] */
   3915     for (i = 0; i < count; i++) {
   3916         /* Ensure that the regex is not too long.  It must be a null terminated string. */
   3917         if (sal_strlen(matches[i].pattern) >= sizeof(matches[i].pattern)) {
   3918             LOG_INFO(BSL_LS_BCM_REGEX,
   3919                      (BSL_META_U(unit,
   3920                                  "regex %d too long\n"),
   3921                       i));
   3922             rv = BCM_E_PARAM;
   3923             goto fail;
   3924         }
   3925         if (device->info->flags & BCM_REGEX_USE_POLICY_ID) {
   3926             if (matches[i].action_flags & BCM_REGEX_MATCH_ACTION_NON_POLICY_ACTIONS) {
   3927                 LOG_INFO(BSL_LS_BCM_REGEX,
   3928                          (BSL_META_U(unit,
   3929                                      "non-policy action flags set with policy-ID flag\n")));
   3930                 rv = BCM_E_PARAM;
   3931                 goto fail;
   3932             }
   3933 
   3934             /*
   3935             The esw-level function checks for the existence and installation
   3936             of the policy ID that is being requested for this match, so at
   3937             this point, all that is checked is that the correct policy-type
   3938             (create w/ regex or use existing) is being requested.  If not,
   3939             return BCM_E_PARAM.
   3940             */
   3941         }
   3942         else {
   3943             if (matches[i].policy_id != -1) {
   3944                 LOG_INFO(BSL_LS_BCM_REGEX,
   3945                          (BSL_META_U(unit,
   3946                                      "attempting to use policy_id with no policy-ID flag\n")));
   3947                 rv = BCM_E_PARAM;
   3948                 goto fail;
   3949             }
   3950         }
   3951         res[i] = matches[i].pattern;
   3952         sig_ids[i] = -1;
   3953         res_flags[i] = 0;
   3954         if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3955             nncs++;
   3956         } else {
   3957             ncs++;
   3958         }
   3959         if (matches[i].provides > 0) {
   3960             need_set_ids += 1;
   3961         }
   3962         if (matches[i].requires > 0) {
   3963             need_check_ids += 1;
   3964         }
   3965     }
   3966 
   3967     /* if the matches are mixed that is, it has both case sensitive and 
   3968      * non-case sensitive matches mixes, we need to expand the case 
   3969      * case insensitive patterns using [xX] */
   3970     if (ncs && nncs) {
   3971         for (i = 0; i < count; i++) {
   3972             if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3973                 res_flags[i] = BCM_TR3_REGEX_CFLAG_EXPAND_LCUC;
   3974             }
   3975         }
   3976     }
   3977 
   3978     if (!ncs && nncs) {
   3979         for (i = 0; i < count; i++) {
   3980             if (matches[i].flags & BCM_REGEX_MATCH_CASE_INSENSITIVE) {
   3981                 res_flags[i] = BCM_TR3_REGEX_CFLAG_EXPAND_LC;
   3982             }
   3983         }
   3984     }
   3985     
   3986     dfa = NULL;
   3987     rv = _bcm_tr3_calc_dfa_memsize(unit, res, res_flags, count, 
   3988                                     cflags, &hw_states, &dfa);
   3989     if (rv) {
   3990         goto fail;
   3991     }
   3992 
   3993     req_lsz = (hw_states + BCM_TR3_NUM_RV_PER_LINE-1)/BCM_TR3_NUM_RV_PER_LINE;
   3994     if (req_lsz > _bcm_tr3_get_tile_line_size(unit)) {
   3995         LOG_INFO(BSL_LS_BCM_REGEX,
   3996                  (BSL_META_U(unit,
   3997                              "required lines %d too large to install\n"),
   3998                   req_lsz));
   3999         rv = BCM_E_RESOURCE;
   4000         goto fail;
   4001     }
   4002 
   4003     LOG_INFO(BSL_LS_BCM_REGEX,
   4004              (BSL_META_U(unit,
   4005                          "%d RV entry, %d lines needed\n"),
   4006               hw_states, req_lsz));
   4007 
   4008     /*
   4009      * Find the new cps slots needs, eliminate the ones for which one leg
   4010      * already exist.
   4011      */
   4012     if (need_set_ids) {
   4013         cps_match_set_ids = sal_alloc(sizeof(int)*count, "cps_set_ids");
   4014         if (!cps_match_set_ids) {
   4015             LOG_INFO(BSL_LS_BCM_REGEX,
   4016                      (BSL_META_U(unit,
   4017                                  "no memory for match set IDs\n")));
   4018             rv = BCM_E_MEMORY;
   4019             goto fail;
   4020         }
   4021         for (i = 0; i < count; i++) {
   4022             cps_match_set_ids[i] = -1;
   4023         }
   4024     }
   4025 
   4026     if (need_check_ids) {
   4027         cps_match_check_ids = sal_alloc(sizeof(int)*count, "cps_check_ids");
   4028         if (!cps_match_check_ids) {
   4029             LOG_INFO(BSL_LS_BCM_REGEX,
   4030                      (BSL_META_U(unit,
   4031                                  "no memory for match check IDs\n")));
   4032             rv = BCM_E_MEMORY;
   4033             goto fail;
   4034         }
   4035         for (i = 0; i < count; i++) {
   4036             cps_match_check_ids[i] = -1;
   4037         }
   4038     }
   4039 
   4040     /* 
   4041      * find the best tile/physical regex engine where this should be installed
   4042      */
   4043     rv = _bcm_tr3_attach_hw_engine(unit, lengine, req_lsz, 
   4044                      cps_match_set_ids, cps_match_check_ids, matches, sig_ids, count);
   4045     if (rv) {
   4046         LOG_INFO(BSL_LS_BCM_REGEX,
   4047                  (BSL_META_U(unit,
   4048                              "could not attach hw_engine, rv %d\n"),
   4049                   rv));
   4050         goto fail;
   4051     }
   4052 
   4053     rv = _bcm_tr3_install_dfa(unit, dfa, matches, cps_match_set_ids, cps_match_check_ids,
   4054                               sig_ids, count, lengine->physical_engine);
   4055     if (rv) {
   4056         LOG_INFO(BSL_LS_BCM_REGEX,
   4057                  (BSL_META_U(unit,
   4058                              "could not install DFA, rv %d\n"),
   4059                   rv));
   4060         goto fail;
   4061     }
   4062 
   4063     /*
   4064     Return the signature ID, if requested
   4065     */
   4066     for (i = 0; i < count; i++) {
   4067         if (matches[i].flags & BCM_REGEX_MATCH_SIG_ID_RETURN) {
   4068             matches[i].sig_id = sig_ids[i];
   4069         }
   4070     }
   4071 
   4072     /* program the mapping table:
   4073      * If any case-sensitive matches, do not remap characters.
   4074      * Else, remap upper case to lower case characters.
   4075      */
   4076     if (ncs) {
   4077         _bcm_tr3_set_remap_table(unit, lengine->physical_engine->hw_idx, NULL);
   4078     } else {
   4079         _bcm_tr3_set_remap_table(unit, lengine->physical_engine->hw_idx,
   4080                                  cmap_lower_tbl);
   4081     }
   4082     
   4083     rv = READ_AXP_SM_REGEX_CONTROL0r(unit, 
   4084                             lengine->physical_engine->hw_idx, &regval);
   4085     if (SOC_FAILURE(rv)) {
   4086         LOG_INFO(BSL_LS_BCM_REGEX,
   4087                  (BSL_META_U(unit,
   4088                              "could not REGEX_CONTROL0 register, rv %d\n"),
   4089                   rv));
   4090         goto fail;
   4091     }
   4092     fval = 0;
   4093     if (cps_match_set_ids || need_check_ids) {
   4094         fval = 2;
   4095     } else if (lengine->config.flags & BCM_REGEX_ENGINE_CONFIG_MULTI_PACKET) {
   4096         fval = 1;
   4097     }
   4098     soc_reg_field_set(unit, AXP_SM_REGEX_CONTROL0r, &regval,
   4099                              CONTEXT_STORAGE_MODEf, fval);
   4100     WRITE_AXP_SM_REGEX_CONTROL0r(unit, lengine->physical_engine->hw_idx, regval);
   4101 
   4102     /*
   4103      * resolve any pending matches.
   4104      */
   4105      if (cps_match_set_ids) {
   4106         for (i = 0; i < count; i++) {
   4107             if (cps_match_set_ids[i] == -1) {
   4108                 continue;
   4109             }
   4110             _bcm_regexdb_handle_setid_avail(unit, 1, 
   4111                                             lengine->physical_engine->hw_idx,
   4112                                             matches[i].provides, cps_match_set_ids[i]);
   4113         }
   4114      }
   4115 
   4116     BCM_REGEX_ENABLE_ENGINE(device, unit, lengine->physical_engine);
   4117 
   4118     /*
   4119      * A signature is successfully configured. INT_SME_ENABLEf is to be SET here
   4120      * so as to let the flow tracker direct the packets to Signature Matching
   4121      * block for pattern matching
   4122      */
   4123     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit,&regval));
   4124     soc_reg_field_set(unit, FT_CONFIGr, &regval, INT_SME_ENABLEf, 1);
   4125     SOC_IF_ERROR_RETURN(WRITE_FT_CONFIGr(unit,regval));
   4126 
   4127 fail:
   4128     if (res) {
   4129         sal_free(res);
   4130     }
   4131 
   4132     if (res_flags) {
   4133         sal_free(res_flags);
   4134     }
   4135 
   4136     if (dfa) {
   4137         bcm_regex_dfa_free(dfa);
   4138     }
   4139 
   4140     if (cps_match_set_ids) {
   4141         sal_free(cps_match_set_ids);
   4142     }
   4143 
   4144     if (cps_match_check_ids) {
   4145         sal_free(cps_match_check_ids);
   4146     }
   4147 
   4148     if (rv) {
   4149         if (pengine) {
   4150             _bcm_tr3_regex_hw_engine_detach(unit, pengine);
   4151             lengine->physical_engine = NULL;
   4152         }
   4153         if (sig_ids) {
   4154             for (i = 0; i < count; i++) {
   4155                 _bcm_tr3_free_sigid(unit, sig_ids[i]);
   4156             }
   4157         }
   4158     }
   4159 
   4160     if (sig_ids) {
   4161         sal_free(sig_ids);
   4162     }
   4163 
   4164     BCM_REGEX_UNLOCK(unit);
   4165 
   4166     return rv;
   4167 }
   4168 
   4169 STATIC int
   4170 _bcm_regex_init_cmn(int unit, bcm_regex_desc_t *d, int cold)
   4171 {
   4172     _bcm_tr3_regex_device_info_t *device;
   4173     int     i, j, count;
   4174     soc_mem_t mem;
   4175     int entry_words[1], min_index_array[1];
   4176     _bcm_regex_cps_obj_t *pcps;
   4177     ft_age_profile_entry_t ftpm;
   4178     uint32          regval, fval;
   4179     bcm_regex_match_t def_mp;
   4180 
   4181     if (!cmap_lower_tbl) {
   4182         cmap_lower_tbl = sal_alloc(sizeof(uint8)*256, "remap_table");
   4183         for (i=0; i<256; i++) {
   4184             cmap_lower_tbl[i] = ((i >= 65) && (i <= 90)) ? i + 32 : i;
   4185         }
   4186     }
   4187 
   4188     /* Init logical engines.  */
   4189     if ((device = REGEX_INFO(unit)) == NULL) {
   4190         device = REGEX_INFO(unit) = sal_alloc(sizeof(_bcm_tr3_regex_device_info_t), 
   4191                               "_bcm_tr3_regex_device_info");
   4192         if (!device) {
   4193             return BCM_E_MEMORY;
   4194         }
   4195         sal_memset(device, 0, sizeof(_bcm_tr3_regex_device_info_t));
   4196         device->info = d;
   4197         BCM_TR3_NUM_ENGINE(device) = d->num_tiles * d->num_engine_per_tile;
   4198 
   4199         for (i = 0; i < 2; i++) {
   4200             device->flex_pools[i].pool_id = -1;
   4201         }
   4202     }
   4203 
   4204     sal_memset(device->sigid, 0xff, BCM_TR3_SIG_ID_MAP_BSZ*sizeof(uint32));
   4205     sal_memset(device->policer_bmp, 0, BCM_TR3_POLICER_NUM/sizeof(uint32));
   4206     device->regex_mutex = sal_mutex_create("regex_mutex");
   4207 
   4208     for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
   4209         sal_memset(&device->engines[i], 0, sizeof(_bcm_regex_lengine_t));
   4210         sal_memset(&device->physical_engines[i], 0, sizeof(_bcm_regex_engine_obj_t));
   4211         device->physical_engines[i].hw_idx = i;
   4212         device->physical_engines[i].tile = (int)i/d->num_engine_per_tile;
   4213         device->physical_engines[i].from_line = -1;
   4214         device->physical_engines[i].req_lsz = 0;
   4215         device->physical_engines[i].flags = 0;
   4216         device->engines[i].id = BCM_REGEX_ENGINE_ID(unit, i);
   4217         if (cold) {
   4218             SOC_IF_ERROR_RETURN(BCM_REGEX_RESET_ENGINE(device, unit, i));
   4219             bcm_regexdb_delete_by_engine_id(unit, i);
   4220         }
   4221         /* reset cps entries */
   4222         pcps = BCM_TR3_CPS_INFO(device, i);
   4223         pcps->foff = i*BCM_REGEX_NUM_SLOT_PER_CPS;
   4224         pcps->flags = 0;
   4225     }
   4226 
   4227     for (i=0; i<d->num_match_mem; i++) {
   4228         sal_memset(device->match_alloc_bmap[i], 0, 
   4229                                 BCM_TR3_MATCH_BMAP_BSZ*sizeof(uint32));
   4230         if (cold) {
   4231             /* clear match memory */
   4232             SOC_IF_ERROR_RETURN(soc_mem_clear(unit, 
   4233                     AXP_SM_MATCH_TABLE_MEM0m + i, COPYNO_ALL, TRUE));
   4234         }
   4235     }
   4236 
   4237     if (_bcm_tr3_ft_policy_profile[unit] == NULL) {
   4238         _bcm_tr3_ft_policy_profile[unit] =
   4239             sal_alloc(sizeof(soc_profile_mem_t), "FT_Policy Profile Mem");
   4240         if (_bcm_tr3_ft_policy_profile[unit] == NULL) {
   4241             return BCM_E_MEMORY;
   4242         }
   4243         soc_profile_mem_t_init(_bcm_tr3_ft_policy_profile[unit]);
   4244     }
   4245     mem = FT_POLICYm;
   4246     entry_words[0] = sizeof(ft_policy_entry_t) / sizeof(uint32);
   4247     min_index_array[0] = 1; /* reserve entry Zero */
   4248     SOC_IF_ERROR_RETURN(soc_profile_mem_index_create(unit, &mem, entry_words, 
   4249              &min_index_array[0], NULL, NULL, 1, _bcm_tr3_ft_policy_profile[unit]));
   4250 
   4251     if (cold) {
   4252         count = soc_mem_index_count(unit, FT_AGE_PROFILEm);
   4253         sal_memset(&ftpm, 0, sizeof(ftpm));
   4254         for (i = 0; i < count; i++) {
   4255             if (i == (count - 1)) {
   4256                 fval = 0x3fff;
   4257             } else {
   4258                 fval = (i <= 8) ? (16 << i) : 0x1000 + (0x400 * (i - 8)) - 1;
   4259             }
   4260             soc_mem_field32_set(unit, FT_AGE_PROFILEm, &ftpm, TIMEOUTf, fval);
   4261             SOC_IF_ERROR_RETURN(WRITE_FT_AGE_PROFILEm(unit, MEM_BLOCK_ALL, 
   4262                                                                     i, &ftpm));
   4263         }
   4264 
   4265         SOC_IF_ERROR_RETURN(READ_FT_REFRESH_CFGr(unit, &regval));
   4266         soc_reg_field_set(unit, FT_REFRESH_CFGr, &regval, ENABLEf, 1);
   4267         soc_reg_field_set(unit, FT_REFRESH_CFGr, &regval, MIN_TIMEf, 0x3fff);
   4268         SOC_IF_ERROR_RETURN(WRITE_FT_REFRESH_CFGr(unit, regval));
   4269 
   4270         /*
   4271         For now, just use defaults for these timeouts
   4272 
   4273         SOC_IF_ERROR_RETURN(READ_FT_NEW_TIMEOUTr(unit, &regval));
   4274         soc_reg_field_set(unit, FT_NEW_TIMEOUTr, &regval, UDPf, 0xfff);
   4275         soc_reg_field_set(unit, FT_NEW_TIMEOUTr, &regval, TCPf, 0xfff);
   4276         SOC_IF_ERROR_RETURN(WRITE_FT_NEW_TIMEOUTr(unit, regval));
   4277 
   4278         SOC_IF_ERROR_RETURN(READ_FT_HOLDWAIT_TIMEOUTr(unit, &regval));
   4279         soc_reg_field_set(unit, FT_HOLDWAIT_TIMEOUTr, &regval, UDPf, 0x7ff);
   4280         soc_reg_field_set(unit, FT_HOLDWAIT_TIMEOUTr, &regval, TCPf, 0x7ff);
   4281         SOC_IF_ERROR_RETURN(WRITE_FT_HOLDWAIT_TIMEOUTr(unit, regval));
   4282 
   4283         SOC_IF_ERROR_RETURN(READ_FT_CMDWAIT_TIMEOUTr(unit, &regval));
   4284         soc_reg_field_set(unit, FT_CMDWAIT_TIMEOUTr, &regval, MAX_TIMEf, 0x3ff);
   4285         SOC_IF_ERROR_RETURN(WRITE_FT_CMDWAIT_TIMEOUTr(unit, regval));
   4286         */
   4287 
   4288         SOC_IF_ERROR_RETURN(READ_FT_HASH_CONTROLr(unit, &regval));
   4289         soc_reg_field_set(unit, FT_HASH_CONTROLr, &regval, HASH_SELECT_Af, 1);
   4290         soc_reg_field_set(unit, FT_HASH_CONTROLr, &regval, HASH_SELECT_Bf, 1);
   4291         SOC_IF_ERROR_RETURN(WRITE_FT_HASH_CONTROLr(unit, regval));
   4292 
   4293         regval = 0;
   4294         SOC_IF_ERROR_RETURN(WRITE_AXP_SM_MEM_ECC_GEN_CONTROLr(unit, regval));
   4295 
   4296         for (j = 0; j < 8; j++) {
   4297             mem = _bcm_tr3_get_axp_sm_memory(unit, j);
   4298             SOC_IF_ERROR_RETURN(soc_mem_clear(unit, mem, MEM_BLOCK_ALL, 1));
   4299         }
   4300         BCM_IF_ERROR_RETURN(_bcm_tr3_regex_exclude_delete_all(unit));
   4301 
   4302         /* create a default policy profile */
   4303         sal_memset(&def_mp, 0, sizeof(bcm_regex_match_t));
   4304         BCM_IF_ERROR_RETURN(_bcm_tr3_install_action_policy(unit, &def_mp, 
   4305                                         _BCM_TR3_SET_DEFAULT_POLICY, NULL));
   4306     
   4307 	BCM_IF_ERROR_RETURN(_bcm_esw_regex_report_reset(unit));
   4308     }
   4309     
   4310     return BCM_E_NONE;
   4311 }
   4312 
   4313 #ifdef BCM_WARM_BOOT_SUPPORT
   4314 
   4315 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
   4316 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_0
   4317 
   4318 typedef struct _bcm_regex_dal_s {
   4319     int (*dal_op_u32)(uint8 **buf, uint32 *data, int in);
   4320     int (*dal_op_u16)(uint8 **buf, uint16 *data, int in);
   4321     int (*dal_op_u8)(uint8 **buf, uint8 *data, int in);
   4322 } _bcm_regex_dal_t;
   4323 
   4324 STATIC int _bcm_regex_dal_op_u32(uint8 **buf, uint32 *data, int in)
   4325 {
   4326     uint8 *pbuf = *buf;
   4327     int i, bshf = (sizeof(uint32) - 1) * 8;
   4328     uint32 v;
   4329 
   4330     if (in) {
   4331         for (i = 0; i < sizeof(uint32); i++, bshf -= 8) {
   4332             *pbuf++ = (uint8)((*data) >> bshf) & 0xff;
   4333         }
   4334     } else {
   4335         v = 0;
   4336         for (i = 0; i < sizeof(uint32); i++) {
   4337             v |= (uint32)((*pbuf) << bshf);
   4338             pbuf++;
   4339         }
   4340         *data = v;
   4341     }
   4342     *buf = pbuf;
   4343     return 0;
   4344 }
   4345 
   4346 STATIC int _bcm_regex_dal_op_u16(uint8 **buf, uint16 *data, int in)
   4347 {
   4348     uint8 *pbuf = *buf;
   4349     int i, bshf = (sizeof(uint16) - 1) * 8;
   4350     uint16 v;
   4351 
   4352     if (in) {
   4353         for (i = 0; i < sizeof(uint16); i++, bshf -= 8) {
   4354             *pbuf++ = (uint8)((*data) >> bshf) & 0xff;
   4355         }
   4356     } else {
   4357         v = 0;
   4358         for (i = 0; i < sizeof(uint16); i++) {
   4359             v |= (uint16)((*pbuf) << bshf);
   4360             pbuf++;
   4361         }
   4362         *data = v;
   4363     }
   4364     *buf = pbuf;
   4365     return 0;
   4366 }
   4367 
   4368 STATIC int _bcm_regex_dal_op_u8(uint8 **buf, uint8 *data, int in)
   4369 {
   4370     uint8 *pbuf = *buf;
   4371 
   4372     if (in) {
   4373         *pbuf++ = *data;
   4374     } else {
   4375         *data = *pbuf++;
   4376     }
   4377     *buf = pbuf;
   4378     return 0;
   4379 }
   4380 
   4381 static _bcm_regex_dal_t bcm_regex_dal = {
   4382                         _bcm_regex_dal_op_u32,
   4383                         _bcm_regex_dal_op_u16,
   4384                         _bcm_regex_dal_op_u8,
   4385                                     };
   4386 
   4387 #define BCM_REGEX_DAL_RD_U32(b,d) bcm_regex_dal.dal_op_u32((b),(d),0)
   4388 #define BCM_REGEX_DAL_RD_U16(b,d) bcm_regex_dal.dal_op_u16((b),(d),0)
   4389 #define BCM_REGEX_DAL_RD_U8(b,d) bcm_regex_dal.dal_op_u8((b),(d),0)
   4390 
   4391 #define BCM_REGEX_DAL_WR_U32(b,d) bcm_regex_dal.dal_op_u32((b),(d),1)
   4392 #define BCM_REGEX_DAL_WR_U16(b,d) bcm_regex_dal.dal_op_u16((b),(d),1)
   4393 #define BCM_REGEX_DAL_WR_U8(b,d) bcm_regex_dal.dal_op_u8((b),(d),1)
   4394 
   4395 #define BCM_REGEX_WARMBOOT_ENGINE_SIG   0x07062005
   4396 #define BCM_REGEX_WARMBOOT_MATCH_SIG    0x07062012
   4397 
   4398 #if 0
   4399 STATIC int _bcm_regex_engine_reinit(int unit, uint8 **regex_data)
   4400 {
   4401     uint32 v, i, leid, peid, req_lsz, cps_lsz;
   4402     uint16 v16;
   4403     uint8  v8, tv8;
   4404     _bcm_tr3_regex_device_info_t *device;
   4405     _bcm_regex_engine_obj_t      engine_info, *pengine;
   4406     _bcm_regex_lengine_t         *lengine;
   4407 
   4408     device = REGEX_INFO(unit);
   4409 
   4410     /* read marker */
   4411     BCM_REGEX_DAL_RD_U32(regex_data, &v);
   4412     if (v != BCM_REGEX_WARMBOOT_ENGINE_SIG) {
   4413         return BCM_E_MEMORY;
   4414     }
   4415 
   4416     BCM_REGEX_DAL_RD_U8(regex_data, &v8);
   4417 
   4418     for (i=0; i<v8; i++) {
   4419         /* logicval engine id */
   4420         BCM_REGEX_DAL_WR_U8(regex_data, &tv8);
   4421         leid = (uint32) tv8;
   4422         /* physical engine id */
   4423         BCM_REGEX_DAL_WR_U8(regex_data, &tv8);
   4424         peid = (uint32) tv8;
   4425         /* engine dfa length */
   4426         BCM_REGEX_DAL_WR_U16(regex_data, &v16);
   4427         req_lsz = (uint16) v16;
   4428         /* engine cps length */
   4429         BCM_REGEX_DAL_WR_U16(regex_data, &v16);
   4430         cps_lsz = (uint16) v16;
   4431 
   4432         BCM_REGEX_GET_ENGINE_INFO(device, unit, peid, &engine_info);
   4433         if (!BCM_REGEX_ENGINE_ALLOCATED(&engine_info)) {
   4434             continue;
   4435         }
   4436         pengine = BCM_TR3_PHYSICAL_ENGINE(device, peid); 
   4437         lengine = BCM_TR3_LOGICAL_ENGINE(device, leid);
   4438         BCM_REGEX_ENGINE_SET_ALLOCATED(lengine);
   4439         BCM_REGEX_ENGINE_SET_ALLOCATED(pengine);
   4440         pengine->from_line = engine_info.from_line;
   4441         pengine->req_lsz = req_lsz;
   4442         pengine->cps.req_lsz = cps_lsz;
   4443         pengine->total_lsz = cps_lsz + req_lsz;
   4444         /* set physical engine mapping */
   4445         lengine->physical_engine = pengine;
   4446     }
   4447     
   4448     BCM_REGEX_DAL_RD_U32(regex_data, &v);
   4449     if (v != ~BCM_REGEX_WARMBOOT_ENGINE_SIG) {
   4450         return BCM_E_MEMORY;
   4451     }
   4452     return BCM_E_NONE;
   4453 }
   4454 #endif
   4455 
   4456 STATIC int _bcm_regex_engine_sync(int unit, uint8 **regex_data)
   4457 {
   4458     uint32 i, v32;
   4459     uint8  v8;
   4460     uint16 v16;
   4461     _bcm_tr3_regex_device_info_t *device;
   4462     _bcm_regex_lengine_t         *lengine;
   4463 
   4464     device = REGEX_INFO(unit);
   4465 
   4466     /* read marker */
   4467     v32 = BCM_REGEX_WARMBOOT_ENGINE_SIG;
   4468     BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4469 
   4470     for (i=0,v8=0; i<BCM_TR3_NUM_ENGINE(device); i++) {
   4471         lengine = BCM_TR3_LOGICAL_ENGINE(device, i);
   4472         if (BCM_REGEX_ENGINE_ALLOCATED(lengine)) {
   4473             v8++;
   4474         }
   4475     }
   4476     
   4477     BCM_REGEX_DAL_WR_U8(regex_data, &v8);
   4478 
   4479     /*
   4480      * write engine data.
   4481      */
   4482     for (i=0; i<BCM_TR3_NUM_ENGINE(device); i++) {
   4483         lengine = BCM_TR3_LOGICAL_ENGINE(device, i);
   4484         if (!BCM_REGEX_ENGINE_ALLOCATED(lengine)) {
   4485             continue;
   4486         }
   4487 
   4488         /* engine data:
   4489          *  engine logical index (u8), engine physical index(u8),
   4490          *  dfa length (u16)
   4491          */
   4492         /* engine logical index */
   4493         v8 = (uint8)i;
   4494         BCM_REGEX_DAL_WR_U8(regex_data, &v8);
   4495         /* engine physical index */
   4496         v8 = (uint8) lengine->physical_engine->hw_idx;
   4497         BCM_REGEX_DAL_WR_U8(regex_data, &v8);
   4498         /* engine dfa size */
   4499         v16 = lengine->physical_engine->req_lsz;
   4500         BCM_REGEX_DAL_WR_U16(regex_data, &v16);
   4501         /* engine cps size */
   4502         v16 = lengine->physical_engine->cps.req_lsz;
   4503         BCM_REGEX_DAL_WR_U16(regex_data, &v16);
   4504     }
   4505 
   4506     v32 = ~BCM_REGEX_WARMBOOT_ENGINE_SIG;
   4507     BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4508     return 0;
   4509 }
   4510 
   4511 #if 0
   4512 STATIC int _bcm_regex_match_reinit(int unit, uint8 **regex_data)
   4513 {
   4514     uint32 i, v32;
   4515     uint16 f, num_match = 0;
   4516     _bcm_tr3_regex_device_info_t *device;
   4517     _bcm_regexdb_entry_t pe;
   4518     axp_sm_match_table_mem0_entry_t match_entry;
   4519     soc_mem_t mem;
   4520     int match_set_id = -1, match_chk_id = -1, hw_match_idx;
   4521     uint32 *alloc_bmap;
   4522     _bcm_regex_engine_obj_t *pengine = NULL;
   4523 
   4524     device = REGEX_INFO(unit);
   4525 
   4526     BCM_REGEX_DAL_RD_U32(regex_data, &v32);
   4527     if (v32 != BCM_REGEX_WARMBOOT_MATCH_SIG) {
   4528         return BCM_E_MEMORY;
   4529     }
   4530 
   4531     /* read the number of match entries */
   4532     BCM_REGEX_DAL_RD_U16(regex_data, &num_match);
   4533 
   4534     for (i=0; i<num_match; i++) {
   4535         sal_memset(&pe, 0, sizeof(_bcm_regexdb_entry_t));
   4536 
   4537         /* read 2 byte flag */
   4538         BCM_REGEX_DAL_RD_U16(regex_data, &f);
   4539 
   4540         /* read match id */
   4541         BCM_REGEX_DAL_RD_U32(regex_data, (uint32*)&pe.engid);
   4542 
   4543         pengine = BCM_TR3_PHYSICAL_ENGINE(device, pe.engid);
   4544 
   4545         /* read signature id */
   4546         BCM_REGEX_DAL_RD_U32(regex_data, (uint32*)&pe.sigid);
   4547 
   4548         device->sigid[pe.sigid/32] |= 1 << (pe.sigid % 32);
   4549 
   4550         /* read match id */
   4551         BCM_REGEX_DAL_RD_U32(regex_data, (uint32*)&pe.match_id);
   4552 
   4553         /* read match index */
   4554         BCM_REGEX_DAL_RD_U32(regex_data, (uint32*)&pe.match_index);
   4555 
   4556         /* read provides and requires ID if valid */
   4557         if (f & BCM_REGEXDB_MATCH_PROVIDES) {
   4558             BCM_REGEX_DAL_RD_U32(regex_data, (uint32*)&pe.provides);
   4559         }
   4560 
   4561         if (f & BCM_REGEXDB_MATCH_REQUIRES) {
   4562             BCM_REGEX_DAL_RD_U32(regex_data, (uint32*)&pe.requires);
   4563         }
   4564 
   4565         /* read match entry and find the match_set_id and match_chk_id */
   4566         mem = AXP_SM_MATCH_TABLE_MEM0m + 
   4567                         BCM_REGEX_ENG2MATCH_MEMIDX(unit,pe.engid);
   4568 
   4569         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
   4570                     MEM_BLOCK_ALL, pe.match_index, &match_entry));
   4571 
   4572         if (soc_mem_field32_get(unit, mem, &match_entry, 
   4573                                             MATCH_CROSS_SIG_FLAG_SETf)) {
   4574             /* set the new setid */
   4575             match_set_id = soc_mem_field32_get(unit, mem, &match_entry,
   4576                                             MATCH_CROSS_SIG_FLAG_INDEXf);
   4577             pengine->cps.alloc_map[match_set_id % BCM_REGEX_NUM_SLOT_PER_CPS] = match_set_id;
   4578             pengine->cps.alloc_map[match_set_id % BCM_REGEX_NUM_SLOT_PER_CPS]++;
   4579         }
   4580 
   4581         if (soc_mem_field32_get(unit, mem, &match_entry,
   4582                                 CHECK_CROSS_SIG_FLAG_IS_SETf)) {
   4583             /* set the new chkid */
   4584             match_chk_id = soc_mem_field32_get(unit, mem, &match_entry,
   4585                                              MATCH_CROSS_SIG_FLAG_INDEXf);
   4586         }
   4587 
   4588         alloc_bmap = BCM_TR3_MATCH_BMAP_PTR(unit, device, pe.engid);
   4589         alloc_bmap[pe.match_index/32] |= 1 << (pe.match_index % 32);
   4590 
   4591         /* 
   4592          * also ref count for match profiles.
   4593          * also cps allocation and reference count 
   4594          */
   4595         hw_match_idx = (pe.match_index % 1024);
   4596 
   4597         alloc_bmap = BCM_TR3_MATCH_BMAP_PTR(unit, device, pe.engid);
   4598         alloc_bmap[hw_match_idx/32] &= ~(1 << (hw_match_idx % 32));
   4599         BCM_IF_ERROR_RETURN(bcm_regexdb_add_entry(unit, pe.match_index, pe.engid, 
   4600                pe.match_id, pe.sigid, pe.provides, pe.requires, match_set_id, match_chk_id));
   4601     }
   4602 
   4603     /* end marker */
   4604     BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4605     if (v32 != ~BCM_REGEX_WARMBOOT_MATCH_SIG) {
   4606         return BCM_E_MEMORY;
   4607     }
   4608 
   4609     return BCM_E_NONE;
   4610 }
   4611 #endif
   4612 
   4613 STATIC int _bcm_regex_match_sync(int unit, uint8 **regex_data)
   4614 {
   4615     uint32 i, v32;
   4616     uint8  *num_match_loc;
   4617     uint16 f, num_match = 0;
   4618     _bcm_tr3_regex_device_info_t *device;
   4619     _bcm_regexdb_entry_t *pe;
   4620 
   4621     device = REGEX_INFO(unit);
   4622 
   4623     v32 = BCM_REGEX_WARMBOOT_MATCH_SIG;
   4624     BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4625 
   4626     /* save the location to write the number of match entries */
   4627     num_match_loc = *regex_data;
   4628     BCM_REGEX_DAL_WR_U16(regex_data, &num_match);
   4629 
   4630     for (i=0; i<BCM_REGEX_DB_BUCKET_MAX; i++) {
   4631         pe = device->l[i];
   4632         while (pe) {
   4633             f = 0;
   4634             if (pe->provides > 0) {
   4635                 f |= BCM_REGEXDB_MATCH_PROVIDES;
   4636             }
   4637             if (pe->requires > 0) {
   4638                 f |= BCM_REGEXDB_MATCH_REQUIRES;
   4639             }
   4640             /* write 2 byte flag */
   4641             BCM_REGEX_DAL_WR_U16(regex_data, &f);
   4642 
   4643             /* write physical engine id */
   4644             v32 = (uint32) pe->engid;
   4645             BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4646 
   4647             /* write signature id */
   4648             v32 = (uint32) pe->sigid;
   4649             BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4650 
   4651             /* write match id */
   4652             v32 = (uint32) pe->match_id;
   4653             BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4654 
   4655             /* write match index */
   4656             v32 = (uint32) pe->match_index;
   4657             BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4658 
   4659             /* write provides and requires ID if valid */
   4660             if (f & BCM_REGEXDB_MATCH_PROVIDES) {
   4661                 v32 = (uint32) pe->provides;
   4662                 BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4663             }
   4664 
   4665             if (f & BCM_REGEXDB_MATCH_REQUIRES) {
   4666                 v32 = (uint32) pe->requires;
   4667                 BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4668             }
   4669             num_match++;
   4670             pe = pe->next;
   4671         }
   4672     }
   4673 
   4674     BCM_REGEX_DAL_WR_U16(&num_match_loc, &num_match);
   4675 
   4676     /* end marker */
   4677     v32 = ~BCM_REGEX_WARMBOOT_MATCH_SIG;
   4678     BCM_REGEX_DAL_WR_U32(regex_data, &v32);
   4679 
   4680     return BCM_E_NONE;
   4681 }
   4682 
   4683 #define REGEX_WB_CACHE_SZ       4096
   4684 
   4685 #if 0
   4686 STATIC int 
   4687 _bcm_tr3_regex_reinit(int unit)
   4688 {
   4689     soc_scache_handle_t scache_handle;
   4690     int     rv = BCM_E_NONE;
   4691     int     stable_size;
   4692     uint8   *regex_data;
   4693 
   4694     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_REGEX, 0);
   4695 
   4696     if (!SOC_WARM_BOOT(unit)) {
   4697         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
   4698                                      REGEX_WB_CACHE_SZ, &regex_data, 
   4699                                      BCM_WB_DEFAULT_VERSION, NULL);
   4700         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   4701             return rv;
   4702         }
   4703         return BCM_E_NONE;
   4704     } else {
   4705 
   4706         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
   4707 
   4708         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
   4709                                      stable_size, &regex_data,
   4710                                      BCM_WB_DEFAULT_VERSION, NULL);
   4711 
   4712         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   4713             return rv;
   4714         }
   4715 
   4716         if (NULL == regex_data) {
   4717             return BCM_E_MEMORY;
   4718         }
   4719 
   4720         SOC_IF_ERROR_RETURN(_bcm_regex_engine_reinit(unit, &regex_data));
   4721 
   4722         SOC_IF_ERROR_RETURN(_bcm_regex_match_reinit(unit, &regex_data));
   4723     }
   4724 
   4725     return rv;
   4726 }
   4727 #endif
   4728 
   4729 int _bcm_esw_tr3_regex_sync(int unit)
   4730 {
   4731     soc_scache_handle_t scache_handle;
   4732     int       stable_size, rv = BCM_E_NONE;
   4733     uint8     *regex_data, *data_start;
   4734 
   4735     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_REGEX, 0);
   4736     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
   4737     
   4738     rv = _bcm_esw_scache_ptr_get(unit,
   4739                                  scache_handle, FALSE,
   4740                                  REGEX_WB_CACHE_SZ, &data_start,
   4741                                  BCM_WB_DEFAULT_VERSION, NULL);
   4742 
   4743     if (BCM_FAILURE(rv) && (rv != BCM_E_INTERNAL)) {
   4744         return rv;
   4745     }
   4746 
   4747     if (NULL == data_start) {
   4748         return BCM_E_MEMORY;
   4749     }
   4750     regex_data = data_start;
   4751     rv = _bcm_regex_engine_sync(unit, &regex_data);
   4752     if (SOC_FAILURE(rv)) {
   4753         goto fail;
   4754     }
   4755 
   4756     rv = _bcm_regex_match_sync(unit, &regex_data);
   4757 
   4758 fail:
   4759     return rv;
   4760 }
   4761 #endif  /* BCM_WARM_BOOT_SUPPORT */
   4762 
   4763 int _bcm_tr3_regex_init(int unit, _bcm_esw_regex_functions_t **functions)
   4764 {
   4765     bcm_regex_desc_t *d = NULL;
   4766     int cold = 1, rv = BCM_E_NONE;
   4767 
   4768     if (SOC_IS_TRIUMPH3(unit)) {
   4769         d = &tr3_regex_info;
   4770     }
   4771 
   4772     if (!d) {
   4773         return BCM_E_UNAVAIL;
   4774     }
   4775 
   4776     BCM_REGEX_LOCK(unit);
   4777 
   4778     rv = _bcm_regex_init_cmn(unit, d, cold);
   4779     if (SOC_FAILURE(rv)) {
   4780         goto fail;
   4781     }
   4782 
   4783 #ifdef BCM_WARM_BOOT_SUPPORT
   4784     /* No WARMBOOT support for REGEX */ 
   4785 #endif
   4786 
   4787     *functions = &_regex_tr3_functions;
   4788 
   4789 fail:
   4790     return rv;
   4791 }
   4792 
   4793 extern int _bcm_ft_key_field_set(uint32 *fld, int bp, int len, uint32 *kfld);
   4794 extern int _bcm_ft_key_field_get(uint32 *fld, int bp, int len, uint32 *kfld);
   4795 extern int _bcm_ft_key_field_get_char(uint32 *fld, int bp, int len, uint8 *kfld);
   4796 extern int _bcm_ft_key_field_set_char(uint32 *fld, int bp, int len, uint8 *kfld);
   4797 
   4798 /*
   4799  * Function:
   4800  *      _bcm_tr3_ft_session_to_hw
   4801  * Purpose:
   4802  *      Convert a hardware-independent FT session entry to a TR3 FT
   4803  *      session HW entry
   4804  * Parameters:
   4805  *      unit - Unit number
   4806  *      hw_entry - (OUT) Triumph 3 HW entry
   4807  *      flags - FT session flags (e.g. static entry)
   4808  *      key - Hardware-independent FT session key
   4809  *      session - Hardware-independent FT session info
   4810  */
   4811 
   4812 STATIC int
   4813 _bcm_tr3_ft_session_to_hw(int unit, ft_session_entry_t *hw_entry, int flags,
   4814                           bcm_regex_session_key_t *key,
   4815                           bcm_regex_session_t *session)
   4816 {
   4817     uint32 key_field[_REGEX_KEY_FIELD_LENGTH/32 + 1], direction;
   4818     uint32 ip1, ip2, port1, port2, protocol;
   4819     int i, age_profile = -1, max_index, ticks;
   4820     ft_age_profile_entry_t ftpm;
   4821     uint32 regval, flow_state;
   4822     uint8 *p8;
   4823 
   4824     soc_FT_SESSIONm_field32_set(unit, hw_entry, VALIDf, 1);
   4825     soc_FT_SESSIONm_field32_set(unit, hw_entry, KEY_TYPEf,
   4826                                 _REGEX_SESSION_KEY_TYPE_IPV4);
   4827 
   4828     if (session != NULL) {
   4829         soc_FT_SESSIONm_field32_set(unit, hw_entry, POLICY_INDEXf,
   4830                                     session->policy);
   4831 
   4832         /*
   4833         Granularity of AGE_PROFILE entries is 10ms, and inactivity_timeout
   4834         is in usecs.
   4835         */
   4836         ticks = session->inactivity_timeout/_REGEX_SESSION_AGE_PROFILE_TICKS_US;
   4837         max_index = soc_mem_index_max(unit, FT_AGE_PROFILEm);
   4838         for (i = max_index; i >= 0; i--) {
   4839             SOC_IF_ERROR_RETURN(READ_FT_AGE_PROFILEm(unit, MEM_BLOCK_ALL,
   4840                                                         i, &ftpm));
   4841             if (ticks >= soc_mem_field32_get(unit,
   4842                                     FT_AGE_PROFILEm, &ftpm, TIMEOUTf)) {
   4843                 age_profile = (i == max_index) ? i : i + 1;
   4844                 break;
   4845             }
   4846         }
   4847 
   4848         if (age_profile == -1) {
   4849             age_profile = soc_mem_index_max(unit, FT_AGE_PROFILEm);
   4850         }
   4851 
   4852         LOG_INFO(BSL_LS_BCM_REGEX,
   4853                  (BSL_META_U(unit,
   4854                              "ticks = %d (0x%x), age_profile = 0x%x\n"),
   4855                   ticks, ticks, age_profile));
   4856 
   4857         soc_FT_SESSIONm_field32_set(unit, hw_entry, AGE_PROFILEf,
   4858                                     age_profile);
   4859 
   4860         if (session->flags & BCM_REGEX_SESSION_STATIC) {
   4861             soc_FT_SESSIONm_field32_set(unit, hw_entry, STATIC_BITf, 1);
   4862         }
   4863 
   4864         /* Entries that are added will be set to flow state ACTIVE */
   4865 
   4866         flow_state = _REGEX_SESSION_FLOW_STATE_ACTIVE;
   4867 
   4868         soc_FT_SESSIONm_field32_set(unit, hw_entry, FLOW_STATEf,
   4869                                     flow_state);
   4870 
   4871         LOG_INFO(BSL_LS_BCM_REGEX,
   4872                  (BSL_META_U(unit,
   4873                              "flow_state: 0x%x\n"),
   4874                   flow_state));
   4875     }
   4876 
   4877     /*
   4878     Current time and flow timestamp are both in units of 10ms
   4879     */
   4880     SOC_IF_ERROR_RETURN(READ_FT_CURRENT_TIMEr(unit, &regval));
   4881     soc_FT_SESSIONm_field32_set(unit, hw_entry, ID_TIMESTAMPf, regval);
   4882 
   4883     if (key->dip < key->sip) {
   4884         direction = _REGEX_SESSION_DIRECTION_REVERSE;
   4885     } else {
   4886         direction = _REGEX_SESSION_DIRECTION_FORWARD;
   4887     }
   4888 
   4889     protocol = key->protocol;
   4890 
   4891     if (direction == _REGEX_SESSION_DIRECTION_REVERSE) {
   4892       ip1 = key->sip;
   4893       ip2 = key->dip;
   4894       port1 = key->src_port;
   4895       port2 = key->dst_port;
   4896     } else {
   4897       ip1 = key->dip;
   4898       ip2 = key->sip;
   4899       port1 = key->dst_port;
   4900       port2 = key->src_port;
   4901     }
   4902 
   4903     LOG_INFO(BSL_LS_BCM_REGEX,
   4904              (BSL_META_U(unit,
   4905                          "ip1 = 0x%08x\n"),
   4906               ip1));
   4907     LOG_INFO(BSL_LS_BCM_REGEX,
   4908              (BSL_META_U(unit,
   4909                          "ip2 = 0x%08x\n"),
   4910               ip2));
   4911     LOG_INFO(BSL_LS_BCM_REGEX,
   4912              (BSL_META_U(unit,
   4913                          "port1 = 0x%04x\n"),
   4914               port1));
   4915     LOG_INFO(BSL_LS_BCM_REGEX,
   4916              (BSL_META_U(unit,
   4917                          "port2 = 0x%04x\n"),
   4918               port2));
   4919     LOG_INFO(BSL_LS_BCM_REGEX,
   4920              (BSL_META_U(unit,
   4921                          "protocol = 0x%02x\n"),
   4922               protocol));
   4923 
   4924     /*
   4925     _bcm_ft_key_field_set uses bit or to set the various bits in
   4926     the field, so the fields must be set to 0 before use
   4927     */
   4928     for (i = 0; i < (_REGEX_KEY_FIELD_LENGTH/32 + 1); i++) {
   4929         key_field[i] = 0;
   4930     }
   4931 
   4932     _bcm_ft_key_field_set(key_field, _REGEX_KEY_FIELD_V4_OFFSET_PORT_1,
   4933                           _REGEX_KEY_FIELD_V4_LENGTH_PORT_1, &port1);
   4934     _bcm_ft_key_field_set(key_field, _REGEX_KEY_FIELD_V4_OFFSET_PORT_2,
   4935                           _REGEX_KEY_FIELD_V4_LENGTH_PORT_2, &port2);
   4936     _bcm_ft_key_field_set(key_field, _REGEX_KEY_FIELD_V4_OFFSET_PROTOCOL,
   4937                           _REGEX_KEY_FIELD_V4_LENGTH_PROTOCOL, &protocol);
   4938     _bcm_ft_key_field_set(key_field, _REGEX_KEY_FIELD_V4_OFFSET_IP_1,
   4939                           _REGEX_KEY_FIELD_V4_LENGTH_IP_1, &ip1);
   4940     _bcm_ft_key_field_set(key_field, _REGEX_KEY_FIELD_V4_OFFSET_IP_2,
   4941                           _REGEX_KEY_FIELD_V4_LENGTH_IP_2, &ip2);
   4942 
   4943     LOG_INFO(BSL_LS_BCM_REGEX,
   4944              (BSL_META_U(unit,
   4945                          "direction = 0x%x\n"),
   4946               direction));
   4947     soc_FT_SESSIONm_field32_set(unit, hw_entry, KEY_DIRECTIONf, direction);
   4948     p8 = (uint8*) key_field;
   4949     LOG_INFO(BSL_LS_BCM_REGEX,
   4950              (BSL_META_U(unit,
   4951                          "key_field = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"),
   4952               *p8, *(p8+1), *(p8+2), *(p8+3), *(p8+4), *(p8+5), *(p8+6), *(p8+7), *(p8+8), *(p8+9), *(p8+10), *(p8+11), *(p8+12)));
   4953     soc_FT_SESSIONm_field_set(unit, hw_entry, KEYf, key_field);
   4954 
   4955     return BCM_E_NONE;
   4956 }
   4957 
   4958 /*
   4959  * Function:
   4960  *      _bcm_tr3_ft_session_ipv6_to_hw
   4961  * Purpose:
   4962  *      Convert a hardware-independent FT session IPV6 entry to a TR3 FT
   4963  *      session IPV6 HW entry
   4964  * Parameters:
   4965  *      unit - Unit number
   4966  *      hw_entry6 - (OUT) Triumph 3 HW entry
   4967  *      flags - FT session flags (e.g. static entry)
   4968  *      key - Hardware-independent FT session key
   4969  *      session - Hardware-independent FT session info
   4970  */
   4971 
   4972 STATIC int
   4973 _bcm_tr3_ft_session_ipv6_to_hw(int unit, ft_session_ipv6_entry_t *hw_entry6,
   4974                                int flags, bcm_regex_session_key_t *key,
   4975                                bcm_regex_session_t *session)
   4976 {
   4977     uint32 key_upper[_REGEX_KEY_UPPER_LENGTH/32 + 1];
   4978     uint32 key_lower[_REGEX_KEY_LOWER_LENGTH/32 + 1], direction;
   4979     bcm_ip6_t sip6, dip6;
   4980     uint32 port1, port2, protocol;
   4981     int i, age_profile = -1, max_index, ticks;
   4982     ft_age_profile_entry_t ftpm;
   4983     uint32 regval, flow_state;
   4984 
   4985     soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, VALIDf, 1);
   4986     soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, VALID_0f, 1);
   4987     soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, KEY_TYPEf,
   4988                                      _REGEX_SESSION_KEY_TYPE_IPV6_UPPER);
   4989     soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, KEY_TYPE_0f,
   4990                                      _REGEX_SESSION_KEY_TYPE_IPV6_LOWER);
   4991     if (session != NULL) {
   4992         soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, POLICY_INDEXf,
   4993                                          session->policy);
   4994 
   4995         /*
   4996         Granularity of AGE_PROFILE entries is 10ms, and inactivity_timeout
   4997         is in usecs.
   4998         */
   4999         ticks = session->inactivity_timeout/_REGEX_SESSION_AGE_PROFILE_TICKS_US;
   5000         max_index = soc_mem_index_max(unit, FT_AGE_PROFILEm);
   5001         for (i = max_index; i >= 0; i--) {
   5002             SOC_IF_ERROR_RETURN(READ_FT_AGE_PROFILEm(unit, MEM_BLOCK_ALL,
   5003                                                         i, &ftpm));
   5004             if (ticks >= soc_mem_field32_get(unit,
   5005                                     FT_AGE_PROFILEm, &ftpm, TIMEOUTf)) {
   5006                 age_profile = (i == max_index) ? i : i + 1;
   5007                 break;
   5008             }
   5009         }
   5010 
   5011         if (age_profile == -1) {
   5012             age_profile = soc_mem_index_max(unit, FT_AGE_PROFILEm);
   5013         }
   5014 
   5015         LOG_INFO(BSL_LS_BCM_REGEX,
   5016                  (BSL_META_U(unit,
   5017                              "ticks = %d (0x%x), age_profile = 0x%x\n"),
   5018                   ticks, ticks, age_profile));
   5019 
   5020         soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, AGE_PROFILEf,
   5021                                          age_profile);
   5022 
   5023         if (session->flags & BCM_REGEX_SESSION_STATIC) {
   5024             soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, STATIC_BITf, 1);
   5025         }
   5026 
   5027         /* Entries that are added will be set to flow state ACTIVE */
   5028 
   5029         flow_state = _REGEX_SESSION_FLOW_STATE_ACTIVE;
   5030 
   5031         soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, FLOW_STATEf,
   5032                                          flow_state);
   5033 
   5034         LOG_INFO(BSL_LS_BCM_REGEX,
   5035                  (BSL_META_U(unit,
   5036                              "flow_state: 0x%x\n"),
   5037                   flow_state));
   5038     }
   5039 
   5040     /*
   5041     Current time and flow timestamp are both in units of 10ms
   5042     */
   5043     SOC_IF_ERROR_RETURN(READ_FT_CURRENT_TIMEr(unit, &regval));
   5044     soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, ID_TIMESTAMPf, regval);
   5045 
   5046     direction = 0;
   5047     for (i = 0; i < _SHR_L3_IP6_ADDRLEN; i++) {
   5048         if (key->dip6[i] < key->sip6[i]) {
   5049             direction = _REGEX_SESSION_DIRECTION_REVERSE;
   5050             break;
   5051         } else if (key->sip6[i] < key->dip6[i]) {
   5052             direction = _REGEX_SESSION_DIRECTION_FORWARD;
   5053             break;
   5054         } else if (i == _SHR_L3_IP6_ADDRLEN) {
   5055             direction = _REGEX_SESSION_DIRECTION_FORWARD;
   5056             break;
   5057         } else {
   5058             continue;
   5059         }
   5060     }
   5061 
   5062     protocol = key->protocol;
   5063 
   5064     if (direction == _REGEX_SESSION_DIRECTION_REVERSE) {
   5065       port1 = key->src_port;
   5066       port2 = key->dst_port;
   5067     } else {
   5068       port1 = key->dst_port;
   5069       port2 = key->src_port;
   5070     }
   5071 
   5072     /*
   5073     _bcm_ft_key_field_set uses bit or to set the various bits in
   5074     the field, so the fields must be set to 0 before use
   5075     */
   5076     for (i = 0; i < (_REGEX_KEY_UPPER_LENGTH/32 + 1); i++) {
   5077         key_upper[i] = 0;
   5078     }
   5079 
   5080     for (i = 0; i < (_REGEX_KEY_LOWER_LENGTH/32 + 1); i++) {
   5081         key_lower[i] = 0;
   5082     }
   5083 
   5084     _bcm_ft_key_field_set(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_PORT_1,
   5085                           _REGEX_KEY_LOWER_V6_LENGTH_PORT_1, &port1);
   5086     _bcm_ft_key_field_set(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_PORT_2,
   5087                           _REGEX_KEY_LOWER_V6_LENGTH_PORT_2, &port2);
   5088     _bcm_ft_key_field_set(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_PROTOCOL,
   5089                           _REGEX_KEY_LOWER_V6_LENGTH_PROTOCOL, &protocol);
   5090     /*
   5091     IPv6 addresses will go into hardware in reverse order, so reverse
   5092     the addresses here
   5093     */
   5094 
   5095     for (i = 0; i < _SHR_L3_IP6_ADDRLEN; i++) {
   5096         sip6[i] = key->sip6[_SHR_L3_IP6_ADDRLEN - i - 1];
   5097         dip6[i] = key->dip6[_SHR_L3_IP6_ADDRLEN - i - 1];
   5098     }
   5099 
   5100     if (direction == _REGEX_SESSION_DIRECTION_FORWARD) {
   5101         _bcm_ft_key_field_set_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_1,
   5102                               _REGEX_KEY_LOWER_V6_LENGTH_IP_1, dip6);
   5103     } else {
   5104         _bcm_ft_key_field_set_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_1,
   5105                               _REGEX_KEY_LOWER_V6_LENGTH_IP_1, sip6);
   5106     }
   5107     if (direction == _REGEX_SESSION_DIRECTION_FORWARD) {
   5108         _bcm_ft_key_field_set_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_2,
   5109                               _REGEX_KEY_LOWER_V6_LENGTH_IP_2, sip6);
   5110     } else {
   5111         _bcm_ft_key_field_set_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_2,
   5112                               _REGEX_KEY_LOWER_V6_LENGTH_IP_2, dip6);
   5113     }
   5114     if (direction == _REGEX_SESSION_DIRECTION_FORWARD) {
   5115         _bcm_ft_key_field_set_char(key_upper, _REGEX_KEY_UPPER_V6_OFFSET_IP_2,
   5116                                    _REGEX_KEY_UPPER_V6_LENGTH_IP_2,
   5117                                    &sip6[_REGEX_KEY_LOWER_V6_LENGTH_IP_2/8]);
   5118     } else {
   5119         _bcm_ft_key_field_set_char(key_upper, _REGEX_KEY_UPPER_V6_OFFSET_IP_2,
   5120                                    _REGEX_KEY_UPPER_V6_LENGTH_IP_2,
   5121                                    &dip6[_REGEX_KEY_LOWER_V6_LENGTH_IP_2/8]);
   5122     }
   5123 
   5124     LOG_INFO(BSL_LS_BCM_REGEX,
   5125              (BSL_META_U(unit,
   5126                          "direction = 0x%x\n"),
   5127               direction));
   5128     soc_FT_SESSION_IPV6m_field32_set(unit, hw_entry6, KEY_DIRECTIONf, direction);
   5129     LOG_INFO(BSL_LS_BCM_REGEX,
   5130              (BSL_META_U(unit,
   5131                          "set mem %s field %s\n"),
   5132               soc_mem_name[FT_SESSION_IPV6m], soc_fieldnames[KEYf]));
   5133     soc_FT_SESSION_IPV6m_field_set(unit, hw_entry6, KEYf, key_upper);
   5134     LOG_INFO(BSL_LS_BCM_REGEX,
   5135              (BSL_META_U(unit,
   5136                          "set mem %s field %s\n"),
   5137               soc_mem_name[FT_SESSION_IPV6m], soc_fieldnames[IPV6_LOWER_KEYf]));
   5138     soc_FT_SESSION_IPV6m_field_set(unit, hw_entry6, IPV6_LOWER_KEYf, key_lower);
   5139 
   5140     return BCM_E_NONE;
   5141 }
   5142 
   5143 /*
   5144  * Function:
   5145  *      _bcm_tr3_ft_session_from_hw
   5146  * Purpose:
   5147  *      Convert a TR3 FT session HW entry to a hardware-independent
   5148  *      FT session entry
   5149  * Parameters:
   5150  *      unit - Unit number
   5151  *      flags - (OUT) FT session flags (e.g. static entry)
   5152  *      key - (OUT) Hardware-independent FT session key
   5153  *      session - (OUT) Hardware-independent FT session info
   5154  *      hw_entry - Triumph 3 HW entry
   5155  */
   5156 
   5157 STATIC int
   5158 _bcm_tr3_ft_session_from_hw(int unit, int flags,
   5159                             bcm_regex_session_t *session,
   5160                             bcm_regex_session_key_t *key,
   5161                             ft_session_entry_t *ft_hw_entry)
   5162 {
   5163     uint32 static_bit, flow_state;
   5164     uint32 key_field[_REGEX_KEY_FIELD_LENGTH/32 + 1], direction;
   5165     uint32 type, valid, ip1, ip2, port1, port2, protocol;
   5166 
   5167     soc_mem_t mem = FT_SESSIONm;
   5168     const void *hw_entry = (const void *) ft_hw_entry;
   5169     int age_profile, ticks;
   5170     ft_age_profile_entry_t ftpm;
   5171 
   5172     soc_mem_field_get(unit, mem, hw_entry, KEY_TYPEf, &type);
   5173     if (type != _REGEX_SESSION_KEY_TYPE_IPV4) {
   5174         return BCM_E_UNAVAIL;
   5175     }
   5176 
   5177     soc_mem_field_get(unit, mem, hw_entry, VALIDf, &valid);
   5178     if (valid != 1) {
   5179         return BCM_E_UNAVAIL;
   5180     }
   5181 
   5182     soc_mem_field_get(unit, mem, hw_entry, POLICY_INDEXf, (uint32 *) &session->policy);
   5183 
   5184     /*
   5185     Granularity of AGE_PROFILE entries is 10ms, and inactivity_timeout
   5186     is in usecs.
   5187     */
   5188 
   5189     age_profile = soc_FT_SESSIONm_field32_get(unit, hw_entry, AGE_PROFILEf);
   5190     LOG_INFO(BSL_LS_BCM_REGEX,
   5191              (BSL_META_U(unit,
   5192                          "age_profile = 0x%x\n"),
   5193               age_profile));
   5194     SOC_IF_ERROR_RETURN(READ_FT_AGE_PROFILEm(unit, MEM_BLOCK_ALL, age_profile, &ftpm));
   5195     ticks = soc_mem_field32_get(unit, FT_AGE_PROFILEm, &ftpm, TIMEOUTf);
   5196     session->inactivity_timeout = ticks * _REGEX_SESSION_AGE_PROFILE_TICKS_US;
   5197     LOG_INFO(BSL_LS_BCM_REGEX,
   5198              (BSL_META_U(unit,
   5199                          "ticks = 0x%x, timeout = %d\n"),
   5200               ticks, session->inactivity_timeout));
   5201 
   5202     soc_mem_field_get(unit, mem, hw_entry, ID_TIMESTAMPf, &session->timestamp);
   5203     soc_mem_field_get(unit, mem, hw_entry, STATIC_BITf, &static_bit);
   5204 
   5205     session->flags = 0;
   5206     if (static_bit) {
   5207         session->flags |= BCM_REGEX_SESSION_STATIC;
   5208     }
   5209 
   5210     soc_mem_field_get(unit, mem, hw_entry, FLOW_STATEf, &flow_state);
   5211     LOG_INFO(BSL_LS_BCM_REGEX,
   5212              (BSL_META_U(unit,
   5213                          "flow_state = 0x%08x\n"),
   5214               flow_state));
   5215 
   5216     LOG_INFO(BSL_LS_BCM_REGEX,
   5217              (BSL_META_U(unit,
   5218                          "session->flags = 0x%x\n"),
   5219               session->flags));
   5220 
   5221     if (flags & _REGEX_GET_KEY_FROM_HW_ENTRY) {
   5222         direction = soc_mem_field32_get(unit, mem, hw_entry, KEY_DIRECTIONf);
   5223         soc_mem_field_get(unit, mem, hw_entry, KEYf, key_field);
   5224 
   5225         _bcm_ft_key_field_get(key_field, _REGEX_KEY_FIELD_V4_OFFSET_PORT_1,
   5226                               _REGEX_KEY_FIELD_V4_LENGTH_PORT_1, &port1);
   5227         _bcm_ft_key_field_get(key_field, _REGEX_KEY_FIELD_V4_OFFSET_PORT_2,
   5228                               _REGEX_KEY_FIELD_V4_LENGTH_PORT_2, &port2);
   5229         _bcm_ft_key_field_get(key_field, _REGEX_KEY_FIELD_V4_OFFSET_PROTOCOL,
   5230                               _REGEX_KEY_FIELD_V4_LENGTH_PROTOCOL, &protocol);
   5231         _bcm_ft_key_field_get(key_field, _REGEX_KEY_FIELD_V4_OFFSET_IP_1,
   5232                               _REGEX_KEY_FIELD_V4_LENGTH_IP_1, &ip1);
   5233         _bcm_ft_key_field_get(key_field, _REGEX_KEY_FIELD_V4_OFFSET_IP_2,
   5234                               _REGEX_KEY_FIELD_V4_LENGTH_IP_2, &ip2);
   5235 
   5236         key->protocol = protocol;
   5237 
   5238         key->flags = 0;
   5239 
   5240         if (direction == _REGEX_SESSION_DIRECTION_REVERSE) {
   5241           key->sip = ip1;
   5242           key->dip = ip2;
   5243           key->src_port = port1;
   5244           key->dst_port = port2;
   5245         } else {
   5246           key->dip = ip1;
   5247           key->sip = ip2;
   5248           key->dst_port = port1;
   5249           key->src_port = port2;
   5250         }
   5251     }
   5252 
   5253     return BCM_E_NONE;
   5254 }
   5255 
   5256 /*
   5257  * Function:
   5258  *      _bcm_tr3_ft_session_ipv6_from_hw
   5259  * Purpose:
   5260  *      Convert a TR3 FT session IPV6 HW entry to a hardware-independent
   5261  *      FT session IPV6 entry
   5262  * Parameters:
   5263  *      unit - Unit number
   5264  *      flags - (OUT) FT session flags (e.g. static entry)
   5265  *      key - (OUT) Hardware-independent FT session key
   5266  *      session - (OUT) Hardware-independent FT session info
   5267  *      hw_entry6 - Triumph 3 HW entry
   5268  */
   5269 
   5270 STATIC int
   5271 _bcm_tr3_ft_session_ipv6_from_hw(int unit, int flags,
   5272                             bcm_regex_session_t *session,
   5273                             bcm_regex_session_key_t *key,
   5274                             ft_session_ipv6_entry_t *ft_hw_entry6)
   5275 {
   5276     uint32 key_upper[_REGEX_KEY_UPPER_LENGTH/32 + 1], static_bit, flow_state;
   5277     uint32 key_lower[_REGEX_KEY_LOWER_LENGTH/32 + 1], direction;
   5278     bcm_ip6_t sip6, dip6;
   5279     uint32 type, type_0, valid, port1, port2, protocol;
   5280     soc_mem_t mem = FT_SESSION_IPV6m;
   5281     const void *hw_entry6 = (const void *) ft_hw_entry6;
   5282     int i, age_profile, ticks;
   5283     ft_age_profile_entry_t ftpm;
   5284 
   5285     /* Check for both key types in IPV6 entry */
   5286     soc_mem_field_get(unit, mem, hw_entry6, KEY_TYPEf, &type);
   5287     if (type != _REGEX_SESSION_KEY_TYPE_IPV6_UPPER) {
   5288         return BCM_E_UNAVAIL;
   5289     }
   5290 
   5291     soc_mem_field_get(unit, mem, hw_entry6, KEY_TYPE_0f, &type_0);
   5292     if (type_0 != _REGEX_SESSION_KEY_TYPE_IPV6_LOWER) {
   5293         return BCM_E_UNAVAIL;
   5294     }
   5295 
   5296     /* Check validity of upper and lower keys */
   5297     soc_mem_field_get(unit, mem, hw_entry6, VALIDf, &valid);
   5298     if (valid != 1) {
   5299         return BCM_E_UNAVAIL;
   5300     }
   5301 
   5302     soc_mem_field_get(unit, mem, hw_entry6, VALID_0f, &valid);
   5303     if (valid != 1) {
   5304         return BCM_E_UNAVAIL;
   5305     }
   5306 
   5307     soc_mem_field_get(unit, mem, hw_entry6, POLICY_INDEXf, (uint32 *) &session->policy);
   5308 
   5309     /*
   5310     Granularity of AGE_PROFILE entries is 10ms, and inactivity_timeout
   5311     is in usecs.
   5312     */
   5313 
   5314     age_profile = soc_FT_SESSION_IPV6m_field32_get(unit, hw_entry6, AGE_PROFILEf);
   5315     LOG_INFO(BSL_LS_BCM_REGEX,
   5316              (BSL_META_U(unit,
   5317                          "age_profile = 0x%x\n"),
   5318               age_profile));
   5319     SOC_IF_ERROR_RETURN(READ_FT_AGE_PROFILEm(unit, MEM_BLOCK_ALL, age_profile, &ftpm));
   5320     ticks = soc_mem_field32_get(unit, FT_AGE_PROFILEm, &ftpm, TIMEOUTf);
   5321     session->inactivity_timeout = ticks * _REGEX_SESSION_AGE_PROFILE_TICKS_US;
   5322     LOG_INFO(BSL_LS_BCM_REGEX,
   5323              (BSL_META_U(unit,
   5324                          "ticks = 0x%x, timeout = %d\n"),
   5325               ticks, session->inactivity_timeout));
   5326 
   5327     soc_mem_field_get(unit, mem, hw_entry6, ID_TIMESTAMPf, &session->timestamp);
   5328     soc_mem_field_get(unit, mem, hw_entry6, STATIC_BITf, &static_bit);
   5329 
   5330     session->flags = 0;
   5331     if (static_bit) {
   5332         session->flags |= BCM_REGEX_SESSION_STATIC;
   5333     }
   5334 
   5335     soc_mem_field_get(unit, mem, hw_entry6, FLOW_STATEf, &flow_state);
   5336     LOG_INFO(BSL_LS_BCM_REGEX,
   5337              (BSL_META_U(unit,
   5338                          "flow_state = 0x%08x\n"),
   5339               flow_state));
   5340 
   5341     LOG_INFO(BSL_LS_BCM_REGEX,
   5342              (BSL_META_U(unit,
   5343                          "session->flags = 0x%x\n"),
   5344               session->flags));
   5345 
   5346     if (flags & _REGEX_GET_KEY_FROM_HW_ENTRY) {
   5347         /*
   5348         IPV6 addresses are stored in two different fields -- the KEY field,
   5349         and the IPV6_LOWER_KEY field.  To reconstruct the addresses, both
   5350         fields must be used, especially as 104 bits of one IPV6 address is
   5351         in  the upper key field, and the other 24 bits are in the lower key
   5352         field, while one IPV6 address is stored entirely in the lower key
   5353         field.
   5354         */
   5355 
   5356         direction = soc_mem_field32_get(unit, mem, hw_entry6, KEY_DIRECTIONf);
   5357         soc_mem_field_get(unit, mem, hw_entry6, KEYf, key_upper);
   5358         soc_mem_field_get(unit, mem, hw_entry6, IPV6_LOWER_KEYf, key_lower);
   5359 
   5360         _bcm_ft_key_field_get(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_PORT_1,
   5361                               _REGEX_KEY_LOWER_V6_LENGTH_PORT_1, &port1);
   5362         _bcm_ft_key_field_get(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_PORT_2,
   5363                               _REGEX_KEY_LOWER_V6_LENGTH_PORT_2, &port2);
   5364         _bcm_ft_key_field_get(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_PROTOCOL,
   5365                               _REGEX_KEY_LOWER_V6_LENGTH_PROTOCOL, &protocol);
   5366 
   5367         key->protocol = protocol;
   5368 
   5369         key->flags = BCM_REGEX_SESSION_KEY_IPV6;
   5370 
   5371         if (direction == _REGEX_SESSION_DIRECTION_REVERSE) {
   5372           key->src_port = port1;
   5373           key->dst_port = port2;
   5374         } else {
   5375           key->dst_port = port1;
   5376           key->src_port = port2;
   5377         }
   5378 
   5379         if (direction == _REGEX_SESSION_DIRECTION_FORWARD) {
   5380             _bcm_ft_key_field_get_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_1,
   5381                                   _REGEX_KEY_LOWER_V6_LENGTH_IP_1, dip6);
   5382         } else {
   5383             _bcm_ft_key_field_get_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_1,
   5384                                   _REGEX_KEY_LOWER_V6_LENGTH_IP_1, sip6);
   5385         }
   5386         if (direction == _REGEX_SESSION_DIRECTION_FORWARD) {
   5387             _bcm_ft_key_field_get_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_2,
   5388                                   _REGEX_KEY_LOWER_V6_LENGTH_IP_2, sip6);
   5389         } else {
   5390             _bcm_ft_key_field_get_char(key_lower, _REGEX_KEY_LOWER_V6_OFFSET_IP_2,
   5391                                   _REGEX_KEY_LOWER_V6_LENGTH_IP_2, dip6);
   5392         }
   5393         if (direction == _REGEX_SESSION_DIRECTION_FORWARD) {
   5394             _bcm_ft_key_field_get_char(key_upper, _REGEX_KEY_UPPER_V6_OFFSET_IP_2,
   5395                                        _REGEX_KEY_UPPER_V6_LENGTH_IP_2,
   5396                                        &sip6[_REGEX_KEY_LOWER_V6_LENGTH_IP_2/8]);
   5397         } else {
   5398             _bcm_ft_key_field_get_char(key_upper, _REGEX_KEY_UPPER_V6_OFFSET_IP_2,
   5399                                        _REGEX_KEY_UPPER_V6_LENGTH_IP_2,
   5400                                        &dip6[_REGEX_KEY_LOWER_V6_LENGTH_IP_2/8]);
   5401         }
   5402 
   5403         /*
   5404         IPv6 addresses will go into hardware in reverse order, so reverse
   5405         the addresses here before returning them
   5406         */
   5407 
   5408         for (i = 0; i < _SHR_L3_IP6_ADDRLEN; i++) {
   5409             key->sip6[i] = sip6[_SHR_L3_IP6_ADDRLEN - i - 1];
   5410             key->dip6[i] = dip6[_SHR_L3_IP6_ADDRLEN - i - 1];
   5411         }
   5412     }
   5413 
   5414     return BCM_E_NONE;
   5415 }
   5416 
   5417 int _bcm_tr3_regex_session_add(int unit,
   5418                               int flags,
   5419                               bcm_regex_session_key_t *key,
   5420                               bcm_regex_session_t *session)
   5421 {
   5422     int index, rv = BCM_E_UNAVAIL;
   5423     ft_session_entry_t session_entry, session_entry_lookup;
   5424     ft_session_ipv6_entry_t session_entry6, session_entry_lookup6;
   5425     soc_mem_t mem;
   5426 
   5427     BCM_REGEX_LOCK(unit);
   5428     if (key->flags & BCM_REGEX_SESSION_KEY_IPV6) {
   5429         sal_memset(&session_entry6, 0, sizeof(ft_session_ipv6_entry_t));
   5430         mem = FT_SESSION_IPV6m;
   5431         BCM_IF_ERROR_RETURN
   5432             (_bcm_tr3_ft_session_ipv6_to_hw(unit, &session_entry6, flags, key, session));
   5433         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5434                             (void *)&session_entry6,
   5435                             (void *)&session_entry_lookup6, 0);
   5436         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   5437             goto end;
   5438         } else if (rv == BCM_E_NOT_FOUND) {
   5439             if ((key->flags & BCM_REGEX_SESSION_KEY_REPLACE) != 0) {
   5440                 LOG_INFO(BSL_LS_BCM_REGEX,
   5441                          (BSL_META_U(unit,
   5442                                      "soc_mem_insert ipv6 rv: %d, can't replace non-existent entry\n"),
   5443                           rv));
   5444                 goto end;
   5445             }
   5446             LOG_INFO(BSL_LS_BCM_REGEX,
   5447                      (BSL_META_U(unit,
   5448                                  "session_add ipv6\n")));
   5449             rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, (void *)&session_entry6);
   5450         } else if (rv == BCM_E_NONE) {
   5451             if ((key->flags & BCM_REGEX_SESSION_KEY_REPLACE) == 0) {
   5452                 rv = BCM_E_EXISTS;
   5453                 goto end;
   5454             } else {
   5455                 BCM_IF_ERROR_RETURN
   5456                     (_bcm_tr3_ft_session_ipv6_to_hw(unit, &session_entry_lookup6, flags, key, session));
   5457                 LOG_INFO(BSL_LS_BCM_REGEX,
   5458                          (BSL_META_U(unit,
   5459                                      "session_modify ipv6\n")));
   5460                 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, (void *)&session_entry_lookup6);
   5461                 LOG_INFO(BSL_LS_BCM_REGEX,
   5462                          (BSL_META_U(unit,
   5463                                      "soc_mem_insert ipv6 rv: %d, OK for modify\n"),
   5464                           rv));
   5465                 if (rv == BCM_E_EXISTS) {
   5466                     rv = BCM_E_NONE; /* OK to get BCM_E_EXISTS in update case, insert still happens */
   5467                 }
   5468             }
   5469         }
   5470     } else {
   5471         sal_memset(&session_entry, 0, sizeof(ft_session_entry_t));
   5472         mem = FT_SESSIONm;
   5473         BCM_IF_ERROR_RETURN
   5474             (_bcm_tr3_ft_session_to_hw(unit, &session_entry, flags, key, session));
   5475         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5476                             (void *)&session_entry,
   5477                             (void *)&session_entry_lookup, 0);
   5478         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   5479             goto end;
   5480         } else if (rv == BCM_E_NOT_FOUND) {
   5481             if ((key->flags & BCM_REGEX_SESSION_KEY_REPLACE) != 0) {
   5482                 LOG_INFO(BSL_LS_BCM_REGEX,
   5483                          (BSL_META_U(unit,
   5484                                      "soc_mem_insert ipv4 rv: %d, can't replace non-existent entry\n"),
   5485                           rv));
   5486                 goto end;
   5487             }
   5488             LOG_INFO(BSL_LS_BCM_REGEX,
   5489                      (BSL_META_U(unit,
   5490                                  "session_add ipv4\n")));
   5491             rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, (void *)&session_entry);
   5492         } else if (rv == BCM_E_NONE) {
   5493             if ((key->flags & BCM_REGEX_SESSION_KEY_REPLACE) == 0) {
   5494                 rv = BCM_E_EXISTS;
   5495                 goto end;
   5496             } else {
   5497                 BCM_IF_ERROR_RETURN
   5498                     (_bcm_tr3_ft_session_to_hw(unit, &session_entry_lookup, flags, key, session));
   5499                 LOG_INFO(BSL_LS_BCM_REGEX,
   5500                          (BSL_META_U(unit,
   5501                                      "session_modify ipv4\n")));
   5502                 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, (void *)&session_entry_lookup);
   5503                 LOG_INFO(BSL_LS_BCM_REGEX,
   5504                          (BSL_META_U(unit,
   5505                                      "soc_mem_insert ipv4 rv: %d, OK for modify\n"),
   5506                           rv));
   5507                 if (rv == BCM_E_EXISTS) {
   5508                     rv = BCM_E_NONE; /* OK to get BCM_E_EXISTS in update case, insert still happens */
   5509                 }
   5510             }
   5511         }
   5512     }
   5513 
   5514 end:
   5515     BCM_REGEX_UNLOCK(unit);
   5516     return rv;
   5517 }
   5518 
   5519 
   5520 int _bcm_tr3_regex_session_policy_update(int unit, int flags, int flow_index,
   5521                                          bcm_regex_policy_t policy)
   5522 {
   5523     int rv = BCM_E_UNAVAIL;
   5524     ft_session_entry_t session_entry;
   5525     ft_session_ipv6_entry_t session_entry6;
   5526     soc_mem_t mem;
   5527 
   5528     BCM_REGEX_LOCK(unit);
   5529     if (flags & BCM_REGEX_SESSION_KEY_IPV6) {
   5530         sal_memset(&session_entry6, 0, sizeof(ft_session_ipv6_entry_t));
   5531         mem = FT_SESSION_IPV6m;
   5532         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, flow_index, &session_entry6);
   5533         if (BCM_FAILURE(rv)) {
   5534             LOG_INFO(BSL_LS_BCM_REGEX,
   5535                      (BSL_META_U(unit,
   5536                                  "soc_mem_read ipv6 rv: %d, can't update non-existent entry\n"),
   5537                       rv));
   5538             goto end;
   5539         }
   5540         soc_FT_SESSION_IPV6m_field32_set(unit, &session_entry6, POLICY_INDEXf,
   5541                                          policy);
   5542         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, flow_index, &session_entry6);
   5543         if (BCM_FAILURE(rv)) {
   5544             LOG_INFO(BSL_LS_BCM_REGEX,
   5545                      (BSL_META_U(unit,
   5546                                  "soc_mem_write ipv6 rv: %d, can't write entry\n"),
   5547                       rv));
   5548             goto end;
   5549         }
   5550     } else {
   5551         sal_memset(&session_entry, 0, sizeof(ft_session_entry_t));
   5552         mem = FT_SESSIONm;
   5553         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, flow_index, &session_entry);
   5554         if (BCM_FAILURE(rv)) {
   5555             LOG_INFO(BSL_LS_BCM_REGEX,
   5556                      (BSL_META_U(unit,
   5557                                  "soc_mem_read ipv4 rv: %d, can't update non-existent entry\n"),
   5558                       rv));
   5559             goto end;
   5560         }
   5561         soc_FT_SESSIONm_field32_set(unit, &session_entry, POLICY_INDEXf,
   5562                                          policy);
   5563         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, flow_index, &session_entry);
   5564         if (BCM_FAILURE(rv)) {
   5565             LOG_INFO(BSL_LS_BCM_REGEX,
   5566                      (BSL_META_U(unit,
   5567                                  "soc_mem_write ipv4 rv: %d, can't write entry\n"),
   5568                       rv));
   5569             goto end;
   5570         }
   5571     }
   5572 
   5573 end:
   5574     BCM_REGEX_UNLOCK(unit);
   5575     return rv;
   5576 }
   5577 
   5578 int _bcm_tr3_regex_session_delete_all(int unit)
   5579 {
   5580     int rv = BCM_E_NONE;
   5581 
   5582     BCM_REGEX_LOCK(unit);
   5583     /*
   5584      * Session table is common for IPv4 and IPv6 entries
   5585      * Clearing FT_SESSIONm will remove all entries
   5586      */
   5587     rv = soc_mem_clear(unit, FT_SESSIONm, MEM_BLOCK_ALL, TRUE);
   5588     BCM_REGEX_UNLOCK(unit);
   5589 
   5590     return rv;
   5591 }
   5592 
   5593 int _bcm_tr3_regex_session_delete(int unit,
   5594                               bcm_regex_session_key_t *key)
   5595 {
   5596     int index, rv = BCM_E_UNAVAIL;
   5597     int flags = 0;
   5598     ft_session_entry_t session_entry, session_entry_lookup;
   5599     ft_session_ipv6_entry_t session_entry6, session_entry_lookup6;
   5600     soc_mem_t mem;
   5601 
   5602     BCM_REGEX_LOCK(unit);
   5603     if (key->flags & BCM_REGEX_SESSION_KEY_IPV6) {
   5604         sal_memset(&session_entry6, 0, sizeof(ft_session_ipv6_entry_t));
   5605         mem = FT_SESSION_IPV6m;
   5606         BCM_IF_ERROR_RETURN
   5607             (_bcm_tr3_ft_session_ipv6_to_hw(unit, &session_entry6, flags, key, NULL));
   5608         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5609                             (void *)&session_entry6,
   5610                             (void *)&session_entry_lookup6, 0);
   5611         if (BCM_FAILURE(rv)) {
   5612             goto end;
   5613         } else if (rv == BCM_E_NONE) {
   5614             rv = soc_mem_delete(unit, mem, MEM_BLOCK_ALL, (void *)&session_entry6);
   5615         }
   5616     } else {
   5617         sal_memset(&session_entry, 0, sizeof(ft_session_entry_t));
   5618         mem = FT_SESSIONm;
   5619         BCM_IF_ERROR_RETURN
   5620             (_bcm_tr3_ft_session_to_hw(unit, &session_entry, flags, key, NULL));
   5621         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5622                             (void *)&session_entry,
   5623                             (void *)&session_entry_lookup, 0);
   5624         if (BCM_FAILURE(rv)) {
   5625             goto end;
   5626         } else if (rv == BCM_E_NONE) {
   5627             rv = soc_mem_delete(unit, mem, MEM_BLOCK_ALL, (void *)&session_entry);
   5628         }
   5629     }
   5630 
   5631 end:
   5632     BCM_REGEX_UNLOCK(unit);
   5633     return rv;
   5634 }
   5635 
   5636 int _bcm_tr3_regex_session_get(int unit,
   5637                               int flags,
   5638                               bcm_regex_session_key_t *key,
   5639                               bcm_regex_session_t *session)
   5640 {
   5641     int index, rv = BCM_E_UNAVAIL;
   5642     ft_session_entry_t session_entry, session_entry_lookup;
   5643     ft_session_ipv6_entry_t session_entry6, session_entry_lookup6;
   5644     soc_mem_t mem;
   5645 
   5646     if (key->flags & BCM_REGEX_SESSION_KEY_IPV6) {
   5647         sal_memset(&session_entry6, 0, sizeof(ft_session_ipv6_entry_t));
   5648         mem = FT_SESSION_IPV6m;
   5649         BCM_IF_ERROR_RETURN
   5650             (_bcm_tr3_ft_session_ipv6_to_hw(unit, &session_entry6, flags, key, NULL));
   5651         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5652                             (void *)&session_entry6,
   5653                             (void *)&session_entry_lookup6, 0);
   5654         if (BCM_FAILURE(rv)) {
   5655             return rv;
   5656         } else if (rv == BCM_E_NONE) {
   5657             return _bcm_tr3_ft_session_ipv6_from_hw(unit, flags, session, key,
   5658                                                     &session_entry_lookup6);
   5659         }
   5660     } else {
   5661         sal_memset(&session_entry, 0, sizeof(ft_session_entry_t));
   5662         mem = FT_SESSIONm;
   5663         BCM_IF_ERROR_RETURN
   5664             (_bcm_tr3_ft_session_to_hw(unit, &session_entry, flags, key, NULL));
   5665         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5666                             (void *)&session_entry,
   5667                             (void *)&session_entry_lookup, 0);
   5668         if (BCM_FAILURE(rv)) {
   5669             return rv;
   5670         } else if (rv == BCM_E_NONE) {
   5671             return _bcm_tr3_ft_session_from_hw(unit, flags, session, key,
   5672                                                     &session_entry_lookup);
   5673         }
   5674     }
   5675 
   5676     return rv;
   5677 }
   5678 
   5679 int _bcm_tr3_regex_session_get_by_index(int unit, int flags, int index,
   5680                                         bcm_regex_session_key_t *key,
   5681                                         bcm_regex_session_t *session)
   5682 {
   5683     int rv = BCM_E_UNAVAIL;
   5684     ft_session_entry_t session_entry;
   5685     ft_session_ipv6_entry_t session_entry6;
   5686     soc_mem_t mem;
   5687 
   5688     if (flags & _REGEX_ENTRY_TYPE_IS_IPV6) {
   5689         sal_memset(&session_entry6, 0, sizeof(ft_session_ipv6_entry_t));
   5690         mem = FT_SESSION_IPV6m;
   5691         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &session_entry6);
   5692         if (BCM_FAILURE(rv)) {
   5693             LOG_INFO(BSL_LS_BCM_REGEX,
   5694                      (BSL_META_U(unit,
   5695                                  "soc_mem_read ipv6 rv: %d, can't get non-existent entry\n"),
   5696                       rv));
   5697             goto end;
   5698         } else if (rv == BCM_E_NONE) {
   5699             return _bcm_tr3_ft_session_ipv6_from_hw(unit, flags, session, key,
   5700                                                     &session_entry6);
   5701         }
   5702     } else {
   5703         sal_memset(&session_entry, 0, sizeof(ft_session_entry_t));
   5704         mem = FT_SESSIONm;
   5705         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &session_entry);
   5706         if (BCM_FAILURE(rv)) {
   5707             LOG_INFO(BSL_LS_BCM_REGEX,
   5708                      (BSL_META_U(unit,
   5709                                  "soc_mem_read ipv4 rv: %d, can't get non-existent entry\n"),
   5710                       rv));
   5711             goto end;
   5712         } else if (rv == BCM_E_NONE) {
   5713             return _bcm_tr3_ft_session_from_hw(unit, flags, session, key,
   5714                                                     &session_entry);
   5715         }
   5716     }
   5717 
   5718 end:
   5719     return rv;
   5720 }
   5721 
   5722 int _bcm_tr3_regex_session_traverse(int unit,
   5723                                     int flags,
   5724                                     bcm_regex_session_traverse_cb cb,
   5725                                     void *user_data)
   5726 {
   5727     int i, index_min4, index_max4, rv = BCM_E_NONE;
   5728     int index_min6, index_max6;
   5729     int valid, type, *buffer4 = NULL, *buffer6 = NULL;
   5730     ft_session_entry_t *hw_entry4 = NULL;
   5731     ft_session_ipv6_entry_t *hw_entry6 = NULL;
   5732     bcm_regex_session_t info;
   5733     bcm_regex_session_key_t key;
   5734     uint32 static_bit, flow_state;
   5735 
   5736     index_min4 = soc_mem_index_min(unit, FT_SESSIONm);
   5737     index_max4 = soc_mem_index_max(unit, FT_SESSIONm);
   5738     index_min6 = soc_mem_index_min(unit, FT_SESSION_IPV6m);
   5739     index_max6 = soc_mem_index_max(unit, FT_SESSION_IPV6m);
   5740 
   5741     LOG_INFO(BSL_LS_BCM_REGEX,
   5742              (BSL_META_U(unit,
   5743                          "index_min4: %d, index_max4: %d, index_min6: %d, index_max6: %d\n"),
   5744               index_min4, index_max4, index_min6, index_max6));
   5745 
   5746     BCM_REGEX_LOCK(unit);
   5747     buffer4 = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, FT_SESSIONm),
   5748                            "flow tracker session traverse ipv4");
   5749     if (NULL == buffer4) {
   5750         rv = BCM_E_MEMORY;
   5751         goto end;
   5752     }
   5753 
   5754     if ((rv = soc_mem_read_range(unit, FT_SESSIONm, MEM_BLOCK_ALL,
   5755                                  index_min4, index_max4, buffer4)) < 0 ) {
   5756         soc_cm_sfree(unit, buffer4);
   5757         goto end;
   5758     }
   5759 
   5760     buffer6 = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, FT_SESSION_IPV6m),
   5761                            "flow tracker session traverse ipv6");
   5762     if (NULL == buffer6) {
   5763         soc_cm_sfree(unit, buffer4);
   5764         rv = BCM_E_MEMORY;
   5765         goto end;
   5766     }
   5767 
   5768     if ((rv = soc_mem_read_range(unit, FT_SESSION_IPV6m, MEM_BLOCK_ALL,
   5769                                  index_min6, index_max6, buffer6)) < 0 ) {
   5770         goto free_end;
   5771     }
   5772 
   5773     for (i = index_min4; i <= index_max4; i++) {
   5774         hw_entry4 = soc_mem_table_idx_to_pointer(unit, FT_SESSIONm,
   5775                                          ft_session_entry_t *, buffer4, i);
   5776         valid = soc_FT_SESSIONm_field32_get(unit, hw_entry4, VALIDf);
   5777         if (!valid) {
   5778             continue;
   5779         }
   5780 
   5781         /*
   5782         Only look at entries of type IPV4 or IPV6 lower (which will
   5783         account for the IPV6 upper half when taken as a whole
   5784         */
   5785         type = soc_FT_SESSIONm_field32_get(unit, hw_entry4, KEY_TYPEf);
   5786         LOG_INFO(BSL_LS_BCM_REGEX,
   5787                  (BSL_META_U(unit,
   5788                              "entry: %d, key_type = %d\n"),
   5789                   i, type));
   5790 
   5791         if (type == _REGEX_SESSION_KEY_TYPE_RESERVED ||
   5792             type == _REGEX_SESSION_KEY_TYPE_IPV6_UPPER) {
   5793             continue;
   5794         }
   5795 
   5796         if (type != _REGEX_SESSION_KEY_TYPE_IPV4) {
   5797             hw_entry6 = soc_mem_table_idx_to_pointer(unit, FT_SESSION_IPV6m,
   5798                                              ft_session_ipv6_entry_t *, buffer6, i/2);
   5799 
   5800             valid = soc_FT_SESSION_IPV6m_field32_get(unit, hw_entry6, VALID_0f);
   5801             if (!valid) {
   5802                 continue;
   5803             }
   5804 
   5805             static_bit = soc_FT_SESSION_IPV6m_field32_get(unit, hw_entry6, STATIC_BITf);
   5806             flow_state = soc_FT_SESSION_IPV6m_field32_get(unit, hw_entry6, FLOW_STATEf);
   5807         }
   5808         else {
   5809             static_bit = soc_FT_SESSIONm_field32_get(unit, hw_entry4, STATIC_BITf);
   5810             flow_state = soc_FT_SESSIONm_field32_get(unit, hw_entry4, FLOW_STATEf);
   5811         }
   5812 
   5813         LOG_INFO(BSL_LS_BCM_REGEX,
   5814                  (BSL_META_U(unit,
   5815                              "flow_state = 0x%08x, static_bit = 0x%x\n"),
   5816                   flow_state, static_bit));
   5817 
   5818         if ((flags & BCM_REGEX_SESSION_TRAVERSE_ALL) == 0 && static_bit == 0) {
   5819             continue;
   5820         }
   5821 
   5822         if (flow_state == _REGEX_SESSION_FLOW_STATE_INVALID ||
   5823             flow_state == _REGEX_SESSION_FLOW_STATE_RETIRED ||
   5824             flow_state == _REGEX_SESSION_FLOW_STATE_RESERVED) {
   5825             continue;
   5826         }
   5827 
   5828         bcm_regex_session_t_init(&info);
   5829         bcm_regex_session_key_t_init(&key);
   5830 
   5831         if (type != _REGEX_SESSION_KEY_TYPE_IPV4) {
   5832             rv = _bcm_tr3_ft_session_ipv6_from_hw(unit, _REGEX_GET_KEY_FROM_HW_ENTRY, &info, &key, hw_entry6);
   5833         }
   5834         else
   5835         {
   5836             rv = _bcm_tr3_ft_session_from_hw(unit, _REGEX_GET_KEY_FROM_HW_ENTRY, &info, &key, hw_entry4);
   5837         }
   5838         LOG_INFO(BSL_LS_BCM_REGEX,
   5839                  (BSL_META_U(unit,
   5840                              "rv = %d (0x%08x)\n"),
   5841                   rv, rv));
   5842 
   5843         if (BCM_FAILURE(rv)) {
   5844             goto free_end;
   5845         }
   5846 
   5847         rv = cb(unit, &key, &info, user_data);
   5848 
   5849         if (BCM_FAILURE(rv)) {
   5850             goto free_end;
   5851         }
   5852     }
   5853 
   5854 free_end:
   5855     soc_cm_sfree(unit, buffer4);
   5856     soc_cm_sfree(unit, buffer6);
   5857 
   5858 end:
   5859     BCM_REGEX_UNLOCK(unit);
   5860     return rv;
   5861 }
   5862 
   5863 STATIC int
   5864 _bcm_tr3_regex_hw_dfa_relocate(int unit, 
   5865                                 soc_mem_t state_mem,
   5866                                 int num_lines, int prev_offset, int new_offset,
   5867                                 axp_sm_state_table_mem0_entry_t *state_membuf,
   5868                                 soc_mem_t to_match_mem, 
   5869                                 soc_mem_t from_match_mem,
   5870                                 axp_sm_match_table_mem0_entry_t *match_membuf, 
   5871                                 int *to_match_alloc_base,
   5872                                 int *setid_remap, int setid_tblsz,
   5873                                 int update_db)
   5874 {
   5875     int i, rvo, adj, sigid, ptrv;
   5876     soc_field_t minf, maxf, matchf, ptrf;
   5877     uint32  minv, maxv, matchv;
   5878     axp_sm_state_table_mem0_entry_t *pstmem;
   5879     axp_sm_match_table_mem0_entry_t *pmtmem;
   5880     int old_chkid, old_setid;
   5881     int next_index = *to_match_alloc_base;
   5882     _bcm_regexdb_entry_t* dbe = NULL;
   5883 
   5884     adj = (new_offset - prev_offset) * BCM_TR3_NUM_RV_PER_LINE;
   5885     for (i = 0; i < num_lines; i++) {
   5886         pstmem = state_membuf + i;
   5887         for (rvo = 0; rvo < BCM_TR3_NUM_RV_PER_LINE; rvo++) {
   5888             _bcm_tr3_regex_rv_fields_get(unit, rvo, &minf, &maxf, &matchf, &ptrf);
   5889             
   5890             minv = soc_mem_field32_get(unit, state_mem, (void*)pstmem, minf);
   5891             maxv = soc_mem_field32_get(unit, state_mem, (void*)pstmem, maxf);
   5892             if ((minv == 255) && ((maxv == 2) || (maxv == 1))) {
   5893                 /* match state */
   5894                 matchv = soc_mem_field32_get(unit, state_mem, 
   5895                                              (void*)pstmem, matchf);
   5896                 /* get the match entry */
   5897                 pmtmem = match_membuf + matchv;
   5898                 
   5899                 sigid = soc_mem_field32_get(unit, from_match_mem, pmtmem, 
   5900                                                            REPORT_SIGNATURE_IDf);
   5901 
   5902                 if (update_db) {
   5903                     dbe = bcm_regexdb_find_match_entry_by_sig_id(unit, sigid);
   5904                     if (!dbe) {
   5905                         return BCM_E_INTERNAL;
   5906                     }
   5907                 }
   5908 
   5909                 /* check if setid or checkid needs relocation. */
   5910                 if (soc_mem_field32_get(unit, from_match_mem, pmtmem, 
   5911                                                     MATCH_ENTRY_VALIDf)) {
   5912                     if (soc_mem_field32_get(unit, from_match_mem, 
   5913                                         pmtmem, MATCH_CROSS_SIG_FLAG_SETf)) {
   5914                         /* set the new setid */
   5915                         old_chkid = soc_mem_field32_get(unit, from_match_mem, 
   5916                                           pmtmem, MATCH_CROSS_SIG_FLAG_INDEXf);
   5917                         
   5918                         soc_mem_field32_set(unit, from_match_mem, 
   5919                                         pmtmem, MATCH_CROSS_SIG_FLAG_INDEXf, 
   5920                                         setid_remap[old_chkid]);
   5921                         dbe->match_set_id = setid_remap[old_chkid];
   5922                     }
   5923                     
   5924                     if (soc_mem_field32_get(unit, from_match_mem, 
   5925                                         pmtmem, CHECK_CROSS_SIG_FLAG_IS_SETf)) {
   5926                         /* set the new chkid */
   5927                         old_setid  = soc_mem_field32_get(unit, from_match_mem, 
   5928                                           pmtmem, CHECK_CROSS_SIG_FLAG_INDEXf);
   5929                         
   5930                         soc_mem_field32_set(unit, from_match_mem, 
   5931                                         pmtmem, CHECK_CROSS_SIG_FLAG_INDEXf, 
   5932                                         setid_remap[old_setid]);
   5933                         dbe->match_chk_id = setid_remap[old_setid];
   5934                     }
   5935                 }
   5936                 
   5937                 /* write the entry to new match memory */
   5938                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, to_match_mem, 
   5939                                     MEM_BLOCK_ALL, next_index, pmtmem));
   5940                 next_index++;
   5941 
   5942             } else {
   5943                 ptrv = soc_mem_field32_get(unit, state_mem, (void*)pstmem, ptrf);
   5944                 if (ptrv != 0xffff) {
   5945                     ptrv += adj;
   5946                     if (ptrv >= 0xffff) {
   5947                         ptrv=0xffff; 
   5948                     }
   5949                 }
   5950                 soc_mem_field32_set(unit, state_mem, (void*)pstmem, ptrf, ptrv);
   5951             }
   5952         }
   5953 	soc_mem_write(unit, state_mem, MEM_BLOCK_ALL, new_offset+i, pstmem);
   5954     }
   5955 
   5956     *to_match_alloc_base = next_index;
   5957     return 0;
   5958 }
   5959 
   5960 STATIC int
   5961 _bcm_tr3_arrange_resources_in_tiles(int unit, _bcm_regex_resource_t *res, 
   5962                                     int num_res, int to_tiles, int to_tilee,
   5963                                     _bcm_regex_tile_t *_tr3tile, int num_tile)
   5964 {
   5965     _bcm_tr3_regex_device_info_t *device;
   5966     int i, t, tile_lsz, placed;
   5967     int max_per_tile;
   5968 
   5969     if (to_tilee >= num_tile) {
   5970         return BCM_E_PARAM;
   5971     }
   5972 
   5973     device = REGEX_INFO(unit);
   5974 
   5975     max_per_tile = BCM_TR3_ENGINE_PER_TILE(device);
   5976     tile_lsz = _bcm_tr3_get_tile_line_size(unit);
   5977     sal_memset(_tr3tile, 0, sizeof(_bcm_regex_tile_t)*num_tile);
   5978     for (i = to_tiles; i <= to_tilee; i++) {
   5979         _tr3tile[i].valid = 1;
   5980         _tr3tile[i].avail = tile_lsz;
   5981         _tr3tile[i].num_o = 0;
   5982     }
   5983 
   5984     for (i = 0; i < num_res; i++) {
   5985         placed = 0;
   5986         for (t = to_tiles; t <= to_tilee; t++) {
   5987             if (!_tr3tile[t].valid) {
   5988                 continue;
   5989             }
   5990 
   5991             if ((_tr3tile[t].avail >= res[i].lsize) && 
   5992                 (_tr3tile[t].num_o < max_per_tile)) {
   5993                 _tr3tile[t].oidx[_tr3tile[t].num_o++] = i;
   5994                 _tr3tile[t].avail -= res[i].lsize;
   5995                 placed = 1;
   5996                 break;
   5997             }
   5998         }
   5999         if (!placed) {
   6000             return BCM_E_RESOURCE;
   6001         }
   6002     }
   6003 
   6004     return BCM_E_NONE;
   6005 }
   6006 
   6007 STATIC int
   6008 _bcm_tr3_rearrange_engines_in_hw(int unit, _bcm_regex_resource_t *res, 
   6009                            int num_res, int to_tiles, int to_tilee, 
   6010                            _bcm_regex_tile_t *_tr3tile)
   6011 {
   6012     _bcm_tr3_regex_device_info_t *device;
   6013     int i, t, j, k, last_match_offset, off;
   6014     int max_per_tile, maxm, old_tile;
   6015     axp_sm_state_table_mem0_entry_t *pmem;
   6016     _bcm_regex_resource_t *pres;
   6017     _bcm_regex_engine_obj_t physical_engines[BCM_TR3_MAX_ENGINE];
   6018     int *old2new, *new2old, *oldleid2peid, *old_setid2new;
   6019     int new_peid, old_peid, new_setidb, old_setidb;
   6020     soc_mem_t mem, from_match_mem, to_match_mem;
   6021     _bcm_regex_engine_obj_t *pengine = NULL, *old_pe, *new_pe;
   6022     int rv = BCM_E_NONE, match_off;
   6023     _bcm_regex_lengine_t *lengine;
   6024     uint32 *alloc_bmap;
   6025     axp_sm_state_table_mem0_entry_t *dfa_cp[BCM_TR3_MAX_ENGINE], *pdfa; 
   6026 
   6027     if (!num_res) {
   6028         return BCM_E_NONE;
   6029     }
   6030 
   6031     device = REGEX_INFO(unit);
   6032 
   6033     max_per_tile = BCM_TR3_ENGINE_PER_TILE(device);
   6034     for (t=to_tiles; t <= to_tilee; t++) {
   6035         _tr3tile[t].match_mem =  NULL;
   6036     }
   6037    
   6038     old2new = sal_alloc(sizeof(int)*BCM_TR3_MAX_ENGINE, "old2new_emap");
   6039     new2old = sal_alloc(sizeof(int)*BCM_TR3_MAX_ENGINE, "new2old_emap");
   6040     oldleid2peid = sal_alloc(sizeof(int)*BCM_TR3_MAX_ENGINE, "old2new_peid");
   6041     old_setid2new = sal_alloc(sizeof(int)*BCM_TR3_MAX_SLOTS, "setid_map");
   6042     sal_memset(dfa_cp, 0, 
   6043                sizeof(axp_sm_state_table_mem0_entry_t*)*BCM_TR3_MAX_ENGINE);
   6044 
   6045     if (!(old2new && new2old && oldleid2peid && old_setid2new)) {
   6046         rv = BCM_E_MEMORY;
   6047         goto fail;
   6048     }
   6049 
   6050     for (i = 0; i < BCM_TR3_MAX_ENGINE; i++) {
   6051         old2new[i] = -1;
   6052         new2old[i] = -1;
   6053         oldleid2peid[i] = -1;
   6054     }
   6055 
   6056     for (i = 0; i < BCM_TR3_MAX_SLOTS; i++) {
   6057         old_setid2new[i] = -1;
   6058     }
   6059 
   6060     /*
   6061      * Read the dfa states from HW.
   6062      */
   6063     for (t=to_tiles; t<=to_tilee; t++) {
   6064         if (_tr3tile[t].num_o == 0) {
   6065             continue;
   6066         }
   6067 
   6068         /* disable the tile */
   6069         _bcm_tr3_disable_tile(unit, t);
   6070 
   6071         for (i = 0; i < _tr3tile[t].num_o; i++) {
   6072             new_peid = (t * max_per_tile) + i;
   6073             pres = res + _tr3tile[t].oidx[i];
   6074             pengine = pres->pres;
   6075             old_peid = pengine->hw_idx;
   6076             /* add to old2new map table */
   6077             old2new[old_peid] = new_peid;
   6078             new2old[new_peid] = old_peid;
   6079             pmem = sal_alloc(sizeof(axp_sm_state_table_mem0_entry_t)*pengine->req_lsz, 
   6080                                 "dfa_cp");
   6081             dfa_cp[old_peid] = pmem;
   6082             _bcm_tr3_regex_read_hw_dfa(unit, pengine, pmem);
   6083         }
   6084         if (_tr3tile[t].match_mem == NULL) {
   6085             mem = AXP_SM_MATCH_TABLE_MEM0m + 
   6086                 BCM_REGEX_ENG2MATCH_MEMIDX(unit,pengine->hw_idx);
   6087             maxm = soc_mem_index_max(unit, mem);
   6088             _tr3tile[t].match_mem = sal_alloc(
   6089                 sizeof(axp_sm_match_table_mem0_entry_t)*(maxm+1), "match_mem_cp");
   6090     
   6091             /* read the match memory */
   6092             soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 0, 
   6093                                 maxm, _tr3tile[t].match_mem);
   6094 
   6095             /* clear out the match memory */
   6096             soc_mem_clear(unit, mem, MEM_BLOCK_ALL, 1);
   6097         }
   6098     }
   6099 
   6100     /*
   6101      * Adjust the logical to physical engine mapping.
   6102      */
   6103     sal_memcpy(physical_engines, device->physical_engines, 
   6104                 sizeof(physical_engines));
   6105    
   6106     /* remap logical to physcial mapping */
   6107     for (i=0; i<BCM_TR3_NUM_ENGINE(device); i++) {
   6108         lengine = &device->engines[i];
   6109         if ((pengine = lengine->physical_engine) == NULL) {
   6110             continue;
   6111         }
   6112         old_peid = pengine->hw_idx;
   6113         oldleid2peid[i] = old_peid;
   6114         lengine->physical_engine = NULL;
   6115 
   6116         pengine->total_lsz = 0;
   6117         pengine->flags = 0;
   6118         pengine->from_line = -1;
   6119         pengine->req_lsz = 0;
   6120         pengine->cps.flags = 0;
   6121         pengine->cps.from_line = -1;
   6122         pengine->cps.req_lsz = 0;
   6123         pengine->total_lsz = 0;
   6124     }
   6125 
   6126     /* remap logical engines to new physical engines */
   6127     for (i=0; i<BCM_TR3_NUM_ENGINE(device); i++) {
   6128         if (oldleid2peid[i] == -1) {
   6129             continue;
   6130         }
   6131         old_peid = oldleid2peid[i];
   6132         old_pe = &physical_engines[old_peid];
   6133         new_peid = old2new[old_peid];
   6134         new_pe = &device->physical_engines[new_peid];
   6135         device->engines[i].physical_engine = new_pe;
   6136 
   6137         /* assign engine info/params to new engine from old engine */
   6138 
   6139         /* keep the from offset since we might have to adjust the 
   6140          * jump offsets in the DFA code. */
   6141         new_pe->from_line   = old_pe->from_line;
   6142         new_pe->req_lsz     = old_pe->req_lsz;
   6143         new_pe->total_lsz   = old_pe->total_lsz;
   6144         new_pe->flags       = old_pe->flags;
   6145         sal_memcpy(&new_pe->cps, &old_pe->cps, sizeof(_bcm_regex_cps_obj_t));
   6146         new_setidb = new_peid * BCM_REGEX_NUM_SLOT_PER_CPS;
   6147         new_pe->cps.foff = new_setidb;
   6148         old_setidb = old_peid * BCM_REGEX_NUM_SLOT_PER_CPS;
   6149         for (k = 0; k < BCM_REGEX_NUM_SLOT_PER_CPS; k++) {
   6150             old_setid2new[old_setidb + k] = new_setidb + k;
   6151         }
   6152     }
   6153 
   6154     /* flush the DFA to new location/tiles */
   6155     for (t = to_tiles; t <= to_tilee; t++) {
   6156         sal_memset(device->match_alloc_bmap[t], 0, 
   6157                                         BCM_TR3_MATCH_BMAP_BSZ*sizeof(uint32));
   6158         off = 0;
   6159         match_off = 0;
   6160         pengine = &device->physical_engines[t*max_per_tile];
   6161         mem = _bcm_tr3_get_axp_sm_memory(unit, t);
   6162         for (i = 0; i < BCM_TR3_ENGINE_PER_TILE(device); i++, pengine++) {
   6163             if (!BCM_REGEX_ENGINE_ALLOCATED(pengine)) {
   6164                 continue;
   6165             }
   6166             pdfa = dfa_cp[new2old[pengine->hw_idx]];   
   6167             if (pdfa == NULL) {
   6168                 continue;
   6169             }
   6170 
   6171             to_match_mem = AXP_SM_MATCH_TABLE_MEM0m + 
   6172                     BCM_REGEX_ENG2MATCH_MEMIDX(unit,pengine->hw_idx);
   6173 
   6174             from_match_mem = AXP_SM_MATCH_TABLE_MEM0m + 
   6175                     BCM_REGEX_ENG2MATCH_MEMIDX(unit,new2old[pengine->hw_idx]);
   6176 
   6177             old_tile = new2old[pengine->hw_idx]/max_per_tile;
   6178 
   6179             last_match_offset = match_off;
   6180 
   6181             /* adjust the jump offsets */
   6182             _bcm_tr3_regex_hw_dfa_relocate(unit, mem, pengine->req_lsz, 
   6183                                            pengine->from_line, off,
   6184                                            pdfa,
   6185                                            to_match_mem, 
   6186                                            from_match_mem, 
   6187                                            _tr3tile[old_tile].match_mem,
   6188                                            &match_off,
   6189                                            old_setid2new, 512, 1);
   6190 
   6191             /* set the base for DFA in this engine */
   6192             pengine->from_line = off;
   6193             off += pengine->total_lsz;
   6194 
   6195             if (pengine->cps.from_line >= 0) {
   6196                 
   6197             }
   6198 
   6199             /* update the alloc map */
   6200             alloc_bmap = &device->match_alloc_bmap[t][0];
   6201             for (j = last_match_offset; j < match_off; j++) {
   6202                 alloc_bmap[j/32] |= (1 << (j % 32));
   6203             }
   6204 
   6205             sal_free(pdfa);
   6206             dfa_cp[new2old[pengine->hw_idx]] = NULL;
   6207         }
   6208     }
   6209 
   6210     /* free up the alloced resources */
   6211     for (t = to_tiles; t <= to_tilee; t++) {
   6212         if (_tr3tile[t].num_o) {
   6213             _bcm_tr3_enable_tile(unit, t);
   6214         }
   6215     }
   6216 
   6217 fail:
   6218     if (old2new) {
   6219         sal_free(old2new);
   6220     }
   6221 
   6222     if (new2old) {
   6223         sal_free(new2old);
   6224     }
   6225 
   6226     if (oldleid2peid) {
   6227         sal_free(oldleid2peid);
   6228     }
   6229 
   6230     if (old_setid2new) {
   6231         sal_free(old_setid2new);
   6232     }
   6233 
   6234     for (t = to_tiles; t <= to_tilee; t++) {
   6235         if (_tr3tile[t].match_mem) {
   6236             sal_free(_tr3tile[t].match_mem);
   6237             _tr3tile[t].match_mem = NULL;
   6238         }
   6239     }
   6240     return rv;
   6241 }
   6242 
   6243 STATIC int 
   6244 _bcm_tr3_alloc_lines_in_tile(int unit, int tile, int require_lsz,
   6245                              int *start_line, int compress)
   6246 {
   6247     _bcm_tr3_regex_device_info_t *device;
   6248     int maxlines, i, num_res, as, ae, top = 0;
   6249     _bcm_regex_resource_t *pres, *a;
   6250     _bcm_regex_engine_obj_t *peng = NULL;
   6251     int rv = BCM_E_NONE, lines_avail, hole;
   6252     _bcm_regex_tile_t  tmp_tiles[BCM_TR3_MAX_TILES];
   6253 
   6254     *start_line = -1;
   6255 
   6256     device = REGEX_INFO(unit);
   6257 
   6258     maxlines = lines_avail = _bcm_tr3_get_tile_line_size(unit);
   6259     peng = BCM_TR3_PHYSICAL_ENGINE(device, 
   6260                                     tile*BCM_TR3_ENGINE_PER_TILE(device));
   6261     for (i=0; i<BCM_TR3_ENGINE_PER_TILE(device); i++, peng++) {
   6262         if (!BCM_REGEX_ENGINE_ALLOCATED(peng)) {
   6263             continue;
   6264         }
   6265         lines_avail -= peng->total_lsz;
   6266     }
   6267 
   6268     if (lines_avail < require_lsz) {
   6269         return BCM_E_RESOURCE;
   6270     }
   6271     
   6272     _bcm_tr3_make_resource_objs(unit, &pres, &num_res, tile, tile);
   6273 
   6274     if (compress) {
   6275         /* Arrange the objects by size. */
   6276         _bcm_regex_sort_resources_by_size(unit, pres, num_res);
   6277 
   6278         _bcm_tr3_arrange_resources_in_tiles(unit, pres, num_res, tile, tile,
   6279                                             tmp_tiles, BCM_TR3_MAX_TILES);
   6280         /* compress */
   6281         if (_bcm_tr3_rearrange_engines_in_hw(unit, pres, num_res, 
   6282                                              tile, tile, tmp_tiles)) {
   6283             return BCM_E_INTERNAL;
   6284         }
   6285     } else {
   6286         _bcm_regex_sort_resources_by_offset(unit, pres, num_res);
   6287     }
   6288 
   6289     top = 0; 
   6290     *start_line = -1;
   6291     for (i=0; i<num_res; i++) {
   6292         a = pres + i;
   6293         as = a->pres->from_line;
   6294         hole = as - top;
   6295         if (hole >= require_lsz) {
   6296             *start_line = top;
   6297             break;
   6298         }
   6299         ae = as + a->pres->total_lsz - 1;
   6300         top = ae+1;
   6301     }
   6302 
   6303     if ((*start_line < 0) && (maxlines - top) >= require_lsz) {
   6304         *start_line = top;
   6305     }
   6306 
   6307     if (pres) {
   6308         _bcm_tr3_free_resource_objs(unit, &pres, &num_res);
   6309     }
   6310     return rv;
   6311 }
   6312 
   6313 STATIC int _bcm_tr3_alloc_regex_engine(int unit, int clsz, int extra_lsz,
   6314                             _bcm_regex_engine_obj_t **ppeng, int tile)
   6315 {
   6316     _bcm_tr3_regex_device_info_t *device;
   6317     int i, j, try, alloc_lsz;
   6318     int tiles, tilee, start_line, rv;
   6319     _bcm_regex_engine_obj_t *peng = NULL;
   6320 
   6321     device = REGEX_INFO(unit);
   6322 
   6323     if (tile >= 0) {
   6324         tiles = tilee = tile;
   6325     } else {
   6326         tiles = 0;
   6327         tilee = device->info->num_tiles - 1;
   6328     }
   6329 
   6330     *ppeng = NULL;
   6331     alloc_lsz = clsz + extra_lsz;
   6332 
   6333     /*
   6334      * 2 stage allocation, first try find memory where contingious
   6335      * memory available, if not found, in second try, compress the
   6336      * state memory to allocate CPS memory.
   6337      */
   6338     for (try=0; (try<2); try++) {
   6339         /* iterate all the tiles and alocate cps resource */
   6340         for (i = tiles; i <= tilee; i++) {
   6341             peng = BCM_TR3_PHYSICAL_ENGINE(device, 
   6342                                 i*BCM_TR3_ENGINE_PER_TILE(device));
   6343             for (j=0; j<BCM_TR3_ENGINE_PER_TILE(device); j++, peng++) {
   6344                 if (BCM_REGEX_ENGINE_ALLOCATED(peng)) {
   6345                     continue;
   6346                 }
   6347                 /* allocate state mem. */
   6348                 rv = _bcm_tr3_alloc_lines_in_tile(unit, peng->tile,
   6349                                         alloc_lsz, &start_line, try);
   6350                 /* unable to alloc lines in this tile, try next tile. */
   6351                 if (rv) {
   6352                     break;
   6353                 }
   6354                 peng->from_line = start_line;
   6355                 peng->req_lsz = clsz;
   6356                 *ppeng = peng;
   6357                 BCM_REGEX_ENGINE_SET_ALLOCATED(peng);
   6358                 peng->cps.from_line = peng->from_line + peng->req_lsz;
   6359                 peng->cps.req_lsz = extra_lsz;
   6360                 peng->total_lsz = clsz + extra_lsz;
   6361                 if (extra_lsz) {
   6362                     _bcm_tr3_init_cps_block(unit, &peng->cps);
   6363                     BCM_REGEX_CPS_SET_ALLOCED(&peng->cps);
   6364                 }
   6365                 goto phy_engine_alloced;
   6366             }
   6367         }
   6368     }
   6369 
   6370 phy_engine_alloced:
   6371     LOG_INFO(BSL_LS_BCM_REGEX,
   6372              (BSL_META_U(unit,
   6373                          "engine engine %d allocated\n"),
   6374               peng->hw_idx));
   6375     return (*ppeng) ? BCM_E_NONE : BCM_E_RESOURCE;
   6376 }
   6377 
   6378 int 
   6379 _bcm_tr3_get_match_id(int unit, int signature_id, int *match_id)
   6380 {
   6381     _bcm_regexdb_entry_t *pe;
   6382     
   6383     pe = bcm_regexdb_find_match_entry_by_sig_id(unit, signature_id);
   6384     if (!pe) {
   6385         return BCM_E_NOT_FOUND;
   6386     }
   6387 
   6388     *match_id = pe->match_id;
   6389 
   6390     return BCM_E_NONE;
   6391 }
   6392 
   6393 int
   6394 _bcm_tr3_get_sig_id(int unit, int match_id, int *signature_id)
   6395 {
   6396     _bcm_regexdb_entry_t *pe;
   6397 
   6398     pe = bcm_regexdb_find_match_entry_by_match_id(unit, match_id);
   6399     if (!pe) {
   6400         return BCM_E_NOT_FOUND;
   6401     }
   6402 
   6403     *signature_id = pe->sigid;
   6404 
   6405     return BCM_E_NONE;
   6406 }
   6407 
   6408 int
   6409 _bcm_tr3_regex_info_get(int unit, bcm_regex_info_t *regex_info)
   6410 {
   6411     uint32  regval, fval;
   6412     soc_profile_mem_table_t *table;  /* Table info array */
   6413     int ref_count = 0, i;
   6414     _bcm_tr3_regex_device_info_t *device;
   6415 
   6416     /*
   6417     Session size
   6418     */
   6419 
   6420     SOC_IF_ERROR_RETURN(READ_FT_CONFIGr(unit, &regval));
   6421     fval = soc_reg_field_get(unit, FT_CONFIGr, regval, TABLE_SIZEf);
   6422     regex_info->session_size = _decode_max_flow(fval);
   6423 
   6424     /*
   6425     Session free sizes
   6426     */
   6427 
   6428     READ_FT_IN_USEr(unit, &fval);
   6429     fval &= BCM_TR3_IN_USE_MASK;
   6430 
   6431     regex_info->session_free_size_ipv4 = regex_info->session_size - fval;
   6432     regex_info->session_free_size_ipv6 = regex_info->session_free_size_ipv4 / 2;
   6433 
   6434     /*
   6435     Policy sizes
   6436     */
   6437 
   6438     device = REGEX_INFO(unit);
   6439 
   6440     if ((device->info->flags & BCM_REGEX_USE_POLICY_ID) == 0) {
   6441         if (_bcm_tr3_ft_policy_profile[unit] != NULL &&
   6442             _bcm_tr3_ft_policy_profile[unit]->tables != NULL) {
   6443             table = &_bcm_tr3_ft_policy_profile[unit]->tables[0];
   6444             regex_info->policy_size = table->index_max + 1;
   6445             for (i = table->index_min; i <= table->index_max; i++) {
   6446                 ref_count += table->entries[i-1].ref_count ? 1 : 0;
   6447             }
   6448             regex_info->policy_free_size = table->index_max - ref_count;
   6449         }
   6450         else{
   6451             regex_info->policy_size = 0;
   6452             regex_info->policy_free_size = 0;
   6453         }
   6454     }
   6455     
   6456     return BCM_E_NONE;
   6457         }
   6458 
   6459 
   6460 int
   6461 _bcm_tr3_regex_stat_get(int unit, bcm_regex_stat_t type, uint64 *val)
   6462 {
   6463     uint32 statval;
   6464 
   6465     if (val == NULL) {
   6466         return BCM_E_PARAM;
   6467     }
   6468 
   6469     switch(type) {
   6470         case bcmStatRegexSessionEntriesInUse:
   6471             READ_FT_IN_USEr(unit, &statval);
   6472             statval &= BCM_TR3_IN_USE_MASK;
   6473             *val = (uint64) statval;
   6474             break;
   6475 
   6476         case bcmStatRegexSessionFlowsCreated:
   6477             READ_FT_FLOWS_CREATEDr(unit, &statval);
   6478             break;
   6479 
   6480         case bcmStatRegexSessionMaxFlowsInUse:
   6481             READ_FT_IN_USEr(unit, &statval);
   6482             statval &= BCM_TR3_MAX_IN_USE_MASK;
   6483             /*
   6484             Shift the counter down to remove the "in-use" part of the register
   6485             and leave just the "max in-use"
   6486             */
   6487             statval >>= BCM_TR3_IN_USE_MASK_SIZE;
   6488             break;
   6489 
   6490         case bcmStatRegexSessionFlowsMissedTCP:
   6491             READ_FT_FLOWS_MISSED_TCPr(unit, &statval);
   6492             break;
   6493 
   6494         case bcmStatRegexSessionFlowsMissedUDP:
   6495             READ_FT_FLOWS_MISSED_UDPr(unit, &statval);
   6496             break;
   6497 
   6498         case bcmStatRegexSessionCmdWaitTimeouts:
   6499             READ_FT_CMDWAIT_TIMEOUTr(unit, &statval);
   6500             break;
   6501 
   6502         case bcmStatRegexSessionUnusedResults:
   6503             READ_FT_UPDATE_ERRr(unit, &statval);
   6504             break;
   6505 
   6506         case bcmStatRegexSessionSuppressedActions:
   6507             READ_FT_ACTION_INHIBITEDr(unit, &statval);
   6508             break;
   6509 
   6510         case bcmStatRegexSessionTcpSynData:
   6511             READ_FT_SYN_DATAr(unit, &statval);
   6512             break;
   6513 
   6514         case bcmStatRegexSessionL4Invalid:
   6515             READ_FT_L4_INVALIDr(unit, &statval);
   6516             break;
   6517 
   6518         case bcmStatRegexSessionL4PortsExcluded:
   6519             READ_FT_L4_PORTS_EXCLUDEDr(unit, &statval);
   6520             break;
   6521 
   6522         /*
   6523         The following stats are for signature match
   6524         */
   6525 
   6526         case bcmStatRegexSigMatchPacketsReceived:
   6527             READ_AXP_SM_PACKETS_RECEIVED_COUNTERr(unit, &statval);
   6528             break;
   6529 
   6530         case bcmStatRegexSigMatchPacketsSent:
   6531             READ_AXP_SM_PACKETS_SENT_COUNTERr(unit, &statval);
   6532             break;
   6533 
   6534         case bcmStatRegexSigMatchPacketsDropped:
   6535             READ_AXP_SM_PACKETS_DROPPED_COUNTERr(unit, &statval);
   6536             break;
   6537 
   6538         case bcmStatRegexSigMatchBytesMatched:
   6539             READ_AXP_SM_BYTES_MATCHED_COUNTERr(unit, &statval);
   6540             break;
   6541 
   6542         case bcmStatRegexSigMatchMatchedFlows:
   6543             READ_AXP_SM_MATCHED_FLOWS_COUNTERr(unit, &statval);
   6544             break;
   6545 
   6546         case bcmStatRegexSigMatchUnmatchedFlows:
   6547             READ_AXP_SM_UNMATCHED_FLOWS_COUNTERr(unit, &statval);
   6548             break;
   6549             
   6550         case bcmStatRegexSigMatchTotalMatch:
   6551             READ_AXP_SM_TOTAL_MATCH_COUNTERr(unit, &statval);
   6552             break;
   6553 
   6554         case bcmStatRegexSigMatchCrossSigFlags:
   6555             READ_AXP_SM_TOTAL_CROSS_SIG_FLAGS_COUNTERr(unit, &statval);
   6556             break;
   6557 
   6558         case bcmStatRegexSigMatchFragmentsReceived:
   6559             READ_AXP_SM_FRAGMENTS_RECEIVED_COUNTERr(unit, &statval);
   6560             break;
   6561 
   6562         case bcmStatRegexSigMatchInPacketError:
   6563             READ_AXP_SM_IN_PACKET_ERROR_COUNTERr(unit, &statval);
   6564             break;
   6565 
   6566         case bcmStatRegexSigMatchFlowTrackerError:
   6567             READ_AXP_SM_FLOW_TRACKER_ERROR_COUNTERr(unit, &statval);
   6568             break;
   6569 
   6570         case bcmStatRegexSigMatchPacketLengthError:
   6571             READ_AXP_SM_PACKET_LENGTH_ERROR_COUNTERr(unit, &statval);
   6572             break;
   6573 
   6574         case bcmStatRegexSigMatchL4ChecksumError:
   6575             READ_AXP_SM_L4_CHECKSUM_ERROR_COUNTERr(unit, &statval);
   6576             break;
   6577 
   6578         case bcmStatRegexSigMatchFlowDonePacketDrop:
   6579             READ_AXP_SM_FLOW_DONE_PACKET_DROP_COUNTERr(unit, &statval);
   6580             break;
   6581 
   6582         case bcmStatRegexSigMatchFlowTimestampError:
   6583             READ_AXP_SM_FLOW_TIMESTAMP_ERROR_COUNTERr(unit, &statval);
   6584             break;
   6585 
   6586         case bcmStatRegexSigMatchFlowPacketNumError:
   6587             READ_AXP_SM_FLOW_PACKET_NUM_ERROR_COUNTERr(unit, &statval);
   6588             break;
   6589 
   6590         case bcmStatRegexSigMatchECCError:
   6591             READ_AXP_SM_ECC_ERROR_COUNTERr(unit, &statval);
   6592             break;
   6593 
   6594         default:
   6595             return BCM_E_PARAM;
   6596             break;
   6597     }
   6598 
   6599     *val = (uint64) statval;
   6600 
   6601     return BCM_E_NONE;
   6602 }
   6603 
   6604 int
   6605 _bcm_tr3_regex_stat_set(int unit, bcm_regex_stat_t type, uint64 val)
   6606 {
   6607     uint32 statval = (uint32) val;
   6608     uint32 statval2;
   6609 
   6610     switch(type) {
   6611         case bcmStatRegexSessionEntriesInUse:
   6612             READ_FT_IN_USEr(unit, &statval2);
   6613             statval2 &= BCM_TR3_MAX_IN_USE_MASK;
   6614             statval &= BCM_TR3_IN_USE_MASK;
   6615             statval |= statval2;
   6616             WRITE_FT_IN_USEr(unit, statval);
   6617             break;
   6618 
   6619         case bcmStatRegexSessionFlowsCreated:
   6620             WRITE_FT_FLOWS_CREATEDr(unit, statval);
   6621             break;
   6622 
   6623         case bcmStatRegexSessionMaxFlowsInUse:
   6624             READ_FT_IN_USEr(unit, &statval2);
   6625             /*
   6626             Save the "in-use" part of the register before adding the
   6627             new "max in-use" value
   6628             */
   6629             statval2 &= BCM_TR3_IN_USE_MASK;
   6630             statval <<= BCM_TR3_IN_USE_MASK_SIZE;
   6631             statval &= BCM_TR3_MAX_IN_USE_MASK;
   6632             statval |= statval2;
   6633             WRITE_FT_IN_USEr(unit, statval);
   6634             break;
   6635 
   6636         case bcmStatRegexSessionFlowsMissedTCP:
   6637             WRITE_FT_FLOWS_MISSED_TCPr(unit, statval);
   6638             break;
   6639 
   6640         case bcmStatRegexSessionFlowsMissedUDP:
   6641             WRITE_FT_FLOWS_MISSED_UDPr(unit, statval);
   6642             break;
   6643 
   6644         case bcmStatRegexSessionCmdWaitTimeouts:
   6645             WRITE_FT_CMDWAIT_TIMEOUTr(unit, statval);
   6646             break;
   6647 
   6648         case bcmStatRegexSessionUnusedResults:
   6649             WRITE_FT_UPDATE_ERRr(unit, statval);
   6650             break;
   6651 
   6652         case bcmStatRegexSessionSuppressedActions:
   6653             WRITE_FT_ACTION_INHIBITEDr(unit, statval);
   6654             break;
   6655 
   6656         case bcmStatRegexSessionTcpSynData:
   6657             WRITE_FT_SYN_DATAr(unit, statval);
   6658             break;
   6659 
   6660         case bcmStatRegexSessionL4Invalid:
   6661             WRITE_FT_L4_INVALIDr(unit, statval);
   6662             break;
   6663 
   6664         case bcmStatRegexSessionL4PortsExcluded:
   6665             WRITE_FT_L4_PORTS_EXCLUDEDr(unit, statval);
   6666             break;
   6667 
   6668         /*
   6669         The following stats are for signature match
   6670         */
   6671 
   6672         case bcmStatRegexSigMatchPacketsReceived:
   6673             WRITE_AXP_SM_PACKETS_RECEIVED_COUNTERr(unit, statval);
   6674             break;
   6675 
   6676         case bcmStatRegexSigMatchPacketsSent:
   6677             WRITE_AXP_SM_PACKETS_SENT_COUNTERr(unit, statval);
   6678             break;
   6679 
   6680         case bcmStatRegexSigMatchPacketsDropped:
   6681             WRITE_AXP_SM_PACKETS_DROPPED_COUNTERr(unit, statval);
   6682             break;
   6683 
   6684         case bcmStatRegexSigMatchBytesMatched:
   6685             WRITE_AXP_SM_BYTES_MATCHED_COUNTERr(unit, statval);
   6686             break;
   6687 
   6688         case bcmStatRegexSigMatchMatchedFlows:
   6689             WRITE_AXP_SM_MATCHED_FLOWS_COUNTERr(unit, statval);
   6690             break;
   6691 
   6692         case bcmStatRegexSigMatchUnmatchedFlows:
   6693             WRITE_AXP_SM_UNMATCHED_FLOWS_COUNTERr(unit, statval);
   6694             break;
   6695             
   6696         case bcmStatRegexSigMatchTotalMatch:
   6697             WRITE_AXP_SM_TOTAL_MATCH_COUNTERr(unit, statval);
   6698             break;
   6699 
   6700         case bcmStatRegexSigMatchCrossSigFlags:
   6701             WRITE_AXP_SM_TOTAL_CROSS_SIG_FLAGS_COUNTERr(unit, statval);
   6702             break;
   6703 
   6704         case bcmStatRegexSigMatchFragmentsReceived:
   6705             WRITE_AXP_SM_FRAGMENTS_RECEIVED_COUNTERr(unit, statval);
   6706             break;
   6707 
   6708         case bcmStatRegexSigMatchInPacketError:
   6709             WRITE_AXP_SM_IN_PACKET_ERROR_COUNTERr(unit, statval);
   6710             break;
   6711 
   6712         case bcmStatRegexSigMatchFlowTrackerError:
   6713             WRITE_AXP_SM_FLOW_TRACKER_ERROR_COUNTERr(unit, statval);
   6714             break;
   6715 
   6716         case bcmStatRegexSigMatchPacketLengthError:
   6717             WRITE_AXP_SM_PACKET_LENGTH_ERROR_COUNTERr(unit, statval);
   6718             break;
   6719 
   6720         case bcmStatRegexSigMatchL4ChecksumError:
   6721             WRITE_AXP_SM_L4_CHECKSUM_ERROR_COUNTERr(unit, statval);
   6722             break;
   6723 
   6724         case bcmStatRegexSigMatchFlowDonePacketDrop:
   6725             WRITE_AXP_SM_FLOW_DONE_PACKET_DROP_COUNTERr(unit, statval);
   6726             break;
   6727 
   6728         case bcmStatRegexSigMatchFlowTimestampError:
   6729             WRITE_AXP_SM_FLOW_TIMESTAMP_ERROR_COUNTERr(unit, statval);
   6730             break;
   6731 
   6732         case bcmStatRegexSigMatchFlowPacketNumError:
   6733             WRITE_AXP_SM_FLOW_PACKET_NUM_ERROR_COUNTERr(unit, statval);
   6734             break;
   6735 
   6736         case bcmStatRegexSigMatchECCError:
   6737             WRITE_AXP_SM_ECC_ERROR_COUNTERr(unit, statval);
   6738             break;
   6739 
   6740         default:
   6741             return BCM_E_PARAM;
   6742             break;
   6743     }
   6744     
   6745     return BCM_E_NONE;
   6746     }
   6747 
   6748 /*
   6749  * Function:
   6750  *     _regex_tr3_policer_hw_update
   6751  * Purpose:
   6752  *     Update (Install) the policer parameters
   6753  * Parameters:
   6754  *     unit          - (IN) BCM device number.
   6755  *     f_ent         - (IN) Field entry policer attached to.
   6756  *     index_mtr     - (IN) Peak/Committed
   6757  *     bucket_size   - (IN) Encoded bucket size.
   6758  *     refresh_rate  - (IN) Tokens refresh rate.
   6759  *     granularity   - (IN) Tokens granularity.
   6760  * Returns:
   6761  *     BCM_E_XXX
   6762  */
   6763 STATIC int _regex_tr3_policer_hw_update(int unit,
   6764                                         _field_policer_t *f_pl, uint8 index_mtr,
   6765                                         uint32 bucket_size, uint32 refresh_rate,
   6766                                         uint32 granularity, soc_mem_t meter_table)
   6767 {
   6768     _field_stage_t  *stage_fc;               /* Field stage control.         */
   6769     uint32          meter_entry[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.*/
   6770     int             bucket_cnt_bitsize;      /* Bucket count field bit size. */
   6771     int             bucket_max_bitsize;      /* Bucket size field bit size.  */
   6772     int             meter_hw_idx;            /* Meter table index.           */
   6773     uint32          bucketcount;             /* Bucket count initial value.  */
   6774     int             meter_offset;            /* Peak/Comm meter selection.   */
   6775     int             rv;                      /* Operation return status.     */
   6776 
   6777     if ((NULL == f_pl) || (INVALIDm == meter_table)) {
   6778         return (BCM_E_PARAM);
   6779     }
   6780 
   6781     /* Get stage field control structure. */
   6782     rv = _field_stage_control_get(unit, _BCM_FIELD_STAGE_INGRESS, &stage_fc);
   6783     BCM_IF_ERROR_RETURN(rv);
   6784 
   6785     /* Calculate initial backet count.
   6786      * bucket size << (bit count diff - 1(sign) -1 (overflow))  - 1
   6787      */
   6788     if (bucket_size) {
   6789         bucket_cnt_bitsize = soc_mem_field_length(unit, meter_table,
   6790                                                   BUCKETCOUNTf);
   6791         bucket_max_bitsize = soc_mem_field_length(unit, meter_table,
   6792                                                   BUCKETSIZEf);
   6793         bucketcount = (bucket_size
   6794                         << (bucket_cnt_bitsize - bucket_max_bitsize - 2))  - 1;
   6795         bucketcount &= ((1 << bucket_cnt_bitsize) - 1);
   6796     } else {
   6797         bucketcount = 0;
   6798     }
   6799 
   6800     meter_offset = (BCM_FIELD_METER_PEAK == index_mtr) ? 0 : 1;
   6801 
   6802     meter_hw_idx = (f_pl->pool_index * stage_fc->meter_pool[_FP_DEF_INST][0]->pool_size) + 
   6803                                                       (2 * f_pl->hw_index) + meter_offset;
   6804 
   6805     /* Update meter config in hw. */
   6806     rv = soc_mem_read(unit, meter_table, MEM_BLOCK_ANY,
   6807                       meter_hw_idx, &meter_entry);
   6808     BCM_IF_ERROR_RETURN(rv);
   6809 
   6810     soc_mem_field32_set(unit, meter_table, &meter_entry, REFRESHCOUNTf,
   6811                         refresh_rate);
   6812     soc_mem_field32_set(unit, meter_table, &meter_entry, BUCKETSIZEf,
   6813                         bucket_size);
   6814     soc_mem_field32_set(unit, meter_table, &meter_entry, METER_GRANf,
   6815                         granularity);
   6816     soc_mem_field32_set(unit, meter_table, &meter_entry, BUCKETCOUNTf,
   6817                         bucketcount);
   6818 
   6819     /* Refresh mode is only set to 1 for Single Rate. Other modes get 0 */
   6820     if (f_pl->cfg.mode  == bcmPolicerModeSrTcm) {
   6821         soc_mem_field32_set(unit, meter_table, &meter_entry, REFRESH_MODEf, 1);
   6822     } else if (f_pl->cfg.mode  == bcmPolicerModeCoupledTrTcmDs) {
   6823         soc_mem_field32_set(unit, meter_table, &meter_entry, REFRESH_MODEf, 2);
   6824     } else {
   6825         soc_mem_field32_set(unit, meter_table, &meter_entry, REFRESH_MODEf, 0);
   6826     }
   6827 
   6828     if ((soc_feature(unit, soc_feature_field_packet_based_metering)) &&
   6829         (soc_mem_field_valid(unit, meter_table, PKTS_BYTESf))) {
   6830         if (f_pl->cfg.flags & BCM_POLICER_MODE_PACKETS) {
   6831             soc_mem_field32_set(unit, meter_table, &meter_entry, PKTS_BYTESf, 1);
   6832         } else {
   6833             soc_mem_field32_set(unit, meter_table, &meter_entry, PKTS_BYTESf, 0);
   6834         }
   6835     }
   6836 
   6837     rv = soc_mem_write(unit, meter_table, MEM_BLOCK_ALL,
   6838                        meter_hw_idx, meter_entry);
   6839 
   6840     return (rv);
   6841     }
   6842 
   6843 STATIC int _regex_tr3_policer_action_set(int              unit,
   6844                                          _regex_policy_t *p_ent,
   6845                                          uint32          *policy_buf)
   6846 {
   6847     _field_entry_policer_t *f_ent_pl;
   6848     unsigned               api_mode, api_flags, pool_idx, hw_idx;
   6849     uint8                  hw_mode, modifier, sh_mode;
   6850     _field_policer_t       *f_pl = NULL;
   6851 
   6852     /* Level 0 */
   6853 
   6854     f_ent_pl = &p_ent->policer[0];
   6855     if (f_ent_pl->flags & _FP_POLICER_INSTALLED) {
   6856         BCM_IF_ERROR_RETURN(_bcm_regex_policer_get(unit, f_ent_pl->pid, &f_pl));
   6857         api_mode  = f_pl->cfg.mode;
   6858         api_flags = f_pl->cfg.flags;
   6859         pool_idx  = f_pl->pool_index;
   6860         hw_idx    = f_pl->hw_index;
   6861     } else {
   6862         api_mode = bcmPolicerModePassThrough;
   6863         api_flags = pool_idx = hw_idx = 0;
   6864     }
   6865 
   6866     switch (api_mode) {
   6867         case bcmPolicerModeGreen:
   6868         case bcmPolicerModePassThrough:
   6869             hw_mode = 0;
   6870             modifier = (api_mode == bcmPolicerModePassThrough) ? 1 : 0;
   6871             break;
   6872         case bcmPolicerModeCommitted:
   6873             hw_mode  = 1;
   6874             modifier = (_FP_POLICER_EXCESS_HW_METER(f_pl)) ? 0 : 1;
   6875             break;
   6876         case bcmPolicerModeSrTcm:
   6877         case bcmPolicerModeSrTcmModified:
   6878             hw_mode  = (api_flags & BCM_POLICER_COLOR_BLIND) ? 6 : 7;
   6879             modifier = (api_mode == bcmPolicerModeSrTcmModified) ? 1 : 0;
   6880             break;
   6881         case bcmPolicerModeTrTcm:
   6882             hw_mode = (api_flags & BCM_POLICER_COLOR_BLIND) ? 2 : 3;
   6883             modifier = 0;
   6884             break;
   6885         case bcmPolicerModeTrTcmDs:
   6886         case bcmPolicerModeCoupledTrTcmDs:
   6887             hw_mode = (api_flags & BCM_POLICER_COLOR_BLIND) ? 4 : 5;
   6888             modifier = 0;
   6889             break;
   6890         default:
   6891             return (BCM_E_INTERNAL);
   6892     }
   6893 
   6894     soc_mem_field32_set(unit,
   6895                         FT_POLICYm,
   6896                         policy_buf,
   6897                         METER_PAIR_POOL_NUMBERf,
   6898                         pool_idx);
   6899     soc_mem_field32_set(unit,
   6900                         FT_POLICYm,
   6901                         policy_buf,
   6902                         METER_PAIR_POOL_INDEXf,
   6903                         hw_idx);
   6904     soc_mem_field32_set(unit,
   6905                         FT_POLICYm,
   6906                         policy_buf,
   6907                         METER_PAIR_MODEf,
   6908                         hw_mode);
   6909     soc_mem_field32_set(unit,
   6910                         FT_POLICYm,
   6911                         policy_buf,
   6912                         METER_PAIR_MODE_MODIFIERf,
   6913                         modifier);
   6914 
   6915     /* Level 1 */
   6916 #if defined(ESW_REGEX_HIERARCHICAL_METERS)
   6917     f_ent_pl = &p_ent->policer[1];
   6918     if (f_ent_pl->flags & _FP_POLICER_INSTALLED) {
   6919         BCM_IF_ERROR_RETURN(_bcm_regex_policer_get(unit, f_ent_pl->pid, &f_pl));
   6920         api_mode  = f_pl->cfg.mode;
   6921         api_flags = f_pl->cfg.flags;
   6922         pool_idx  = f_pl->pool_index;
   6923         hw_idx    = f_pl->hw_index;
   6924     } else
   6925 #endif
   6926     {
   6927         api_mode = bcmPolicerModePassThrough;
   6928         api_flags = pool_idx = hw_idx = 0;
   6929     }
   6930 
   6931     if (api_mode == bcmPolicerModePassThrough) {
   6932         hw_mode = sh_mode = modifier = 0;
   6933     } else {
   6934         switch (api_mode) {
   6935             case bcmPolicerModeCommitted:
   6936                 hw_mode = 0;
   6937                 modifier = (_FP_POLICER_EXCESS_HW_METER(f_pl)) ? 0 : 1;
   6938                 break;
   6939             case bcmPolicerModeTrTcmDs:
   6940             case bcmPolicerModeCoupledTrTcmDs:
   6941                 hw_mode = 1;
   6942                 modifier = (api_flags & BCM_POLICER_COLOR_BLIND) ? 0 : 1;
   6943                 break;
   6944             default:
   6945                 return (BCM_E_INTERNAL);
   6946     }
   6947 
   6948         switch (api_flags & BCM_POLICER_COLOR_MERGE_MASK) {
   6949             case BCM_POLICER_COLOR_MERGE_AND:
   6950                 sh_mode = 2;
   6951                 break;
   6952             case BCM_POLICER_COLOR_MERGE_OR:
   6953                 sh_mode = 1;
   6954                 break;
   6955             case BCM_POLICER_COLOR_MERGE_DUAL:
   6956                 sh_mode = 3;
   6957                 break;
   6958             default:
   6959                 return (BCM_E_INTERNAL);
   6960         }
   6961     }
   6962 
   6963     soc_mem_field32_set(unit,
   6964                         FT_POLICYm,
   6965                         policy_buf,
   6966                         SHARED_METER_PAIR_POOL_NUMBERf,
   6967                         pool_idx);
   6968     soc_mem_field32_set(unit,
   6969                         FT_POLICYm,
   6970                         policy_buf,
   6971                         SHARED_METER_PAIR_POOL_INDEXf,
   6972                         hw_idx);
   6973     soc_mem_field32_set(unit,
   6974                         FT_POLICYm,
   6975                         policy_buf,
   6976                         SHARED_METER_PAIR_MODEf,
   6977                         hw_mode);
   6978     soc_mem_field32_set(unit,
   6979                         FT_POLICYm,
   6980                         policy_buf,
   6981                         METER_SHARING_MODEf,
   6982                         sh_mode);
   6983     soc_mem_field32_set(unit,
   6984                         FT_POLICYm,
   6985                         policy_buf,
   6986                         METER_SHARING_MODE_MODIFIERf,
   6987                         modifier);
   6988 
   6989     return (BCM_E_NONE);
   6990 }
   6991 
   6992 /*
   6993  * Function:
   6994  *     _regex_tr3_policy_redirect_profile_get
   6995  * Purpose:
   6996  *     Get the redirect profile for the unit
   6997  * Parameters:
   6998  *     unit             - BCM device number
   6999  *     redirect_profile - (OUT) redirect profile
   7000  * Returns:
   7001  *     BCM_E_XXX
   7002  * Notes:
   7003  *     For triumph, External TCAM and IFP refer to same IFP_REDIRECTION_PROFILEm
   7004  */
   7005 STATIC int _regex_tr3_policy_redirect_profile_get(int unit, soc_profile_mem_t **redirect_profile)
   7006 {
   7007     _field_control_t *fc = NULL;
   7008  
   7009     /* Get field control structure. */
   7010     BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc));
   7011  
   7012     *redirect_profile = &fc->redirect_profile;
   7013 
   7014     return (BCM_E_NONE);
   7015 }
   7016 
   7017 /*
   7018  * Function:
   7019  *     _regex_tr3_policy_redirect_profile_ref_count_get
   7020  * Purpose:
   7021  *     Get redirect profile entry use count.
   7022  * Parameters:
   7023  *     unit      - (IN) BCM device number.
   7024  *     index     - (IN) Profile entry index.
   7025  *     ref_count - (OUT) redirect profile use count.
   7026  * Returns:
   7027  *     BCM_E_XXX
   7028  */
   7029 STATIC int _regex_tr3_policy_redirect_profile_ref_count_get(int unit, int index, int *ref_count)
   7030 {
   7031     soc_profile_mem_t *redirect_profile;
   7032 
   7033     if (NULL == ref_count) {
   7034         return (BCM_E_PARAM);
   7035     }
   7036 
   7037     /* Get the redirect profile */
   7038     BCM_IF_ERROR_RETURN(_regex_tr3_policy_redirect_profile_get(unit, &redirect_profile));
   7039 
   7040     BCM_IF_ERROR_RETURN(soc_profile_mem_ref_count_get(unit, redirect_profile,
   7041                                                       index, ref_count));
   7042     return (BCM_E_NONE);
   7043 }
   7044 
   7045 /*
   7046  * Function:
   7047  *     _regex_tr3_policy_redirect_profile_delete
   7048  * Purpose:
   7049  *     Delete redirect profile entry.
   7050  * Parameters:
   7051  *     unit      - (IN) BCM device number.
   7052  *     index     - (IN) Profile entry index.
   7053  * Returns:
   7054  *     BCM_E_XXX
   7055  */
   7056 STATIC int _regex_tr3_policy_redirect_profile_delete(int unit, int index)
   7057 {
   7058     soc_profile_mem_t *redirect_profile;
   7059 
   7060     /* Get the redirect profile */
   7061     BCM_IF_ERROR_RETURN(_regex_tr3_policy_redirect_profile_get(unit, &redirect_profile));
   7062 
   7063     BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, redirect_profile, index));
   7064     return (BCM_E_NONE);
   7065 }
   7066 
   7067 /*
   7068  * Function:
   7069  *     _regex_tr3_policy_redirect_profile_alloc
   7070  * Purpose:
   7071  *     Allocate redirect profile index
   7072  * Parameters:
   7073  *     unit     - (IN) BCM device number.
   7074  *     f_ent    - (IN) Field entry structure to get policy info from.
   7075  *     fa       - (IN) Field action.
   7076  * Returns:
   7077  *     BCM_E_XXX
   7078  */
   7079 STATIC int _regex_tr3_policy_redirect_profile_alloc(int unit, _regex_policy_t *p_ent,
   7080                                                     _regex_policy_action_t *pa)
   7081 {
   7082     ifp_redirection_profile_entry_t  entry_arr[2];
   7083     uint32                          *entry_ptr[2];
   7084     soc_profile_mem_t               *redirect_profile;
   7085     int                              rv;
   7086 #ifdef INCLUDE_L3
   7087     bcm_pbmp_t                       ipmc_l2_pbmp, ipmc_l3_pbmp;
   7088     int                              ipmc_index;
   7089     int                              entry_count;
   7090 #endif /* INCLUDE_L3 */
   7091     bcm_mcast_addr_t                 mcaddr;
   7092     bcm_pbmp_t                       pbmp;
   7093     void                            *entries[1];
   7094     soc_mem_t                        profile_mem = IFP_REDIRECTION_PROFILEm;
   7095 
   7096     entry_ptr[0] = (uint32 *)entry_arr;
   7097     entry_ptr[1] =  entry_ptr[0] + soc_mem_entry_words(unit, profile_mem);
   7098     entries[0] = (void *)&entry_arr;
   7099 
   7100     if ((NULL == p_ent) || (NULL == pa)) {
   7101         return (BCM_E_PARAM);
   7102     }
   7103 
   7104     /* Reset redirection profile entry. */
   7105     sal_memcpy(entry_ptr[0], soc_mem_entry_null(unit, profile_mem),
   7106                soc_mem_entry_words(unit, profile_mem) * sizeof(uint32));
   7107     sal_memcpy(entry_ptr[1], soc_mem_entry_null(unit, profile_mem),
   7108                soc_mem_entry_words(unit, profile_mem) * sizeof(uint32));
   7109 
   7110     /* Get the redirect profile */
   7111     rv = _regex_tr3_policy_redirect_profile_get(unit, &redirect_profile);
   7112     BCM_IF_ERROR_RETURN(rv);
   7113 
   7114     switch (pa->action) {
   7115         case bcmFieldActionRedirectPbmp:
   7116         case bcmFieldActionRedirectBcastPbmp:
   7117         case bcmFieldActionEgressMask:
   7118         case bcmFieldActionEgressPortsAdd:
   7119             SOC_PBMP_CLEAR(pbmp);
   7120             SOC_PBMP_WORD_SET(pbmp, 0, pa->param[0]);
   7121             SOC_PBMP_WORD_SET(pbmp, 1, pa->param[1]);
   7122             /* Trident family could support more than 64-ports on a device*/
   7123             if (SOC_IS_TD_TT(unit)) {
   7124                 SOC_PBMP_WORD_SET(pbmp, 2, pa->param[2]);
   7125             }
   7126             /* Trident2 device can support more than 96-ports */
   7127             if (SOC_IS_TD2_TT2(unit)) {
   7128                 SOC_PBMP_WORD_SET(pbmp, 3, pa->param[3]);
   7129             }
   7130             soc_mem_pbmp_field_set(unit, profile_mem, entry_ptr[0], BITMAPf, &pbmp);
   7131             rv = soc_profile_mem_add(unit, redirect_profile, entries,
   7132                                      1, (uint32 *)&pa->hw_index);
   7133             BCM_IF_ERROR_RETURN(rv);
   7134             break;
   7135 #ifdef INCLUDE_L3
   7136         case bcmFieldActionRedirectIpmc:
   7137             if (_BCM_MULTICAST_IS_SET(pa->param[0])) {
   7138                 if ((0 == _BCM_MULTICAST_IS_L3(pa->param[0])) &&
   7139                     (0 == _BCM_MULTICAST_IS_WLAN(pa->param[0]))) {
   7140                     return (BCM_E_PARAM);
   7141                 }
   7142                 ipmc_index = _BCM_MULTICAST_ID_GET(pa->param[0]);
   7143             } else {
   7144                 ipmc_index = pa->param[0];
   7145             }
   7146             rv = _bcm_esw_multicast_ipmc_read(unit, ipmc_index,
   7147                                               &ipmc_l2_pbmp, &ipmc_l3_pbmp);
   7148             BCM_IF_ERROR_RETURN(rv);
   7149             entry_count = 2;
   7150             soc_mem_pbmp_field_set(unit, profile_mem, entry_ptr[0], BITMAPf,
   7151                                    &ipmc_l3_pbmp);
   7152             soc_mem_pbmp_field_set(unit, profile_mem, entry_ptr[1], BITMAPf,
   7153                                    &ipmc_l2_pbmp);
   7154             soc_mem_field32_set(unit, profile_mem, entry_ptr[0], MC_INDEXf, ipmc_index);
   7155             /* MTU profile index overlayed on MC_INDEXf. */
   7156             rv = soc_profile_mem_add(unit, redirect_profile,
   7157                                      entries, entry_count, (uint32 *)&pa->hw_index);
   7158             BCM_IF_ERROR_RETURN(rv);
   7159             break;
   7160 #endif /* INCLUDE_L3 */
   7161         case bcmFieldActionRedirectMcast:
   7162             rv = _bcm_xgs3_mcast_index_port_get(unit, pa->param[0], &mcaddr);
   7163             BCM_IF_ERROR_RETURN(rv);
   7164             soc_mem_pbmp_field_set(unit, profile_mem, entry_ptr[0], BITMAPf,
   7165                                    &mcaddr.pbmp);
   7166             soc_mem_field32_set(unit, profile_mem, entry_ptr[0], MC_INDEXf, pa->param[0]);
   7167             rv = soc_profile_mem_add(unit, redirect_profile, entries,
   7168                                      1, (uint32 *)&pa->hw_index);
   7169             BCM_IF_ERROR_RETURN(rv);
   7170             break;
   7171         default:
   7172             return (BCM_E_PARAM);
   7173     }
   7174     return (BCM_E_NONE);
   7175 }
   7176 
   7177 /*
   7178  * Function:
   7179  *     _regex_tr3_policy_action_redirect
   7180  * Purpose:
   7181  *     Install redirect action in policy table.
   7182  * Parameters:
   7183  *     unit     - (IN) BCM device number.
   7184  *     mem      - (IN) Policy table memory.
   7185  *     f_ent    - (IN) Field entry structure to get policy info from.
   7186  *     fa       - (IN) Field action.
   7187  *     buf      - (OUT) Field Policy table entry.
   7188  * Returns:
   7189  *     BCM_E_XXX
   7190  */
   7191 STATIC int _regex_tr3_policy_action_redirect(int unit, soc_mem_t mem, _regex_policy_t *p_ent,
   7192                                              _regex_policy_action_t *pa, uint32 *buf)
   7193 {
   7194     uint32          redir_field = 0;
   7195     int             shift_val;
   7196     soc_field_t     redir_field_type = INVALIDf;
   7197 
   7198     if (NULL == p_ent || NULL == pa || NULL == buf) {
   7199         return (BCM_E_PARAM);
   7200     }
   7201 
   7202     switch (pa->action) {
   7203         case bcmFieldActionOffloadRedirect:
   7204             redir_field = ((pa->param[0] & 0x7f) << 6);
   7205             redir_field |= (pa->param[1] & 0x3f);
   7206             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x1);
   7207             PolicySet(unit, mem, buf, REDIRECTIONf, redir_field);
   7208 
   7209             PolicySet(unit, mem, buf, HI_PRI_ACTION_CONTROLf, 0x1);
   7210             PolicySet(unit, mem, buf, HI_PRI_RESOLVEf, 0x1);
   7211             PolicySet(unit, mem, buf, SUPPRESS_COLOR_SENSITIVE_ACTIONSf, 0x1);
   7212             PolicySet(unit, mem, buf, DEFER_QOS_MARKINGSf, 0x1);
   7213             PolicySet(unit, mem, buf, SUPPRESS_SW_ACTIONSf, 0x1);
   7214             PolicySet(unit, mem, buf, SUPPRESS_VXLTf, 0x1);
   7215             break;
   7216         case bcmFieldActionRedirect: /* param0 = modid, param1 = port*/
   7217             redir_field_type = REDIRECTIONf;
   7218             redir_field_type = REDIRECT_DVPf;
   7219             if (BCM_GPORT_IS_MPLS_PORT(pa->param[1])) {
   7220                 redir_field = BCM_GPORT_MPLS_PORT_ID_GET((int)pa->param[1]);
   7221                 PolicySet(unit, mem, buf, UNICAST_REDIRECT_CONTROLf, 0x6);
   7222             } else if (BCM_GPORT_IS_MIM_PORT(pa->param[1])) {
   7223                 redir_field = BCM_GPORT_MIM_PORT_ID_GET((int)pa->param[1]);
   7224                 PolicySet(unit, mem, buf, UNICAST_REDIRECT_CONTROLf, 0x6);
   7225             } else if (BCM_GPORT_IS_NIV_PORT(pa->param[1])) {
   7226                 redir_field = BCM_GPORT_NIV_PORT_ID_GET((int)pa->param[1]);
   7227                 PolicySet(unit, mem, buf, UNICAST_REDIRECT_CONTROLf, 0x6);
   7228             } else if (BCM_GPORT_IS_TRILL_PORT(pa->param[1])) {
   7229                 redir_field = BCM_GPORT_TRILL_PORT_ID_GET((int)pa->param[1]);
   7230                 PolicySet(unit, mem, buf, UNICAST_REDIRECT_CONTROLf, 0x6);
   7231             } else if (BCM_GPORT_IS_L2GRE_PORT(pa->param[1])) {
   7232                 redir_field = BCM_GPORT_L2GRE_PORT_ID_GET((int)pa->param[1]);
   7233                 PolicySet(unit, mem, buf, UNICAST_REDIRECT_CONTROLf, 0x6);
   7234             } else {
   7235                 redir_field_type = REDIRECTIONf;
   7236                 redir_field = ((pa->param[0] & 0xff) << 7);
   7237                 redir_field |= (pa->param[1] & 0x7f);
   7238             }
   7239             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x1);
   7240             PolicySet(unit, mem, buf, redir_field_type, redir_field);
   7241             break;
   7242         case bcmFieldActionRedirectTrunk:    /* param0 = trunk ID */
   7243             shift_val = 9;
   7244             redir_field |= (0x40 << shift_val);  /* Trunk indicator. */
   7245             redir_field |= pa->param[0];
   7246 
   7247             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x1);
   7248             PolicySet(unit, mem, buf, REDIRECTIONf, redir_field);
   7249             break;
   7250         case bcmFieldActionRedirectCancel:
   7251             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 2);
   7252             break;
   7253         case bcmFieldActionRedirectPbmp:
   7254             PolicySet(unit, mem, buf, REDIRECTIONf, pa->hw_index);
   7255             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x3);
   7256             p_ent->flags |= _FP_ENTRY_COLOR_INDEPENDENT;
   7257             break;
   7258         case bcmFieldActionEgressMask:
   7259             PolicySet(unit, mem, buf, REDIRECTIONf, pa->hw_index);
   7260             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x4);
   7261             break;
   7262         case bcmFieldActionEgressPortsAdd:
   7263             PolicySet(unit, mem, buf, REDIRECTIONf, pa->hw_index);
   7264             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x5);
   7265             break;
   7266 #ifdef INCLUDE_L3
   7267         case bcmFieldActionRedirectIpmc:
   7268             if (soc_feature(unit, soc_feature_field_action_redirect_ipmc)) {
   7269                 if (_BCM_MULTICAST_IS_SET(pa->param[0])) {
   7270                     if ((0 == _BCM_MULTICAST_IS_L3(pa->param[0])) &&
   7271                         (0 == _BCM_MULTICAST_IS_WLAN(pa->param[0]))) {
   7272                         return (BCM_E_PARAM);
   7273                     }
   7274                     redir_field = _BCM_MULTICAST_ID_GET(pa->param[0]);
   7275                 } else {
   7276                     redir_field = pa->param[0];
   7277                 }
   7278             } else {
   7279                 redir_field = pa->hw_index;
   7280             }
   7281             /* Assign IPMC action to redirect profile index. */
   7282             shift_val = 16;
   7283 
   7284             PolicySet(unit, mem, buf, REDIRECTIONf,
   7285                       (redir_field | (3 << shift_val)));
   7286             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x3);
   7287             break;
   7288 #endif /* INCLUDE_L3 */
   7289         case bcmFieldActionRedirectMcast:
   7290             if (soc_feature(unit, soc_feature_field_action_redirect_ipmc)) {
   7291                 if (_BCM_MULTICAST_IS_SET(pa->param[0])) {
   7292                     if (0 == _BCM_MULTICAST_IS_L2(pa->param[0])) {
   7293                         return (BCM_E_PARAM);
   7294                     }
   7295                     redir_field = _BCM_MULTICAST_ID_GET(pa->param[0]);
   7296                 } else {
   7297                     redir_field = pa->param[0];
   7298                 }
   7299             } else {
   7300                 redir_field = pa->hw_index;
   7301             }
   7302 
   7303             /* Assign MCAST action to redirect profile index. */
   7304             shift_val = 16;
   7305             PolicySet(unit, mem, buf, REDIRECTIONf,
   7306                       (redir_field | (2 << shift_val)));
   7307             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x3);
   7308             break;
   7309         case bcmFieldActionRedirectVlan:
   7310             shift_val = 16;
   7311             PolicySet(unit, mem, buf, REDIRECTIONf, (1 << shift_val));
   7312             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x3);
   7313             break;
   7314         case bcmFieldActionRedirectBcastPbmp:
   7315             shift_val = 16;
   7316             redir_field = pa->hw_index;
   7317             PolicySet(unit, mem, buf, REDIRECTIONf,
   7318                       (redir_field | (1 << 11) | (1 << shift_val)));
   7319             PolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 0x3);
   7320             break;
   7321         default:
   7322             return (BCM_E_PARAM);
   7323     }
   7324     return (BCM_E_NONE);
   7325 }
   7326 
   7327 STATIC int _regex_tr3_policy_index_min_get(int unit)
   7328 {
   7329     return soc_mem_index_min(unit, FT_POLICYm);
   7330 }
   7331 
   7332 STATIC int _regex_tr3_policy_index_max_get(int unit)
   7333 {
   7334     return soc_mem_index_max(unit, FT_POLICYm);
   7335 }
   7336 
   7337 STATIC int _regex_tr3_policy_action_support_check(int                 unit,
   7338                                                   bcm_field_action_t  action)
   7339 {
   7340     switch (action) {
   7341 /* Following cases from _field_tr3_stage_action_support_check */
   7342         case bcmFieldActionNewClassId:
   7343         case bcmFieldActionTrunkLoadBalanceCancel:
   7344         case bcmFieldActionEgressClassSelect:
   7345         case bcmFieldActionHiGigClassSelect:
   7346         case bcmFieldActionOamDmTimeFormat:
   7347         case bcmFieldActionOamLmDmSampleEnable:
   7348         case bcmFieldActionOamTagStatusCheck:
   7349         case bcmFieldActionOamTunnelControl:
   7350             return (BCM_E_NONE);
   7351 
   7352         case bcmFieldActionEcmpLoadBalanceCancel:
   7353             if (soc_feature(unit, soc_feature_ecmp_dlb)) {
   7354                 return (BCM_E_NONE);
   7355             }
   7356             break;
   7357 
   7358         case bcmFieldActionPortPrioIntCosQNew:
   7359         case bcmFieldActionRpPortPrioIntCosQNew:
   7360         case bcmFieldActionYpPortPrioIntCosQNew:
   7361         case bcmFieldActionGpPortPrioIntCosQNew:
   7362             if (soc_feature(unit, soc_feature_field_ingress_cosq_override)) {
   7363                 return (BCM_E_NONE);
   7364             }
   7365             break;
   7366 
   7367         case bcmFieldActionCopyToCpu:
   7368         case bcmFieldActionRpCopyToCpu:
   7369         case bcmFieldActionYpCopyToCpu:
   7370         case bcmFieldActionGpCopyToCpu:
   7371             return (BCM_E_NONE);
   7372 
   7373         case bcmFieldActionRedirectEgrNextHop:
   7374 #if defined(INCLUDE_L3)
   7375             if (soc_feature(unit, soc_feature_field_action_redirect_nexthop) ||
   7376                 soc_feature(unit, soc_feature_field_action_redirect_ecmp)) {
   7377                 return (BCM_E_NONE);
   7378             }
   7379 #endif
   7380             break;
   7381 
   7382 /* Following cases from _bcm_field_trx_stage_action_support_check */
   7383         case bcmFieldActionAddClassTag:
   7384         case bcmFieldActionCopyToCpuCancel:
   7385         case bcmFieldActionDrop:
   7386         case bcmFieldActionDropCancel:
   7387         case bcmFieldActionDropPrecedence:
   7388         case bcmFieldActionColorIndependent:
   7389         case bcmFieldActionL3ChangeVlan:
   7390         case bcmFieldActionL3ChangeVlanCancel:
   7391         case bcmFieldActionL3ChangeMacDa:
   7392         case bcmFieldActionL3ChangeMacDaCancel:
   7393         case bcmFieldActionL3Switch:
   7394         case bcmFieldActionL3SwitchCancel:
   7395         case bcmFieldActionPrioPktCopy:
   7396         case bcmFieldActionPrioPktNew:
   7397         case bcmFieldActionPrioPktTos:
   7398         case bcmFieldActionPrioPktCancel:
   7399         case bcmFieldActionEcnNew:
   7400         case bcmFieldActionDscpNew:
   7401         case bcmFieldActionDscpCancel:
   7402         case bcmFieldActionCosQNew:
   7403         case bcmFieldActionCosQCpuNew:
   7404         case bcmFieldActionVlanCosQNew:
   7405         case bcmFieldActionMirrorOverride:
   7406         case bcmFieldActionSwitchToCpuCancel:
   7407         case bcmFieldActionSwitchToCpuReinstate:
   7408         case bcmFieldActionRedirect:
   7409         case bcmFieldActionRedirectTrunk:
   7410         case bcmFieldActionRedirectCancel:
   7411         case bcmFieldActionRedirectPbmp:
   7412         case bcmFieldActionRedirectIpmc:
   7413         case bcmFieldActionRedirectMcast:
   7414             return (BCM_E_NONE);
   7415             break;
   7416 
   7417         case bcmFieldActionRedirectBcastPbmp:
   7418             return (BCM_E_NONE);
   7419             break;
   7420 
   7421         case bcmFieldActionRedirectVlan:
   7422             if (SOC_IS_TR_VL(unit)) {
   7423                 return (BCM_E_NONE);
   7424             }
   7425             break;
   7426 
   7427         case bcmFieldActionEgressMask:
   7428         case bcmFieldActionEgressPortsAdd:
   7429         case bcmFieldActionDoNotChangeTtl:
   7430             return (BCM_E_NONE);
   7431             break;
   7432 
   7433         case bcmFieldActionDoNotCheckUrpf:
   7434             if (SOC_MEM_FIELD_VALID(unit, FT_POLICYm, DO_NOT_URPFf)) {
   7435                 return (BCM_E_NONE);
   7436             }
   7437             break;
   7438 
   7439         case bcmFieldActionPrioPktAndIntCopy:
   7440         case bcmFieldActionPrioPktAndIntNew:
   7441         case bcmFieldActionPrioPktAndIntTos:
   7442         case bcmFieldActionPrioPktAndIntCancel:
   7443         case bcmFieldActionPrioIntCopy:
   7444         case bcmFieldActionPrioIntNew:
   7445         case bcmFieldActionPrioIntTos:
   7446         case bcmFieldActionPrioIntCancel:
   7447         case bcmFieldActionMirrorIngress:
   7448         case bcmFieldActionMirrorEgress:
   7449         case bcmFieldActionRpDrop:
   7450         case bcmFieldActionRpDropCancel:
   7451         case bcmFieldActionRpDropPrecedence:
   7452         case bcmFieldActionRpCopyToCpuCancel:
   7453         case bcmFieldActionRpPrioPktCopy:
   7454         case bcmFieldActionRpPrioPktNew:
   7455         case bcmFieldActionRpPrioPktTos:
   7456         case bcmFieldActionRpPrioPktCancel:
   7457         case bcmFieldActionRpDscpNew:
   7458         case bcmFieldActionRpDscpCancel:
   7459         case bcmFieldActionRpEcnNew:
   7460         case bcmFieldActionRpCosQNew:
   7461         case bcmFieldActionRpVlanCosQNew:
   7462         case bcmFieldActionRpPrioPktAndIntCopy:
   7463         case bcmFieldActionRpPrioPktAndIntNew:
   7464         case bcmFieldActionRpPrioPktAndIntTos:
   7465         case bcmFieldActionRpPrioPktAndIntCancel:
   7466         case bcmFieldActionRpSwitchToCpuCancel:
   7467         case bcmFieldActionRpSwitchToCpuReinstate:
   7468         case bcmFieldActionRpPrioIntCopy:
   7469         case bcmFieldActionRpPrioIntNew:
   7470         case bcmFieldActionRpPrioIntTos:
   7471         case bcmFieldActionRpPrioIntCancel:
   7472 
   7473         case bcmFieldActionYpDrop:
   7474         case bcmFieldActionYpDropCancel:
   7475         case bcmFieldActionYpDropPrecedence:
   7476         case bcmFieldActionYpCopyToCpuCancel:
   7477         case bcmFieldActionYpPrioPktCopy:
   7478         case bcmFieldActionYpPrioPktNew:
   7479         case bcmFieldActionYpPrioPktTos:
   7480         case bcmFieldActionYpPrioPktCancel:
   7481         case bcmFieldActionYpDscpNew:
   7482         case bcmFieldActionYpDscpCancel:
   7483         case bcmFieldActionYpEcnNew:
   7484         case bcmFieldActionYpCosQNew:
   7485         case bcmFieldActionYpVlanCosQNew:
   7486         case bcmFieldActionYpPrioPktAndIntCopy:
   7487         case bcmFieldActionYpPrioPktAndIntNew:
   7488         case bcmFieldActionYpPrioPktAndIntTos:
   7489         case bcmFieldActionYpPrioPktAndIntCancel:
   7490         case bcmFieldActionYpSwitchToCpuCancel:
   7491         case bcmFieldActionYpSwitchToCpuReinstate:
   7492         case bcmFieldActionYpPrioIntCopy:
   7493         case bcmFieldActionYpPrioIntNew:
   7494         case bcmFieldActionYpPrioIntTos:
   7495         case bcmFieldActionYpPrioIntCancel:
   7496 
   7497         case bcmFieldActionGpDrop:
   7498         case bcmFieldActionGpDropCancel:
   7499         case bcmFieldActionGpDropPrecedence:
   7500         case bcmFieldActionGpCopyToCpuCancel:
   7501         case bcmFieldActionGpPrioPktCopy:
   7502         case bcmFieldActionGpPrioPktNew:
   7503         case bcmFieldActionGpPrioPktTos:
   7504         case bcmFieldActionGpPrioPktCancel:
   7505         case bcmFieldActionGpDscpNew:
   7506         case bcmFieldActionGpTosPrecedenceNew:
   7507         case bcmFieldActionGpTosPrecedenceCopy:
   7508         case bcmFieldActionGpDscpCancel:
   7509         case bcmFieldActionGpEcnNew:
   7510         case bcmFieldActionGpCosQNew:
   7511         case bcmFieldActionGpVlanCosQNew:
   7512         case bcmFieldActionGpPrioPktAndIntCopy:
   7513         case bcmFieldActionGpPrioPktAndIntNew:
   7514         case bcmFieldActionGpPrioPktAndIntTos:
   7515         case bcmFieldActionGpPrioPktAndIntCancel:
   7516         case bcmFieldActionGpSwitchToCpuCancel:
   7517         case bcmFieldActionGpSwitchToCpuReinstate:
   7518         case bcmFieldActionGpPrioIntCopy:
   7519         case bcmFieldActionGpPrioIntNew:
   7520         case bcmFieldActionGpPrioIntTos:
   7521         case bcmFieldActionGpPrioIntCancel:
   7522             return (BCM_E_NONE);
   7523             break;
   7524 
   7525         case bcmFieldActionMultipathHash:
   7526             if (SOC_MEM_FIELD_VALID(unit, FT_POLICYm, ECMP_HASH_SELf)) {
   7527                 return (BCM_E_NONE);
   7528             }
   7529             break;
   7530 
   7531         case bcmFieldActionIpFix:
   7532         case bcmFieldActionIpFixCancel:
   7533             if (soc_feature(unit, soc_feature_ipfix)) {
   7534                 return (BCM_E_NONE);
   7535             }
   7536             break;
   7537 
   7538         case bcmFieldActionOamUpMep:
   7539         case bcmFieldActionOamTx:
   7540         case bcmFieldActionOamLmepMdl:
   7541         case bcmFieldActionOamServicePriMappingPtr:
   7542         case bcmFieldActionOamLmBasePtr:
   7543         case bcmFieldActionOamDmEnable:
   7544         case bcmFieldActionOamLmEnable:
   7545         case bcmFieldActionOamLmepEnable:
   7546             if (soc_feature(unit, soc_feature_field_oam_actions)) {
   7547                 return (BCM_E_NONE);
   7548             }
   7549             break;
   7550 
   7551         case bcmFieldActionTimeStampToCpu:
   7552         case bcmFieldActionRpTimeStampToCpu:
   7553         case bcmFieldActionYpTimeStampToCpu:
   7554         case bcmFieldActionGpTimeStampToCpu:
   7555         case bcmFieldActionTimeStampToCpuCancel:
   7556         case bcmFieldActionRpTimeStampToCpuCancel:
   7557         case bcmFieldActionYpTimeStampToCpuCancel:
   7558         case bcmFieldActionGpTimeStampToCpuCancel:
   7559             if (soc_feature(unit, soc_feature_field_action_timestamp)) {
   7560                 return (BCM_E_NONE);
   7561             }
   7562             break;
   7563 
   7564         case bcmFieldActionOffloadRedirect:
   7565         case bcmFieldActionOffloadClassSet:
   7566         case bcmFieldActionOffloadDropIndication:
   7567             if (SOC_MEM_FIELD_VALID(unit, FT_POLICYm, HI_PRI_ACTION_CONTROLf)) {
   7568                 return (BCM_E_NONE);
   7569             }
   7570             break;
   7571 
   7572         case bcmFieldActionFabricQueue:
   7573             if (soc_feature(unit, soc_feature_field_action_fabric_queue)) {
   7574                 return (BCM_E_NONE);
   7575             }
   7576             break;
   7577 
   7578         case bcmFieldActionSrcMacNew:
   7579 #if defined(INCLUDE_L3)
   7580             if (soc_feature(unit, soc_feature_field_action_l2_change) &&
   7581                 soc_feature(unit, soc_feature_l3)) {
   7582                 return (BCM_E_NONE);
   7583             }
   7584 #endif /* !INCLUDE_L3 */
   7585             break;
   7586 
   7587         case bcmFieldActionDstMacNew:
   7588         case bcmFieldActionOuterVlanNew:
   7589 #if defined(INCLUDE_L3)
   7590             if (soc_feature(unit, soc_feature_field_action_l2_change)) {
   7591                 return (BCM_E_NONE);
   7592             }
   7593 #endif /* !INCLUDE_L3 */
   7594             break;
   7595 
   7596         case bcmFieldActionVnTagNew:
   7597         case bcmFieldActionVnTagDelete:
   7598             if (soc_feature(unit, soc_feature_niv)) {
   7599                 return (BCM_E_NONE);
   7600             }
   7601             break;
   7602 
   7603         case bcmFieldActionCnmCancel:
   7604             if (SOC_MEM_FIELD_VALID(unit, FT_POLICYm, DO_NOT_GENERATE_CNMf)) {
   7605                 return (BCM_E_NONE);
   7606             }
   7607             break;
   7608 
   7609         case bcmFieldActionDynamicHgTrunkCancel:
   7610             if (SOC_MEM_FIELD_VALID(unit, FT_POLICYm, DISABLE_DYNAMIC_LOAD_BALANCINGf)) {
   7611                 return (BCM_E_NONE);
   7612             }
   7613             break;
   7614         case bcmFieldActionUcastCosQNew:
   7615         case bcmFieldActionGpUcastCosQNew:
   7616         case bcmFieldActionYpUcastCosQNew:
   7617         case bcmFieldActionRpUcastCosQNew:
   7618             if (soc_feature(unit, soc_feature_ets)) {
   7619                 return (BCM_E_NONE);
   7620             }
   7621             break;
   7622 
   7623         case bcmFieldActionMcastCosQNew:
   7624         case bcmFieldActionGpMcastCosQNew:
   7625         case bcmFieldActionYpMcastCosQNew:
   7626         case bcmFieldActionRpMcastCosQNew:
   7627             if (soc_feature(unit, soc_feature_ets)) {
   7628                 return (BCM_E_NONE);
   7629             }
   7630             break;
   7631 
   7632         case bcmFieldActionUseGlobalMeterColor:
   7633             if (soc_feature(unit, soc_feature_global_meter)) {
   7634                 return (BCM_E_NONE);
   7635             }
   7636             break;
   7637 
   7638         default:
   7639             ;
   7640     }
   7641 
   7642         return BCM_E_PARAM;
   7643     }
   7644 
   7645 /*
   7646  * Function:
   7647  *     _regex_tr3_policy_action_conflict_check
   7648  *
   7649  * Purpose:
   7650  *     Check if two actions conflict (occupy the same field in FT policy table)
   7651  *
   7652  * Parameters:
   7653  *     unit    - (IN) BCM device number
   7654  *     action  - (IN) Action to check(bcmFieldActionXXX)
   7655  *     action1 - (IN) Action to check(bcmFieldActionXXX)
   7656  *
   7657  * Returns:
   7658  *     BCM_E_CONFIG - if actions do conflict
   7659  *     BCM_E_NONE   - if there is no conflict
   7660  */
   7661 STATIC int _regex_tr3_policy_action_conflict_check(int                unit,
   7662                                                    bcm_field_action_t action1,
   7663                                                    bcm_field_action_t action)
   7664 {
   7665     /* Two identical actions are forbidden. */
   7666     if (action1 == action) {
   7667         if ((action != bcmFieldActionMirrorIngress) &&
   7668             (action != bcmFieldActionMirrorEgress)) {
   7669             return (BCM_E_CONFIG);
   7670         }
   7671     }
   7672 
   7673     switch (action1) {
   7674         case bcmFieldActionCopyToCpu:
   7675         case bcmFieldActionCopyToCpuCancel:
   7676         case bcmFieldActionSwitchToCpuCancel:
   7677         case bcmFieldActionSwitchToCpuReinstate:
   7678             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu);
   7679             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel);
   7680             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel);
   7681             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuReinstate);
   7682             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpu);
   7683             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpuCancel);
   7684             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpSwitchToCpuCancel);
   7685             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpSwitchToCpuReinstate);
   7686             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpu);
   7687             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpuCancel);
   7688             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpSwitchToCpuCancel);
   7689             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpSwitchToCpuReinstate);
   7690             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpu);
   7691             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpuCancel);
   7692             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpSwitchToCpuCancel);
   7693             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpSwitchToCpuReinstate);
   7694             break;
   7695         case bcmFieldActionRpCopyToCpu:
   7696         case bcmFieldActionRpCopyToCpuCancel:
   7697         case bcmFieldActionRpSwitchToCpuCancel:
   7698         case bcmFieldActionRpSwitchToCpuReinstate:
   7699             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu);
   7700             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel);
   7701             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel);
   7702             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuReinstate);
   7703             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpu);
   7704             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCopyToCpuCancel);
   7705             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpSwitchToCpuCancel);
   7706             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpSwitchToCpuReinstate);
   7707             break;
   7708         case bcmFieldActionYpCopyToCpu:
   7709         case bcmFieldActionYpCopyToCpuCancel:
   7710         case bcmFieldActionYpSwitchToCpuCancel:
   7711         case bcmFieldActionYpSwitchToCpuReinstate:
   7712             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu);
   7713             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel);
   7714             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel);
   7715             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuReinstate);
   7716             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpu);
   7717             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCopyToCpuCancel);
   7718             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpSwitchToCpuCancel);
   7719             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpSwitchToCpuReinstate);
   7720             break;
   7721         case bcmFieldActionGpCopyToCpu:
   7722         case bcmFieldActionGpCopyToCpuCancel:
   7723         case bcmFieldActionGpSwitchToCpuCancel:
   7724         case bcmFieldActionGpSwitchToCpuReinstate:
   7725             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpu);
   7726             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCopyToCpuCancel);
   7727             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuCancel);
   7728             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSwitchToCpuReinstate);
   7729             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpu);
   7730             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCopyToCpuCancel);
   7731             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpSwitchToCpuCancel);
   7732             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpSwitchToCpuReinstate);
   7733             break;
   7734         case bcmFieldActionDrop:
   7735         case bcmFieldActionDropCancel:
   7736             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDrop);
   7737             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropCancel);
   7738             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDrop);
   7739             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDropCancel);
   7740             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDrop);
   7741             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDropCancel);
   7742             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDrop);
   7743             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDropCancel);
   7744             break;
   7745         case bcmFieldActionRpDrop:
   7746         case bcmFieldActionRpDropCancel:
   7747             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDrop);
   7748             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropCancel);
   7749             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDrop);
   7750             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDropCancel);
   7751             break;
   7752         case bcmFieldActionYpDrop:
   7753         case bcmFieldActionYpDropCancel:
   7754             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDrop);
   7755             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropCancel);
   7756             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDrop);
   7757             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDropCancel);
   7758             break;
   7759         case bcmFieldActionGpDrop:
   7760         case bcmFieldActionGpDropCancel:
   7761             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDrop);
   7762             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropCancel);
   7763             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDrop);
   7764             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDropCancel);
   7765             break;
   7766         case bcmFieldActionL3ChangeVlan:
   7767         case bcmFieldActionL3ChangeVlanCancel:
   7768         case bcmFieldActionL3ChangeMacDa:
   7769         case bcmFieldActionL3ChangeMacDaCancel:
   7770         case bcmFieldActionL3Switch:
   7771         case bcmFieldActionL3SwitchCancel:
   7772         case bcmFieldActionAddClassTag:
   7773         case bcmFieldActionFabricQueue:
   7774             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionAddClassTag);
   7775             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan);
   7776             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel);
   7777             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa);
   7778             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel);
   7779             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3Switch);
   7780             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel);
   7781             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSrcMacNew);
   7782             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDstMacNew);
   7783             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionOuterVlanNew);
   7784             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionFabricQueue);
   7785             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVnTagNew);
   7786             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVnTagDelete);
   7787             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectEgrNextHop);
   7788             break;
   7789         case bcmFieldActionOuterVlanNew:
   7790             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionOuterVlanNew);
   7791             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionFabricQueue);
   7792             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionAddClassTag);
   7793             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan);
   7794             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel);
   7795             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa);
   7796             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel);
   7797             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3Switch);
   7798             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel);
   7799             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectEgrNextHop);
   7800             break;
   7801         case bcmFieldActionVnTagDelete:
   7802         case bcmFieldActionVnTagNew:
   7803             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVnTagDelete);
   7804             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVnTagNew);
   7805             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionFabricQueue);
   7806             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionAddClassTag);
   7807             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan);
   7808             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel);
   7809             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa);
   7810             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel);
   7811             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3Switch);
   7812             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel);
   7813             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectEgrNextHop);
   7814             break;
   7815         case bcmFieldActionSrcMacNew:
   7816             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSrcMacNew);
   7817             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionFabricQueue);
   7818             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionAddClassTag);
   7819             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan);
   7820             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel);
   7821             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa);
   7822             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel);
   7823             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3Switch);
   7824             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel);
   7825             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectEgrNextHop);
   7826             break;
   7827         case bcmFieldActionDstMacNew:
   7828             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDstMacNew);
   7829             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionFabricQueue);
   7830             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionAddClassTag);
   7831             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan);
   7832             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel);
   7833             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa);
   7834             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel);
   7835             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3Switch);
   7836             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel);
   7837             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectEgrNextHop);
   7838             break;
   7839         case bcmFieldActionRedirect:
   7840         case bcmFieldActionRedirectTrunk:
   7841         case bcmFieldActionRedirectCancel:
   7842         case bcmFieldActionRedirectPbmp:
   7843         case bcmFieldActionRedirectIpmc:
   7844         case bcmFieldActionRedirectMcast:
   7845         case bcmFieldActionRedirectVlan:
   7846         case bcmFieldActionRedirectBcastPbmp:
   7847         case bcmFieldActionOffloadRedirect:
   7848         case bcmFieldActionEgressMask:
   7849         case bcmFieldActionEgressPortsAdd:
   7850         case bcmFieldActionRedirectEgrNextHop:
   7851             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionOffloadRedirect);
   7852             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEgressMask);
   7853             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEgressPortsAdd);
   7854             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirect);
   7855             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectTrunk);
   7856             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectCancel);
   7857             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectPbmp);
   7858             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectIpmc);
   7859             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectMcast);
   7860             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectVlan);
   7861             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectBcastPbmp);
   7862             break;
   7863         case bcmFieldActionPrioPktCopy:
   7864         case bcmFieldActionPrioPktNew:
   7865         case bcmFieldActionPrioPktTos:
   7866         case bcmFieldActionPrioPktCancel:
   7867             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   7868             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   7869             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   7870             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   7871             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   7872             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   7873             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   7874             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   7875             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCopy);
   7876             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktNew);
   7877             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktTos);
   7878             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCancel);
   7879             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy);
   7880             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   7881             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos);
   7882             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel);
   7883             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCopy);
   7884             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktNew);
   7885             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktTos);
   7886             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCancel);
   7887             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy);
   7888             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   7889             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos);
   7890             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel);
   7891             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCopy);
   7892             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktNew);
   7893             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktTos);
   7894             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCancel);
   7895             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy);
   7896             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   7897             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos);
   7898             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel);
   7899             break;
   7900         case bcmFieldActionPrioPktAndIntCopy:
   7901         case bcmFieldActionPrioPktAndIntNew:
   7902         case bcmFieldActionPrioPktAndIntTos:
   7903         case bcmFieldActionPrioPktAndIntCancel:
   7904             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   7905             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   7906             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   7907             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   7908             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   7909             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   7910             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   7911             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   7912             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCopy);
   7913             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktNew);
   7914             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktTos);
   7915             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCancel);
   7916             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy);
   7917             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   7918             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos);
   7919             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel);
   7920             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCopy);
   7921             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktNew);
   7922             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktTos);
   7923             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCancel);
   7924             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy);
   7925             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   7926             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos);
   7927             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel);
   7928             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCopy);
   7929             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktNew);
   7930             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktTos);
   7931             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCancel);
   7932             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy);
   7933             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   7934             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos);
   7935             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel);
   7936             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   7937             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   7938             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   7939             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   7940             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   7941             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   7942             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   7943             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   7944             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   7945             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   7946             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   7947             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   7948             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   7949             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   7950             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   7951             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   7952             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   7953             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   7954             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   7955             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   7956             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   7957             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   7958             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   7959             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   7960             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   7961             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   7962             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   7963             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   7964             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   7965             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   7966             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   7967             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   7968             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   7969             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   7970             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   7971             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   7972             break;
   7973         case bcmFieldActionPrioIntNew:
   7974             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   7975             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   7976             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   7977             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   7978             /*
   7979              * coverity[fallthrough]
   7980              * This is intentional as the rest of the statements should be
   7981              * executed for this case also
   7982              */
   7983         case bcmFieldActionPrioIntCopy:
   7984         case bcmFieldActionPrioIntTos:
   7985         case bcmFieldActionPrioIntCancel:
   7986         case bcmFieldActionVlanCosQNew:
   7987             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   7988             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   7989             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   7990             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   7991             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   7992             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   7993             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   7994             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   7995             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   7996             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   7997             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   7998             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   7999             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8000             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8001             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8002             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8003             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8004             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8005             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8006             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8007             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8008             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8009             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8010             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8011             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8012             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8013             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8014             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8015             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8016             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8017             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8018             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8019             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8020             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8021             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8022             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8023             break;
   8024         case bcmFieldActionCosQNew:
   8025             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8026             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8027             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8028             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8029             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8030             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8031             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8032             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8033             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8034             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8035             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8036             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8037             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8038             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8039             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8040             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8041             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8042             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8043             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8044             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8045             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8046             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8047             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8048             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8049             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8050             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8051             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8052             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8053             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8054             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8055             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8056             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8057             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8058             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8059             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8060             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8061             break;
   8062         case bcmFieldActionUcastCosQNew:
   8063             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8064             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8065             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8066             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8067             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8068             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8069             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8070             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8071             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8072             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8073             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8074             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8075             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8076             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8077             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8078             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8079             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8080             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8081             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8082             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8083             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8084             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8085             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8086             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8087             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8088             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8089             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8090             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8091             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8092             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8093             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8094             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8095             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8096             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8097             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8098             break;
   8099         case bcmFieldActionMcastCosQNew:
   8100             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8101             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8102             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8103             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8104             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8105             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8106             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8107             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8108             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8109             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8110             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8111             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8112             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8113             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8114             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8115             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8116             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8117             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8118             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8119             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8120             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8121             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8122             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8123             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8124             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8125             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8126             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8127             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8128             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8129             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8130             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8131             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8132             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8133             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8134             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8135             break;
   8136         case bcmFieldActionRpPrioPktCopy:
   8137         case bcmFieldActionRpPrioPktNew:
   8138         case bcmFieldActionRpPrioPktTos:
   8139         case bcmFieldActionRpPrioPktCancel:
   8140             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   8141             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   8142             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   8143             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   8144             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8145             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8146             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8147             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8148             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCopy);
   8149             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktNew);
   8150             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktTos);
   8151             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCancel);
   8152             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy);
   8153             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   8154             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos);
   8155             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel);
   8156             break;
   8157         case bcmFieldActionRpPrioPktAndIntCopy:
   8158         case bcmFieldActionRpPrioPktAndIntNew:
   8159         case bcmFieldActionRpPrioPktAndIntTos:
   8160         case bcmFieldActionRpPrioPktAndIntCancel:
   8161             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   8162             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   8163             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   8164             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   8165             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8166             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8167             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8168             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8169             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCopy);
   8170             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktNew);
   8171             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktTos);
   8172             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktCancel);
   8173             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy);
   8174             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   8175             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos);
   8176             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel);
   8177             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8178             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8179             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8180             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8181             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8182             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8183             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8184             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8185             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8186             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8187             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8188             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8189             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8190             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8191             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8192             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8193             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8194             break;
   8195         case bcmFieldActionRpPrioIntCopy:
   8196         case bcmFieldActionRpPrioIntNew:
   8197         case bcmFieldActionRpPrioIntTos:
   8198         case bcmFieldActionRpPrioIntCancel:
   8199         case bcmFieldActionRpCosQNew:
   8200             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8201             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8202             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8203             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8204             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8205             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8206             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8207             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8208             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8209             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8210             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8211             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8212             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8213             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8214             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8215             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8216             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8217             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8218             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8219             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8220             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8221             break;
   8222         case bcmFieldActionRpUcastCosQNew:
   8223             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8224             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8225             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8226             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8227             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8228             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8229             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8230             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8231             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8232             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8233             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8234             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8235             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8236             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8237             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8238             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8239             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8240             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8241             break;
   8242         case bcmFieldActionRpMcastCosQNew:
   8243             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8244             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8245             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8246             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8247             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8248             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8249             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8250             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8251             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8252             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8253             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8254             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8255             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8256             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8257             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8258             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8259             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8260             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPortPrioIntCosQNew);
   8261             break;
   8262         case bcmFieldActionYpPrioPktCopy:
   8263         case bcmFieldActionYpPrioPktNew:
   8264         case bcmFieldActionYpPrioPktTos:
   8265         case bcmFieldActionYpPrioPktCancel:
   8266             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   8267             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   8268             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   8269             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   8270             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8271             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8272             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8273             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8274             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCopy);
   8275             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktNew);
   8276             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktTos);
   8277             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCancel);
   8278             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy);
   8279             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   8280             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos);
   8281             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel);
   8282             break;
   8283         case bcmFieldActionYpPrioPktAndIntCopy:
   8284         case bcmFieldActionYpPrioPktAndIntNew:
   8285         case bcmFieldActionYpPrioPktAndIntTos:
   8286         case bcmFieldActionYpPrioPktAndIntCancel:
   8287             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   8288             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   8289             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   8290             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   8291             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8292             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8293             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8294             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8295             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCopy);
   8296             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktNew);
   8297             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktTos);
   8298             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktCancel);
   8299             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy);
   8300             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   8301             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos);
   8302             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel);
   8303             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8304             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8305             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8306             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8307             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8308             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8309             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8310             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8311             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8312             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8313             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8314             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8315             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8316             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8317             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8318             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8319             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8320             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8321             break;
   8322         case bcmFieldActionYpPrioIntCopy:
   8323         case bcmFieldActionYpPrioIntNew:
   8324         case bcmFieldActionYpPrioIntTos:
   8325         case bcmFieldActionYpPrioIntCancel:
   8326         case bcmFieldActionYpCosQNew:
   8327             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8328             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8329             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8330             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8331             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8332             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8333             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8334             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8335             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8336             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8337             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8338             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8339             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8340             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8341             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8342             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8343             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8344             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8345             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8346             break;
   8347         case bcmFieldActionYpUcastCosQNew:
   8348             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8349             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8350             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8351             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8352             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8353             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8354             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8355             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8356             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8357             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8358             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8359             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8360             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8361             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8362             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8363             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8364             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8365             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8366             break;
   8367         case bcmFieldActionYpMcastCosQNew:
   8368             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8369             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8370             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8371             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8372             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8373             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8374             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8375             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8376             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8377             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8378             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8379             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8380             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8381             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8382             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8383             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8384             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPortPrioIntCosQNew);
   8385             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8386             break;
   8387         case bcmFieldActionGpPrioPktCopy:
   8388         case bcmFieldActionGpPrioPktNew:
   8389         case bcmFieldActionGpPrioPktTos:
   8390         case bcmFieldActionGpPrioPktCancel:
   8391             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   8392             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   8393             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   8394             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   8395             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8396             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8397             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8398             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8399             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCopy);
   8400             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktNew);
   8401             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktTos);
   8402             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCancel);
   8403             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy);
   8404             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   8405             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos);
   8406             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel);
   8407             break;
   8408         case bcmFieldActionGpPrioPktAndIntCopy:
   8409         case bcmFieldActionGpPrioPktAndIntNew:
   8410         case bcmFieldActionGpPrioPktAndIntTos:
   8411         case bcmFieldActionGpPrioPktAndIntCancel:
   8412             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCopy);
   8413             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktNew);
   8414             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktTos);
   8415             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktCancel);
   8416             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8417             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8418             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8419             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8420             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCopy);
   8421             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktNew);
   8422             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktTos);
   8423             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktCancel);
   8424             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy);
   8425             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   8426             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos);
   8427             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel);
   8428             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8429             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8430             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8431             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8432             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8433             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8434             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8435             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8436             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8437             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8438             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8439             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8440             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8441             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8442             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8443             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8444             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8445             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8446             break;
   8447         case bcmFieldActionGpPrioIntCopy:
   8448         case bcmFieldActionGpPrioIntNew:
   8449         case bcmFieldActionGpPrioIntTos:
   8450         case bcmFieldActionGpPrioIntCancel:
   8451             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8452             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8453             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8454             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8455             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8456             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8457             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8458             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8459             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8460             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8461             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8462             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8463             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8464             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8465             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8466             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8467             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8468             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8469             break;
   8470         case bcmFieldActionGpCosQNew:
   8471             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8472             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8473             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8474             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8475             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8476             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8477             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8478             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8479             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8480             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8481             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8482             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8483             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8484             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8485             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8486             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8487             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8488             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8489             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8490             break;
   8491         case bcmFieldActionGpUcastCosQNew:
   8492             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8493             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8494             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8495             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8496             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8497             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8498             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8499             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8500             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8501             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8502             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8503             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8504             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8505             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8506             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8507             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8508             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8509             break;
   8510         case bcmFieldActionGpMcastCosQNew:
   8511             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8512             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8513             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8514             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8515             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8516             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQCpuNew);
   8517             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8518             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8519             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8520             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8521             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8522             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8523             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8524             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8525             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8526             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPortPrioIntCosQNew);
   8527             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPortPrioIntCosQNew);
   8528             break;
   8529         case bcmFieldActionDropPrecedence:
   8530             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDropPrecedence);
   8531             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDropPrecedence);
   8532             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDropPrecedence);
   8533             break;
   8534         case bcmFieldActionRpDropPrecedence:
   8535             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropPrecedence);
   8536             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDropPrecedence);
   8537             break;
   8538         case bcmFieldActionYpDropPrecedence:
   8539             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropPrecedence);
   8540             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDropPrecedence);
   8541             break;
   8542         case bcmFieldActionGpDropPrecedence:
   8543             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDropPrecedence);
   8544             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDropPrecedence);
   8545             break;
   8546         case bcmFieldActionTimeStampToCpu:
   8547         case bcmFieldActionTimeStampToCpuCancel:
   8548             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpu);
   8549             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpuCancel);
   8550             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpTimeStampToCpu);
   8551             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpTimeStampToCpuCancel);
   8552             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpTimeStampToCpu);
   8553             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpTimeStampToCpuCancel);
   8554             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTimeStampToCpu);
   8555             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTimeStampToCpuCancel);
   8556             break;
   8557         case bcmFieldActionRpTimeStampToCpu:
   8558         case bcmFieldActionRpTimeStampToCpuCancel:
   8559             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpu);
   8560             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpuCancel);
   8561             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpTimeStampToCpu);
   8562             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpTimeStampToCpuCancel);
   8563             break;
   8564         case bcmFieldActionYpTimeStampToCpu:
   8565         case bcmFieldActionYpTimeStampToCpuCancel:
   8566             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpu);
   8567             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpuCancel);
   8568             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpTimeStampToCpu);
   8569             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpTimeStampToCpuCancel);
   8570             break;
   8571         case bcmFieldActionGpTimeStampToCpu:
   8572         case bcmFieldActionGpTimeStampToCpuCancel:
   8573             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpu);
   8574             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionTimeStampToCpuCancel);
   8575             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTimeStampToCpu);
   8576             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTimeStampToCpuCancel);
   8577             break;
   8578         case bcmFieldActionIpFix:
   8579         case bcmFieldActionIpFixCancel:
   8580             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionIpFix);
   8581             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionIpFixCancel);
   8582             break;
   8583         case bcmFieldActionDscpNew:
   8584         case bcmFieldActionDscpCancel:
   8585             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpNew);
   8586             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpCancel);
   8587             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDscpNew);
   8588             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDscpCancel);
   8589             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDscpNew);
   8590             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDscpCancel);
   8591             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDscpNew);
   8592             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTosPrecedenceNew);
   8593             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTosPrecedenceCopy);
   8594             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDscpCancel);
   8595             break;
   8596         case bcmFieldActionRpDscpNew:
   8597         case bcmFieldActionRpDscpCancel:
   8598             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpNew);
   8599             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpCancel);
   8600             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDscpNew);
   8601             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpDscpCancel);
   8602             break;
   8603         case bcmFieldActionYpDscpNew:
   8604         case bcmFieldActionYpDscpCancel:
   8605             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpNew);
   8606             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpCancel);
   8607             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDscpNew);
   8608             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpDscpCancel);
   8609             break;
   8610         case bcmFieldActionGpDscpNew:
   8611         case bcmFieldActionGpDscpCancel:
   8612         case bcmFieldActionGpTosPrecedenceNew:
   8613         case bcmFieldActionGpTosPrecedenceCopy:
   8614             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpNew);
   8615             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDscpCancel);
   8616             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDscpNew);
   8617             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTosPrecedenceNew);
   8618             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpTosPrecedenceCopy);
   8619             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpDscpCancel);
   8620             break;
   8621         case bcmFieldActionEcnNew:
   8622             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpEcnNew);
   8623             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpEcnNew);
   8624             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpEcnNew);
   8625             break;
   8626         case bcmFieldActionRpEcnNew:
   8627             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEcnNew);
   8628             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpEcnNew);
   8629             break;
   8630         case bcmFieldActionYpEcnNew:
   8631             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEcnNew);
   8632             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpEcnNew);
   8633             break;
   8634         case bcmFieldActionGpEcnNew:
   8635             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEcnNew);
   8636             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpEcnNew);
   8637             break;
   8638         case bcmFieldActionMirrorIngress:
   8639             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMirrorOverride);
   8640             break;
   8641         case bcmFieldActionMirrorEgress:
   8642             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMirrorOverride);
   8643             break;
   8644         case bcmFieldActionMirrorOverride:
   8645             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMirrorIngress);
   8646             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMirrorEgress);
   8647             break;
   8648         case bcmFieldActionPortPrioIntCosQNew:
   8649             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8650             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8651             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8652             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8653             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8654             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8655             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8656             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8657             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8658             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8659             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8660             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8661             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8662             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8663             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8664             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8665             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8666             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8667             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   8668             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy);
   8669             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos);
   8670             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel);
   8671             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8672             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8673             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8674             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8675             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8676             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8677             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8678             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8679             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   8680             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy);
   8681             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos);
   8682             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel);
   8683             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8684             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8685             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8686             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8687             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8688             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8689             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8690             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8691             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   8692             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy);
   8693             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos);
   8694             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel);
   8695             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8696             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8697             break;
   8698         case bcmFieldActionRpPortPrioIntCosQNew:
   8699             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8700             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8701             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8702             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8703             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8704             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8705             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8706             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8707             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8708             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8709             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8710             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8711             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpCosQNew);
   8712             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpVlanCosQNew);
   8713             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCopy);
   8714             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntNew);
   8715             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntTos);
   8716             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioIntCancel);
   8717             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntNew);
   8718             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCopy);
   8719             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntTos);
   8720             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpPrioPktAndIntCancel);
   8721             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpUcastCosQNew);
   8722             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRpMcastCosQNew);
   8723             break;
   8724         case bcmFieldActionYpPortPrioIntCosQNew:
   8725             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8726             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8727             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8728             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8729             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8730             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8731             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8732             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8733             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8734             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8735             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8736             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8737             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpCosQNew);
   8738             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpVlanCosQNew);
   8739             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCopy);
   8740             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntNew);
   8741             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntTos);
   8742             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioIntCancel);
   8743             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntNew);
   8744             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCopy);
   8745             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntTos);
   8746             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpPrioPktAndIntCancel);
   8747             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpUcastCosQNew);
   8748             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionYpMcastCosQNew);
   8749             break;
   8750         case bcmFieldActionGpPortPrioIntCosQNew:
   8751             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionCosQNew);
   8752             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVlanCosQNew);
   8753             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCopy);
   8754             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntNew);
   8755             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntTos);
   8756             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioIntCancel);
   8757             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntNew);
   8758             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCopy);
   8759             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntTos);
   8760             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionPrioPktAndIntCancel);
   8761             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionUcastCosQNew);
   8762             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMcastCosQNew);
   8763             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpCosQNew);
   8764             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpVlanCosQNew);
   8765             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCopy);
   8766             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntNew);
   8767             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntTos);
   8768             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioIntCancel);
   8769             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntNew);
   8770             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCopy);
   8771             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntTos);
   8772             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpPrioPktAndIntCancel);
   8773             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpUcastCosQNew);
   8774             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionGpMcastCosQNew);
   8775             break;
   8776         case bcmFieldActionColorIndependent:
   8777             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionColorIndependent);
   8778             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlan);
   8779             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeVlanCancel);
   8780             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDa);
   8781             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionSrcMacNew);
   8782             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionDstMacNew);
   8783             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3ChangeMacDaCancel);
   8784             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3Switch);
   8785             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionL3SwitchCancel);
   8786             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionAddClassTag);
   8787             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionOuterVlanNew);
   8788             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectVlan);
   8789             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectMcast);
   8790             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectIpmc);
   8791             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEgressPortsAdd);
   8792             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionEgressMask);
   8793             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectCancel);
   8794             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirect);
   8795             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectTrunk);
   8796             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectEgrNextHop);
   8797             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVnTagNew);
   8798             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionVnTagDelete);
   8799             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectPbmp);
   8800             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionOffloadRedirect);
   8801             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionRedirectBcastPbmp);
   8802             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionFabricQueue);
   8803             _REGEX_POLICY_ACTIONS_CONFLICT(bcmFieldActionMirrorEgress);
   8804             break;
   8805         case bcmFieldActionDoNotChangeTtl:
   8806         case bcmFieldActionDoNotCheckUrpf:
   8807         case bcmFieldActionMultipathHash:
   8808         case bcmFieldActionOamUpMep:
   8809         case bcmFieldActionOamTx:
   8810         case bcmFieldActionOamLmepMdl:
   8811         case bcmFieldActionOamServicePriMappingPtr:
   8812         case bcmFieldActionOamLmBasePtr:
   8813         case bcmFieldActionOamDmEnable:
   8814         case bcmFieldActionOamLmEnable:
   8815         case bcmFieldActionOamLmepEnable:
   8816         case bcmFieldActionOffloadClassSet:
   8817         case bcmFieldActionOffloadDropIndication:
   8818         case bcmFieldActionCnmCancel:
   8819         case bcmFieldActionDynamicHgTrunkCancel:
   8820             break;
   8821         default:
   8822             break;
   8823     }
   8824     return (BCM_E_NONE);
   8825 }
   8826 
   8827 STATIC int _regex_tr3_policy_action_params_check(int                     unit,
   8828                                                  _regex_policy_t        *p_ent,
   8829                                                  _regex_policy_action_t *pa)
   8830 {
   8831     uint32     arg  = pa->param[0];     /* Action param value      */
   8832     uint32     arg2 = pa->param[1];     /* Action param value      */
   8833     soc_mem_t  mem  = FT_POLICYm;       /* Policy table memory id. */
   8834     bcm_port_t local_port;
   8835     int        index;
   8836     int        rv;
   8837     int        shift_val;
   8838     uint32     redir_field = 0;
   8839 #if defined(INCLUDE_L3)
   8840     uint32     flags;            /* L3 forwarding flags.    */
   8841     int        nh_ecmp_id;          /* Next hop/Ecmp group id. */
   8842 #endif /* INCLUDE_L3 */
   8843 
   8844     switch (pa->action) {
   8845         case bcmFieldActionNewClassId:
   8846             RegexPolicyCheck(unit, mem, I2E_CLASSIDf, arg);
   8847             return (BCM_E_NONE);
   8848 
   8849         case bcmFieldActionEgressClassSelect:
   8850             return (arg <= BCM_FIELD_EGRESS_CLASS_SELECT_NEW ? BCM_E_NONE : BCM_E_PARAM);
   8851 
   8852         case bcmFieldActionHiGigClassSelect:
   8853             return (arg <= BCM_FIELD_HIGIG_CLASS_SELECT_PORT ? BCM_E_NONE : BCM_E_PARAM);
   8854 
   8855         case bcmFieldActionOamDmTimeFormat:
   8856             return (arg <= BCM_FIELD_OAM_DM_TIME_FORMAT_NTP ? BCM_E_NONE : BCM_E_PARAM);
   8857 
   8858         case bcmFieldActionOamTagStatusCheck:
   8859             return (arg < (BCM_FIELD_OAM_TAG_STATUS_INNER_L2_INNER_MASK << 1) ? BCM_E_NONE : BCM_E_PARAM);
   8860 
   8861         case bcmFieldActionOamTunnelControl:
   8862             return (arg <= BCM_FIELD_OAM_TUNNEL_CONTROL_NOT_TUNNELDED ? BCM_E_NONE : BCM_E_PARAM);
   8863 
   8864         case bcmFieldActionEcnNew:
   8865         case bcmFieldActionRpEcnNew:
   8866         case bcmFieldActionYpEcnNew:
   8867         case bcmFieldActionGpEcnNew:
   8868             return (arg <= 3 ? BCM_E_NONE : BCM_E_PARAM);
   8869 
   8870         case bcmFieldActionCosQNew:
   8871         case bcmFieldActionUcastCosQNew:
   8872             BCM_IF_ERROR_RETURN(_bcm_tr3_cosq_index_resolve(unit, pa->param[0], 0,
   8873                                                             _BCM_TR3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   8874                                                             &local_port, &index, NULL));
   8875 
   8876             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, index);
   8877             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, index);
   8878             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, index);
   8879             return (BCM_E_NONE);
   8880 
   8881         case bcmFieldActionGpCosQNew:
   8882         case bcmFieldActionGpUcastCosQNew:
   8883             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, arg);
   8884             return (BCM_E_NONE);
   8885 
   8886         case bcmFieldActionYpCosQNew:
   8887         case bcmFieldActionYpUcastCosQNew:
   8888             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, arg);
   8889             return (BCM_E_NONE);
   8890 
   8891         case bcmFieldActionRpCosQNew:
   8892         case bcmFieldActionRpUcastCosQNew:
   8893             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, arg);
   8894             return (BCM_E_NONE);
   8895 
   8896         case bcmFieldActionMcastCosQNew:
   8897             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, (arg << 4));
   8898             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, (arg << 4));
   8899             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, (arg << 4));
   8900             return (BCM_E_NONE);
   8901 
   8902         case bcmFieldActionGpMcastCosQNew:
   8903             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, (arg << 4));
   8904             return (BCM_E_NONE);
   8905 
   8906         case bcmFieldActionYpMcastCosQNew:
   8907             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, (arg << 4));
   8908             return (BCM_E_NONE);
   8909 
   8910         case bcmFieldActionRpMcastCosQNew:
   8911             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, (arg << 4));
   8912             return (BCM_E_NONE);
   8913 
   8914         case bcmFieldActionPortPrioIntCosQNew:
   8915         case bcmFieldActionRpPortPrioIntCosQNew:
   8916             if (arg2 & (0x1 << 9)) {
   8917                 return (BCM_E_PARAM);
   8918             }
   8919             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, arg2);
   8920             return (BCM_E_NONE);
   8921         case bcmFieldActionYpPortPrioIntCosQNew:
   8922             if (arg2 & (0x1 << 9)) {
   8923                 return (BCM_E_PARAM);
   8924             }
   8925             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, arg2);
   8926             return (BCM_E_NONE);
   8927         case bcmFieldActionGpPortPrioIntCosQNew:
   8928             if (arg2 & (0x1 << 9)) {
   8929                 return (BCM_E_PARAM);
   8930             }
   8931             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, arg2);
   8932             return (BCM_E_NONE);
   8933         case bcmFieldActionMultipathHash:
   8934             RegexPolicyCheck(unit, mem, ECMP_HASH_SELf, arg);
   8935             break;
   8936         case bcmFieldActionCopyToCpu:
   8937         case bcmFieldActionRpCopyToCpu:
   8938         case bcmFieldActionYpCopyToCpu:
   8939         case bcmFieldActionGpCopyToCpu:
   8940         case bcmFieldActionTimeStampToCpu:
   8941         case bcmFieldActionRpTimeStampToCpu:
   8942         case bcmFieldActionYpTimeStampToCpu:
   8943         case bcmFieldActionGpTimeStampToCpu:
   8944             if (arg != 0) {
   8945                 RegexPolicyCheck(unit, mem, MATCHED_RULEf, arg2);
   8946             }
   8947             break;
   8948         case bcmFieldActionDropPrecedence:
   8949             RegexPolicyCheck(unit, mem, R_DROP_PRECEDENCEf, arg);
   8950             RegexPolicyCheck(unit, mem, Y_DROP_PRECEDENCEf, arg);
   8951             RegexPolicyCheck(unit, mem, G_DROP_PRECEDENCEf, arg);
   8952             break;
   8953         case bcmFieldActionPrioPktNew:
   8954             RegexPolicyCheck(unit, mem, R_NEW_PKT_PRIf, arg);
   8955             RegexPolicyCheck(unit, mem, Y_NEW_PKT_PRIf, arg);
   8956             RegexPolicyCheck(unit, mem, G_NEW_PKT_PRIf, arg);
   8957             break;
   8958         case bcmFieldActionDscpNew:
   8959             RegexPolicyCheck(unit, mem, R_NEW_DSCPf, arg);
   8960             RegexPolicyCheck(unit, mem, Y_NEW_DSCPf, arg);
   8961             RegexPolicyCheck(unit, mem, G_NEW_DSCP_TOSf, arg);
   8962             break;
   8963     
   8964         case bcmFieldActionVlanCosQNew:
   8965             /* Add 8 to the value since VLAN shaping queues are 8..23 */
   8966             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, arg + 8);
   8967             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, arg + 8);
   8968             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, arg + 8);
   8969             break;
   8970 
   8971         case bcmFieldActionPrioIntNew:
   8972             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, (0xf & arg));
   8973             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, (0xf & arg));
   8974             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, (0xf & arg));
   8975             break;
   8976 
   8977         case bcmFieldActionPrioPktAndIntNew:
   8978             RegexPolicyCheck(unit, mem, R_NEW_PKT_PRIf, arg);
   8979             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, (0xf & arg));
   8980             RegexPolicyCheck(unit, mem, Y_NEW_PKT_PRIf, arg);
   8981             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, (0xf & arg));
   8982             RegexPolicyCheck(unit, mem, G_NEW_PKT_PRIf, arg);
   8983             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, (0xf & arg));
   8984             break;
   8985 
   8986         case bcmFieldActionCosQCpuNew:
   8987             RegexPolicyCheck(unit, mem, CPU_COSf, arg);
   8988             break;
   8989 
   8990         case bcmFieldActionOuterVlanNew:
   8991             RegexPolicyCheck(unit, EGR_L3_NEXT_HOPm, INTF_NUMf,
   8992                              arg);
   8993             break;
   8994 
   8995         case bcmFieldActionMirrorIngress:
   8996         case bcmFieldActionMirrorEgress:
   8997             rv = _bcm_regex_policy_action_dest_check(unit, pa);
   8998             BCM_IF_ERROR_RETURN(rv);
   8999             break;
   9000         case bcmFieldActionOffloadRedirect:
   9001         case bcmFieldActionRedirect:
   9002             rv = _bcm_regex_policy_action_dest_check(unit, pa);
   9003             BCM_IF_ERROR_RETURN(rv);
   9004             if (BCM_GPORT_IS_MPLS_PORT(arg2)) {
   9005                 redir_field = BCM_GPORT_MPLS_PORT_ID_GET((int)arg2);
   9006                 redir_field |= (6 << 18);
   9007             } else if(BCM_GPORT_IS_MIM_PORT(arg2)) {
   9008                 redir_field = BCM_GPORT_MIM_PORT_ID_GET((int)arg2);
   9009                 redir_field |= (6 << 18);
   9010             } else if (BCM_GPORT_IS_NIV_PORT(arg2)) {
   9011                 redir_field = BCM_GPORT_NIV_PORT_ID_GET((int)arg2);
   9012                 redir_field |= (6 << 18);
   9013             } else if (BCM_GPORT_IS_TRILL_PORT(arg2)) {
   9014                 redir_field = BCM_GPORT_TRILL_PORT_ID_GET((int)arg2);
   9015                 redir_field |= (6 << 18);
   9016             } else if (BCM_GPORT_IS_L2GRE_PORT(arg2)) {
   9017                 redir_field = BCM_GPORT_L2GRE_PORT_ID_GET((int)arg2);
   9018                 redir_field |= (6 << 18);
   9019             } else {
   9020                 redir_field = ((arg & 0xff) << 7);
   9021                 redir_field |= (arg2 & 0x7f);
   9022             }
   9023             RegexPolicyCheck(unit, mem, REDIRECTIONf, redir_field);
   9024             break;
   9025         case bcmFieldActionRedirectTrunk:    /* param0 = trunk ID */
   9026             shift_val = SOC_IS_TR_VL(unit) ? 7 : 8;
   9027             redir_field |= (0x40 << shift_val);  /* Trunk indicator. */
   9028             redir_field |= arg;
   9029 
   9030             RegexPolicyCheck(unit, mem, REDIRECTIONf, redir_field);
   9031             break;
   9032 #ifdef INCLUDE_L3
   9033         case bcmFieldActionRedirectIpmc:
   9034             if (soc_feature(unit, soc_feature_field_action_redirect_ipmc)) {
   9035                 if (_BCM_MULTICAST_IS_SET(arg)) {
   9036                     if ((0 == _BCM_MULTICAST_IS_L3(arg)) &&
   9037                         (0 == _BCM_MULTICAST_IS_WLAN(arg))) {
   9038                         return (BCM_E_PARAM);
   9039                     }
   9040                     redir_field = _BCM_MULTICAST_ID_GET(arg);
   9041                 } else {
   9042                     redir_field = arg;
   9043                 }
   9044             } else {
   9045                 redir_field = 0;
   9046             }
   9047             /* Assign IPMC action to redirect profile index. */
   9048             shift_val = SOC_IS_TR_VL(unit) ? 12 : 13;
   9049             RegexPolicyCheck(unit, mem, REDIRECTIONf,
   9050                              (redir_field | (3 << shift_val)));
   9051             break;
   9052 #endif /* INCLUDE_L3 */
   9053         case bcmFieldActionRedirectMcast:
   9054             if (soc_feature(unit, soc_feature_field_action_redirect_ipmc)) {
   9055                 if (_BCM_MULTICAST_IS_SET(arg)) {
   9056                     if (0 == _BCM_MULTICAST_IS_L2(arg)) {
   9057                         return (BCM_E_PARAM);
   9058                     }
   9059                     redir_field = _BCM_MULTICAST_ID_GET(arg);
   9060                 } else {
   9061                     redir_field = arg;
   9062                 }
   9063             } else {
   9064                 redir_field = 0;
   9065 }
   9066 
   9067             /* Assign MCAST action to redirect profile index. */
   9068             shift_val = SOC_IS_TR_VL(unit) ? 12 : 13;
   9069             RegexPolicyCheck(unit, mem, REDIRECTIONf,
   9070                              (redir_field | (2 << shift_val)));
   9071             break;
   9072         case bcmFieldActionOffloadClassSet:
   9073             RegexPolicyCheck(unit, mem, PPD3_CLASS_TAGf, arg);
   9074             break;
   9075         case bcmFieldActionRpDropPrecedence:
   9076             RegexPolicyCheck(unit, mem, R_DROP_PRECEDENCEf, arg);
   9077             break;
   9078         case bcmFieldActionRpPrioPktNew:
   9079             RegexPolicyCheck(unit, mem, R_NEW_PKT_PRIf, arg);
   9080             break;
   9081         case bcmFieldActionRpDscpNew:
   9082             RegexPolicyCheck(unit, mem, R_NEW_DSCPf, arg);
   9083             break;
   9084         case bcmFieldActionRpPrioPktAndIntNew:
   9085             RegexPolicyCheck(unit, mem, R_NEW_PKT_PRIf, arg);
   9086             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, (0xf & arg));
   9087             break;
   9088         case bcmFieldActionRpPrioIntNew:
   9089             RegexPolicyCheck(unit, mem, R_COS_INT_PRIf, (0xf & arg));
   9090             break;
   9091         case bcmFieldActionYpDropPrecedence:
   9092             RegexPolicyCheck(unit, mem, Y_DROP_PRECEDENCEf, arg);
   9093             break;
   9094         case bcmFieldActionYpPrioPktNew:
   9095             RegexPolicyCheck(unit, mem, Y_NEW_PKT_PRIf, arg);
   9096             break;
   9097         case bcmFieldActionYpDscpNew:
   9098             RegexPolicyCheck(unit, mem, Y_NEW_DSCPf, arg);
   9099             break;
   9100         case bcmFieldActionYpVlanCosQNew:
   9101             /* Add 8 to the value since VLAN shaping queues are 8..23 */
   9102             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, arg + 8);
   9103             break;
   9104         case bcmFieldActionYpPrioPktAndIntNew:
   9105             RegexPolicyCheck(unit, mem, Y_NEW_PKT_PRIf, arg);
   9106             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, (0xf & arg));
   9107             break;
   9108         case bcmFieldActionYpPrioIntNew:
   9109             RegexPolicyCheck(unit, mem, Y_COS_INT_PRIf, (0xf & arg));
   9110             break;
   9111         case bcmFieldActionGpDropPrecedence:
   9112             RegexPolicyCheck(unit, mem, G_DROP_PRECEDENCEf, arg);
   9113             break;
   9114         case bcmFieldActionGpPrioPktNew:
   9115             RegexPolicyCheck(unit, mem, G_NEW_PKT_PRIf, arg);
   9116             break;
   9117         case bcmFieldActionGpDscpNew:
   9118             RegexPolicyCheck(unit, mem, G_NEW_DSCP_TOSf, arg);
   9119             break;
   9120         case bcmFieldActionGpTosPrecedenceNew:
   9121             RegexPolicyCheck(unit, mem, G_NEW_DSCP_TOSf, arg);
   9122             break;
   9123         case bcmFieldActionGpVlanCosQNew:
   9124             /* Add 8 to the value since VLAN shaping queues are 8..23 */
   9125             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, arg + 8);
   9126             break;
   9127         case bcmFieldActionGpPrioPktAndIntNew:
   9128             RegexPolicyCheck(unit, mem, G_NEW_PKT_PRIf, arg);
   9129             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, (0xf & arg));
   9130             break;
   9131         case bcmFieldActionGpPrioIntNew:
   9132             RegexPolicyCheck(unit, mem, G_COS_INT_PRIf, (0xf & arg));
   9133             break;
   9134         case bcmFieldActionAddClassTag:
   9135             /*
   9136              * The NEXT_HOP_INDEXf is 14-bits wide in FT_POLICYm view.
   9137              * But only 13-bits are valid for this action
   9138              */
   9139             if (SOC_IS_TR_VL(unit)) {
   9140                 if (!(arg <= ((1 << 13) - 1))) {
   9141                     return BCM_E_PARAM;
   9142                 }
   9143             } else
   9144 {
   9145                 RegexPolicyCheck(unit, mem, NEXT_HOP_INDEXf, arg);
   9146             }
   9147             break;
   9148         case bcmFieldActionFabricQueue:
   9149             if ((arg & BCM_FABRIC_QUEUE_QOS_BASE)  &&
   9150                 (arg & BCM_FABRIC_QUEUE_DEST_OFFSET)) {
   9151                 return (BCM_E_PARAM);
   9152             }
   9153 
   9154             if (arg &
   9155                 ~(BCM_FABRIC_QUEUE_CUSTOMER |
   9156                   BCM_FABRIC_QUEUE_QOS_BASE |
   9157                   BCM_FABRIC_QUEUE_DEST_OFFSET |
   9158                   0xffff)) {
   9159                 return (BCM_E_PARAM);
   9160             }
   9161 
   9162             break;
   9163 
   9164 #ifdef INCLUDE_L3
   9165         case bcmFieldActionL3ChangeVlan:
   9166         case bcmFieldActionL3ChangeMacDa:
   9167         case bcmFieldActionL3Switch:
   9168             rv = _bcm_field_policy_set_l3_nh_resolve(unit,  arg,
   9169                                                      &flags, &nh_ecmp_id);
   9170             BCM_IF_ERROR_RETURN(rv);
   9171             if (flags & BCM_L3_MULTIPATH) {
   9172                 RegexPolicyCheck(unit, mem, ECMP_PTRf, nh_ecmp_id);
   9173             } else {
   9174                 RegexPolicyCheck(unit, mem, NEXT_HOP_INDEXf, nh_ecmp_id);
   9175         }
   9176             break;
   9177 #endif /* INCLUDE_L3 */
   9178         case bcmFieldActionOamUpMep:
   9179             RegexPolicyCheck(unit, mem, OAM_UP_MEPf, arg);
   9180             break;
   9181         case bcmFieldActionOamTx:
   9182             RegexPolicyCheck(unit, mem, OAM_TXf, arg);
   9183             break;
   9184         case bcmFieldActionOamLmepMdl:
   9185             RegexPolicyCheck(unit, mem, OAM_LMEP_MDLf, arg);
   9186             break;
   9187         case bcmFieldActionOamServicePriMappingPtr:
   9188             RegexPolicyCheck(unit, mem, OAM_SERVICE_PRI_MAPPING_PTRf, arg);
   9189             break;
   9190         case bcmFieldActionOamLmBasePtr:
   9191             RegexPolicyCheck(unit, mem, OAM_LM_BASE_PTRf, arg);
   9192             break;
   9193         case bcmFieldActionOamDmEnable:
   9194             RegexPolicyCheck(unit, mem, OAM_DM_ENf, arg);
   9195             break;
   9196         case bcmFieldActionOamLmEnable:
   9197             RegexPolicyCheck(unit, mem, OAM_LM_ENf, arg);
   9198             break;
   9199         case bcmFieldActionOamLmepEnable:
   9200             RegexPolicyCheck(unit, mem, OAM_LMEP_ENf, arg);
   9201             break;
   9202 #ifdef INCLUDE_L3
   9203         case bcmFieldActionRedirectEgrNextHop:
   9204             /* Get next hop info from Egress Object ID param */
   9205             BCM_IF_ERROR_RETURN(_bcm_field_policy_set_l3_nh_resolve(unit,
   9206                                                                     arg, &flags, &nh_ecmp_id));
   9207 
   9208             if (flags & BCM_L3_MULTIPATH) {
   9209                 /* Param0 - ECMP next hop */
   9210                 if (0 == soc_feature(unit, soc_feature_field_action_redirect_ecmp)) {
   9211                     return (BCM_E_PARAM);
   9212                 }
   9213                 RegexPolicyCheck(unit, mem, REDIRECTIONf, (nh_ecmp_id | (0x3 << 16)));
   9214             } else {
   9215                 /* Param0 - Regular next hop */
   9216                 RegexPolicyCheck(unit, mem, REDIRECTIONf, (nh_ecmp_id | (0x1 << 14)));
   9217     }
   9218             break;
   9219 #endif
   9220         default:
   9221     return BCM_E_NONE;
   9222 }
   9223     return (BCM_E_NONE);
   9224 }
   9225 
   9226 #ifdef INCLUDE_L3
   9227 /*
   9228  * Function:
   9229  *     _regex_tr3_policy_set_l3_info
   9230  * Purpose:
   9231  *     Install l3 forwarding policy entry.
   9232  * Parameters:
   9233  *     unit      - (IN) BCM device number
   9234  *     mem       - (IN) Policy table memory.
   9235  *     value     - (IN) Egress object id or combined next hop information.
   9236  *     buf       - (IN/OUT) Hw entry buffer to write.
   9237  * Returns:
   9238  *     BCM_E_XXX
   9239  */
   9240 
   9241 STATIC int _regex_tr3_policy_set_l3_info(int unit, soc_mem_t mem, int value, uint32 *buf)
   9242 {
   9243     uint32 flags;         /* L3 forwarding flags           */
   9244     int nh_ecmp_id;       /* Next hop/Ecmp group id.       */
   9245     int retval;           /* Operation return value.       */
   9246 
   9247     /* Resove next hop /ecmp group id. */
   9248     retval = _bcm_regex_policy_set_l3_nh_resolve(unit,  value,
   9249                                                  &flags, &nh_ecmp_id);
   9250     BCM_IF_ERROR_RETURN(retval);
   9251 
   9252     if (flags & BCM_L3_MULTIPATH) {
   9253         LOG_DEBUG(BSL_LS_BCM_REGEX,
   9254                   (BSL_META_U(unit,
   9255                               "FT(unit %d) vverb: Install mpath L3 policy "
   9256                               "(Ecmp_group: %d)))"),
   9257                    unit, nh_ecmp_id));
   9258         RegexPolicySet(unit, mem, buf, ECMPf, 1);
   9259         RegexPolicySet(unit, mem, buf, ECMP_PTRf, nh_ecmp_id);
   9260     } else {
   9261         LOG_DEBUG(BSL_LS_BCM_REGEX,
   9262                   (BSL_META_U(unit,
   9263                               "FT(unit %d) vverb: Install unipath L3 policy"
   9264                               "(Next hop id: %d)))"),
   9265                    unit, nh_ecmp_id));
   9266         if (SOC_MEM_FIELD_VALID(unit, mem, ECMPf)) {
   9267             RegexPolicySet(unit, mem, buf, ECMPf, 0);
   9268         }
   9269         RegexPolicySet(unit, mem, buf, NEXT_HOP_INDEXf, nh_ecmp_id);
   9270     }
   9271     return (BCM_E_NONE);
   9272 }
   9273 
   9274 /*
   9275  * Function:
   9276  *     _regex_tr3_policy_egr_nexthop_info_set
   9277  * Purpose:
   9278  *     Set next hop redirection value in the policy table entry.
   9279  * Parameters:
   9280  *     unit      - (IN) BCM device number
   9281  *     mem       - (IN) Policy table memory.
   9282  *     value     - (IN) Egress object id or combined next hop information.
   9283  *     buf       - (IN/OUT) Hw entry buffer to write.
   9284  * Returns:
   9285  *     BCM_E_XXX
   9286  */
   9287 STATIC int _regex_tr3_policy_egr_nexthop_info_set(int unit, soc_mem_t mem,
   9288                                                   int value, uint32 *buf)
   9289 {
   9290     uint32 redirect_to_nhi = 0; /* Hw config + (ECMP or NH Info)    */
   9291     uint32 flags;               /* L3 forwarding flags.             */
   9292     int nh_ecmp_id;             /* Next hop/Ecmp group id.          */
   9293 
   9294     /* Resove next hop /ecmp group id. */
   9295     BCM_IF_ERROR_RETURN(_bcm_regex_policy_set_l3_nh_resolve(unit,  value,
   9296                                                             &flags, &nh_ecmp_id));
   9297 
   9298     /* Check if NextHop is ECMP or regular Next Hop */
   9299     if (flags & BCM_L3_MULTIPATH) {
   9300         /* ECMP next hop */
   9301         if (soc_feature(unit, soc_feature_field_action_redirect_ecmp)) {
   9302             redirect_to_nhi = (0x3 << 16) | nh_ecmp_id;
   9303         } else {
   9304             /* Non-Trident devices do not support redirect to ECMP action */
   9305             return (BCM_E_UNAVAIL);
   9306         }
   9307         LOG_DEBUG(BSL_LS_BCM_REGEX,
   9308                   (BSL_META_U(unit,
   9309                               "FT(unit %d) vverb: Set ECMP (Group id: %d\n)))"),
   9310                    unit, nh_ecmp_id));
   9311     } else {
   9312         /* Regular next hop */
   9313         redirect_to_nhi = (0x1 << 14) | nh_ecmp_id;
   9314         LOG_DEBUG(BSL_LS_BCM_REGEX,
   9315                   (BSL_META_U(unit,
   9316                               "FT(unit %d) vverb: Set unipath (Nexthop index: %d\n)))"),
   9317                    unit, nh_ecmp_id));
   9318     }
   9319 
   9320     /* Set policy table redirection fields */
   9321     RegexPolicySet(unit, mem, buf, REDIRECTIONf, redirect_to_nhi);
   9322     RegexPolicySet(unit, mem, buf, G_PACKET_REDIRECTIONf, 1);
   9323     return (BCM_E_NONE);
   9324 }
   9325 #endif /* INCLUDE_L3 */
   9326 
   9327 /*
   9328  * Function:
   9329  *     _regex_tr3_policy_action_fabricQueue_actions_set
   9330  * Purpose:
   9331  *     Install add fabric tag action
   9332  * Parameters:
   9333  *     unit        - (IN) BCM device number
   9334  *     mem         - (IN) Policy table memory
   9335  *     cosq_idx    - (IN) cosq index or (ucast_queue_group/ucast_subscriber) cosq gport
   9336  *     profile_idx - (IN) QoS map profile index
   9337  *     buf         - (IN/OUT) Hw entry buffer to write.
   9338  * Returns:
   9339  *     BCM_E_XXX
   9340  */
   9341 STATIC int _regex_tr3_policy_action_fabricQueue_actions_set(int unit, soc_mem_t mem,
   9342                                                             int cosq_idx, int profile_idx, uint32 *buf)
   9343 {
   9344     int traffic_manager;  /* Indicates the intended application for the
   9345                              SBX_QUEUE_TAG.0x0-Fabric Interface Chip.
   9346                              0x1 Traffic Manager.*/
   9347     int tag_type;        /*  SBX tag type.                    */
   9348     uint32 param0 = 0;
   9349     uint32 in_flags = 0;
   9350 
   9351     if (NULL == buf) {
   9352         return (BCM_E_PARAM);
   9353     }
   9354 
   9355     param0 = cosq_idx;
   9356 
   9357     in_flags = param0;
   9358 
   9359     /* Tag type resolution. */
   9360     if (in_flags & BCM_FABRIC_QUEUE_QOS_BASE) {
   9361         tag_type = 0x3;  /* Offset to base queue number from the
   9362                             QUEUE_MAP Table. Index into QUEUE_MAP
   9363                             Table is {DST_MODID, DST_PID} */
   9364     } else if (in_flags & BCM_FABRIC_QUEUE_DEST_OFFSET) {
   9365         tag_type = 0x2;  /* Index into QUEUE_MAP Table used for lookup. */
   9366     } else {
   9367         tag_type = 0x1;  /* Explicit queue number. */
   9368     }
   9369 
   9370     RegexPolicySet(unit, mem, buf, EH_TAG_TYPEf, tag_type);
   9371 
   9372     /* Traffic manager vs Fabric chip queue selection. */
   9373     if (soc_mem_field_valid (unit, mem, EH_TMf)) {
   9374         traffic_manager = (cosq_idx & BCM_FABRIC_QUEUE_CUSTOMER) ? 0x1 : 0x0;
   9375         RegexPolicySet(unit, mem, buf, EH_TMf, traffic_manager);
   9376     }
   9377 
   9378     /* Set queue number. */
   9379     RegexPolicySet(unit, mem, buf, EH_QUEUE_TAGf, cosq_idx & 0xffff);
   9380 
   9381     return (BCM_E_NONE);
   9382 }
   9383 
   9384 /*
   9385  * Function:
   9386  *     _regex_tr3_policy_action_copy_to_cpu
   9387  * Purpose:
   9388  *     Install copy to cpu action in policy table.
   9389  * Parameters:
   9390  *     unit     - (IN) BCM device number
   9391  *     mem      - (IN) Policy table memory
   9392  *     p_ent    - (IN) Regex policy structure to get policy info from
   9393  *     pa       - (IN  Policy action
   9394  *     buf      - (OUT) Policy table entry
   9395  * Returns:
   9396  *     BCM_E_XXX
   9397  */
   9398 int _regex_tr3_policy_action_copy_to_cpu(int unit, soc_mem_t mem,
   9399                                          _regex_policy_t *p_ent,
   9400                                          _regex_policy_action_t *pa,
   9401                                          uint32 *buf)
   9402 {
   9403     if (NULL == p_ent || NULL == pa || NULL == buf) {
   9404         return (BCM_E_PARAM);
   9405     }
   9406 
   9407     switch (pa->action) {
   9408         case bcmFieldActionTimeStampToCpu:
   9409             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x5);
   9410             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x5);
   9411             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x5);
   9412             RegexPolicySet(unit, mem, buf, R_DROPf, 0x1);
   9413             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x1);
   9414             RegexPolicySet(unit, mem, buf, G_DROPf, 0x1);
   9415             break;
   9416         case bcmFieldActionRpTimeStampToCpu:
   9417             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x5);
   9418             RegexPolicySet(unit, mem, buf, R_DROPf, 0x1);
   9419             break;
   9420         case bcmFieldActionYpTimeStampToCpu:
   9421             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x5);
   9422             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x1);
   9423             break;
   9424         case bcmFieldActionGpTimeStampToCpu:
   9425             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x5);
   9426             RegexPolicySet(unit, mem, buf, G_DROPf, 0x1);
   9427             break;
   9428         case bcmFieldActionCopyToCpu:
   9429             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x1);
   9430             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x1);
   9431             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x1);
   9432             break;
   9433         case bcmFieldActionRpCopyToCpu:
   9434             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x1);
   9435             break;
   9436         case bcmFieldActionYpCopyToCpu:
   9437             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x1);
   9438             break;
   9439         case bcmFieldActionGpCopyToCpu:
   9440             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x1);
   9441             break;
   9442         default:
   9443             return (BCM_E_INTERNAL);
   9444     }
   9445 
   9446     if (pa->param[0] != 0) {
   9447         RegexPolicySet(unit, mem, buf, MATCHED_RULEf, pa->param[1]);
   9448     }
   9449     return (BCM_E_NONE);
   9450 }
   9451 
   9452 /*
   9453  * Function:
   9454  *     _regex_tr3_policy_action_copy_to_cpu_cancel
   9455  * Purpose:
   9456  *     Override copy to cpu action in policy table.
   9457  * Parameters:
   9458  *     unit     - (IN) BCM device number
   9459  *     mem      - (IN) Policy table memory
   9460  *     p_ent    - (IN) Regex policy structure to get policy info from
   9461  *     pa       - (IN  Policy action
   9462  *     buf      - (OUT) Policy table entry
   9463  * Returns:
   9464  *     BCM_E_XXX
   9465  */
   9466 STATIC int _regex_tr3_policy_action_copy_to_cpu_cancel(int unit, soc_mem_t mem,
   9467                                                        _regex_policy_t *p_ent,
   9468                                                        _regex_policy_action_t *pa,
   9469                                                        uint32 *buf)
   9470 {
   9471     if (NULL == p_ent || NULL == pa || NULL == buf) {
   9472         return (BCM_E_PARAM);
   9473     }
   9474 
   9475     switch (pa->action) {
   9476         case bcmFieldActionTimeStampToCpuCancel:
   9477             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x2);
   9478             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x2);
   9479             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x2);
   9480             RegexPolicySet(unit, mem, buf, R_DROPf, 0x2);
   9481             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x2);
   9482             RegexPolicySet(unit, mem, buf, G_DROPf, 0x2);
   9483             break;
   9484         case bcmFieldActionRpTimeStampToCpuCancel:
   9485             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x2);
   9486             RegexPolicySet(unit, mem, buf, R_DROPf, 0x2);
   9487             break;
   9488         case bcmFieldActionYpTimeStampToCpuCancel:
   9489             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x2);
   9490             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x2);
   9491             break;
   9492         case bcmFieldActionGpTimeStampToCpuCancel:
   9493             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x2);
   9494             RegexPolicySet(unit, mem, buf, G_DROPf, 0x2);
   9495             break;
   9496         case bcmFieldActionCopyToCpuCancel:
   9497             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x2);
   9498             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x2);
   9499             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x2);
   9500             break;
   9501         case bcmFieldActionRpCopyToCpuCancel:
   9502             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x2);
   9503             break;
   9504         case bcmFieldActionYpCopyToCpuCancel:
   9505             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x2);
   9506             break;
   9507         case bcmFieldActionGpCopyToCpuCancel:
   9508             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x2);
   9509             break;
   9510         default:
   9511             return (BCM_E_INTERNAL);
   9512     }
   9513     return (BCM_E_NONE);
   9514 }
   9515 
   9516 /*
   9517  * Function:
   9518  *     _regex_tr3_policy_cosq_action_param_get
   9519  * Purpose:
   9520  *     Returns CosQ action's param value if action is set for the
   9521  *     entry.
   9522  * Parameters:
   9523  *     unit     - BCM device number
   9524  *     p_ent    - pointer to policy entry structure
   9525  *     action   - CosQ action for which param value needs to be retrieved
   9526  *     cosq     - (OUT) CoS value
   9527  * Returns:
   9528  *     BCM_E_XXX
   9529  */
   9530 STATIC int _regex_tr3_policy_cosq_action_param_get(int unit,
   9531                                                    _regex_policy_t *p_ent,
   9532                                                    bcm_field_action_t action,
   9533                                                    int *cosq)
   9534 {
   9535     _regex_policy_action_t *pa_iter = NULL;    /* Policy action */
   9536 
   9537     if (NULL == cosq || NULL == p_ent) {
   9538         return (BCM_E_INTERNAL);
   9539     }
   9540 
   9541     /* Get the requested action param. */
   9542     pa_iter = p_ent->actions;
   9543     while (pa_iter != NULL) {
   9544         if (action == pa_iter->action) {
   9545             *cosq = pa_iter->param[0];
   9546             return (BCM_E_NONE);
   9547         }
   9548         pa_iter = pa_iter->next;
   9549     }
   9550 
   9551     /* Specified action not found in policy action list. */
   9552     return (BCM_E_NOT_FOUND);
   9553 }
   9554 
   9555 /*
   9556  * Function:
   9557  *     _regex_tr3_policy_ucast_mcast_action_set
   9558  * Purpose:
   9559  *     Set Unicast and Multicast CoS action in the policy buffer
   9560  * Parameters:
   9561  *     unit     - BCM device number
   9562  *     mem      - Policy table memory
   9563  *     p_ent    - policy structure to get policy info from
   9564  *     pa       - policy action
   9565  *     buf      - (OUT) Regex Policy table entry
   9566  * Returns:
   9567  *     BCM_E_XXX
   9568  */
   9569 STATIC int _regex_tr3_policy_ucast_mcast_action_set(int unit,
   9570                                                     soc_mem_t mem,
   9571                                                     _regex_policy_t *p_ent,
   9572                                                     _regex_policy_action_t *pa,
   9573                                                     uint32 *buf)
   9574 {
   9575     int m_cos = BCM_COS_INVALID;
   9576     int u_cos = BCM_COS_INVALID;
   9577     int cos = BCM_COS_INVALID;
   9578     int rv;
   9579 
   9580     if (NULL == p_ent || NULL == pa || NULL == buf) {
   9581         return (BCM_E_PARAM);
   9582     }
   9583 
   9584     cos = (int)pa->param[0];
   9585 
   9586     switch (pa->action) {
   9587         case bcmFieldActionMcastCosQNew:
   9588             m_cos = cos;
   9589             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9590                                                          p_ent,
   9591                                                          bcmFieldActionUcastCosQNew,
   9592                                                          &u_cos);
   9593             if (BCM_SUCCESS(rv)) {
   9594                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9595                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9596                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9597                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9598                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9599                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9600 
   9601                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9602                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9603                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9604                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9605                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9606                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9607             } else {
   9608                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9609                                _REGEX_ACTION_MCAST_QUEUE_NEW_MODE);
   9610                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9611                                _REGEX_ACTION_MCAST_QUEUE_NEW_MODE);
   9612                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9613                                _REGEX_ACTION_MCAST_QUEUE_NEW_MODE);
   9614 
   9615                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9616                                _REGEX_ACTION_MCAST_QUEUE_SET(m_cos));
   9617                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9618                                _REGEX_ACTION_MCAST_QUEUE_SET(m_cos));
   9619                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9620                                _REGEX_ACTION_MCAST_QUEUE_SET(m_cos));
   9621             }
   9622             break;
   9623 
   9624         case bcmFieldActionGpMcastCosQNew:
   9625             m_cos = cos;
   9626             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9627                                                          p_ent, bcmFieldActionGpUcastCosQNew, &u_cos);
   9628             if (BCM_SUCCESS(rv)) {
   9629                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9630                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9631 
   9632                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9633                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9634             } else {
   9635                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9636                                _REGEX_ACTION_MCAST_QUEUE_NEW_MODE);
   9637 
   9638                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9639                                _REGEX_ACTION_MCAST_QUEUE_SET(m_cos));
   9640             }
   9641             break;
   9642 
   9643         case bcmFieldActionYpMcastCosQNew:
   9644             m_cos = cos;
   9645             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9646                                                          p_ent, bcmFieldActionYpUcastCosQNew, &u_cos);
   9647             if (BCM_SUCCESS(rv)) {
   9648                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9649                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9650 
   9651                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9652                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9653             } else {
   9654                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9655                                _REGEX_ACTION_MCAST_QUEUE_NEW_MODE);
   9656 
   9657                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9658                                _REGEX_ACTION_MCAST_QUEUE_SET(m_cos));
   9659             }
   9660             break;
   9661 
   9662         case bcmFieldActionRpMcastCosQNew:
   9663             m_cos = cos;
   9664             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9665                                                          p_ent, bcmFieldActionRpUcastCosQNew, &u_cos);
   9666             if (BCM_SUCCESS(rv)) {
   9667                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9668                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9669 
   9670                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9671                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9672             } else {
   9673                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9674                                _REGEX_ACTION_MCAST_QUEUE_NEW_MODE);
   9675 
   9676                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9677                                _REGEX_ACTION_MCAST_QUEUE_SET(m_cos));
   9678             }
   9679             break;
   9680 
   9681         case bcmFieldActionUcastCosQNew:
   9682             u_cos = cos;
   9683             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9684                                                          p_ent, bcmFieldActionMcastCosQNew, &m_cos);
   9685             if (BCM_SUCCESS(rv)) {
   9686                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9687                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9688                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9689                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9690                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9691                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9692 
   9693                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9694                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9695                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9696                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9697                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9698                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9699             } else {
   9700                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9701                                _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
   9702                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9703                                _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
   9704                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9705                                _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
   9706 
   9707                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9708                                _REGEX_ACTION_UCAST_QUEUE_SET(u_cos));
   9709                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9710                                _REGEX_ACTION_UCAST_QUEUE_SET(u_cos));
   9711                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9712                                _REGEX_ACTION_UCAST_QUEUE_SET(u_cos));
   9713             }
   9714             break;
   9715 
   9716         case bcmFieldActionGpUcastCosQNew:
   9717             u_cos = cos;
   9718             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9719                                                          p_ent, bcmFieldActionGpMcastCosQNew, &m_cos);
   9720             if (BCM_SUCCESS(rv)) {
   9721                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9722                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9723 
   9724                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9725                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9726             } else {
   9727                 RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
   9728                                _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
   9729 
   9730                 RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
   9731                                _REGEX_ACTION_UCAST_QUEUE_SET(u_cos));
   9732             }
   9733             break;
   9734 
   9735         case bcmFieldActionYpUcastCosQNew:
   9736             u_cos = cos;
   9737             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9738                                                          p_ent, bcmFieldActionYpMcastCosQNew, &m_cos);
   9739             if (BCM_SUCCESS(rv)) {
   9740                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9741                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9742 
   9743                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9744                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9745             } else {
   9746                 RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
   9747                                _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
   9748 
   9749                 RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
   9750                                _REGEX_ACTION_UCAST_QUEUE_SET(u_cos));
   9751             }
   9752             break;
   9753 
   9754         case bcmFieldActionRpUcastCosQNew:
   9755             u_cos = cos;
   9756             rv = _regex_tr3_policy_cosq_action_param_get(unit,
   9757                                                          p_ent, bcmFieldActionRpMcastCosQNew, &m_cos);
   9758             if (BCM_SUCCESS(rv)) {
   9759                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9760                                _REGEX_ACTION_UCAST_MCAST_QUEUE_NEW_MODE);
   9761 
   9762                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9763                                _REGEX_ACTION_UCAST_MCAST_QUEUE_SET(u_cos, m_cos));
   9764             } else {
   9765                 RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
   9766                                _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
   9767 
   9768                 RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
   9769                                _REGEX_ACTION_UCAST_QUEUE_SET(u_cos));
   9770             }
   9771             break;
   9772 
   9773         default:
   9774             return (BCM_E_INTERNAL);
   9775     }
   9776 
   9777     return (BCM_E_NONE);
   9778 }
   9779 
   9780 /*
   9781  * Function:
   9782  *     _regex_tr3_policy_mirror_add
   9783  * Purpose:
   9784  *     Set mirroring destination & enable mirroring for rule matching
   9785  *     packets.
   9786  * Parameters:
   9787  *     unit     - (IN) BCM device number
   9788  *     mem      - (IN) Policy table memory
   9789  *     f_ent    - (IN) Entry structure to get policy info from
   9790  *     fa       - (IN) field action
   9791  *     buf      - (IN/OUT) Field Policy table entry
   9792  * Returns:
   9793  *     BCM_E_XXX
   9794  */
   9795 STATIC int _regex_tr3_policy_mirror_add(int unit, soc_mem_t mem, _regex_policy_t *p_ent,
   9796                                         _regex_policy_action_t *pa, uint32 *buf)
   9797 {
   9798     int    mtp_index;
   9799     uint32 enable;
   9800     int    index;
   9801 
   9802     soc_field_t mtp_field[] = {
   9803         MTP_INDEX0f, MTP_INDEX1f,
   9804         MTP_INDEX2f, MTP_INDEX3f};
   9805 
   9806     /* Input parameters check. */
   9807     if (NULL == p_ent || NULL == pa || NULL == buf) {
   9808         return (BCM_E_PARAM);
   9809     }
   9810     mtp_index = pa->hw_index;
   9811     index     = pa->hw_index;
   9812     if (index >= COUNTOF(mtp_field)) {
   9813         return (BCM_E_INTERNAL);
   9814     }
   9815 
   9816     enable = PolicyGet(unit, mem, buf, MIRRORf);
   9817     PolicySet(unit, mem, buf, mtp_field[index], mtp_index);
   9818     PolicySet(unit, mem, buf, MIRRORf, (enable | (0x1 << index)));
   9819 
   9820     return (BCM_E_NONE);
   9821 }
   9822 
   9823 /*
   9824  * Function:
   9825  *     _regex_tr3_policy_action_get
   9826  * Purpose:
   9827  *     Get the actions to be written
   9828  * Parameters:
   9829  *     unit     - BCM device number
   9830  *     mem      - Policy table memory
   9831  *     p_ent    - policy structure to get policy info from
   9832  *     pa       - policy action
   9833  *     buf      - (OUT) Policy table entry
   9834  * Returns:
   9835  *     BCM_E_NONE
   9836  *     BCM_E_PARAM - Action parameter out-of-range or unrecognized action.
   9837  * Notes:
   9838  *     This is a simple read/modify/write pattern.
   9839  *     Regex unit lock should be held by calling function.
   9840  */
   9841 STATIC int _regex_tr3_policy_action_get(int unit, soc_mem_t mem, _regex_policy_t *p_ent,
   9842                                         _regex_policy_action_t *pa, uint32 *buf)
   9843 {
   9844     int         rv;
   9845     soc_field_t l3sw_or_change_l2 = INVALIDf;
   9846     uint32      arg;
   9847     uint32      arg2;
   9848 
   9849     if (NULL == p_ent || NULL == pa || NULL == buf) {
   9850         return (BCM_E_PARAM);
   9851     }
   9852 
   9853     LOG_DEBUG(BSL_LS_BCM_REGEX,
   9854               (BSL_META_U(unit,
   9855                           "FT(unit %d) vverb: BEGIN %s(eid=%d)\n"),
   9856                unit, FUNCTION_NAME(), p_ent->eid));
   9857 
   9858     arg  = pa->param[0];
   9859     arg2 = pa->param[1];
   9860 
   9861     if (SOC_MEM_FIELD_VALID(unit, mem, G_L3SW_CHANGE_MACDA_OR_VLANf)) {
   9862         l3sw_or_change_l2 = G_L3SW_CHANGE_MACDA_OR_VLANf;
   9863     } else {
   9864         l3sw_or_change_l2 = G_L3SW_CHANGE_L2_FIELDSf;
   9865     }
   9866 
   9867     switch (pa->action) {
   9868         case bcmFieldActionNewClassId:
   9869             RegexPolicySet(unit, mem, buf, I2E_CLASSIDf, arg);
   9870             RegexPolicySet(unit, mem, buf, G_L3SW_CHANGE_L2_FIELDSf, 0x8);
   9871             break;
   9872         case bcmFieldActionTrunkLoadBalanceCancel:
   9873             RegexPolicySet(unit, mem, buf, LAG_DLB_DISABLEf, 1);
   9874             RegexPolicySet(unit, mem, buf, HGT_DLB_DISABLEf, 1);
   9875             break;
   9876 
   9877         case bcmFieldActionEcmpLoadBalanceCancel:
   9878             RegexPolicySet(unit, mem, buf, ECMP_DLB_DISABLEf, 1);
   9879             break;
   9880 
   9881         case bcmFieldActionEgressClassSelect:
   9882         {
   9883             unsigned i2e_cl_sel;
   9884 
   9885             switch (arg) {
   9886                 case BCM_FIELD_EGRESS_CLASS_SELECT_PORT:
   9887                     i2e_cl_sel = 0x1;
   9888                     break;
   9889                 case BCM_FIELD_EGRESS_CLASS_SELECT_SVP:
   9890                     i2e_cl_sel = 0x2;
   9891                     break;
   9892                 case BCM_FIELD_EGRESS_CLASS_SELECT_L3_IIF:
   9893                     i2e_cl_sel = 0x3;
   9894                     break;
   9895                 case BCM_FIELD_EGRESS_CLASS_SELECT_FIELD_SRC:
   9896                     i2e_cl_sel = 0x4; /* VFP hi */
   9897                     break;
   9898                 case BCM_FIELD_EGRESS_CLASS_SELECT_FIELD_DST:
   9899                     i2e_cl_sel = 0x5; /* VFP lo */
   9900                     break;
   9901                 case BCM_FIELD_EGRESS_CLASS_SELECT_L2_SRC:
   9902                     i2e_cl_sel = 0x6;
   9903                     break;
   9904                 case BCM_FIELD_EGRESS_CLASS_SELECT_L2_DST:
   9905                     i2e_cl_sel = 0x7;
   9906                     break;
   9907                 case BCM_FIELD_EGRESS_CLASS_SELECT_L3_SRC:
   9908                     i2e_cl_sel = 0x8;
   9909                     break;
   9910                 case BCM_FIELD_EGRESS_CLASS_SELECT_L3_DST:
   9911                     i2e_cl_sel = 0x9;
   9912                     break;
   9913                 case BCM_FIELD_EGRESS_CLASS_SELECT_VLAN:
   9914                     i2e_cl_sel = 0xa;
   9915                     break;
   9916                 case BCM_FIELD_EGRESS_CLASS_SELECT_VRF:
   9917                     i2e_cl_sel = 0xb;
   9918                     break;
   9919                 case BCM_FIELD_EGRESS_CLASS_SELECT_NEW:
   9920                     i2e_cl_sel = 0xf;
   9921                     break;
   9922                 default:
   9923                     /* Invalid parameter should have been caught earlier */
   9924                     return (BCM_E_INTERNAL);
   9925             }
   9926 
   9927             RegexPolicySet(unit, mem, buf, I2E_CLASSID_SELf, i2e_cl_sel);
   9928         }
   9929         break;
   9930 
   9931         case bcmFieldActionHiGigClassSelect:
   9932         {
   9933             unsigned hg_cl_sel;
   9934 
   9935             switch (arg) {
   9936                 case BCM_FIELD_HIGIG_CLASS_SELECT_EGRESS:
   9937                     hg_cl_sel = 1;
   9938                     break;
   9939                 case BCM_FIELD_HIGIG_CLASS_SELECT_EGR_DVP:
   9940                     hg_cl_sel = 4;
   9941                     break;
   9942                 case BCM_FIELD_HIGIG_CLASS_SELECT_EGR_L3_INTERFACE:
   9943                     hg_cl_sel = 3;
   9944                     break;
   9945                 case BCM_FIELD_HIGIG_CLASS_SELECT_EGR_NEXT_HOP:
   9946                     hg_cl_sel = 2;
   9947                     break;
   9948                 case BCM_FIELD_HIGIG_CLASS_SELECT_PORT:
   9949                     hg_cl_sel = 7;
   9950                     break;
   9951                 default:
   9952                     /* Invalid parameter should have been caught earlier */
   9953                     return (BCM_E_INTERNAL);
   9954             }
   9955 
   9956             RegexPolicySet(unit, mem, buf, HG_CLASSID_SELf, hg_cl_sel);
   9957         }
   9958         break;
   9959 
   9960         case bcmFieldActionOamDmTimeFormat:
   9961         {
   9962             unsigned oam_dm_type;
   9963 
   9964             switch (arg) {
   9965                 case BCM_FIELD_OAM_DM_TIME_FORMAT_IEEE1588:
   9966                     oam_dm_type = 0;
   9967                     break;
   9968                 case BCM_FIELD_OAM_DM_TIME_FORMAT_NTP:
   9969                     oam_dm_type = 1;
   9970                     break;
   9971                 default:
   9972                     /* Invalid parameter should have been caught earlier */
   9973                     return (BCM_E_INTERNAL);
   9974             }
   9975 
   9976             RegexPolicySet(unit, mem, buf, OAM_DM_TYPEf, oam_dm_type);
   9977         }
   9978         break;
   9979 
   9980         case bcmFieldActionOamLmDmSampleEnable:
   9981             RegexPolicySet(unit, mem, buf, OAM_ENABLE_LM_DM_SAMPLEf, arg ? 1 : 0);
   9982             break;
   9983 
   9984         case bcmFieldActionOamTagStatusCheck:
   9985             RegexPolicySet(unit, mem, buf, OAM_TAG_STATUS_CHECK_CONTROLf, arg);
   9986             break;
   9987 
   9988         case bcmFieldActionOamTunnelControl:
   9989         {
   9990             unsigned oam_tnl_cntl;
   9991 
   9992             switch (arg) {
   9993                 case BCM_FIELD_OAM_TUNNEL_CONTROL_ANY:
   9994                     oam_tnl_cntl = 0;
   9995                     break;
   9996                 case BCM_FIELD_OAM_TUNNEL_CONTROL_NOT_TUNNELDED:
   9997                     oam_tnl_cntl = 1;
   9998                     break;
   9999                 default:
  10000                     /* Invalid parameter should have been caught earlier */
  10001                     return (BCM_E_INTERNAL);
  10002             }
  10003 
  10004             RegexPolicySet(unit, mem, buf, OAM_TUNNEL_CONTROLf, oam_tnl_cntl);
  10005         }
  10006         break;
  10007 
  10008         case bcmFieldActionEcnNew:
  10009             RegexPolicySet(unit, mem, buf, R_CHANGE_ECNf, 1);
  10010             RegexPolicySet(unit, mem, buf, R_NEW_ECNf, arg);
  10011             RegexPolicySet(unit, mem, buf, Y_CHANGE_ECNf, 1);
  10012             RegexPolicySet(unit, mem, buf, Y_NEW_ECNf, arg);
  10013             RegexPolicySet(unit, mem, buf, G_CHANGE_ECNf, 1);
  10014             RegexPolicySet(unit, mem, buf, G_NEW_ECNf, arg);
  10015             break;
  10016 
  10017         case bcmFieldActionRpEcnNew:
  10018             RegexPolicySet(unit, mem, buf, R_CHANGE_ECNf, 1);
  10019             RegexPolicySet(unit, mem, buf, R_NEW_ECNf, arg);
  10020             break;
  10021 
  10022         case bcmFieldActionYpEcnNew:
  10023             RegexPolicySet(unit, mem, buf, Y_CHANGE_ECNf, 1);
  10024             RegexPolicySet(unit, mem, buf, Y_NEW_ECNf, arg);
  10025             break;
  10026 
  10027         case bcmFieldActionGpEcnNew:
  10028             RegexPolicySet(unit, mem, buf, G_CHANGE_ECNf, 1);
  10029             RegexPolicySet(unit, mem, buf, G_NEW_ECNf, arg);
  10030             break;
  10031 
  10032         case bcmFieldActionCosQNew:
  10033             /* Apply this action for Gp/Yp/Rp unicast packets. */
  10034             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
  10035                            _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
  10036 
  10037             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
  10038                            _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
  10039 
  10040             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
  10041                            _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
  10042 
  10043             /* Set new CoSQ/hardware queue value. */
  10044             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
  10045                            _REGEX_ACTION_UCAST_QUEUE_SET(arg));
  10046 
  10047             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
  10048                            _REGEX_ACTION_UCAST_QUEUE_SET(arg));
  10049 
  10050             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
  10051                            _REGEX_ACTION_UCAST_QUEUE_SET(arg));
  10052             break;
  10053 
  10054         case bcmFieldActionGpCosQNew:
  10055             /* Apply this action for Gp unicast packets. */
  10056             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf,
  10057                            _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
  10058 
  10059             /* Set new CoSQ/hardware queue value. */
  10060             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
  10061                            _REGEX_ACTION_UCAST_QUEUE_SET(arg));
  10062 
  10063             break;
  10064 
  10065         case bcmFieldActionYpCosQNew:
  10066             /* Apply this action for Yp unicast packets. */
  10067             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf,
  10068                            _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
  10069 
  10070             /* Set new CoSQ/hardware queue value. */
  10071             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
  10072                            _REGEX_ACTION_UCAST_QUEUE_SET(arg));
  10073             break;
  10074 
  10075         case bcmFieldActionRpCosQNew:
  10076             /* Apply this action for Rp unicast packets. */
  10077             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf,
  10078                            _REGEX_ACTION_UCAST_QUEUE_NEW_MODE);
  10079 
  10080             /* Set new CoSQ/hardware queue value. */
  10081             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
  10082                            _REGEX_ACTION_UCAST_QUEUE_SET(arg));
  10083             break;
  10084 
  10085         case bcmFieldActionUcastCosQNew:
  10086         case bcmFieldActionMcastCosQNew:
  10087         case bcmFieldActionGpMcastCosQNew:
  10088         case bcmFieldActionYpMcastCosQNew:
  10089         case bcmFieldActionRpMcastCosQNew:
  10090         case bcmFieldActionGpUcastCosQNew:
  10091         case bcmFieldActionYpUcastCosQNew:
  10092         case bcmFieldActionRpUcastCosQNew:
  10093             BCM_IF_ERROR_RETURN(_regex_tr3_policy_ucast_mcast_action_set(unit, mem, p_ent,
  10094                                                                          pa, buf));
  10095             break;
  10096         case bcmFieldActionPortPrioIntCosQNew:
  10097             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 10);
  10098             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 10);
  10099             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 10);
  10100             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
  10101                            (_BCM_COSQ_CLASSIFIER_FIELD_GET(arg) << 9 | arg2));
  10102             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
  10103                            (_BCM_COSQ_CLASSIFIER_FIELD_GET(arg) << 9 | arg2));
  10104             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
  10105                            (_BCM_COSQ_CLASSIFIER_FIELD_GET(arg) << 9 | arg2));
  10106             break;
  10107         case bcmFieldActionRpPortPrioIntCosQNew:
  10108             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 10);
  10109             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf,
  10110                            (_BCM_COSQ_CLASSIFIER_FIELD_GET(arg) << 9 | arg2));
  10111             break;
  10112         case bcmFieldActionYpPortPrioIntCosQNew:
  10113             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 10);
  10114             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf,
  10115                            (_BCM_COSQ_CLASSIFIER_FIELD_GET(arg) << 9 | arg2));
  10116             break;
  10117         case bcmFieldActionGpPortPrioIntCosQNew:
  10118             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 10);
  10119             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf,
  10120                            (_BCM_COSQ_CLASSIFIER_FIELD_GET(arg) << 9 | arg2));
  10121             break;
  10122         case bcmFieldActionCopyToCpu:
  10123         case bcmFieldActionRpCopyToCpu:
  10124         case bcmFieldActionYpCopyToCpu:
  10125         case bcmFieldActionGpCopyToCpu:
  10126             BCM_IF_ERROR_RETURN(_regex_tr3_policy_action_copy_to_cpu(unit, mem, p_ent,
  10127                                                                      pa, buf));
  10128             break;
  10129 
  10130 
  10131 
  10132 
  10133 
  10134 
  10135         case bcmFieldActionMultipathHash:
  10136             RegexPolicySet(unit, mem, buf, ECMP_HASH_SELf, pa->param[0]);
  10137             break;
  10138         case bcmFieldActionTimeStampToCpu:
  10139         case bcmFieldActionRpTimeStampToCpu:
  10140         case bcmFieldActionYpTimeStampToCpu:
  10141         case bcmFieldActionGpTimeStampToCpu:
  10142             rv = _regex_tr3_policy_action_copy_to_cpu(unit, mem, p_ent, pa, buf);
  10143             BCM_IF_ERROR_RETURN(rv);
  10144             break;
  10145 
  10146         case bcmFieldActionCopyToCpuCancel:
  10147         case bcmFieldActionRpCopyToCpuCancel:
  10148         case bcmFieldActionYpCopyToCpuCancel:
  10149         case bcmFieldActionGpCopyToCpuCancel:
  10150         case bcmFieldActionTimeStampToCpuCancel:
  10151         case bcmFieldActionRpTimeStampToCpuCancel:
  10152         case bcmFieldActionYpTimeStampToCpuCancel:
  10153         case bcmFieldActionGpTimeStampToCpuCancel:
  10154             rv = _regex_tr3_policy_action_copy_to_cpu_cancel(unit, mem, p_ent, pa, buf);
  10155             BCM_IF_ERROR_RETURN(rv);
  10156             break;
  10157 
  10158         case bcmFieldActionDrop:
  10159             RegexPolicySet(unit, mem, buf, R_DROPf, 0x1);
  10160             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x1);
  10161             RegexPolicySet(unit, mem, buf, G_DROPf, 0x1);
  10162             break;
  10163 
  10164         case bcmFieldActionDropCancel:
  10165             RegexPolicySet(unit, mem, buf, R_DROPf, 0x2);
  10166             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x2);
  10167             RegexPolicySet(unit, mem, buf, G_DROPf, 0x2);
  10168             break;
  10169 
  10170         case bcmFieldActionDropPrecedence:
  10171             RegexPolicySet(unit, mem, buf, R_DROP_PRECEDENCEf, pa->param[0]);
  10172             RegexPolicySet(unit, mem, buf, Y_DROP_PRECEDENCEf, pa->param[0]);
  10173             RegexPolicySet(unit, mem, buf, G_DROP_PRECEDENCEf, pa->param[0]);
  10174             break;
  10175 
  10176         case bcmFieldActionPrioPktCopy:
  10177             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x4);
  10178             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x4);
  10179             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x4);
  10180             break;
  10181 
  10182         case bcmFieldActionPrioPktNew:
  10183             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x5);
  10184             RegexPolicySet(unit, mem, buf, R_NEW_PKT_PRIf, pa->param[0]);
  10185             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x5);
  10186             RegexPolicySet(unit, mem, buf, Y_NEW_PKT_PRIf, pa->param[0]);
  10187             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x5);
  10188             RegexPolicySet(unit, mem, buf, G_NEW_PKT_PRIf, pa->param[0]);
  10189             break;
  10190 
  10191         case bcmFieldActionPrioPktTos:
  10192             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x6);
  10193             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x6);
  10194             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x6);
  10195             break;
  10196 
  10197         case bcmFieldActionPrioPktCancel:
  10198             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x7);
  10199             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x7);
  10200             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x7);
  10201             break;
  10202 
  10203         case bcmFieldActionDscpNew:
  10204             RegexPolicySet(unit, mem, buf, R_CHANGE_DSCPf, 0x1);
  10205             RegexPolicySet(unit, mem, buf, R_NEW_DSCPf, pa->param[0]);
  10206             RegexPolicySet(unit, mem, buf, Y_CHANGE_DSCPf, 0x1);
  10207             RegexPolicySet(unit, mem, buf, Y_NEW_DSCPf, pa->param[0]);
  10208             RegexPolicySet(unit, mem, buf, G_CHANGE_DSCP_TOSf, 0x3);
  10209             RegexPolicySet(unit, mem, buf, G_NEW_DSCP_TOSf, pa->param[0]);
  10210             break;
  10211 
  10212         case bcmFieldActionDscpCancel:
  10213             RegexPolicySet(unit, mem, buf, R_CHANGE_DSCPf, 0x2);
  10214             RegexPolicySet(unit, mem, buf, Y_CHANGE_DSCPf, 0x2);
  10215             RegexPolicySet(unit, mem, buf, G_CHANGE_DSCP_TOSf, 0x4);
  10216             break;
  10217 
  10218         case bcmFieldActionVlanCosQNew:
  10219             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x2);
  10220             /* Add 8 to the value since VLAN shaping queues are 8..23 */
  10221             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf, pa->param[0] + 8);
  10222             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x2);
  10223             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf, pa->param[0] + 8);
  10224             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x2);
  10225             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf, pa->param[0] + 8);
  10226             break;
  10227 
  10228         case bcmFieldActionPrioIntCopy:
  10229             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x4);
  10230             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x4);
  10231             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x4);
  10232             break;
  10233 
  10234         case bcmFieldActionPrioIntNew:
  10235             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x5);
  10236             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf, (0xf & pa->param[0]));
  10237             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x5);
  10238             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf, (0xf & pa->param[0]));
  10239             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x5);
  10240             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf, (0xf & pa->param[0]));
  10241             break;
  10242 
  10243         case bcmFieldActionPrioIntTos:
  10244             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x6);
  10245             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x6);
  10246             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x6);
  10247             break;
  10248 
  10249         case bcmFieldActionPrioIntCancel:
  10250             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x7);
  10251             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x7);
  10252             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x7);
  10253             break;
  10254 
  10255         case bcmFieldActionPrioPktAndIntNew:
  10256             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x5);
  10257             RegexPolicySet(unit, mem, buf, R_NEW_PKT_PRIf, pa->param[0]);
  10258             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x5);
  10259             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf, (0xf & pa->param[0]));
  10260             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x5);
  10261             RegexPolicySet(unit, mem, buf, Y_NEW_PKT_PRIf, pa->param[0]);
  10262             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x5);
  10263             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf, (0xf & pa->param[0]));
  10264             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x5);
  10265             RegexPolicySet(unit, mem, buf, G_NEW_PKT_PRIf, pa->param[0]);
  10266             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x5);
  10267             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf, (0xf & pa->param[0]));
  10268             break;
  10269 
  10270         case bcmFieldActionPrioPktAndIntCopy:
  10271             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x4);
  10272             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x4);
  10273             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x4);
  10274             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x4);
  10275             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x4);
  10276             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x4);
  10277             break;
  10278 
  10279         case bcmFieldActionPrioPktAndIntTos:
  10280             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x6);
  10281             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x6);
  10282             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x6);
  10283             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x6);
  10284             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x6);
  10285             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x6);
  10286             break;
  10287 
  10288         case bcmFieldActionPrioPktAndIntCancel:
  10289             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x7);
  10290             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x7);
  10291             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x7);
  10292             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x7);
  10293             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x7);
  10294             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x7);
  10295             break;
  10296 
  10297         case bcmFieldActionCosQCpuNew:
  10298             RegexPolicySet(unit, mem, buf, CHANGE_CPU_COSf, 0x1);
  10299             RegexPolicySet(unit, mem, buf, CPU_COSf, pa->param[0]);
  10300             break;
  10301 
  10302         case bcmFieldActionSwitchToCpuCancel:
  10303             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x3);
  10304             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x3);
  10305             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x3);
  10306             break;
  10307 
  10308         case bcmFieldActionSwitchToCpuReinstate:
  10309             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x4);
  10310             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x4);
  10311             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x4);
  10312             break;
  10313 
  10314         case bcmFieldActionIpFix:
  10315             RegexPolicySet(unit, mem, buf, IPFIX_CONTROLf, 0x1);
  10316             break;
  10317 
  10318         case bcmFieldActionIpFixCancel:
  10319             RegexPolicySet(unit, mem, buf, IPFIX_CONTROLf, 0x2);
  10320             break;
  10321 
  10322         case bcmFieldActionOuterVlanNew:
  10323             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x1);
  10324             if (SOC_MEM_FIELD_VALID(unit, mem, ECMPf)) {
  10325                 RegexPolicySet(unit, mem, buf, ECMPf, 0);
  10326             }
  10327             RegexPolicySet(unit, mem, buf, NEXT_HOP_INDEXf, pa->hw_index);
  10328             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10329             break;
  10330 
  10331         case bcmFieldActionSrcMacNew:
  10332         case bcmFieldActionDstMacNew:
  10333             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x1);
  10334             if (SOC_MEM_FIELD_VALID(unit, mem, ECMPf)) {
  10335                 RegexPolicySet(unit, mem, buf, ECMPf, 0);
  10336             }
  10337             RegexPolicySet(unit, mem, buf, NEXT_HOP_INDEXf, pa->hw_index);
  10338             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10339             break;
  10340         case bcmFieldActionVnTagNew:
  10341         case bcmFieldActionVnTagDelete:
  10342             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x1);
  10343             if (SOC_MEM_FIELD_VALID(unit, mem, ECMPf)) {
  10344                 RegexPolicySet(unit, mem, buf, ECMPf, 0);
  10345             }
  10346             RegexPolicySet(unit, mem, buf, NEXT_HOP_INDEXf, pa->hw_index);
  10347             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10348             break;
  10349 
  10350         case bcmFieldActionMirrorOverride:
  10351             RegexPolicySet(unit, mem, buf, MIRROR_OVERRIDEf, 1);
  10352             break;
  10353 
  10354         case bcmFieldActionDoNotChangeTtl:
  10355             RegexPolicySet(unit, mem, buf, DO_NOT_CHANGE_TTLf, 1);
  10356             break;
  10357 
  10358         case bcmFieldActionDoNotCheckUrpf:
  10359             RegexPolicySet(unit, mem, buf, DO_NOT_URPFf, 1);
  10360             break;
  10361 
  10362         case bcmFieldActionCnmCancel:
  10363             RegexPolicySet(unit, mem, buf, DO_NOT_GENERATE_CNMf, 1);
  10364             break;
  10365 
  10366         case bcmFieldActionDynamicHgTrunkCancel:
  10367             RegexPolicySet(unit, mem, buf, DISABLE_DYNAMIC_LOAD_BALANCINGf, 1);
  10368             break;
  10369         case bcmFieldActionMirrorIngress:    /* param0=modid, param1=port/tgid */
  10370             BCM_IF_ERROR_RETURN(_regex_tr3_policy_mirror_add(unit, mem, p_ent, pa, buf));
  10371             break;
  10372         case bcmFieldActionMirrorEgress:     /* param0=modid, param1=port/tgid */
  10373             BCM_IF_ERROR_RETURN(_regex_tr3_policy_mirror_add(unit, mem, p_ent, pa, buf));
  10374             break;
  10375         case bcmFieldActionOffloadRedirect:
  10376         case bcmFieldActionRedirect:
  10377         case bcmFieldActionRedirectTrunk:
  10378         case bcmFieldActionRedirectCancel:
  10379         case bcmFieldActionRedirectPbmp:
  10380 #ifdef INCLUDE_L3
  10381         case bcmFieldActionRedirectIpmc:
  10382 #endif /* INCLUDE_L3 */
  10383         case bcmFieldActionRedirectMcast:
  10384         case bcmFieldActionRedirectVlan:
  10385         case bcmFieldActionRedirectBcastPbmp:
  10386         case bcmFieldActionEgressMask:
  10387         case bcmFieldActionEgressPortsAdd:
  10388             BCM_IF_ERROR_RETURN(_regex_tr3_policy_action_redirect(unit, mem, p_ent, pa, buf));
  10389             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10390             break;
  10391         case bcmFieldActionOffloadDropIndication:
  10392             RegexPolicySet(unit, mem, buf, SPLIT_DROP_RESOLVEf, 0x1);
  10393             break;
  10394         case bcmFieldActionOffloadClassSet:
  10395             RegexPolicySet(unit, mem, buf, PPD3_CLASS_TAGf, pa->param[0]);
  10396             break;
  10397         case bcmFieldActionRpDrop:
  10398             RegexPolicySet(unit, mem, buf, R_DROPf, 0x1);
  10399             break;
  10400         case bcmFieldActionRpDropCancel:
  10401             RegexPolicySet(unit, mem, buf, R_DROPf, 0x2);
  10402             break;
  10403         case bcmFieldActionRpDropPrecedence:
  10404             RegexPolicySet(unit, mem, buf, R_DROP_PRECEDENCEf, pa->param[0]);
  10405             break;
  10406         case bcmFieldActionRpSwitchToCpuCancel:
  10407             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x3);
  10408             break;
  10409         case bcmFieldActionRpSwitchToCpuReinstate:
  10410             RegexPolicySet(unit, mem, buf, R_COPY_TO_CPUf, 0x4);
  10411             break;
  10412         case bcmFieldActionRpPrioPktCopy:
  10413             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x4);
  10414             break;
  10415         case bcmFieldActionRpPrioPktNew:
  10416             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x5);
  10417             RegexPolicySet(unit, mem, buf, R_NEW_PKT_PRIf, pa->param[0]);
  10418             break;
  10419         case bcmFieldActionRpPrioPktTos:
  10420             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x6);
  10421             break;
  10422         case bcmFieldActionRpPrioPktCancel:
  10423             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x7);
  10424             break;
  10425         case bcmFieldActionRpDscpNew:
  10426             RegexPolicySet(unit, mem, buf, R_CHANGE_DSCPf, 0x1);
  10427             RegexPolicySet(unit, mem, buf, R_NEW_DSCPf, pa->param[0]);
  10428             break;
  10429         case bcmFieldActionRpDscpCancel:
  10430             RegexPolicySet(unit, mem, buf, R_CHANGE_DSCPf, 0x2);
  10431             break;
  10432         case bcmFieldActionRpVlanCosQNew:
  10433             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x2);
  10434             /* Add 8 to the value since VLAN shaping queues are 8..23 */
  10435             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf, pa->param[0] + 8);
  10436             break;
  10437         case bcmFieldActionRpPrioPktAndIntCopy:
  10438             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x4);
  10439             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x4);
  10440             break;
  10441         case bcmFieldActionRpPrioPktAndIntNew:
  10442             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x5);
  10443             RegexPolicySet(unit, mem, buf, R_NEW_PKT_PRIf, pa->param[0]);
  10444             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x5);
  10445             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf, (0xf & pa->param[0]));
  10446             break;
  10447         case bcmFieldActionRpPrioPktAndIntTos:
  10448             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x6);
  10449             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x6);
  10450             break;
  10451         case bcmFieldActionRpPrioPktAndIntCancel:
  10452             RegexPolicySet(unit, mem, buf, R_CHANGE_PKT_PRIf, 0x7);
  10453             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x7);
  10454             break;
  10455         case bcmFieldActionRpPrioIntCopy:
  10456             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x4);
  10457             break;
  10458         case bcmFieldActionRpPrioIntNew:
  10459             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x5);
  10460             RegexPolicySet(unit, mem, buf, R_COS_INT_PRIf, (0xf & pa->param[0]));
  10461             break;
  10462         case bcmFieldActionRpPrioIntTos:
  10463             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x6);
  10464             break;
  10465         case bcmFieldActionRpPrioIntCancel:
  10466             RegexPolicySet(unit, mem, buf, R_CHANGE_COS_OR_INT_PRIf, 0x7);
  10467             break;
  10468         case bcmFieldActionYpDrop:
  10469             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x1);
  10470             break;
  10471         case bcmFieldActionYpDropCancel:
  10472             RegexPolicySet(unit, mem, buf, Y_DROPf, 0x2);
  10473             break;
  10474         case bcmFieldActionYpDropPrecedence:
  10475             RegexPolicySet(unit, mem, buf, Y_DROP_PRECEDENCEf, pa->param[0]);
  10476             break;
  10477         case bcmFieldActionYpSwitchToCpuCancel:
  10478             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x3);
  10479             break;
  10480         case bcmFieldActionYpSwitchToCpuReinstate:
  10481             RegexPolicySet(unit, mem, buf, Y_COPY_TO_CPUf, 0x4);
  10482             break;
  10483         case bcmFieldActionYpPrioPktCopy:
  10484             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x4);
  10485             break;
  10486         case bcmFieldActionYpPrioPktNew:
  10487             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x5);
  10488             RegexPolicySet(unit, mem, buf, Y_NEW_PKT_PRIf, pa->param[0]);
  10489             break;
  10490         case bcmFieldActionYpPrioPktTos:
  10491             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x6);
  10492             break;
  10493         case bcmFieldActionYpPrioPktCancel:
  10494             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x7);
  10495             break;
  10496         case bcmFieldActionYpDscpNew:
  10497             RegexPolicySet(unit, mem, buf, Y_CHANGE_DSCPf, 0x1);
  10498             RegexPolicySet(unit, mem, buf, Y_NEW_DSCPf, pa->param[0]);
  10499             break;
  10500         case bcmFieldActionYpDscpCancel:
  10501             RegexPolicySet(unit, mem, buf, Y_CHANGE_DSCPf, 0x2);
  10502             break;
  10503         case bcmFieldActionYpVlanCosQNew:
  10504             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x2);
  10505             /* Add 8 to the value since VLAN shaping queues are 8..23 */
  10506             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf, pa->param[0] + 8);
  10507             break;
  10508         case bcmFieldActionYpPrioPktAndIntCopy:
  10509             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x4);
  10510             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x4);
  10511             break;
  10512         case bcmFieldActionYpPrioPktAndIntNew:
  10513             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x5);
  10514             RegexPolicySet(unit, mem, buf, Y_NEW_PKT_PRIf, pa->param[0]);
  10515             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x5);
  10516             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf, (0xf & pa->param[0]));
  10517             break;
  10518         case bcmFieldActionYpPrioPktAndIntTos:
  10519             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x6);
  10520             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x6);
  10521             break;
  10522         case bcmFieldActionYpPrioPktAndIntCancel:
  10523             RegexPolicySet(unit, mem, buf, Y_CHANGE_PKT_PRIf, 0x7);
  10524             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x7);
  10525             break;
  10526         case bcmFieldActionYpPrioIntCopy:
  10527             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x4);
  10528             break;
  10529         case bcmFieldActionYpPrioIntNew:
  10530             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x5);
  10531             RegexPolicySet(unit, mem, buf, Y_COS_INT_PRIf, (0xf & pa->param[0]));
  10532             break;
  10533         case bcmFieldActionYpPrioIntTos:
  10534             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x6);
  10535             break;
  10536         case bcmFieldActionYpPrioIntCancel:
  10537             RegexPolicySet(unit, mem, buf, Y_CHANGE_COS_OR_INT_PRIf, 0x7);
  10538             break;
  10539         case bcmFieldActionGpDrop:
  10540             RegexPolicySet(unit, mem, buf, G_DROPf, 0x1);
  10541             break;
  10542         case bcmFieldActionGpDropCancel:
  10543             RegexPolicySet(unit, mem, buf, G_DROPf, 0x2);
  10544             break;
  10545         case bcmFieldActionGpDropPrecedence:
  10546             RegexPolicySet(unit, mem, buf, G_DROP_PRECEDENCEf, pa->param[0]);
  10547             break;
  10548         case bcmFieldActionGpSwitchToCpuCancel:
  10549             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x3);
  10550             break;
  10551         case bcmFieldActionGpSwitchToCpuReinstate:
  10552             RegexPolicySet(unit, mem, buf, G_COPY_TO_CPUf, 0x4);
  10553             break;
  10554         case bcmFieldActionGpPrioPktCopy:
  10555             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x4);
  10556             break;
  10557         case bcmFieldActionGpPrioPktNew:
  10558             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x5);
  10559             RegexPolicySet(unit, mem, buf, G_NEW_PKT_PRIf, pa->param[0]);
  10560             break;
  10561         case bcmFieldActionGpPrioPktTos:
  10562             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x6);
  10563             break;
  10564         case bcmFieldActionGpPrioPktCancel:
  10565             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x7);
  10566             break;
  10567         case bcmFieldActionGpTosPrecedenceNew:
  10568             RegexPolicySet(unit, mem, buf, G_CHANGE_DSCP_TOSf, 0x1);
  10569             RegexPolicySet(unit, mem, buf, G_NEW_DSCP_TOSf, pa->param[0]);
  10570             break;
  10571         case bcmFieldActionGpTosPrecedenceCopy:
  10572             RegexPolicySet(unit, mem, buf, G_CHANGE_DSCP_TOSf, 0x2);
  10573             break;
  10574         case bcmFieldActionGpDscpNew:
  10575             RegexPolicySet(unit, mem, buf, G_CHANGE_DSCP_TOSf, 0x3);
  10576             RegexPolicySet(unit, mem, buf, G_NEW_DSCP_TOSf, pa->param[0]);
  10577             break;
  10578         case bcmFieldActionGpDscpCancel:
  10579             RegexPolicySet(unit, mem, buf, G_CHANGE_DSCP_TOSf, 0x4);
  10580             break;
  10581         case bcmFieldActionGpVlanCosQNew:
  10582             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x2);
  10583             /* Add 8 to the value since VLAN shaping queues are 8..23 */
  10584             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf, pa->param[0] + 8);
  10585             break;
  10586         case bcmFieldActionGpPrioPktAndIntCopy:
  10587             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x4);
  10588             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x4);
  10589             break;
  10590         case bcmFieldActionGpPrioPktAndIntNew:
  10591             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x5);
  10592             RegexPolicySet(unit, mem, buf, G_NEW_PKT_PRIf, pa->param[0]);
  10593             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x5);
  10594             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf, (0xf & pa->param[0]));
  10595             break;
  10596         case bcmFieldActionGpPrioPktAndIntTos:
  10597             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x6);
  10598             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x6);
  10599             break;
  10600         case bcmFieldActionGpPrioPktAndIntCancel:
  10601             RegexPolicySet(unit, mem, buf, G_CHANGE_PKT_PRIf, 0x7);
  10602             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x7);
  10603             break;
  10604         case bcmFieldActionGpPrioIntCopy:
  10605             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x4);
  10606             break;
  10607         case bcmFieldActionGpPrioIntNew:
  10608             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x5);
  10609             RegexPolicySet(unit, mem, buf, G_COS_INT_PRIf, (0xf & pa->param[0]));
  10610             break;
  10611         case bcmFieldActionGpPrioIntTos:
  10612             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x6);
  10613             break;
  10614         case bcmFieldActionGpPrioIntCancel:
  10615             RegexPolicySet(unit, mem, buf, G_CHANGE_COS_OR_INT_PRIf, 0x7);
  10616             break;
  10617         case bcmFieldActionAddClassTag:
  10618             if (SOC_MEM_FIELD_VALID(unit, mem, G_L3SW_CHANGE_L2_FIELDSf)) {
  10619                 RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x4);
  10620             } else {
  10621                 RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x3);
  10622             }
  10623             RegexPolicySet(unit, mem, buf, NEXT_HOP_INDEXf, pa->param[0]);
  10624             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10625             break;
  10626         case bcmFieldActionFabricQueue:
  10627             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x3);
  10628             BCM_IF_ERROR_RETURN(_regex_tr3_policy_action_fabricQueue_actions_set(unit, mem, pa->param[0],
  10629                                                                                  pa->param[1], buf));
  10630             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10631             break;
  10632 #ifdef INCLUDE_L3
  10633         case bcmFieldActionL3ChangeVlan:
  10634             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x1);
  10635             BCM_IF_ERROR_RETURN(_regex_tr3_policy_set_l3_info(unit, mem, pa->param[0], buf));
  10636             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10637             break;
  10638         case bcmFieldActionL3ChangeVlanCancel:
  10639             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x2);
  10640             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10641             break;
  10642         case bcmFieldActionL3ChangeMacDa:
  10643             if (SOC_MEM_FIELD_VALID(unit, mem, G_L3SW_CHANGE_L2_FIELDSf)) {
  10644                 RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x1);
  10645             } else {
  10646                 RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x4);
  10647             }
  10648             BCM_IF_ERROR_RETURN(_regex_tr3_policy_set_l3_info(unit, mem,  pa->param[0], buf));
  10649             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10650             break;
  10651         case bcmFieldActionL3ChangeMacDaCancel:
  10652             if (SOC_MEM_FIELD_VALID(unit, mem, G_L3SW_CHANGE_L2_FIELDSf)) {
  10653                 RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x2);
  10654             } else {
  10655                 RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x5);
  10656             }
  10657             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10658             break;
  10659         case bcmFieldActionL3Switch:
  10660             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x6);
  10661             BCM_IF_ERROR_RETURN(_regex_tr3_policy_set_l3_info(unit, mem, pa->param[0], buf));
  10662             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10663             break;
  10664         case bcmFieldActionL3SwitchCancel:
  10665             RegexPolicySet(unit, mem, buf, l3sw_or_change_l2, 0x7);
  10666             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10667             break;
  10668 #endif /* INCLUDE_L3 */
  10669         case bcmFieldActionOamUpMep:
  10670             RegexPolicySet(unit, mem, buf, OAM_UP_MEPf, pa->param[0]);
  10671             break;
  10672         case bcmFieldActionOamTx:
  10673             RegexPolicySet(unit, mem, buf, OAM_TXf, pa->param[0]);
  10674             break;
  10675         case bcmFieldActionOamLmepMdl:
  10676             RegexPolicySet(unit, mem, buf, OAM_LMEP_MDLf, pa->param[0]);
  10677             break;
  10678         case bcmFieldActionOamServicePriMappingPtr:
  10679             RegexPolicySet(unit, mem, buf, OAM_SERVICE_PRI_MAPPING_PTRf, pa->param[0]);
  10680             break;
  10681         case bcmFieldActionOamLmBasePtr:
  10682             RegexPolicySet(unit, mem, buf, OAM_LM_BASE_PTRf, pa->param[0]);
  10683             break;
  10684         case bcmFieldActionOamDmEnable:
  10685             RegexPolicySet(unit, mem, buf, OAM_DM_ENf, pa->param[0]);
  10686             break;
  10687         case bcmFieldActionOamLmEnable:
  10688             RegexPolicySet(unit, mem, buf, OAM_LM_ENf, pa->param[0]);
  10689             break;
  10690         case bcmFieldActionOamLmepEnable:
  10691             RegexPolicySet(unit, mem, buf, OAM_LMEP_ENf, pa->param[0]);
  10692             break;
  10693         case bcmFieldActionUseGlobalMeterColor:
  10694             if (soc_feature(unit, soc_feature_global_meter)) {
  10695                 RegexPolicySet(unit, mem, buf, USE_SVC_METER_COLORf,1);
  10696             }
  10697             break;
  10698 #ifdef INCLUDE_L3
  10699         case bcmFieldActionRedirectEgrNextHop:
  10700             BCM_IF_ERROR_RETURN(_regex_tr3_policy_egr_nexthop_info_set(unit, mem,
  10701                                                                        pa->param[0], buf));
  10702             p_ent->flags |= _REGEX_POLICY_COLOR_INDEPENDENT;
  10703                 break;
  10704 #endif
  10705         default:
  10706             return (BCM_E_UNAVAIL);
  10707             }
  10708 
  10709     pa->flags &= ~_REGEX_ACTION_DIRTY; /* Mark action as installed. */
  10710 
  10711     LOG_DEBUG(BSL_LS_BCM_REGEX,
  10712               (BSL_META_U(unit,
  10713                           "FT(unit %d) vverb: END %s()\n"),
  10714                unit, FUNCTION_NAME()));
  10715     return (BCM_E_NONE);
  10716         }
  10717 
  10718 /*
  10719  * Function:
  10720  *     _regex_tr3_policy_install
  10721  * Purpose:
  10722  *     Write policy into the chip's memory.
  10723  * Parameters:
  10724  *     unit     -   BCM Unit
  10725  *     p_ent    -   Physical policy structure to be installed
  10726  * Returns:
  10727  *     BCM_E_XXX        On TCAM read/write errors
  10728  *     BCM_E_NONE
  10729  * Note:
  10730  *     Unit lock should be held by calling function.
  10731  */
  10732 STATIC int _regex_tr3_policy_install(int unit, _regex_policy_t *p_ent)
  10733 {
  10734     uint32                  e[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to fill Policy entry. */
  10735     soc_mem_t               policy_mem;                 /* Policy table memory id.      */
  10736     int                     rv;                         /* Operation return status.     */
  10737     _regex_policy_action_t *pa = NULL;
  10738 
  10739     /* Input parameters check. */
  10740     if (NULL == p_ent) {
  10741         return (BCM_E_PARAM);
  10742     }
  10743 
  10744     policy_mem = FT_POLICYm;
  10745 
  10746     /* Start with an empty POLICY entry */
  10747     sal_memset(e, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
  10748     /* Extract the policy info from the entry structure. */
  10749     for (pa = p_ent->actions; ((pa != NULL) && (_REGEX_ACTION_VALID & pa->flags)); pa = pa->next) {
  10750         rv = _regex_tr3_policy_action_get(unit, policy_mem, p_ent,
  10751                                           pa, e);
  10752         BCM_IF_ERROR_RETURN(rv);
  10753     }
  10754 
  10755     /* Handle color dependence/independence */
  10756     if (soc_mem_field_valid(unit, policy_mem, GREEN_TO_PIDf)) {
  10757         soc_mem_field32_set(unit, policy_mem, e, GREEN_TO_PIDf,
  10758                             (p_ent->flags & _REGEX_POLICY_COLOR_INDEPENDENT) ? 1 : 0);
  10759     }
  10760 
  10761     /* Extract meter related policy fields */
  10762     rv = _regex_tr3_policer_action_set(unit, p_ent, e);
  10763     BCM_IF_ERROR_RETURN(rv);
  10764 
  10765 #ifdef ESW_REGEX_STAT_SUPPORT
  10766     /* Extract counter related policy fields */
  10767     rv = _bcm_field_tr3_stat_action_set(unit,
  10768                                         p_ent,
  10769                                         policy_mem,
  10770                                         tcam_idx,
  10771                                         e);
  10772     BCM_IF_ERROR_RETURN(rv);
  10773 #endif  /* ESW_REGEX_STAT_SUPPORT */
  10774 
  10775     /* Write the POLICY Table */
  10776     rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, p_ent->eid, e);
  10777     BCM_IF_ERROR_RETURN(rv);
  10778 
  10779     return BCM_E_NONE;
  10780 }
  10781 
  10782 /*
  10783  * Function:
  10784  *     _regex_tr3_policy_remove
  10785  * Purpose:
  10786  *     Remove a previously installed physical entry.
  10787  * Parameters:
  10788  *     unit   - BCM device number
  10789  *     p_ent  - Physical policy structure to be removed
  10790  * Returns:
  10791  *     BCM_E_XXX
  10792  *     BCM_E_NONE
  10793  * Notes:
  10794  *     Regex unit lock should be held by calling function.
  10795  */
  10796 STATIC int _regex_tr3_policy_remove(int unit, _regex_policy_t *p_ent)
  10797 {
  10798     soc_mem_t policy_mem = FT_POLICYm;  /* Policy table memory id.           */
  10799 
  10800     if (NULL == p_ent) {
  10801         return (BCM_E_PARAM);
  10802     }
  10803 
  10804     SOC_IF_ERROR_RETURN(soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, p_ent->eid,
  10805                                       soc_mem_entry_null(unit, policy_mem)));
  10806     p_ent->flags |= _REGEX_POLICY_DIRTY; /* Mark entry as not installed */
  10807 
  10808     return (BCM_E_NONE);
  10809 }
  10810 
  10811 /*
  10812  * Function:
  10813  *     _regex_tr3_policer_install
  10814  * Purpose:
  10815  *     Install a meter pair into the hardware tables.
  10816  * Parameters:
  10817  *     unit   - (IN) BCM device number.
  10818  *     f_ent  - (IN) Field entry.
  10819  *     f_pl   - (IN) Field policer descriptor.
  10820  * Returns:
  10821  *     BCM_E_XXX
  10822  */
  10823 STATIC int _regex_tr3_policer_install(int unit, _field_policer_t *f_pl)
  10824 {
  10825     uint32    bucketsize_peak = 0;      /* Bucket size.             */
  10826     uint32    refresh_rate_peak = 0;    /* Policer refresh rate.    */
  10827     uint32    granularity_peak = 0;     /* Policer granularity.     */
  10828     uint32    bucketsize_commit = 0;    /* Bucket size.             */
  10829     uint32    refresh_rate_commit = 0;  /* Policer refresh rate.    */
  10830     uint32    granularity_commit = 0;   /* Policer granularity.     */
  10831     int       refresh_bitsize;          /* Number of bits for the
  10832                                            refresh rate field.      */
  10833     int       bucket_max_bitsize;       /* Number of bits for the
  10834                                            bucket max field.        */
  10835     int       rv = BCM_E_NONE;          /* Operation return status. */
  10836     soc_mem_t meter_table;              /* Meter table name.        */
  10837     uint32    flags;                    /* Policer flags.           */
  10838 
  10839     /* Input parameters check. */
  10840     if (NULL == f_pl) {
  10841         return (BCM_E_PARAM);
  10842     }
  10843 
  10844     if (0 == (f_pl->hw_flags & _FP_POLICER_DIRTY)) {
  10845         return (BCM_E_NONE);
  10846     }
  10847 
  10848     /* Resolve meter table name. */
  10849     meter_table = FP_METER_TABLEm;
  10850 
  10851     refresh_bitsize = soc_mem_field_length(unit, meter_table, REFRESHCOUNTf);
  10852     bucket_max_bitsize = soc_mem_field_length(unit, meter_table, BUCKETSIZEf);
  10853 
  10854     /* lookup bucket size from tables */
  10855     flags = _BCM_XGS_METER_FLAG_GRANULARITY | _BCM_XGS_METER_FLAG_FP_POLICER;
  10856 
  10857     /* Set packet mode flags setting */
  10858     if (f_pl->cfg.flags & BCM_POLICER_MODE_PACKETS) {
  10859         flags |= _BCM_XGS_METER_FLAG_PACKET_MODE;
  10860     } else {
  10861         flags &= ~_BCM_XGS_METER_FLAG_PACKET_MODE;
  10862     }
  10863 
  10864     if (f_pl->cfg.mode  != bcmPolicerModeSrTcm) {
  10865         if (f_pl->hw_flags & _FP_POLICER_COMMITTED_DIRTY) {
  10866             /* Calculate policer bucket size/refresh_rate/granularity. */
  10867             rv = _bcm_xgs_kbits_to_bucket_encoding(f_pl->cfg.ckbits_sec,
  10868                                                    f_pl->cfg.ckbits_burst,
  10869                                                    flags, refresh_bitsize,
  10870                                                    bucket_max_bitsize,
  10871                                                    &refresh_rate_commit,
  10872                                                    &bucketsize_commit,
  10873                                                    &granularity_commit);
  10874             /* Program policer parameters into hw. */
  10875             rv =  _regex_tr3_policer_hw_update(unit, f_pl,
  10876                                                BCM_FIELD_METER_COMMITTED,
  10877                                                bucketsize_commit,
  10878                                                refresh_rate_commit,
  10879                                                granularity_commit, meter_table);
  10880 
  10881             f_pl->hw_flags &= ~_FP_POLICER_COMMITTED_DIRTY;
  10882         }
  10883 
  10884         if (f_pl->hw_flags & _FP_POLICER_PEAK_DIRTY) {
  10885 
  10886             if (_FP_POLICER_EXCESS_HW_METER(f_pl)) {
  10887                 /*
  10888                  * Rates are always set in committed variables,
  10889                  * for flow meters.
  10890                  */
  10891                 f_pl->cfg.pkbits_sec = f_pl->cfg.ckbits_sec;
  10892                 f_pl->cfg.pkbits_burst = f_pl->cfg.ckbits_burst;
  10893             }
  10894 
  10895             /* Calculate policer bucket size/refresh_rate/granularity. */
  10896             rv = _bcm_xgs_kbits_to_bucket_encoding(f_pl->cfg.pkbits_sec,
  10897                                                    f_pl->cfg.pkbits_burst,
  10898                                                    flags,
  10899                                                    refresh_bitsize,
  10900                                                    bucket_max_bitsize,
  10901                                                    &refresh_rate_peak,
  10902                                                    &bucketsize_peak,
  10903                                                    &granularity_peak);
  10904             /* Programm policer parameters into hw. */
  10905             rv =  _regex_tr3_policer_hw_update(unit, f_pl,
  10906                                                BCM_FIELD_METER_PEAK,
  10907                                                bucketsize_peak, refresh_rate_peak,
  10908                                                granularity_peak, meter_table);
  10909 
  10910             f_pl->hw_flags &= ~_FP_POLICER_PEAK_DIRTY;
  10911 
  10912             if (_FP_POLICER_EXCESS_HW_METER(f_pl)) {
  10913                 /* Reset peak meter rates. */
  10914                 f_pl->cfg.pkbits_sec = 0;
  10915                 f_pl->cfg.pkbits_burst = 0;
  10916             }
  10917         }
  10918     } else {
  10919         if (f_pl->hw_flags & _FP_POLICER_COMMITTED_DIRTY) {
  10920             /* Calculate policer bucket size/refresh_rate/granularity. */
  10921             rv = _bcm_xgs_kbits_to_bucket_encoding(f_pl->cfg.ckbits_sec,
  10922                                                    f_pl->cfg.ckbits_burst,
  10923                                                    flags, refresh_bitsize,
  10924                                                    bucket_max_bitsize,
  10925                                                    &refresh_rate_commit,
  10926                                                    &bucketsize_commit,
  10927                                                    &granularity_commit);
  10928             BCM_IF_ERROR_RETURN(rv);
  10929         }
  10930 
  10931         if (f_pl->hw_flags & _FP_POLICER_PEAK_DIRTY) {
  10932             /* Calculate policer bucket size/refresh_rate/granularity. */
  10933             rv = _bcm_xgs_kbits_to_bucket_encoding(f_pl->cfg.pkbits_sec,
  10934                                                    f_pl->cfg.pkbits_burst,
  10935                                                    flags,
  10936                                                    refresh_bitsize,
  10937                                                    bucket_max_bitsize,
  10938                                                    &refresh_rate_peak,
  10939                                                    &bucketsize_peak,
  10940                                                    &granularity_peak);
  10941             BCM_IF_ERROR_RETURN(rv);
  10942         }
  10943 
  10944         if (granularity_commit != granularity_peak) {
  10945             if (granularity_commit < granularity_peak) {
  10946                 rv = _bcm_xgs_kbits_to_dual_bucket_encoding(f_pl->cfg.ckbits_sec,
  10947                                                             f_pl->cfg.ckbits_burst,
  10948                                                             flags,
  10949                                                             refresh_bitsize,
  10950                                                             bucket_max_bitsize,
  10951                                                             granularity_peak,
  10952                                                             &refresh_rate_commit,
  10953                                                             &bucketsize_commit,
  10954                                                             &granularity_commit);
  10955             } else if (granularity_commit > granularity_peak) {
  10956                 rv = _bcm_xgs_kbits_to_dual_bucket_encoding(f_pl->cfg.pkbits_sec,
  10957                                                             f_pl->cfg.pkbits_burst,
  10958                                                             flags,
  10959                                                             refresh_bitsize,
  10960                                                             bucket_max_bitsize,
  10961                                                             granularity_commit,
  10962                                                             &refresh_rate_peak,
  10963                                                             &bucketsize_peak,
  10964                                                             &granularity_peak);
  10965             }
  10966             BCM_IF_ERROR_RETURN(rv);
  10967         }
  10968         /* Program policer parameters into hw. */
  10969         rv =  _regex_tr3_policer_hw_update(unit, f_pl,
  10970                                            BCM_FIELD_METER_COMMITTED,
  10971                                            bucketsize_commit,
  10972                                            refresh_rate_commit,
  10973                                            granularity_commit, meter_table);
  10974 
  10975         f_pl->hw_flags &= ~_FP_POLICER_COMMITTED_DIRTY;
  10976 
  10977         /* Program policer parameters into hw. */
  10978         rv =  _regex_tr3_policer_hw_update(unit, f_pl,
  10979                                            BCM_FIELD_METER_PEAK,
  10980                                            bucketsize_peak, refresh_rate_peak,
  10981                                            granularity_peak, meter_table);
  10982 
  10983         f_pl->hw_flags &= ~_FP_POLICER_PEAK_DIRTY;
  10984     }
  10985     return rv;
  10986 }
  10987 
  10988 #define TR3_REGEX_DUMP_DFA_MEM_OFFSET 1
  10989 
  10990 void _bcm_regex_dump_dfa(int unit, bcm_regex_engine_t engid)
  10991 {
  10992     _bcm_regex_lengine_t *lengine = NULL;
  10993     _bcm_regex_engine_obj_t *pengine = NULL;
  10994     axp_sm_state_table_mem0_entry_t *state_storage;
  10995     soc_mem_t   mem;
  10996     int     i, j, num_states, num_final;
  10997     uint8 fc, tc;
  10998     int match_index;
  10999     uint32 jump_offset, jump_offset_last;
  11000     int *jump_table, this_state, base, print_id;
  11001     int jump_table_size;
  11002 
  11003     if (_bcm_tr3_find_engine(unit, engid, &lengine) || 
  11004         ((pengine = lengine->physical_engine) == NULL)) {
  11005         return;
  11006     }
  11007 
  11008     if (pengine->from_line < 0) {
  11009         LOG_CLI((BSL_META_U(unit,
  11010                             "Invalid DFA state memory offset of allocated engine.\n")));
  11011         return;
  11012     }
  11013 
  11014     base = pengine->from_line*BCM_TR3_NUM_RV_PER_LINE;
  11015     jump_table_size = pengine->req_lsz * BCM_TR3_NUM_RV_PER_LINE;
  11016 
  11017     mem = _bcm_tr3_get_axp_sm_memory(unit, pengine->tile);
  11018     state_storage = sal_alloc(sizeof(axp_sm_state_table_mem0_entry_t) * pengine->req_lsz,
  11019                         "dfa_cpd");
  11020     if (NULL == state_storage) {
  11021         LOG_CLI((BSL_META_U(unit,
  11022                             "Unable to allocate memory storage.\n")));
  11023         return;
  11024     }
  11025 
  11026     _bcm_tr3_regex_read_hw_dfa(unit, pengine, state_storage);
  11027  
  11028     jump_table = sal_alloc(sizeof(jump_table[0]) * jump_table_size,
  11029                      "re_jump_table");
  11030     if (NULL == jump_table) {
  11031         LOG_CLI((BSL_META_U(unit,
  11032                             "Unable to allocate jump table storage.\n")));
  11033         return;
  11034     }
  11035 
  11036     for (i = 0; i < jump_table_size; i++) {
  11037         jump_table[i] = -1;
  11038     }
  11039 
  11040     /*
  11041      * Initialize the jump table.  The jump table will hold the state number of each
  11042      * destination of a jump.  This table is processed in two steps.  Step 1 is to mark
  11043      * all the locations that are targets of jumps.  Step 2 is to assign state numbers.
  11044      * This is done in two steps since it is possible that state numbers will be assigned
  11045      * out of order if a single pass is used.
  11046      */
  11047     /*
  11048      * First, mark all locations that are targets of jumps.
  11049      */
  11050     jump_offset_last = 0;
  11051     for (i = 0; i < pengine->req_lsz; i++) {
  11052         for (j = 0; j < BCM_TR3_NUM_RV_PER_LINE; j++) {
  11053             _bcm_tr3_regex_rv_get(unit, mem, &state_storage[i], &fc, &tc,
  11054                                   j, &jump_offset, &match_index);
  11055             if ((match_index < 0) && (jump_offset != 0xffff)) {
  11056                 if ((jump_offset - base) >= jump_table_size) {
  11057                     LOG_CLI((BSL_META_U(unit,
  11058                                         "Jump offset %d (0x%x) out of range.\n"),
  11059                              jump_offset, jump_offset));
  11060                 } else if (jump_table[jump_offset - base] == -1) {
  11061                     jump_table[jump_offset - base] = 0;
  11062                 }
  11063             }
  11064 
  11065             /*
  11066             Show all states, even if not jumped-to.  This code should
  11067             not be necessary, especially with the changes to remove
  11068             transitions from final states.  Also, when removing the
  11069             extra jump to 0xffff from every state that already has
  11070             transitions for every possible character, this code will
  11071             not work for states following non-final states anyway.
  11072             */
  11073             if (jump_offset_last == 0xffff) {
  11074                 if (jump_table[(i * BCM_TR3_NUM_RV_PER_LINE)+ j] == -1){
  11075                     if (jump_offset != 0xffff || match_index >= 0) {
  11076                         jump_table[(i * BCM_TR3_NUM_RV_PER_LINE)+ j] = 0;
  11077                     }
  11078                 }
  11079             }
  11080 
  11081             jump_offset_last = jump_offset;
  11082         }
  11083     }
  11084 
  11085     /* Now assign state numbers. */
  11086     /* Always begin the DFA with state 0. */
  11087     jump_table[0] = 0;
  11088     num_states = 1;
  11089     for (i = 1; i < jump_table_size; i++) {
  11090         if (-1 != jump_table[i]) {
  11091             jump_table[i] = num_states;
  11092             num_states++;
  11093         }
  11094     }
  11095 
  11096     LOG_CLI((BSL_META_U(unit,
  11097                         "\n------------------DFA-(Tile:%d)---------------\n\n"),
  11098              pengine->tile));
  11099     LOG_CLI((BSL_META_U(unit,
  11100                         "Number of lines = %d\nNumber of states = %d\n"),
  11101              pengine->req_lsz, num_states));
  11102     this_state = 0;
  11103     print_id = 0;
  11104     num_final = 0;
  11105     for (i = 0; i < pengine->req_lsz; i++) {
  11106         for (j=0; j<BCM_TR3_NUM_RV_PER_LINE; j++) {
  11107             /*
  11108              * If this location is the target of a jump, set the flag to print the state number.
  11109              */
  11110             if (jump_table[(i * BCM_TR3_NUM_RV_PER_LINE) + j] != -1) {
  11111                 this_state = jump_table[(i * BCM_TR3_NUM_RV_PER_LINE) + j];
  11112                 print_id = 1;
  11113             }
  11114             
  11115             _bcm_tr3_regex_rv_get(unit, mem, &state_storage[i], &fc, &tc,
  11116                                   j, &jump_offset, &match_index);
  11117 
  11118             if (print_id) {
  11119 #if TR3_REGEX_DUMP_DFA_MEM_OFFSET==0
  11120                 LOG_CLI((BSL_META_U(unit,
  11121                                     "\nState %d %s\n"),
  11122                          (match_index >= 0) ? this_state, "[FINAL]" : ""));
  11123 #else
  11124                 LOG_CLI((BSL_META_U(unit,
  11125                                     "\nState %d %s @line=%d, line offset=%d "
  11126                                     "full offset (0x%x)\n"),
  11127                          this_state, (match_index >= 0) ? "[FINAL]" : "",
  11128                          pengine->from_line + i, j,
  11129                          (pengine->from_line + i) *
  11130                          BCM_TR3_NUM_RV_PER_LINE + j));
  11131 #endif
  11132                 if (match_index >= 0) {
  11133                     num_final++;
  11134                     LOG_CLI((BSL_META_U(unit,
  11135                                         "\tMatch ID = %d, %s\n"),
  11136                              match_index,
  11137                              ((tc == 2) ? "IDLE STOP" :
  11138                              ((tc == 1) ? "IDLE CONT" : ""))));
  11139                 }
  11140                 print_id = 0;
  11141             }
  11142             if (jump_offset != 0xffff) {
  11143                 LOG_CLI((BSL_META_U(unit,
  11144                                     "\t %4d -> %4d : "),
  11145                          this_state, jump_table[jump_offset - base]));
  11146                 if ((tc == 0) && (fc == 255)) {
  11147                     LOG_CLI((BSL_META_U(unit,
  11148                                         "[\\%-3d-\\%-3d], "), fc, tc));
  11149                     LOG_CLI((BSL_META_U(unit,
  11150                                         "Same data offset;\n")));
  11151                 } else {
  11152                     LOG_CLI((BSL_META_U(unit,
  11153                                         "[\\%-3d-\\%-3d]"), fc, tc));
  11154                     if (is_printable(fc) && is_printable(tc)) {
  11155                         LOG_CLI((BSL_META_U(unit,
  11156                                             " (%2c-%-2c)"), fc, tc));
  11157                     } else if (is_printable(fc)) {
  11158                         LOG_CLI((BSL_META_U(unit,
  11159                                             " (%2c-'')"), fc));
  11160                     } else if (is_printable(tc)) {
  11161                         LOG_CLI((BSL_META_U(unit,
  11162                                             " (''-%-2c)"), tc));
  11163                     }
  11164 
  11165                     LOG_CLI((BSL_META_U(unit,
  11166                                         ";\n")));
  11167             }
  11168             } else {
  11169                 LOG_CLI((BSL_META_U(unit,
  11170                                     "\t %4d -> 0xffff (IDLE) : "), this_state));
  11171                 LOG_CLI((BSL_META_U(unit,
  11172                                     "[\\%-3d-\\%-3d]"), fc, tc));
  11173                 if ((fc == 255) && ((tc == 1) || (tc == 2))) {
  11174                     LOG_CLI((BSL_META_U(unit,
  11175                                         " Match Id %d"), match_index));
  11176                 }
  11177                 LOG_CLI((BSL_META_U(unit,
  11178                                     ";\n")));
  11179             }
  11180         }
  11181     }
  11182     LOG_CLI((BSL_META_U(unit,
  11183                         "\n--------------Number of final states %d-----------\n\n"),
  11184              num_final));
  11185     sal_free(state_storage);
  11186     sal_free(jump_table);
  11187     return; 
  11188 }
  11189 
  11190 void _bcm_regex_sw_dump_engine(int unit, bcm_regex_engine_t engid,
  11191                                 uint32 flags)
  11192 {
  11193     _bcm_regex_lengine_t *lengine = NULL;
  11194     _bcm_regex_engine_obj_t *pengine = NULL;
  11195 
  11196     if (_bcm_tr3_find_engine(unit, engid, &lengine) || 
  11197         ((pengine = lengine->physical_engine) == NULL)) {
  11198         return;
  11199     }
  11200 
  11201     /* dump engine info */
  11202     LOG_CLI((BSL_META_U(unit,
  11203                         "Regex Tile %d, Engine %d : "
  11204                         "Start offset:%04d Size (lines):%04d/%04d\n"),
  11205              pengine->tile, pengine->hw_idx,
  11206              pengine->from_line, pengine->req_lsz, pengine->total_lsz));
  11207     LOG_CLI((BSL_META_U(unit,
  11208                         "          CPS   :%s\n"), 
  11209              BCM_REGEX_CPS_ALLOCED(&pengine->cps) ? "Yes" : "No"));
  11210     if (BCM_REGEX_CPS_ALLOCED(&pengine->cps)) {
  11211         LOG_CLI((BSL_META_U(unit,
  11212                             " From line  : %04d Size (lines):%04d\n"),
  11213                  pengine->cps.from_line, pengine->cps.req_lsz));
  11214     }
  11215     if (flags) {
  11216         _bcm_regex_dump_dfa(unit, engid);
  11217     }
  11218 }
  11219 
  11220 void _bcm_regex_sw_load_engine(int unit, bcm_regex_engine_t engid,
  11221                                 uint32 flags, int *eng_hwidx)
  11222 {
  11223     _bcm_regex_lengine_t *lengine = NULL;
  11224     _bcm_regex_engine_obj_t *pengine = NULL;
  11225 
  11226     if (engid == BCM_REGEX_ENGINE_ALL) {
  11227         return;
  11228     }
  11229 
  11230     if (_bcm_tr3_find_engine(unit, engid, &lengine) ||
  11231         ((pengine = lengine->physical_engine) == NULL)) {
  11232         return;
  11233     }
  11234 
  11235     if (eng_hwidx) {
  11236         *eng_hwidx = pengine->hw_idx;
  11237     }
  11238 }
  11239 
  11240 void _bcm_regex_sw_engine_hwid(int unit, bcm_regex_engine_t engid,
  11241                                 int *enghwid)
  11242 {
  11243     _bcm_regex_lengine_t *lengine = NULL;
  11244     _bcm_regex_engine_obj_t *pengine = NULL;
  11245 
  11246     if (_bcm_tr3_find_engine(unit, engid, &lengine) ||
  11247         ((pengine = lengine->physical_engine) == NULL)) {
  11248         return;
  11249     }
  11250 
  11251     if (enghwid != NULL) {
  11252         *enghwid = pengine->hw_idx;
  11253     }
  11254 }
  11255 
  11256 void _bcm_regex_sw_dump(int unit)
  11257 {
  11258     _bcm_tr3_regex_device_info_t *device;
  11259     int i, j, nept, count;
  11260     _bcm_regex_engine_obj_t *pengine = NULL;
  11261     _bcm_regex_lengine_t *tmp;
  11262     
  11263     device = REGEX_INFO(unit);
  11264 
  11265     nept = BCM_TR3_ENGINE_PER_TILE(device);
  11266 
  11267     for (count = 0, i=0; i<device->info->num_tiles; i++, count = 0) {
  11268         for (j=0; j<nept; j++) {
  11269             pengine = BCM_TR3_PHYSICAL_ENGINE(device, (i*nept) + j);
  11270             if (!BCM_REGEX_ENGINE_ALLOCATED(pengine)) {
  11271                 continue;
  11272             }
  11273             count++;
  11274         }
  11275         if (count == 0) {
  11276             continue;
  11277         }
  11278         LOG_CLI((BSL_META_U(unit,
  11279                             "Tile %02d: %0d Engines in use.\n"), i, count));
  11280     }
  11281 
  11282     for (i = 0; i < BCM_TR3_NUM_ENGINE(device); i++) {
  11283         tmp = BCM_TR3_LOGICAL_ENGINE(device, i);
  11284         if (!BCM_REGEX_ENGINE_ALLOCATED(tmp)) {
  11285             continue;
  11286         }
  11287         _bcm_regex_sw_dump_engine(unit, tmp->id, 0);
  11288     }
  11289 }
  11290 
  11291 #endif /* INCLUDE_REGEX */
  11292 
  11293 #endif  /* BCM_TRIUMPH3_SUPPORT */