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

alpm_internal.h (62931B)


      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-2020 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        alpm.h
      8  * Purpose:     Function declarations for ALPM Internal functions.
      9  */
     10 
     11 #ifndef _BCM_INT_ALPM_INTERNAL_H_
     12 #define _BCM_INT_ALPM_INTERNAL_H_
     13 
     14 #ifdef ALPM_ENABLE
     15 
     16 /* ALPM */
     17 #ifdef ALPMSIM
     18 
     19 #include <bcm_int/esw/alpm_stub.h>
     20 
     21 #else
     22 
     23 #include <soc/drv.h>
     24 #include <soc/format.h>
     25 #include <bcm/l3.h>
     26 #include <bcm_int/esw/l3.h>
     27 #include <bcm_int/esw/firebolt.h>
     28 #include <bcm_int/esw/trident3.h>
     29 #include <bcm_int/esw/lpmv6.h>
     30 
     31 #if defined(BCM_TOMAHAWK3_SUPPORT)
     32 #include <soc/soc_mem_bulk.h>
     33 extern int soc_th3_get_alpm_banks(int unit);
     34 #endif /* BCM_TOMAHAWK3_SUPPORT */
     35 #if defined(BCM_TOMAHAWK_SUPPORT)
     36 #include <soc/trident3.h>
     37 #endif /* BCM_TOMAHAWK_SUPPORT */
     38 
     39 #endif /* !ALPMSIM */
     40 
     41 
     42 #if defined(BCM_TOMAHAWK3_SUPPORT)
     43 #include <bcm_int/esw/alpm_th3_acc.h>
     44 #endif /* BCM_TOMAHAWK3_SUPPORT */
     45 #include <bcm_int/esw/alpm_lib_trie.h>
     46 #include <bcm_int/esw/alpm.h>
     47 
     48 #define ALPM_DEBUG          0
     49 
     50 /* #define PSEUDO_ALPM_FMT13 1 */
     51 #define ALPM_FMT_TP_CNT     14
     52 
     53 /* max bank per bucket */
     54 #if defined(BCM_TRIDENT3_SUPPORT)
     55 #define ALPM_BPB_MAX        16
     56 #else
     57 #define ALPM_BPB_MAX        8
     58 #endif
     59 #define ALPM_CB_CNT         2
     60 #define ALPM_ENT_WORDS_MAX  15  /* 480 bits */
     61 
     62 /* Maximum TCAM/ALPM memory entry size in words (640 bits) */
     63 #define ALPM_MEM_ENT_MAX    20
     64 
     65 /* max prefix per bucket */
     66 #define ALPM_PPB_MAX        (BCM_ESW_ALPM_EPB_MAX * ALPM_BPB_MAX)
     67 
     68 #define ALPM_PPG_INSERT     0
     69 #define ALPM_PPG_DELETE     1
     70 #define ALPM_PPG_HBP        3
     71 
     72 #define ALPM_MERGE_THRESHOLD_MAX      10
     73 
     74 /* ALPM Packing Mode definitions */
     75 #define ALPM_PKM_32B        (0)
     76 #define ALPM_PKM_64B        (1)
     77 #define ALPM_PKM_128        (2)
     78 #define ALPM_PKM_CNT        (3)
     79 /* IP database type V4 V6 */
     80 #define ALPM_IPT_V4         (0)
     81 #define ALPM_IPT_V6         (1)
     82 #define ALPM_IPT_CNT        (2)
     83 
     84 #define ALPM_PKM2IPT(pkm)   (!!(pkm))
     85 
     86 #define ALPM_BKT_PRT_PID    0
     87 #define ALPM_BKT_GLB_PID    1
     88 #define ALPM_BKT_PID_CNT    2
     89 #define ALPM_BKT_PID_ACL_CNT 1
     90 
     91 #define ALPM_DEFRAG_OK            0
     92 #define ALPM_DEFRAG_END_NO_MERGE  1
     93 #define ALPM_DEFRAG_DELETE_MIN  100
     94 
     95 /* ALPM Distributed Hitbits */
     96 #define ALPM_HIT_INTERVAL_DEF 1000000   /* 1s */
     97 #define ALPM_HIT_INTERVAL_MIN 100000    /* 100ms  */
     98 #define ALPM_HIT_INTERVAL_MAX 60000000  /* 1 min  */
     99 #define ALPM_HIT_PRIORITY_DEF 200       /* Dist hitbit thread task priority */
    100 #define ALPM_MAX_HIT_ENT_MASK 0xffff    /* max 16 bits of HIT table entry */
    101 
    102 /* ALPM mode */
    103 #define BCM_ALPM_MODE_INVALID       -1
    104 #define BCM_ALPM_MODE_COMBINED      0
    105 #define BCM_ALPM_MODE_PARALLEL      1
    106 #define BCM_ALPM_MODE_TCAM_ALPM     2
    107 
    108 /* SOC_ALPM_DEBUG_SHOW_FLAG_BKT */
    109 /* for ALPM debug show */
    110 #define BCM_ALPM_DEBUG_SHOW_FLAG_PVT    (1U << 0)
    111 #define BCM_ALPM_DEBUG_SHOW_FLAG_BKT    (1U << 1)
    112 #define BCM_ALPM_DEBUG_SHOW_FLAG_BKTUSG (1U << 2)
    113 #define BCM_ALPM_DEBUG_SHOW_FLAG_CNT    (1U << 3)
    114 #define BCM_ALPM_DEBUG_SHOW_FLAG_INTDBG (1U << 4)
    115 #define BCM_ALPM_DEBUG_SHOW_TRIE_TREE   (1U << 5)
    116 #define BCM_ALPM_DEBUG_SHOW_FLAG_ALL    (~0U)
    117 
    118 #if defined (BCM_TRIDENT3_SUPPORT)
    119 #define ALPM_SEPARATE_IPV4MC_KEY_TYPE   BCMI_LPM_SEPARATE_IPV4MC_KEY_TYPE
    120 #define ALPM_SEPARATE_IPV6MC_KEY_TYPE   BCMI_LPM_SEPARATE_IPV6MC_KEY_TYPE
    121 #else
    122 #define ALPM_SEPARATE_IPV4MC_KEY_TYPE   -1
    123 #define ALPM_SEPARATE_IPV6MC_KEY_TYPE   -1
    124 #endif
    125 #define ALPM_IS_SEPARATE_IPV6MC_KEY_TYPE(_u, _kt)                \
    126     (soc_feature(_u, soc_feature_separate_key_for_ipmc_route) && \
    127     ((_kt) == ALPM_SEPARATE_IPV6MC_KEY_TYPE))
    128 #define ALPM_IS_SEPARATE_IPV4MC_KEY_TYPE(_u, _kt)                \
    129     (soc_feature(_u, soc_feature_separate_key_for_ipmc_route) && \
    130     ((_kt) == ALPM_SEPARATE_IPV4MC_KEY_TYPE))
    131 
    132 /* Hit table control for bucket levels
    133    (TCAM level hitbit access uses direct soc_mem cache/hw interface) */
    134 typedef struct _alpm_hit_tbl_ctrl_s {
    135     soc_mem_t mem;          /* Hit table mem */
    136     int     index_cnt;      /* Hit table index count */
    137     int     size;           /* Hit Table size (in bytes) */
    138     int     ent_moved;      /* Entry moved (TRUE or FALSE) */
    139     int     ent_moved_cnt;  /* Entry moved counter */
    140 
    141     void    *cache;         /* Hit cache table */
    142     void    *move;          /* Hit move table */
    143     void    *move_mask;     /* Hit move mask table */
    144 } _alpm_hit_tbl_ctrl_t;
    145 
    146 /* ALPM distributed hitbit control structure */
    147 typedef struct _alpm_dist_hitbit_s {
    148     /* Hit tbl ctrl for Level2 & Level3 per PID */
    149     _alpm_hit_tbl_ctrl_t *hit_tbl[ALPM_CB_CNT][ALPM_BKT_PID_CNT];
    150     char              taskname[16];       /* Dist hitbit thread name */
    151     VOL sal_thread_t  thread;             /* Dist hitbit thread id */
    152     VOL int           interval;           /* Time between dist hitbit thread (us) */
    153     int               priority;           /* task priority */
    154     sal_sem_t         sema;               /* Dist hitbit semaphore */
    155 } _alpm_dist_hitbit_t;
    156 
    157 extern _alpm_dist_hitbit_t *alpm_dist_hitbit[];
    158 
    159 /* threshold in number of HITBIT entries moved (>= threshold use DMA_write) */
    160 #define ALPM_HIT_DMA_THRESHOLD          500
    161 
    162 #define ALPMDH(u)                       (alpm_dist_hitbit[u])
    163 #define ALPM_HTBL(u, i, p)              (ALPMDH(u)->hit_tbl[i][p])
    164 #define ALPM_HTBL_MEM(u, i, p)          (ALPM_HTBL(u, i, p)->mem)
    165 #define ALPM_HTBL_IDX_CNT(u, i, p)      (ALPM_HTBL(u, i, p)->index_cnt)
    166 #define ALPM_HTBL_SIZE(u, i, p)         (ALPM_HTBL(u, i, p)->size)
    167 #define ALPM_HTBL_CACHE(u, i, p)        (ALPM_HTBL(u, i, p)->cache)
    168 #define ALPM_HTBL_MOVE(u, i, p)         (ALPM_HTBL(u, i, p)->move)
    169 #define ALPM_HTBL_MOVE_MASK(u, i, p)    (ALPM_HTBL(u, i, p)->move_mask)
    170 #define ALPM_HTBL_ENT_MOVED(u, i, p)    (ALPM_HTBL(u, i, p)->ent_moved)
    171 #define ALPM_HTBL_ENT_MOVED_CNT(u, i, p) (ALPM_HTBL(u, i, p)->ent_moved_cnt)
    172 
    173 #define ALPM_HIT_LOCK(u)          L3_LOCK(u)
    174 #define ALPM_HIT_UNLOCK(u)        L3_UNLOCK(u)
    175 
    176 #define APP0             0 /* forwarding */
    177 #define ALPM_APP1        1 /* ACL DST */
    178 #define ALPM_APP2        2 /* ACL SRC */
    179 #define ALPM_APPS        3
    180 /* ALPM control block */
    181 
    182 /* Propagation data structure */
    183 typedef struct _alpm_ppg_data_s {
    184     uint32 ipt;
    185     uint32 key_len;
    186     uint32 bpm_len;
    187     uint32 vrf_id;
    188     uint32 key[5];
    189     void   *bkt_def;
    190     int app;
    191 } _alpm_ppg_data_t;
    192 
    193 /* Defines Logical ALPM table ID */
    194 typedef enum _alpm_tbl_e {
    195     alpmTblInvalid = 0,
    196     alpmTblPvtCmodeL1,
    197     alpmTblPvtPmodeL1,
    198     alpmTblPvtCmodeL1P128,
    199     alpmTblPvtPmodeL1P128,
    200     alpmTblBktCmodeL2,
    201     alpmTblBktPmodeL2,
    202     alpmTblBktPmodeGlbL2,
    203     alpmTblBktPmodePrtL2,
    204     alpmTblBktCmodeL3,
    205     alpmTblBktPmodeGlbL3,
    206     alpmTblBktPmodePrtL3,
    207     alpmTblCount
    208 } _alpm_tbl_t;
    209 
    210 typedef struct _alpm_fmt_info_s {
    211     int16       fmt_type;   /* ALPM_FMT_PVT/RTE */
    212     int16       fmt_count;
    213     int16       fmt_ent_max[ALPM_FMT_TP_CNT];
    214     int16       fmt_pfx_len[ALPM_FMT_TP_CNT];
    215     int         fmt_bnk[ALPM_FMT_TP_CNT];
    216     int         fmt_ent[ALPM_FMT_TP_CNT];
    217     int         fmt_ftype[ALPM_FMT_TP_CNT];
    218 } _alpm_fmt_info_t;
    219 
    220 typedef struct _alpm_bnk_info_s {
    221     /* Support max to 131072 (4096 * 32) banks */
    222     SHR_BITDCL      bnk_btmp[4096];
    223     int             bnk_rsvd;
    224     int             bnk_used;
    225     int             bkt_used[ALPM_IPT_CNT]; /* for TD3 IPv4 & IPv6 bucket share */
    226 } _alpm_bnk_info_t;
    227 
    228 typedef struct _alpm_bkt_pool_conf_s {
    229     _alpm_bnk_info_t *bnk_info[ALPM_IPT_CNT];
    230     int             bnk_total;
    231     int             bnk_per_bkt;
    232 
    233     /* Indicating the logical bucket table */
    234     _alpm_tbl_t     bkt_tbl;
    235     int             bkt_wra;
    236     int             bkt_fixed_fmt;
    237     /* Table entry array to store pivot pointer */
    238     void            **pvt_ptr;
    239 
    240     /* Bank fmt configuration */
    241     _alpm_fmt_info_t *fmt_info;
    242 } _alpm_bkt_pool_conf_t;
    243 
    244 typedef struct _alpm_bnk_conf_s {
    245     /* Bank pool config:
    246      * We have 2 bank pool pointer,
    247      * They can point to the same logical pool (Combined Mode)
    248      * or point to the different pools (Parallel & Mixed Mode)
    249      *
    250      * Private routes use pool 0.
    251      * Global routes use pool 1.
    252      */
    253     _alpm_bkt_pool_conf_t *bkt_pool[ALPM_BKT_PID_CNT];
    254 
    255     /* Bucket config */
    256     int16 bkt_bits;
    257     int16 bkt_dw;
    258     int16 phy_bnks_per_bkt;
    259     int16 bnk_bits;
    260 } _alpm_bnk_conf_t;
    261 
    262 typedef struct _alpm_bkt_info_s {
    263     uint8  bnk_fmt[ALPM_BPB_MAX];
    264     uint32 vet_bmp[ALPM_BPB_MAX];
    265     uint16 sub_bkt_idx;
    266     uint16 bkt_idx;
    267     uint8  rofs; /* ROFS */
    268     uint8  reverse;
    269 } _alpm_bkt_info_t;
    270 
    271 typedef struct _alpm_bkt_adata_s {
    272     uint32  defip_flags;
    273     int     defip_ecmp_index;
    274     int     defip_prio;
    275     int     defip_lookup_class;
    276     int     defip_flex_ctr_pool;
    277     int     defip_flex_ctr_mode;
    278     int     defip_flex_ctr_base_id;
    279     int     defip_acl_class_id;
    280     int     defip_acl_class_id_valid;
    281 } _alpm_bkt_adata_t;
    282 
    283 /* Used for bucket trie node */
    284 typedef struct _alpm_bkt_node_s {
    285     alpm_lib_trie_node_t node; /* trie node */
    286     struct _alpm_bkt_node_s *bkt_ptr;   /* pfx_node -> bkt_node */
    287     struct _alpm_bkt_adata_s adata;
    288     uint32 key[5];
    289     uint32 key_len;
    290     /* ent_idx format: ent | bnk | bkt @ALPM_IDX_MAKE */
    291     uint32 ent_idx;             /* HW memory loc */
    292 } _alpm_bkt_node_t;
    293 
    294 /* Used for prefix trie node, same as _alpm_bkt_node_t */
    295 typedef struct _alpm_bkt_node_s _alpm_pfx_node_t;
    296 
    297 typedef struct _alpm_bkt_pfx_arr_s {
    298     _alpm_bkt_node_t *pfx[ALPM_PPB_MAX];
    299     int pfx_cnt;
    300 } _alpm_bkt_pfx_arr_t;
    301 
    302 typedef struct _alpm_bnk_idx_arr_s {
    303     int idx[ALPM_BPB_MAX];
    304     int idx_cnt;
    305 } _alpm_bnk_idx_arr_t;
    306 
    307 typedef struct _alpm_bkt_split_cb_data_s {
    308     struct _alpm_cb_s *acb;
    309     int pvt_len;
    310     int bkt_cur_cnt;
    311     int bkt_max_cnt;
    312 } _alpm_bkt_split_cb_data_t;
    313 
    314 typedef struct _alpm_tcam_write_s {
    315     int rv;
    316     int hw_idx; /* -1 means invalid or already updated */
    317     uint32 ent[SOC_MAX_MEM_FIELD_WORDS];
    318 } _alpm_tcam_write_t;
    319 
    320 /* Pivot Structure */
    321 typedef struct _alpm_pvt_node_s {
    322     alpm_lib_trie_node_t node;           /* trie node */
    323     alpm_lib_trie_t *bkt_trie;           /* Link to bucket trie -> _alpm_bkt_node_t */
    324 
    325     uint32 vrf_id;
    326     uint32 bkt_pkm;             /* V4, V6 */
    327     uint32 key[5];              /* pivot */
    328     uint32 key_len;             /* pivot length, aka kshift */
    329     uint32 bpm_len;             /* pivot bpm_len */
    330     uint32 has_def;             /* has default route */
    331 
    332     uint32 tcam_idx;            /* TCAM index in 1st level */
    333     uint32 pvt_flags;
    334 
    335     struct _alpm_bkt_node_s *def_pfx; /* Link to bkt_node for bkt def route */
    336     struct _alpm_bkt_info_s bkt_info;    /* Bucket info */
    337 } _alpm_pvt_node_t;
    338 
    339 typedef struct _alpm_pvt_ctrl_s {
    340     alpm_lib_trie_t *pvt_trie;           /* -> _alpm_pvt_node_t */
    341     uint32 route_cnt;
    342     uint32 pvt_len_cnt[128];
    343     /* spl_len only valid for acb 1 */
    344     uint32 spl_len_diff1;
    345     uint32 spl_len_diff2;
    346 
    347     /* Debug counter */
    348     uint32 cnt_add;
    349     uint32 cnt_del;
    350 
    351     uint8 dr_inited; /* to indicate direct route inited first */
    352     uint8 db_inited;
    353     /* database type: FULL | REDUCED
    354      * FULL : supports Destination AND
    355      *        flex counter, pri, rpe, dst_discard, class_id
    356      * REDUCED : only supports Destination
    357      */
    358     uint8 db_type;
    359 } _alpm_pvt_ctrl_t;
    360 
    361 typedef struct _alpm_cb_stat_s {
    362     uint32      c_mem[alpmTblCount][2]; /* RD 0, WR 1 */
    363     uint32      c_bulk_mem[alpmTblCount][2]; /* RD 0, WR 1 */
    364 
    365     uint32      c_defrag;
    366     uint32      c_merge;
    367     uint32      c_expand;
    368     uint32      c_split;
    369     uint32      c_ripple;
    370     uint32      c_bnkshrk;
    371     uint32      c_bnkfree;
    372     uint32      c_full;
    373     uint32      c_defragonfull;     /* defrag on full count */
    374     uint32      c_fullafterdefrag;  /* Final API insert Full count after defrag */
    375 
    376     /* Split misplaced case counter */
    377     uint32      c_spl_mp_cs1;
    378     uint32      c_spl_mp_cs21;
    379     uint32      c_spl_mp_cs221;
    380     uint32      c_spl_mp_cs222;
    381 } _alpm_cb_stat_t;
    382 
    383 #define ALPM_FMT_PVT        (0)
    384 #define ALPM_FMT_RTE        (1)
    385 #define ALPM_FMT_CNT        (2)
    386 
    387 typedef struct _alpm_cb_s {
    388     int         app;
    389     int         unit;
    390     _alpm_pvt_ctrl_t *pvt_ctl[ALPM_IPT_CNT];
    391     _alpm_tbl_t pvt_tbl[ALPM_PKM_CNT];
    392 
    393     struct _alpm_bnk_conf_s bnk_conf;
    394     uint32      acb_idx;    /* Current Control Block index */
    395 
    396     struct _alpm_cb_stat_s acb_cnt;
    397 } _alpm_cb_t;
    398 
    399 typedef struct _alpm_pfx_ctrl_s {
    400     alpm_lib_trie_t *pfx_trie[ALPM_IPT_CNT][ALPM_APPS];
    401 } _alpm_pfx_ctrl_t;
    402 
    403 typedef struct _alpm_ctrl_s {
    404     _alpm_pfx_ctrl_t *_vrf_pfx_hdl;
    405     _alpm_cb_t *alpm_cb[ALPM_CB_CNT][ALPM_APPS];   /* ALPM Control Block */
    406 #define _ALPM_MERGE_CHANGE      0
    407 #define _ALPM_MERGE_UNCHANGE    1
    408     /* UNCHANGE -> CHANGE: split/delete
    409      * CHANGE -> UNCHANGE: unsuccessful merge
    410      */
    411     int *_alpm_merge_state;             /* Per VRF merge state */
    412     int _alpm_cb_cnt;                   /* Numbers of ALPM Control Block */
    413     int _alpm_btm_cb_idx[ALPM_BKT_PID_CNT];
    414     int _alpm_no_hit_bit;
    415     int _alpm_tcam_hb_is_ptr;
    416     int _alpm_mode;
    417     int _alpm_tcam_zoned[ALPM_APPS];
    418     int _alpm_half_banks;
    419     int _alpm_128b;
    420     int _alpm_128b_paired_blk_cnt;
    421     int _alpm_128b_bkt_rsvd;
    422     int _alpm_128b_bkt_rsvd_cnt;
    423     int _alpm_inited;
    424     int _alpm_bulk_wr_threshold;
    425     int _alpm_bnk_threshold;
    426     int _alpm_bkt_share_bnk_usage_thres;
    427     int _alpm_max_vrf_id;
    428     int _alpm_spl[ALPM_PKM_CNT];
    429     int _alpm_tcam_tbl_skip[ALPM_PKM_CNT];
    430     int _alpm_data_autosave;
    431     int _alpm_defrag_on_full;
    432     int _alpm_defrag_max_time;
    433     int _alpm_defrag_max_l2cnt;
    434     int _alpm_defrag_max_l3cnt;
    435     int _alpm_defrag_status;
    436     int _alpm_acl_en;
    437 
    438     /* properties for debug purpose */
    439 #define _ALPM_DBG_PVT_SANITY        (1 << 0)    /* 0x1   */
    440 #define _ALPM_DBG_PVT_SANITY_LEN    (1 << 1)    /* 0x2   */
    441 #define _ALPM_DBG_PVT_DEFRAG        (1 << 2)    /* 0x4   */
    442 #define _ALPM_DBG_PVT_SANITY_NODE   (1 << 3)    /* 0x8   */
    443 #define _ALPM_DBG_PVT_SANITY_COUNT  (1 << 4)    /* 0x10  */
    444 #define _ALPM_DBG_WRITE_CACHE_ONLY  (1 << 5)    /* 0x20  */
    445 #define _ALPM_DBG_BNK_CONF          (1 << 6)    /* 0x40  */
    446 #define _ALPM_DBG_PVT_UPDATE_SKIP   (1 << 7)    /* 0x80  */
    447 #define _ALPM_DBG_HITBIT            (1 << 8)    /* 0x100 */
    448 #define _ALPM_DBG_PVT_PTR_CHK       (1 << 9)    /* 0x200 */
    449 #define _ALPM_DBG_PVT_BKT_BNK_CONT  (1 << 10)   /* 0x400 */
    450 #define _ALPM_DBG_PVT_NODE_BKT      (1 << 11)   /* 0x800 */
    451 #define _ALPM_DBG_BNK_CONF_NULL_PVT (1 << 12)   /* 0x1000*/
    452 
    453     uint32 _alpm_dbg_bmp;
    454 
    455     /* properties for debug info purpose */
    456     uint32 _alpm_dbg_info_bmp;
    457 
    458 #define _ALPM_ERR_MSG_BUF_CNT       128
    459 #define _ALPM_ERR_MSG_BUF_ENT_SZ    160
    460     char *_alpm_err_msg_buf;
    461 
    462     uint32 _alpm_schan_fifo_handle;
    463 
    464     struct alpm_functions_s *alpm_driver;
    465 
    466 } _alpm_ctrl_t;
    467 
    468 #define _ALPM_ERR_MSG_ENT(u, idx)  (ALPMC(u)->_alpm_err_msg_buf+1+((idx)*_ALPM_ERR_MSG_BUF_ENT_SZ))
    469 /* First char stores the current index */
    470 #define _ALPM_ERR_MSG_CUR_IDX(u) ((ALPMC(u)->_alpm_err_msg_buf[0]))
    471 #define _ALPM_ERR_MSG_INSERT(u, msg) \
    472     do { \
    473         uint8 cur_idx = _ALPM_ERR_MSG_CUR_IDX(u);\
    474         if (cur_idx < _ALPM_ERR_MSG_BUF_CNT - 1) { \
    475             sal_memcpy(_ALPM_ERR_MSG_ENT(u, cur_idx), msg, _ALPM_ERR_MSG_BUF_ENT_SZ); \
    476             _ALPM_ERR_MSG_CUR_IDX(u) = cur_idx + 1; \
    477         } \
    478     } while(0)
    479 
    480 extern _alpm_ctrl_t *alpm_control[SOC_MAX_NUM_DEVICES];
    481 
    482 /* bcm_esw_alpm_pvt_trav_cb */
    483 typedef int (*bcm_esw_alpm_pvt_trav_cb) (
    484     int                 u,
    485     _alpm_cb_t          *acb,
    486     _alpm_pvt_node_t    *pvt_node,
    487     void                *user_data);
    488 
    489 typedef struct _alpm_pvt_trav_s {
    490     _alpm_cb_t                  *acb;
    491     bcm_esw_alpm_pvt_trav_cb    user_cb;
    492     void                        *user_data;
    493 } _alpm_pvt_trav_t;
    494 
    495 /* bcm_esw_alpm_pfx_trav_cb */
    496 typedef int (*bcm_esw_alpm_pfx_trav_cb)(
    497     _alpm_pfx_node_t *pfx_node,
    498     void *user_data);
    499 
    500 typedef struct _alpm_pfx_trav_s {
    501     bcm_esw_alpm_pfx_trav_cb    user_cb;
    502     void                        *user_data;
    503 } _alpm_pfx_trav_t;
    504 
    505 /* bcm_esw_alpm_bkt_trav_cb */
    506 typedef int (*bcm_esw_alpm_bkt_trav_cb)(
    507     _alpm_bkt_node_t *bkt_node,
    508     void *user_data);
    509 
    510 typedef struct _alpm_bkt_trav_s {
    511     bcm_esw_alpm_bkt_trav_cb    user_cb;
    512     void                        *user_data;
    513 } _alpm_bkt_trav_t;
    514 
    515 typedef struct _alpm_ppg_cb_user_data_s {
    516     int  unit;
    517     int  ppg_op;
    518     int  ppg_cnt;
    519     void *ppg_acb;
    520     void *ppg_data;
    521 } _alpm_ppg_cb_user_data_t;
    522 
    523 typedef struct _alpm_bkt_merge_req_data_s {
    524     _alpm_cb_t       *acb;
    525     int              cover_cnt;
    526     uint32           *new_pvt_key;
    527     uint32           new_pvt_key_len;
    528     _alpm_pvt_node_t *pvt_node;
    529     int              *req_ent;
    530     uint8            def_fmt;
    531 } _alpm_bkt_merge_req_data_t;
    532 
    533 typedef struct _alpm_bkt_pfx_merge_arr_s {
    534     int                 unit;
    535     _alpm_pvt_node_t    *new_pvt;
    536     _alpm_bkt_pfx_arr_t *pfx_arr;
    537 } _alpm_bkt_pfx_merge_arr_t;
    538 
    539 #define ALPM_INFO_MASK_VALID             0x00000001
    540 #define ALPM_INFO_MASK_KEYLEN            0x00000002
    541 #define ALPM_INFO_MASK_ASSOC_DATA        0x00000004
    542 #define ALPM_INFO_MASK_ALPM_DATA         0x00000008
    543 #define ALPM_INFO_MASK_ALPM_DATA_RAW     0x00000010
    544 #define ALPM_INFO_MASK_FIXED_DATA        0x00000020
    545 
    546 /* Used for retrieving alpm info from given entry,
    547  * Entry can be a TCAM entry or a entry entry, not bank entry */
    548 typedef struct _alpm_ent_info_s {
    549     /* Input */
    550     uint32  action_mask;
    551     /* ent_fmt or sub_idx */
    552     int     ent_fmt;
    553     int     vrf_id;
    554     int     pvt_pkm;
    555     int     ipt;
    556 
    557     /* KEY & LENGTH */
    558     uint32  ent_valid;
    559     uint32  key[5];
    560     int     key_len;
    561 
    562     /* ALPM_DATA */
    563     void    *alpm_data_raw;
    564     int     default_miss;
    565     int     kshift;
    566     _alpm_bkt_info_t    bkt_info;
    567 
    568     /* FIXED_DATA */
    569     int     route_pri; /* Global Hi/Lo, Private */
    570 
    571     /* ASSOC_DATA */
    572     _alpm_bkt_adata_t   adata;
    573 
    574 } _alpm_ent_info_t;
    575 
    576 typedef struct _alpm_time_poll_s {
    577     int poll;               /* Poll sequence number (can increment by different weight,
    578                                e.g. 1 for traverse & check, 100 for merge) */
    579     int max_poll;           /* Maximum poll sequence number to check max_duration
    580                                (reset poll sequence when reach this number) */
    581     sal_usecs_t start_time; /* Initial time in usec registered when start the work */
    582     int max_duration;       /* Maximum time duration in usec to finish the work */
    583     int timeout;            /* Timeout check result: TRUE or FALSE */
    584 } _alpm_time_poll_t;
    585 
    586 typedef struct _alpm_cb_merge_ctrl_s {
    587     int unit;
    588     int merge_count;
    589     int vrf_id;
    590     int ipt;
    591     int bnk_pbkt;
    592     int ent_pbnk;
    593 
    594     _alpm_cb_t *acb;
    595 
    596     int max_cnt;
    597 
    598     /* For defrag use */
    599     _alpm_time_poll_t *check_time;  /* NULL for no time_check */
    600     int max_l2_merge_cnt;           /* Maximum l2 merge counter */
    601     int max_l3_merge_cnt;           /* Maximum l3 merge counter */
    602     int l2_merge_cnt;               /* Accumulated l2 merge counter */
    603     int l3_merge_cnt;               /* Accummulated l3 merge counter */
    604     alpm_lib_trie_node_t *lc_trie;  /* for left child trie node when ptrie is internal node */
    605     alpm_lib_trie_node_t *lc_ptrie; /* save lc_trie parent for comparison when check rc_trie */
    606     _alpm_pvt_node_t *l1_pvt_node;  /* for l2 pvt insert during l2_merge */
    607 
    608 } _alpm_cb_merge_ctrl_t;
    609 
    610 typedef enum _alpm_cb_merge_type_e {
    611     ACB_MERGE_INVALID = 0,
    612     ACB_MERGE_CHILD_TO_PARENT,
    613     ACB_MERGE_PARENT_TO_CHILD
    614 } _alpm_cb_merge_type_t;
    615 
    616 #define ACB_REPART_THRESHOLD 8
    617 #define ACB_MERGE_THRESHOLD  8
    618 
    619 #define ALPM_MERGE_REQD(u, vrf_id)              \
    620         (ALPMC(u)->_alpm_merge_state[vrf_id] != _ALPM_MERGE_UNCHANGE)
    621 #define ALPM_MERGE_STATE_CHKED(u, vrf_id)        \
    622         (ALPMC(u)->_alpm_merge_state[vrf_id] = _ALPM_MERGE_UNCHANGE)
    623 #define ALPM_MERGE_STATE_CHANGED(u, vrf_id)     \
    624         (ALPMC(u)->_alpm_merge_state[vrf_id] = _ALPM_MERGE_CHANGE)
    625 
    626 #define ALPM_PVT_UPDATE_ALPM_DATA    (0xffffffff)
    627 #define ALPM_PVT_UPDATE_ASSOC_DATA   (0xffffffff)
    628 #define ALPM_PVT_UPDATE_PREFIX       (0xffffffff)
    629 #define ALPM_PVT_UPDATE_ALL          (0xffffffff)
    630 
    631 /* Data structure for default route usage in route projection */
    632 typedef struct alpm_default_usage_s {
    633     int grp;
    634     int route_cnt;
    635     int usage[BCM_L3_ALPM_LEVELS];
    636     uint8 hlfbnk;
    637     uint8 acb_cnt;
    638     uint8 enable_128b;
    639     uint8 rsvd;
    640     uint8 full;
    641     int cnt_total[BCM_L3_ALPM_LEVELS];
    642 } alpm_default_usage_t;
    643 
    644 /* ALPM functions */
    645 typedef int (*alpm_ctrl_init_f)(int);
    646 typedef void (*alpm_ctrl_deinit_f)(int);
    647 typedef int (*alpm_ctrl_cleanup_f)(int);
    648 typedef int (*alpm_bkt_bnk_copy_f)(int u, _alpm_cb_t *acb,
    649                                    _alpm_pvt_node_t *pvt_node,
    650                                    _alpm_bkt_info_t *src_bkt,
    651                                    _alpm_bkt_info_t *dst_bkt,
    652                                    int src_idx, int dst_idx);
    653 typedef int (*alpm_bkt_bnk_clear_f)(int u, _alpm_cb_t *acb,
    654                                    _alpm_pvt_node_t *pvt_node,
    655                                    int tab_idx);
    656 typedef int (*alpm_bkt_pfx_copy_f)(int u, _alpm_cb_t *acb,
    657                                    _alpm_bkt_pfx_arr_t *pfx_arr,
    658                                    _alpm_pvt_node_t *opvt_node,
    659                                    _alpm_pvt_node_t *npvt_node,
    660                                    _alpm_bkt_info_t *new_bkt);
    661 typedef int (*alpm_bkt_pfx_clean_f)(int u, _alpm_cb_t *acb,
    662                                     _alpm_pvt_node_t *pvt_node,
    663                                     int count, uint32 *ent_idx);
    664 typedef int (*alpm_bkt_pfx_shrink_f)(int u, _alpm_cb_t *acb,
    665                                      _alpm_pvt_node_t *pvt_node,
    666                                      _alpm_bkt_pfx_arr_t *pfx_arr,
    667                                      int shrink_empty_only);
    668 typedef int (*alpm_bkt_ent_write_f)(int u, _alpm_cb_t *acb,
    669                                     _alpm_pvt_node_t *pvt_node,
    670                                     _bcm_defip_cfg_t *lpm_cfg,
    671                                     int ent_idx, uint32 write_flags);
    672 typedef uint8 (*alpm_bkt_def_fmt_get_f)(int u, _alpm_cb_t *acb,
    673                                         int vrf_id, int pkm);
    674 typedef int16 (*alpm_bkt_fmt_type_get_f)(int u, int vrf_id, _alpm_cb_t *acb, uint8 fmt);
    675 typedef int (*alpm_ent_ent_get_f)(int u, int vrf_id, _alpm_cb_t *acb,
    676                                   void *e, uint32 fmt, int eid, void *ftmp);
    677 typedef int (*alpm_ent_pfx_len_get_f)(int u, _alpm_cb_t *acb,
    678                                    _alpm_pvt_node_t *pvt_node, int ent_idx);
    679 typedef int (*alpm_ent_selective_get_f)(int u, _alpm_cb_t *acb, void *e,
    680                                    _alpm_ent_info_t *info);
    681 
    682 /* TCAM function pointer */
    683 typedef int (*tcam_tab_sz_f)(int, int, int);
    684 typedef int (*tcam_hw_cleanup_f)(int, int);
    685 typedef int (*tcam_ent_x_to_y_f)(int, int, int, void *, void *, int, int, int);
    686 typedef int (*tcam_ent_from_cfg_f)(int, int, _bcm_defip_cfg_t *, void *, int, uint32 write_flags);
    687 typedef int (*tcam_ent_to_cfg_f)(int, int, void *, int, _bcm_defip_cfg_t *);
    688 typedef int (*tcam_ent_valid_f)(int, int, int, void *, int);
    689 typedef int (*tcam_ent_valid_set_f)(int, int, int, void *, int, int);
    690 typedef int (*tcam_ent_vrf_id_get_f)(int, int, int, void *, int, int *);
    691 typedef int (*tcam_ent_key_type_get_f)(int, int, int, void *, int, int *);
    692 typedef int (*tcam_ent_pfx_len_get_f)(int, int, int, void *, int, int *);
    693 typedef int (*tcam_ent_to_key_f)(int, int, int, void *, int, uint32 *);
    694 
    695 typedef int (*tcam_ent_mode_get_f)(int u, int app, int pk, void *e,
    696              int *step_size, int *pkm, int *ipv6, int *key_mode, int sub_idx);
    697 typedef int (*tcam_ent_adata_get_f)(int u, int app, int pkm, void *e, int sub_idx,
    698                                     _alpm_bkt_adata_t *adata);
    699 typedef int (*tcam_ent_bdata_get_f)(int u, int app, int pkm, void *e,
    700                                     int sub_idx,  void *fent);
    701 
    702 /* HITBIT function pointer */
    703 typedef int (*alpm_hit_init_f)(int);
    704 typedef void (*alpm_hit_deinit_f)(int);
    705 typedef int (*alpm_hit_cleanup_f)(int);
    706 typedef int (*alpm_bkt_hit_get_f)(int u, int vrf_id, _alpm_cb_t *acb,
    707                                   _alpm_tbl_t tbl, int idx, int ent);
    708 typedef int (*alpm_bkt_hit_set_f)(int u, int vrf_id, _alpm_cb_t *acb,
    709                                   _alpm_tbl_t tbl, int idx, int ent, int hit_val);
    710 typedef int (*alpm_bkt_hit_write_f)(int u, int vrf_id, _alpm_cb_t *acb,
    711                                     _alpm_tbl_t tbl, int ent_idx, int hit_val);
    712 typedef int (*alpm_hit_move_update_f)(int u, int i, int pid);
    713 typedef int (*alpm_hit_cache_sync_f)(int u, int app, int i, int pid);
    714 typedef int (*alpm_hit_hw_write_f)(int u, int app, int i, int pid);
    715 typedef int (*tcam_ent_hit_get_f)(int u, int app, int pkm, void *e, int sub_idx);
    716 typedef int (*tcam_cache_hit_get_f)(int u, _alpm_pvt_node_t *pvt_node,
    717                                     int app, int pkm, int tcam_idx);
    718 typedef int (*tcam_hit_cache_sync_f)(int u);
    719 typedef int (*tcam_hit_write_f)(int u, _alpm_pvt_node_t *pvt_node,
    720                                 int app, int pkm, int tcam_idx, int hit_val);
    721 typedef int (*alpm_table_dump_f)(int u, int app, int vrf_id, soc_mem_t mem, int copyno,
    722                                  int index, int fmt, int ent_idx, int flags);
    723 typedef int (*alpm_cap_get_f)(int u, soc_mem_t mem, int *max, int *min, int app);
    724 typedef int (*alpm_def_usage_get_f)(int u, int grp, int *def_route, int *def_lvl,
    725                                     int *def_usage, int *cur_cnt_total);
    726 typedef int (*alpm_data_op_f)(int u, int app, int op, bcm_esw_alpm_data_cb cb, void *fp);
    727 
    728 /* TCAM/ALPM function pointer */
    729 typedef int (*mem_ent_read_f)(int unit, _alpm_cb_t *acb, _alpm_tbl_t tbl,
    730                               int index, void *entry_data,
    731                               int no_cache);
    732 typedef int (*mem_ent_write_f)(int unit, _alpm_cb_t *acb,
    733                                _alpm_pvt_node_t *pvt_node, _alpm_tbl_t tbl,
    734                                int index, void *entry_data,
    735                                int update_data);
    736 typedef int (*mem_ent_phy_idx_get_f)(int u, _alpm_cb_t *acb,
    737                                      _alpm_tbl_t tbl, int index);
    738 typedef struct alpm_functions_s {
    739     /* ALPM */
    740     alpm_ctrl_init_f        alpm_ctrl_init;
    741     alpm_ctrl_deinit_f      alpm_ctrl_deinit;
    742     alpm_ctrl_cleanup_f     alpm_ctrl_cleanup;
    743     alpm_bkt_bnk_copy_f     alpm_bkt_bnk_copy;
    744     alpm_bkt_bnk_clear_f    alpm_bkt_bnk_clear;
    745     alpm_bkt_pfx_copy_f     alpm_bkt_pfx_copy;
    746     alpm_bkt_pfx_clean_f    alpm_bkt_pfx_clean;
    747     alpm_bkt_pfx_shrink_f   alpm_bkt_pfx_shrink;
    748     alpm_bkt_ent_write_f    alpm_bkt_ent_write;
    749     alpm_bkt_def_fmt_get_f  alpm_bkt_def_fmt_get;
    750     alpm_bkt_fmt_type_get_f alpm_bkt_fmt_type_get;
    751 
    752     alpm_ent_ent_get_f      alpm_ent_ent_get;
    753     alpm_ent_pfx_len_get_f  alpm_ent_pfx_len_get;
    754     alpm_ent_selective_get_f alpm_ent_selective_get;
    755 
    756     /* TCAM */
    757     tcam_tab_sz_f           tcam_table_sz;
    758     tcam_hw_cleanup_f       tcam_hw_cleanup;
    759     tcam_ent_x_to_y_f       tcam_entry_x_to_y;
    760     tcam_ent_from_cfg_f     tcam_entry_from_cfg;
    761     tcam_ent_to_cfg_f       tcam_entry_to_cfg;
    762     tcam_ent_valid_f        tcam_entry_valid;
    763     tcam_ent_valid_set_f    tcam_entry_valid_set;
    764     tcam_ent_vrf_id_get_f   tcam_entry_vrf_id_get;
    765     tcam_ent_key_type_get_f tcam_entry_key_type_get;
    766     tcam_ent_pfx_len_get_f  tcam_entry_pfx_len_get;
    767     tcam_ent_to_key_f       tcam_entry_to_key;
    768 
    769     tcam_ent_mode_get_f     tcam_entry_mode_get;
    770     tcam_ent_adata_get_f    tcam_entry_adata_get;
    771     tcam_ent_bdata_get_f    tcam_entry_bdata_get;
    772 
    773     /* TCAM/ALPM */
    774     mem_ent_read_f          mem_entry_read;
    775     mem_ent_write_f         mem_entry_write;
    776 
    777     /* HITBIT */
    778     alpm_hit_init_f         alpm_hit_init;
    779     alpm_hit_deinit_f       alpm_hit_deinit;
    780     alpm_hit_cleanup_f      alpm_hit_cleanup;
    781     alpm_bkt_hit_get_f      alpm_bkt_hit_get;
    782     alpm_bkt_hit_set_f      alpm_bkt_hit_set;
    783     alpm_bkt_hit_write_f    alpm_bkt_hit_write;
    784     alpm_hit_move_update_f  alpm_hit_move_update;
    785     alpm_hit_cache_sync_f   alpm_hit_cache_sync;
    786     alpm_hit_hw_write_f     alpm_hit_hw_write;
    787     tcam_ent_hit_get_f      tcam_entry_hit_get;
    788     tcam_cache_hit_get_f    tcam_cache_hit_get;
    789     tcam_hit_cache_sync_f   tcam_hit_cache_sync;
    790     tcam_hit_write_f        tcam_hit_write;
    791 
    792     /* dump table */
    793     alpm_table_dump_f       alpm_table_dump;
    794     alpm_cap_get_f          alpm_cap_get;
    795     alpm_def_usage_get_f    alpm_def_usage_get;
    796 
    797     /* data op: save/restore */
    798     alpm_data_op_f          alpm_data_op;
    799 
    800     /* Logical idx to physical idx mapping */
    801     mem_ent_phy_idx_get_f   mem_ent_phy_idx_get;
    802 } alpm_functions_t;
    803 
    804 extern alpm_functions_t th3_alpm_driver;
    805 extern alpm_functions_t th_alpm_driver;
    806 
    807 #define _SHIFT_LEFT(val, count) \
    808     (((count) == 32) ? 0 : (val) << (count))
    809 
    810 #define _SHIFT_RIGHT(val, count) \
    811     (((count) == 32) ? 0 : (val) >> (count))
    812 
    813 #define PVT_BKT_TRIE(pvt_node)          ((pvt_node)->bkt_trie)
    814 #define PVT_BKT_DEF(pvt_node)           ((pvt_node)->def_pfx)
    815 #define PVT_BKT_INFO(pvt_node)          ((pvt_node)->bkt_info)
    816 #define PVT_ROFS(pvt_node)              (PVT_BKT_INFO(pvt_node).rofs)
    817 #define PVT_BKT_IDX(pvt_node)           (PVT_BKT_INFO(pvt_node).bkt_idx)
    818 #define PVT_SUB_BKT_IDX(pvt_node)       (PVT_BKT_INFO(pvt_node).sub_bkt_idx)
    819 #define PVT_BKT_VRF(pvt_node)           ((pvt_node)->vrf_id)
    820 #define PVT_FLAGS(pvt_node)             ((pvt_node)->pvt_flags)
    821 #define PVT_IS_IPMC(pvt_node)           (PVT_FLAGS(pvt_node) & BCM_L3_IPMC)
    822 #define PVT_BKT_PKM(pvt_node)           ((pvt_node)->bkt_pkm)
    823 #define PVT_BKT_IPT(pvt_node)           (ALPM_PKM2IPT((pvt_node)->bkt_pkm))
    824 #define PVT_BPM_LEN(pvt_node)           ((pvt_node)->bpm_len)
    825 #define PVT_KEY_LEN(pvt_node)           ((pvt_node)->key_len)
    826 #define PVT_KEY_CPY(pvt_node, _key)     (sal_memcpy(pvt_node->key, _key, 4 * 5))
    827 #define PVT_IDX(pvt_node)               ((pvt_node)->tcam_idx)
    828 
    829 /* Bucket Info Macros */
    830 #define BI_BNK_IS_USED(bkt_info, bnk)   ((bkt_info)->bnk_fmt[(bnk)] != 0)
    831 #define BI_BNK_FREE(bkt_info, bnk)      ((bkt_info)->bnk_fmt[(bnk)] = 0)
    832 #define BI_SUB_BKT_IDX(bkt_info)        ((bkt_info)->sub_bkt_idx)
    833 #define BI_BKT_IDX(bkt_info)            ((bkt_info)->bkt_idx)
    834 #define BI_ROFS(bkt_info)               ((bkt_info)->rofs)
    835 
    836 /* ALPM Macros */
    837 #define ALPMC(u)                    (alpm_control[u])
    838 #define ALPM_MODE(u)                (ALPMC(u)->_alpm_mode)
    839 #define ALPM_MODE_CHK(u, md)        (ALPM_MODE(u) == md)
    840 #define ALPM_TCAM_ZONED(u, app)     (ALPMC(u)->_alpm_tcam_zoned[app])
    841 #define ALPM_128B(u)                (ALPMC(u)->_alpm_128b)
    842 #define ALPM_TCAM_PAIR_BLK_CNT(u)   (ALPMC(u)->_alpm_128b_paired_blk_cnt)
    843 #define ALPM_BKT_RSVD(u)            (ALPMC(u)->_alpm_128b_bkt_rsvd)
    844 #define ALPM_BKT_RSVD_CNT(u)        (ALPMC(u)->_alpm_128b_bkt_rsvd_cnt)
    845 #define ALPM_BKT_RSVD_TOTAL         8192
    846 #define ALPM_BKT_SHARE_THRES(u)     (ALPMC(u)->_alpm_bkt_share_bnk_usage_thres)
    847 #define ALPM_DRV(u)                 (ALPMC(u)->alpm_driver)
    848 #define ALPM_HIT_SKIP(u)            (ALPMC(u)->_alpm_no_hit_bit)
    849 #define ALPM_TCAM_HB_IS_PTR(u)      (ALPMC(u)->_alpm_tcam_hb_is_ptr)
    850 #define ALPM_TCAM_TBL_SKIP(u, pk)   (ALPMC(u)->_alpm_tcam_tbl_skip[pk])
    851 #define ALPM_SCHAN_FIFO_HDL(u)      (ALPMC(u)->_alpm_schan_fifo_handle)
    852 #define ALPM_HLF_BNKS(u)            (ALPMC(u)->_alpm_half_banks)
    853 #define ALPM_PKM_RECOVER(u, ipt) \
    854     (((ipt) == ALPM_IPT_V4) ? ALPM_PKM_32B : ((ALPM_128B(u)) ? ALPM_PKM_128 : ALPM_PKM_64B))
    855 #define ALPMC_INIT_CHECK(u)         if (ALPMC(u) == NULL) {return BCM_E_INIT;}
    856 #define ALPM_DATA_AUTOSAVE(u)       (ALPMC(u)->_alpm_data_autosave)
    857 #define ALPM_ACL_EN(u)              (ALPMC(u)->_alpm_acl_en)
    858 
    859 /* ALPM VRF/VRF_ID Macros */
    860 #define ALPM_VRF_ID_GHI(u)    (ALPMC(u)->_alpm_max_vrf_id + 2)
    861 #define ALPM_VRF_ID_GLO(u)    (ALPMC(u)->_alpm_max_vrf_id + 1)
    862 #define ALPM_VRF_ID_MAX(u)    (ALPMC(u)->_alpm_max_vrf_id + 2)
    863 #define ALPM_VRF_ID_CNT(u)    (ALPMC(u)->_alpm_max_vrf_id + 3)
    864 
    865 #define ALPM_VRF_ID_TO_VRF(u, vrf_id)                           \
    866     ((vrf_id) == ALPM_VRF_ID_GHI(u) ? BCM_L3_VRF_OVERRIDE :     \
    867      (vrf_id) == ALPM_VRF_ID_GLO(u) ? BCM_L3_VRF_GLOBAL :       \
    868      (vrf_id))
    869 
    870 #define ALPM_VRF_IS_GBL(u, vrf)                                 \
    871     ((vrf) == BCM_L3_VRF_OVERRIDE || (vrf) == BCM_L3_VRF_GLOBAL)
    872 
    873 #define ALPM_VRF_ID_IS_GBL(u, vrf_id)                           \
    874     ((vrf_id) == ALPM_VRF_ID_GHI(u) || (vrf_id) == ALPM_VRF_ID_GLO(u))
    875 #define ALPM_VRF_ID_TO_BPC_PID(u, vrf_id, app)                  \
    876     (alpm_acl_app(app) ? ALPM_BKT_PRT_PID :                     \
    877      ALPM_VRF_ID_IS_GBL(u, (vrf_id)) ? ALPM_BKT_GLB_PID : ALPM_BKT_PRT_PID)
    878 #define ALPM_BPC_PID_TO_VRF_ID(u, pid)                          \
    879     (pid == ALPM_BKT_GLB_PID ? ALPM_VRF_ID_GLO(u) : 1)
    880 #define ALPM_VRF_ID_HAS_BKT(u, vrf_id)                          \
    881     ((vrf_id) == ALPM_VRF_ID_GHI(u) ? 0 :                       \
    882      (vrf_id) == ALPM_VRF_ID_GLO(u) ?                           \
    883      (ALPM_MODE_CHK(u, BCM_ALPM_MODE_TCAM_ALPM) ? 0 : 1) : 1)
    884 
    885 #define ALPM_VRF_TO_VRFID(u, vrf)                               \
    886     ((vrf) == BCM_L3_VRF_OVERRIDE ? ALPM_VRF_ID_GHI(u) :        \
    887      (vrf) == BCM_L3_VRF_GLOBAL ? ALPM_VRF_ID_GLO(u) :          \
    888      (vrf))
    889 
    890 #define ALPM_VRF_TRIE(u, app, vrf_id, ipt)                      \
    891         (ALPMC(u)->_vrf_pfx_hdl[vrf_id].pfx_trie[!!ipt][app])
    892 #define ALPM_VRF_DATA_MODE(u, vrf_id)                           \
    893         (ALPMC(u)->_vrf_pfx_hdl[vrf_id].data_mode)
    894 
    895 #define ALPM_GLO_VRF_IN_HLF_PMODE(u, vrf_id)                    \
    896         (ALPM_HLF_BNKS(u) && ALPM_MODE_CHK(u, BCM_ALPM_MODE_PARALLEL) && \
    897          vrf_id == ALPM_VRF_ID_GLO(u))
    898 
    899 /* ALPM BPC(BUCKET POOL CONFIG) Macros */
    900 #define BPC_BNK_PER_BKT(bp_conf)        ((bp_conf)->bnk_per_bkt)
    901 #define BPC_BNK_INFO(bp_conf, ipt)      ((bp_conf)->bnk_info[ipt])
    902 #define BPC_BNK_CNT(bp_conf)            ((bp_conf)->bnk_total)
    903 #define BPC_BNK_BMP(bp_conf, ipt)       (BPC_BNK_INFO(bp_conf, ipt)->bnk_btmp)
    904 #define BPC_BNK_RSVD(bp_conf, ipt)      (BPC_BNK_INFO(bp_conf, ipt)->bnk_rsvd)
    905 #define BPC_BNK_USED(bp_conf, ipt)      (BPC_BNK_INFO(bp_conf, ipt)->bnk_used)
    906 #define BPC_BKT_USED(bp_conf, ipt)      (BPC_BNK_INFO(bp_conf, ipt)->bkt_used[ipt])
    907 #define BPC_BKT_TOT_USED(bp_conf)       (BPC_BNK_INFO(bp_conf, ALPM_IPT_V4)->bkt_used[ALPM_IPT_V4] + \
    908                                          BPC_BNK_INFO(bp_conf, ALPM_IPT_V6)->bkt_used[ALPM_IPT_V6])
    909 #define BPC_BKT_TBL(bp_conf)            ((bp_conf)->bkt_tbl)
    910 #define BPC_BKT_WRA(bp_conf)            ((bp_conf)->bkt_wra)
    911 #define BPC_BKT_FIXED_FMT(bp_conf)      ((bp_conf)->bkt_fixed_fmt)
    912 #define BPC_FMT_INFO(bp_conf)           ((bp_conf)->fmt_info)
    913 #define BPC_FMT_CNT(bp_conf)            (BPC_FMT_INFO(bp_conf)->fmt_count)
    914 #define BPC_FMT_TYPE(bp_conf)           (BPC_FMT_INFO(bp_conf)->fmt_type)
    915 #define BPC_FMT_PFX_LEN(bp_conf, fmt)   (BPC_FMT_INFO(bp_conf)->fmt_pfx_len[fmt])
    916 #define BPC_FMT_ENT_MAX(bp_conf, fmt)   (BPC_FMT_INFO(bp_conf)->fmt_ent_max[fmt])
    917 #define BPC_FMT_BNK(bp_conf, fmt)       (BPC_FMT_INFO(bp_conf)->fmt_bnk[fmt])
    918 #define BPC_FMT_ENT(bp_conf, fmt)       (BPC_FMT_INFO(bp_conf)->fmt_ent[fmt])
    919 #define BPC_FMT_FULL_TYPE(bp_conf, fmt) (BPC_FMT_INFO(bp_conf)->fmt_ftype[fmt])
    920 #define BPC_IS_LEVEL3_TBL(bp_conf)      (BPC_BKT_TBL(bp_conf) >= alpmTblBktCmodeL3)
    921 
    922 /* ALPM ACB Macros */
    923 #define ACB_IDX(acb)                ((acb)->acb_idx)
    924 #define ACB_APP(acb)                ((acb)->app)
    925 #define ACB_HAS_TCAM(acb)           (ACB_IDX(acb) == 0)
    926 #define ACB(u, i, a)                (ALPMC(u)->alpm_cb[i][a])
    927 #define ACB_UPR(u, acb)             (ACB(u, ACB_IDX(acb) - 1, ACB_APP(acb)))
    928 #define ACB_DWN(u, acb)             (ACB(u, ACB_IDX(acb) + 1, ACB_APP(acb)))
    929 #define ACB_TOP(u, app)             (ACB(u, 0, app))
    930 #define ACB_CNT(u)                  (ALPMC(u)->_alpm_cb_cnt)
    931 #define ACB_BTM(u, app)             (ACB(u, ACB_CNT(u) - 1, app))
    932 #define ACB_VRF_BTM_IDX(u, vrf_id, app)  (ALPMC(u)->_alpm_btm_cb_idx[ALPM_VRF_ID_TO_BPC_PID(u, vrf_id, app)])
    933 #define ACB_VRF_BTM(u, vrf_id, app) (ACB(u, ACB_VRF_BTM_IDX(u, vrf_id, app), app))
    934 
    935 #define ACB_VRF_INITED(u, acb, vrf_id, ipt)                     \
    936         ((acb)->pvt_ctl[!!ipt] &&                               \
    937          ACB_PVT_CTRL(acb, vrf_id, ipt).db_inited)
    938 #define ACB_VRF_INIT_SET(u, acb, vrf_id, ipt)                   \
    939         (ACB_PVT_CTRL(acb, vrf_id, ipt).db_inited = TRUE)
    940 #define ACB_VRF_INIT_CLEAR(u, acb, vrf_id, ipt)                 \
    941         (ACB_PVT_CTRL(acb, vrf_id, ipt).db_inited = FALSE)
    942 #define ACB_VRF_DB_TYPE(u, acb, vrf_id, ipt)                    \
    943         (ACB_PVT_CTRL(acb, vrf_id, ipt).db_type)
    944 #define ACB_VRF_DB_TYPE_SET(u, acb, vrf_id, ipt, rt)            \
    945         (ACB_PVT_CTRL(acb, vrf_id, ipt).db_type = rt)
    946 #define ACB_VRF_SPLEN_DIFF1(u, acb, vrf_id, ipt)                \
    947         (ACB_PVT_CTRL(acb, vrf_id, ipt).spl_len_diff1)
    948 #define ACB_VRF_SPLEN_DIFF2(u, acb, vrf_id, ipt)                \
    949         (ACB_PVT_CTRL(acb, vrf_id, ipt).spl_len_diff2)
    950 
    951 #define ACB_DR_INITED(u, acb, vrf_id, ipt)                     \
    952         ((acb)->pvt_ctl[!!ipt] &&                               \
    953          ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited)
    954 #define ACB_DR_INIT_SET(u, acb, vrf_id, ipt)                   \
    955         (ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited = TRUE)
    956 #define ACB_DR_INIT_CLEAR(u, acb, vrf_id, ipt)                 \
    957         (ACB_PVT_CTRL(acb, vrf_id, ipt).dr_inited = FALSE)
    958 
    959 #define ACB_BNK_CONF(acb)               ((acb)->bnk_conf)
    960 #define ACB_BNK_BMP(acb, vrf_id, ipt)                           \
    961         (BPC_BNK_BMP(ACB_BKT_VRF_POOL(acb, vrf_id), ipt))
    962 #define ACB_BNK_CNT(acb, vrf_id)                                \
    963         (BPC_BNK_CNT(ACB_BKT_VRF_POOL(acb, vrf_id)))
    964 #define ACB_PID_BNK_CNT(acb, pid)                               \
    965         (BPC_BNK_CNT(ACB_BKT_POOL(acb, pid)))
    966 #define ACB_BNK_PER_BKT(acb, vrf_id)                            \
    967         (BPC_BNK_PER_BKT(ACB_BKT_VRF_POOL(acb, vrf_id)))
    968 #define ACB_BKT_POOL(acb, pid)          (ACB_BNK_CONF(acb).bkt_pool[pid])
    969 #define ACB_BKT_VRF_POOL(acb, vrf_id)                           \
    970         (ACB_BKT_POOL(acb, ALPM_VRF_ID_TO_BPC_PID(acb->unit, vrf_id, acb->app)))
    971 #define ACB_POOL_FMT_INFO(acb, pid)     (BPC_FMT_INFO(ACB_BKT_POOL(acb, pid)))
    972 #define ACB_VRF_POOL_FMT_INFO(acb, vrf_id)                      \
    973         (BPC_FMT_INFO(ACB_BKT_POOL(acb, ALPM_VRF_ID_TO_BPC_PID(acb->unit, vrf_id, acb->app))))
    974 #define ACB_BKT_TBL(acb, vrf_id)                                \
    975         (BPC_BKT_TBL(ACB_BKT_VRF_POOL(acb, vrf_id)))
    976 #define ACB_BKT_WRA(acb, vrf_id)                                \
    977         (BPC_BKT_WRA(ACB_BKT_VRF_POOL(acb, vrf_id)))
    978 #define ACB_BKT_FIXED_FMT(acb, vrf_id)                          \
    979         (BPC_BKT_FIXED_FMT(ACB_BKT_VRF_POOL(acb, vrf_id)))
    980 #define ACB_PVT_CTRL(acb, vrf_id, ipt)  (acb->pvt_ctl[!!ipt][vrf_id])
    981 #define ACB_PVT_TRIE(acb, vrf_id, ipt)                          \
    982         (ACB_PVT_CTRL(acb, vrf_id, ipt).pvt_trie)
    983 #define ACB_VRF_PVT_PTR(acb, vrf_id, idx)                       \
    984         (ACB_BKT_VRF_POOL(acb, vrf_id)->pvt_ptr[idx])
    985 #define ACB_PVT_PTR(acb, pvt_node, idx)                         \
    986         (ACB_VRF_PVT_PTR(acb, PVT_BKT_VRF(pvt_node), idx))
    987 
    988 #define ACB_PID_CNT(acb)                                        \
    989         (alpm_acl_app(acb->app) ? ALPM_BKT_PID_ACL_CNT :        \
    990         (ACB_BKT_POOL(acb, ALPM_BKT_PRT_PID) ==                 \
    991          ACB_BKT_POOL(acb, ALPM_BKT_GLB_PID) ? 1 : 2))
    992 #define ACB_BKT_VRF_PID(acb, vrf_id)                            \
    993         (alpm_acl_app(acb->app) ? ALPM_BKT_PRT_PID :              \
    994         (ACB_BKT_POOL(acb, ALPM_BKT_PRT_PID) ==                   \
    995          ACB_BKT_POOL(acb, ALPM_BKT_GLB_PID) ? ALPM_BKT_PRT_PID : \
    996         ALPM_VRF_ID_TO_BPC_PID(acb->unit, vrf_id, acb->app)))
    997 
    998 #define ACB_BKT_BITS(acb)               (ACB_BNK_CONF(acb).bkt_bits)
    999 #define ACB_BKT_CNT(acb)                (1 << ACB_BKT_BITS(acb))
   1000 #define ACB_BKT_DW(acb)                 (ACB_BNK_CONF(acb).bkt_dw)
   1001 #define ACB_BNK_BITS(acb)               (ACB_BNK_CONF(acb).bnk_bits)
   1002 #define ACB_PHY_BNK_PER_BKT(acb)        (ACB_BNK_CONF(acb).phy_bnks_per_bkt)
   1003 #define ACB_FMT_PFX_LEN(acb, vrf_id, fmt)  (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_pfx_len[fmt])
   1004 #define ACB_FMT_ENT_MAX(acb, vrf_id, fmt)  (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_ent_max[fmt])
   1005 #define ACB_FMT_BNK(acb, vrf_id, fmt)   (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_bnk[fmt])
   1006 #define ACB_FMT_ENT(acb, vrf_id, fmt)   (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_ent[fmt])
   1007 #define ACB_FMT_FULL_TYPE(acb, vrf_id, fmt)  (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_ftype[fmt])
   1008 #define ACB_FMT_CNT(acb, vrf_id)        (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_count)
   1009 #define ACB_FMT_TYPE(acb, vrf_id)        (ACB_VRF_POOL_FMT_INFO(acb, vrf_id)->fmt_type)
   1010 #define ACB_HLF_BNK_MD(acb)             (ACB_BNK_BITS(acb) == 2)
   1011 
   1012 #define ACB_HAS_RTE(acb, vrf_id)    (ACB_FMT_TYPE(acb, vrf_id) == ALPM_FMT_RTE)
   1013 #define ACB_HAS_PVT(acb, vrf_id)    (ACB_FMT_TYPE(acb, vrf_id) == ALPM_FMT_PVT)
   1014 #define ACB_VRF_EMPTY(acb, vrf_id)  (ACB_FMT_TYPE(acb, vrf_id) == ALPM_FMT_CNT)
   1015 
   1016 /* ALPM LPM Macros */
   1017 #define ALPM_LPM_DIRECT_RTE(u, lpm_cfg)                         \
   1018     ((lpm_cfg->defip_flags & BCM_L3_IPMC) ||                    \
   1019     (((lpm_cfg)->defip_vrf == BCM_L3_VRF_OVERRIDE) ? 1 :        \
   1020      ((lpm_cfg)->defip_vrf == BCM_L3_VRF_GLOBAL) ?              \
   1021      (ALPM_MODE_CHK(u, BCM_ALPM_MODE_TCAM_ALPM) ? 1 : 0) : 0))
   1022 
   1023 #define ALPM_LPM_PKM(u, lpm_cfg)                                \
   1024     ((lpm_cfg)->defip_flags & BCM_L3_IP6 ?                      \
   1025      (ALPM_128B(u) ? ALPM_PKM_128 : ALPM_PKM_64B) :             \
   1026      ALPM_PKM_32B)
   1027 
   1028 #define ALPM_LPM_IPT(u, lpm_cfg)                                \
   1029     (((lpm_cfg)->defip_flags & BCM_L3_IP6) ? ALPM_IPT_V6 : ALPM_IPT_V4)
   1030 
   1031 #define ALPM_LPM_VRF_ID(u, lpm_cfg)                             \
   1032     ((lpm_cfg)->defip_vrf >= 0 ?    (lpm_cfg)->defip_vrf :      \
   1033      (lpm_cfg)->defip_vrf == BCM_L3_VRF_GLOBAL ?                \
   1034                                     (ALPM_VRF_ID_GLO(u)) :      \
   1035                                     (ALPM_VRF_ID_GHI(u)))
   1036 
   1037 /*  -- ALPM entry IDX Format --
   1038  * IDX:
   1039  *   <ent> | <bnk> | <bkt>
   1040  * TAB_IDX:
   1041  *   <bnk> | <bkt>
   1042  */
   1043 
   1044 /*
   1045  +-----------------------------------+
   1046  | 8 bits    | bnk bits | bkt bits   |
   1047  +-----------------------------------+
   1048  | EntryID   | BankID   | BucketID   |
   1049  +-----------------------------------+
   1050  */
   1051 
   1052 #define ALPM_IDX_ENT_SHIFT          24
   1053 #define ALPM_IDX_ENT_MASK           0xff
   1054 #define ALPM_IDX_BNK_SHIFT(acb)     ACB_BKT_BITS(acb)
   1055 #define ALPM_IDX_BNK_MASK           0xff
   1056 #define ALPM_IDX_BKT_MASK(acb)      ((1 << ALPM_IDX_BNK_SHIFT(acb)) - 1)
   1057 #define ALPM_TAB_IDX_MASK           ((1 << ALPM_IDX_ENT_SHIFT) - 1) /* 0xffffff */
   1058 
   1059 #define ALPM_IDX_TO_BKT(acb, idx)                            \
   1060     ((idx) & ALPM_IDX_BKT_MASK(acb))
   1061 
   1062 #define ALPM_IDX_TO_BNK(acb, idx)                            \
   1063     (((idx) >> ALPM_IDX_BNK_SHIFT(acb)) & ALPM_IDX_BNK_MASK)
   1064 
   1065 #define ALPM_IDX_TO_ENT(idx)                                 \
   1066     (((idx) >> ALPM_IDX_ENT_SHIFT) & ALPM_IDX_ENT_MASK)
   1067 
   1068 #define ALPM_IDX_MAKE(acb, bi, bnk, ent)                     \
   1069     (((ent) & ALPM_IDX_ENT_MASK) << ALPM_IDX_ENT_SHIFT |     \
   1070      (bnk) << ALPM_IDX_BNK_SHIFT(acb) |                      \
   1071      ((BI_BKT_IDX(bi) + ((bnk) < BI_ROFS(bi))) & ALPM_IDX_BKT_MASK(acb)))
   1072 
   1073 /*  -- ALPM Table IDX construct --
   1074  * TAB_IDX:
   1075  *   <bnk> | <bkt>
   1076  */
   1077 #define ALPM_TAB_IDX_GET_BKT_BNK(acb, rofs, bkt, bnk)       \
   1078     ((bnk << ALPM_IDX_BNK_SHIFT(acb)) | (bkt + (rofs > bnk)))
   1079 
   1080 #define ALPM_TAB_IDX_GET(idx)   (idx & ALPM_TAB_IDX_MASK)
   1081 
   1082 #define ALPM_TAB_IDX_GET_BI_BNK(acb, bi, bnk)               \
   1083     ALPM_TAB_IDX_GET_BKT_BNK(acb, BI_ROFS(bi), BI_BKT_IDX(bi), bnk)
   1084 
   1085 /* VRF Based Counter */
   1086 #define VRF_PVT_LEN_CNT_ADD(acb, vrf_id, ipt, pvt_len)  \
   1087 do {                                                    \
   1088     ACB_PVT_CTRL(acb, vrf_id, ipt).pvt_len_cnt[pvt_len] ++;      \
   1089 } while (0)
   1090 
   1091 #define VRF_PVT_LEN_CNT_DEC(acb, vrf_id, ipt, pvt_len)  \
   1092 do {                                                    \
   1093     ACB_PVT_CTRL(acb, vrf_id, ipt).pvt_len_cnt[pvt_len] --;      \
   1094 } while (0)
   1095 
   1096 #define VRF_PVT_LEN_CNT_GET(acb, vrf_id, ipt, pvt_len)  \
   1097     (ACB_PVT_CTRL(acb, vrf_id, ipt).pvt_len_cnt[pvt_len])
   1098 
   1099 #define VRF_PVT_LEN_CNT_PTR(acb, vrf_id, ipt)           \
   1100     (ACB_PVT_CTRL(acb, vrf_id, ipt).pvt_len_cnt)
   1101 
   1102 #define VRF_ROUTE_ADD(acb, vrf_id, ipt)               \
   1103 do {                                                  \
   1104     ACB_PVT_CTRL(acb, vrf_id, ipt).route_cnt ++;      \
   1105     ACB_PVT_CTRL(acb, vrf_id, ipt).cnt_add ++;        \
   1106 } while (0)
   1107 
   1108 #define VRF_ROUTE_DEC(acb, vrf_id, ipt)               \
   1109 do {                                                  \
   1110     ACB_PVT_CTRL(acb, vrf_id, ipt).route_cnt --;      \
   1111     ACB_PVT_CTRL(acb, vrf_id, ipt).cnt_del ++;        \
   1112 } while (0)
   1113 
   1114 #define VRF_ROUTE_CNT(acb, vrf_id, ipt)               \
   1115     (ACB_PVT_CTRL(acb, vrf_id, ipt).route_cnt)
   1116 
   1117 /* ALPM logs */
   1118 /* Macro for invoking "fast" checker */
   1119 #define ALPM_LOG(chk_, stuff_) do {         \
   1120         if (bsl_fast_check(chk_)) {         \
   1121             bsl_printf stuff_;              \
   1122         }                                   \
   1123     } while (0)
   1124 
   1125 extern char alpm_tmpbuf[_ALPM_ERR_MSG_BUF_ENT_SZ];
   1126 extern void alpm_util_snprintf(const char *fmt, ...);
   1127 extern int _alpm_data_save(int, char *);
   1128 
   1129 #define ALPM_ERR_MSG_LOG(stuff_) do {       \
   1130         int tc = bcm_esw_alpm_trace_seq(u); \
   1131         ALPM_LOG(BSL_LS_BCM_ALPM|BSL_ERROR, ("#%d: ", tc));\
   1132         ALPM_LOG(BSL_LS_BCM_ALPM|BSL_ERROR, stuff_);\
   1133         if (ALPMC(u) != NULL) {\
   1134             sal_memset(alpm_tmpbuf, 0, sizeof(alpm_tmpbuf));\
   1135             sal_sprintf(alpm_tmpbuf, "#%d: ", tc);\
   1136             alpm_util_snprintf stuff_;\
   1137             _ALPM_ERR_MSG_INSERT(u, alpm_tmpbuf);  \
   1138             if (ALPM_DATA_AUTOSAVE(u) && _ALPM_ERR_MSG_CUR_IDX(u) == 1) { \
   1139                 (void)_alpm_data_save(u, "alpm_data.bin"); \
   1140             } \
   1141         }\
   1142     } while (0)
   1143 
   1144 /* Any layer log macros */
   1145 #define ALPM_FATAL(stuff_)          ALPM_LOG(BSL_LS_BCM_ALPM|BSL_FATAL, stuff_)
   1146 #define ALPM_ERR(stuff_)            ALPM_ERR_MSG_LOG(stuff_)
   1147 #define ALPM_WARN(stuff_)           ALPM_LOG(BSL_LS_BCM_ALPM|BSL_WARN, stuff_)
   1148 #define ALPM_INFO(stuff_)           ALPM_LOG(BSL_LS_BCM_ALPM|BSL_INFO, stuff_)
   1149 #define ALPM_VERB(stuff_)           ALPM_LOG(BSL_LS_BCM_ALPM|BSL_VERBOSE, stuff_)
   1150 #define ALPM_DBG(stuff_)            ALPM_LOG(BSL_LS_BCM_ALPM|BSL_DEBUG, stuff_)
   1151 #define ALPM_LOG_CHECK(stuff_)      LOG_CHECK(BSL_LS_BCM_ALPM|(stuff_))
   1152 
   1153 /* ALPM ERROR condition check */
   1154 
   1155 #define ALPM_IER_PRT_EXCEPT(op, except_err)            \
   1156     do { int __rv__; if ((__rv__ = (op)) < 0) { \
   1157         if (__rv__ != (except_err) && __rv__ != BCM_E_BUSY) \
   1158         {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, __rv__));} return(__rv__); } } while(0)
   1159 
   1160 /* If error return */
   1161 #define ALPM_IER(op)            \
   1162     do { int __rv__; if ((__rv__ = (op)) < 0) { \
   1163         if (__rv__ != BCM_E_BUSY) \
   1164         {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, __rv__));} return(__rv__); } } while(0)
   1165 
   1166 #define ALPM_IEG_PRT_EXCEPT(op, except_err)            \
   1167     do { if ((rv = (op)) < 0) { \
   1168         if (rv != (except_err) && rv != BCM_E_BUSY) \
   1169         {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, rv));} goto bad; } } while(0)
   1170 
   1171 /* If error goto */
   1172 #define ALPM_IEG(op)            \
   1173     do { if ((rv = (op)) < 0) { \
   1174         if (rv != BCM_E_BUSY) \
   1175         {ALPM_ERR(("ALPMerr: %s : %d rv %d\n", FUNCTION_NAME(), __LINE__, rv));} goto bad; } } while(0)
   1176 
   1177 #define ALPM_REALLOC_EG(_ptr, _size, _str)  \
   1178     do {                                    \
   1179         if (_ptr == NULL) {                 \
   1180             _ptr = alpm_util_alloc(_size, _str);\
   1181         }                                   \
   1182         if (_ptr == NULL) {                 \
   1183             rv = BCM_E_MEMORY;              \
   1184             ALPM_ERR(("ALPMerr: out of memory at %s : %d\n", FUNCTION_NAME(), __LINE__)); \
   1185             goto bad;                       \
   1186         }                                   \
   1187         sal_memset(_ptr, 0, _size);         \
   1188     } while (0)
   1189 
   1190 #define ALPM_ALLOC_EG(_ptr, _size, _str)    \
   1191     do {                                    \
   1192         _ptr = alpm_util_alloc(_size, _str);\
   1193         if (_ptr == NULL) {                 \
   1194             rv = BCM_E_MEMORY;              \
   1195             ALPM_ERR(("ALPMerr: out of memory at %s : %d\n", FUNCTION_NAME(), __LINE__)); \
   1196             goto bad;                       \
   1197         }                                   \
   1198         sal_memset(_ptr, 0, _size);         \
   1199     } while (0)
   1200 
   1201 #define ALPM_DMA_ALLOC_EG(_u, _ptr, _size, _str)    \
   1202     do {                                            \
   1203         _ptr = soc_cm_salloc(_u, _size, _str);      \
   1204         if (_ptr == NULL) {                 \
   1205             rv = BCM_E_MEMORY;              \
   1206             ALPM_ERR(("ALPMerr: out of memory at %s : %d\n", FUNCTION_NAME(), __LINE__)); \
   1207             goto bad;                       \
   1208         }                                   \
   1209         sal_memset(_ptr, 0, _size);         \
   1210     } while (0)
   1211 
   1212 /* ALPM externs */
   1213 extern int alpm_bkt_pfx_idx_backup(int u, _alpm_bkt_pfx_arr_t *pfx_arr,
   1214                                    uint32 **bak_idx);
   1215 extern int alpm_bkt_pfx_copy(int u, _alpm_cb_t *acb, _alpm_bkt_pfx_arr_t *pfx_arr,
   1216                          _alpm_pvt_node_t *opvt_node, _alpm_pvt_node_t *npvt_node);
   1217 extern int alpm_pvt_update_by_pvt_node(int u, _alpm_cb_t *acb,
   1218                          _alpm_pvt_node_t *pvt_node, uint32 write_flags);
   1219 extern int alpm_bkt_pfx_clean(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node,
   1220                               int count, uint32 *ent_idx);
   1221 extern void alpm_bkt_bnk_shrink(int u, int ipt, _alpm_cb_t *acb,
   1222                                 _alpm_bkt_pool_conf_t *bp_conf,
   1223                                 _alpm_bkt_info_t *bkt_info, int *fmt_update);
   1224 extern int alpm_pvt_delete_by_pvt_node(int u, _alpm_cb_t *acb,
   1225                                        _alpm_pvt_node_t *pvt_node);
   1226 extern void alpm_bkt_pfx_idx_restore(int u, _alpm_bkt_pfx_arr_t *pfx_arr,
   1227                                      uint32 *bak_idx);
   1228 extern int alpm_bnk_alloc(int u, _alpm_cb_t *acb, int vrf_id, int ipt,
   1229                int req_bnk_cnt, _alpm_bkt_info_t *bkt_info, int *avl_bnk_cnt);
   1230 extern int alpm_bkt_insert(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg,
   1231                            _alpm_pvt_node_t *pvt_node, uint32 *ent_idx);
   1232 extern void alpm_bkt_free(int u, _alpm_cb_t *acb, int vrf_id, int ipt,
   1233                           _alpm_bkt_info_t *bkt_info);
   1234 extern int alpm_bkt_pfx_shrink(int u, _alpm_cb_t *acb,
   1235                                _alpm_pvt_node_t *pvt_node, void *user_data);
   1236 extern int alpm_bkt_bnks_get(int u, int vrf_id, _alpm_cb_t *acb,
   1237                              _alpm_bkt_info_t *bkt_info, int *count);
   1238 extern int
   1239 alpm_trie_ent_to_pfx(int u, int app, int pkm, void *e, int, int, uint32 *key);
   1240 extern void
   1241 alpm_trie_pfx_to_cfg(int u, uint32 *pfx, int plen, _bcm_defip_cfg_t *cfg);
   1242 
   1243 extern int
   1244 alpm_bkt_free_bnk_range_get(int u, SHR_BITDCL *bnk_bmp, int bnk_sz,
   1245                             int req_cnt, int *rng_left, int *rng_right,
   1246                             int *rng_mid);
   1247 extern int
   1248 alpm_bkt_bnk_nearest_get(int u, SHR_BITDCL *bnk_bmp, int bnk_sz,
   1249                          int left_bnk, int right_bnk, int *nst_bnk);
   1250 extern int
   1251 alpm_bkt_ent_get_attempt(int u, _alpm_cb_t *acb, _alpm_bkt_pool_conf_t *bp_conf,
   1252                  _alpm_bkt_info_t *bkt_info, uint8 def_fmt, int pfx_len,
   1253                  uint32 *ent_idx, int *fmt_update, int bkt_test, int *empty_bnk);
   1254 
   1255 extern int alpm_cb_merge(int u, _alpm_cb_t *acb, int vrf_id, int ipt);
   1256 extern int alpm_cb_delete(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *lpm_cfg);
   1257 extern int alpm_cb_insert(int u, _alpm_cb_t *acb, _bcm_defip_cfg_t *cfg);
   1258 extern int alpm_cb_defrag(int u, _alpm_cb_t *acb, int vrf_id, int ipt);
   1259 extern int alpm_cb_expand(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *, int, int *);
   1260 extern int alpm_cb_expand_in_bkt(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *, int );
   1261 extern int alpm_cb_pvt_sanity_cb(int, _alpm_cb_t *, _alpm_pvt_node_t *, void *);
   1262 extern int alpm_cb_sanity(int u, int app, int acb_bmp, int vrf_id, int);
   1263 extern int alpm_cb_find(int, _alpm_cb_t *, _bcm_defip_cfg_t *,
   1264                         _alpm_pvt_node_t **, _alpm_bkt_node_t **);
   1265 extern int alpm_bkt_pfx_merge_check_and_alloc(int u, _alpm_cb_t *acb,
   1266                                     _alpm_pvt_node_t *pvt_node,
   1267                                     _alpm_bkt_pfx_arr_t *pfx_arr,
   1268                                     _alpm_bkt_info_t *nbkt_info,
   1269                                     int avl_free_bnks, int *req_bnks);
   1270 extern int alpm_bkt_alloc(int u, _alpm_cb_t *acb, int vrf_id, int ipt, int req_bnk_cnt,
   1271                           _alpm_bkt_info_t *bkt_info, int *avl_bnk_cnt, int *pvt_updated);
   1272 extern int alpm_bkt_bnk_clear(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node, int tab_idx);
   1273 extern int alpm_bkt_ent_write(int, _alpm_cb_t *, _alpm_pvt_node_t *,
   1274                               _bcm_defip_cfg_t *, int, uint32 write_flags);
   1275 extern int alpm_bkt_move(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node,
   1276                          _alpm_bkt_info_t *src_bkt, _alpm_bkt_info_t *dst_bkt);
   1277 extern int alpm_trie_pfx_cb(alpm_lib_trie_node_t *node, void *user_data);
   1278 
   1279 extern int soc_alpm_cmn_mode_get(int unit);
   1280 extern int soc_alpm_cmn_banks_get(int unit);
   1281 
   1282 /* ESW externs */
   1283 extern int bcm_esw_alpm_pvt_traverse(int u, int app, int lvlp, int vrf_id, int ipt,
   1284                 bcm_esw_alpm_pvt_trav_cb trav_fn, void *user_data);
   1285 extern int bcm_esw_alpm_pfx_traverse(int u, int app, int vrf_id, int ipt,
   1286                 bcm_esw_alpm_pfx_trav_cb trav_fn, void *user_data);
   1287 extern int bcm_esw_alpm_bkt_traverse(alpm_lib_trie_t *bkt_trie,
   1288                 bcm_esw_alpm_bkt_trav_cb trav_fn, void *user_data);
   1289 extern int bcm_esw_alpm_pvt_count_get(int u, _alpm_pvt_node_t *pvt_node, int *);
   1290 extern int bcm_esw_alpm_warmboot_walk(int u, int app, _bcm_l3_trvrs_data_t *trv_data);
   1291 extern int tcam_entry_to_key(int u, int app, int pkm, void *e, int sub_idx, uint32 *key);
   1292 
   1293 /* Extern functions of alpm_tcam.c */
   1294 extern int alpm_pvt_trie_init(int u, int app, int vrf_id, int ipt);
   1295 extern int alpm_pvt_trie_insert(int u, _bcm_defip_cfg_t *lpm_cfg);
   1296 extern int alpm_pvt_trie_delete(int u, _bcm_defip_cfg_t *lpm_cfg);
   1297 
   1298 /* APIs distributed hitbits */
   1299 extern int alpm_rte_hit_get(int u, int app, int vrf_id, _alpm_tbl_t tbl, int idx, int ent);
   1300 extern int alpm_pvt_ent_idx_get(int u, _alpm_cb_t *acb,
   1301                                 _alpm_pvt_node_t *pvt_node, int *ent_idx);
   1302 extern int alpm_ppg_hitbit(int u, int app, int vrf_id, int ipt, uint32 *key, int key_len);
   1303 
   1304 
   1305 /* ALPM utils */
   1306 #define ALPM_TCAM_SUBCNT    2
   1307 #define ALPM_HALF_FIELD_NAME(half, fld0, fld1) ((half) == 0 ? (fld0) : (fld1))
   1308 #define ALPM_KEY_ENT_CNT(ipt) ((ipt) == ALPM_IPT_V4 ? 1 : 4)
   1309 #define ALPM_IS_IPV4(ipt) ((ipt) == ALPM_IPT_V4 ? TRUE : FALSE)
   1310 #define ALPM_IS_IPV6(ipt) ((ipt) == ALPM_IPT_V4 ? FALSE : TRUE)
   1311 #define TCAM_TBL_NAME(acb, pkm)     (alpm_tbl_str[acb->pvt_tbl[pkm]])
   1312 #define ALPM_TBL_NAME(tbl)          (alpm_tbl_str[tbl])
   1313 #define ALPM_FLAGS_FILTER(flag) ((flag) &= (BCM_L3_MULTIPATH | BCM_L3_RPE | BCM_L3_DST_DISCARD))
   1314 
   1315 extern char *alpm_util_pkm_str[];
   1316 extern char *alpm_util_ipt_str[];
   1317 extern char *alpm_util_acb_str[];
   1318 extern char *alpm_tbl_str[];
   1319 extern const char *alpm_route_grp_name[];
   1320 extern const char *alpm_route_comb_name[];
   1321 
   1322 /* External functions of alpm_ts.c */
   1323 extern int alpm_pfx_hw_route_sanity(int u, int app, int *tot_err);
   1324 
   1325 /* Additional ALPM & TCAM driver wrapper */
   1326 extern int alpm_util_bkt_info_get(int u, int vrf_id, int ipt, int pvt_pkm, _alpm_cb_t *acb,
   1327                                   void *e, int sub_idx, _alpm_bkt_info_t *bkt_info,
   1328                                   int *kshift, int *def_miss);
   1329 extern uint8 alpm_util_bkt_def_fmt_get(int u, _alpm_cb_t *acb, int vrf_id,
   1330                                      int ipt);
   1331 extern int16 alpm_util_bkt_fmt_type_get(int u, int vrf_id, _alpm_cb_t *acb, uint8 fmt);
   1332 extern int alpm_util_ent_ent_get(int u, int vrf_id, _alpm_cb_t *acb, void *e,
   1333                                  uint32 fmt, int eid, void *ftmp);
   1334 extern void alpm_util_pfx_cat(int u, int ipt, uint32 *pfx1, int len1,
   1335                               uint32 *pfx2, int len2, uint32 *new_pfx,
   1336                               int *new_len);
   1337 extern int alpm_util_pfx_len_cmp(void *a, void *b);
   1338 extern int alpm_util_bkt_pfx_get(int u, int vrf_id, _alpm_cb_t *acb, void *e,
   1339                                  uint32 fmt, uint32 *new_key, int *new_len,
   1340                                  uint32 *valid);
   1341 extern int alpm_util_bkt_adata_get(int u, int vrf_id, int ipt, _alpm_cb_t *acb, void *ftmp, int fmt,
   1342                                    _alpm_bkt_adata_t *adata1, int *arg1);
   1343 extern int alpm_util_ent_data_get(int u, int vrf_id, int ipt, _alpm_cb_t *acb, void *ftmp,
   1344                                   int fmt, void *fent1);
   1345 extern int alpm_util_ent_phy_idx_get(int u, _alpm_cb_t *acb,
   1346                                      int vrf_id, int index);
   1347 
   1348 extern int tcam_resource_info_get(int u, int app, int vrf, int ipt, int mc, bcm_l3_alpm_lvl_usage_t *lvl_info);
   1349 
   1350 extern int _tcam_entry_write(int u, int app, int pkm, _alpm_pvt_node_t *pvt_node,
   1351                              void *e, int index, int s_index, int update_data);
   1352 extern int tcam_table_size(int u, int app, int pkm);
   1353 extern int tcam_entry_vrf_id_get(int u, int app, int pkm, void *e,
   1354                                   int sub_idx, int *vrf_id);
   1355 extern int _tcam_pkm_uses_half_wide(int u, int pkm, int mc);
   1356 extern int tcam_entry_key_type_get(int u, int app, int pkm, void *e, int sub_idx, int *key_type);
   1357 extern int tcam_entry_pvt_node_get(int u, int app, int pkm, void *e, int sub_idx, _alpm_pvt_node_t **pvt_node);
   1358 extern int tcam_valid_entry_mode_get(int u, int app, int pk, void *e, int *step_size,
   1359                               int *pkm, int *ipv6, int *key_mode, int sub_idx);
   1360 extern int tcam_entry_valid(int u, int app, int pkm, void *e, int sub_idx);
   1361 extern int tcam_entry_pfx_len_get(int u, int app, int pkm, void *e,
   1362                                    int sub_idx, int *pfx_len);
   1363 extern int tcam_entry_adata_get(int u, int app, int pkm, void *e, int sub_idx,
   1364                                 _alpm_bkt_adata_t *adata);
   1365 extern int tcam_entry_bdata_get(int u, int app, int pkm, void *e,
   1366                                 int sub_idx,  void *fent);
   1367 extern int tcam_entry_hit_get(int u, int app, int pkm, void *e, int sub_dx);
   1368 extern int tcam_cache_hit_get(int u, _alpm_pvt_node_t *pvt_node, int app, int pkm, int tcam_idx);
   1369 extern int tcam_hit_write(int u, _alpm_pvt_node_t *pvt_node, int app, int pkm, int tcam_idx, int hit_val);
   1370 extern int tcam_hitbit_sync_cache(int u);
   1371 extern int tcam_entry_to_cfg(int u, int pkm, void *e, int x,
   1372                               _bcm_defip_cfg_t *lpm_cfg);
   1373 extern int tcam_entry_read(int u, int app, int pkm, void *e, int index, int s_index);
   1374 extern int alpm_bkt_entry_read(int u, _alpm_tbl_t tbl, _alpm_cb_t *acb,
   1375                                void *e, int index);
   1376 extern int tcam_entry_read_no_cache(int u, int app, int pkm, void *e,
   1377                                     int index, int s_index);
   1378 extern int alpm_bkt_entry_read_no_cache(int u, _alpm_tbl_t tbl,
   1379                             _alpm_cb_t *acb, void *e, int index);
   1380 extern int alpm_default_usage_get(int u, int grp, int *def_route, int *def_lvl,
   1381                                   int *def_usage, int *cur_cnt_total);
   1382 extern int alpm_bnk_limit_usage(int u, bcm_l3_route_group_t grp, int max_lvl);
   1383 
   1384 /* ALPM utils */
   1385 extern void * alpm_util_alloc(unsigned int sz, char *s);
   1386 extern void alpm_util_free(void *addr);
   1387 extern void alpm_util_mem_stat_get(uint32 *alloc_cnt, uint32 *free_cnt);
   1388 extern void alpm_util_mem_stat_clear(void);
   1389 extern void alpm_trie_key_to_pfx(int u, int ipt, uint32 *key, uint32 len, uint32 *pfx);
   1390 extern void alpm_trie_pfx_to_key(int u, int ipt, uint32 *pfx, uint32 len, uint32 *key);
   1391 extern void alpm_util_key_to_cfg(int u, int ipt, uint32 *key, _bcm_defip_cfg_t *lpm_cfg);
   1392 extern void alpm_util_len_to_mask(int ipt, uint32 len, uint32 *mask);
   1393 extern int alpm_util_cfg_construct(int u, int vrf_id, int ipt, uint32 *key, int key_len,
   1394                         _alpm_bkt_adata_t *adata, _bcm_defip_cfg_t *lpm_cfg);
   1395 extern int alpm_util_key_to_str(int u, int pkm, char * ipstr, uint32 *key, uint32 key_len,
   1396                      _alpm_bkt_node_t *bkt_node, _alpm_pvt_node_t *pvt_node);
   1397 extern int alpm_util_trie_max_key_len(int u, int ipt);
   1398 extern int alpm_util_trie_max_split_len(int u, int pkm);
   1399 extern void alpm_util_trie_pfx_str(int u, int ipt, uint32 *pfx, uint32 len, char *str);
   1400 extern void alpm_util_trie_pfx_print(int u, int ipt, uint32 *pfx, uint32 len, const char *str);
   1401 extern void alpm_util_adata_cfg_to_trie(int unit, _bcm_defip_cfg_t *lpm_cfg,
   1402                             _alpm_bkt_adata_t *bkt_adata);
   1403 extern void alpm_util_adata_trie_to_cfg(int unit, _alpm_bkt_adata_t *bkt_adata,
   1404                             _bcm_defip_cfg_t *lpm_cfg);
   1405 extern void alpm_util_adata_zero_cfg(int unit, _bcm_defip_cfg_t *lpm_cfg);
   1406 extern uint8 alpm_util_route_type_get(int u, _bcm_defip_cfg_t *lpm_cfg, int app);
   1407 extern int alpm_util_route_type_check(int u, _bcm_defip_cfg_t *lpm_cfg);
   1408 extern int alpm_util_def_check(int u, _bcm_defip_cfg_t *lpm_cfg, int is_add);
   1409 extern void alpm_util_cfg_to_key(int u, int ipt, _bcm_defip_cfg_t *lpm_cfg, uint32 *key);
   1410 extern void alpm_util_cfg_to_msk(int u, int ipt, _bcm_defip_cfg_t *lpm_cfg, uint32 *msk);
   1411 extern void alpm_util_ipmask_apply(int u, _bcm_defip_cfg_t *lpm_cfg);
   1412 extern int alpm_util_pvt_idx_get(int u, _alpm_cb_t *acb,
   1413                       _alpm_pvt_node_t *pvt_node, int *idx, int *sub_idx);
   1414 extern int alpm_util_trie_pvt_node_print(alpm_lib_trie_node_t *trie, void *datum);
   1415 extern int alpm_util_trie_pvt_node_print1(alpm_lib_trie_node_t *trie,
   1416                                           uint32 *key, uint32 key_len, void *datum);
   1417 extern int alpm_util_trie_pvt_bkt_print1(alpm_lib_trie_node_t *trie,
   1418                                           uint32 *key, uint32 key_len, void *datum);
   1419 extern int alpm_util_trie_bkt_node_print(alpm_lib_trie_node_t *trie, void *datum);
   1420 extern int alpm_util_trie_pvt_bkt_print(alpm_lib_trie_node_t *trie, void *datum);
   1421 extern uint8 alpm_app_get(int u, uint32 defip_inter_flags);
   1422 extern uint32 alpm_app_flag_get(int u, int app);
   1423 extern int alpm_app_cnt(int u);
   1424 extern int alpm_pid_count(int app);
   1425 extern int alpm_acl_app(int app);
   1426 
   1427 extern void alpm_pvt_node_print(int u, _alpm_cb_t *acb, _alpm_pvt_node_t *pvt_node);
   1428 
   1429 #endif /* ALPM_ENABLE */
   1430 
   1431 #endif /* _BCM_INT_ALPM_INTERNAL_H_ */
   1432