alpm_int.h (37739B)
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 * common defines between v4 and v6-128 code 7 */ 8 9 #ifndef _ESW_TRIDENT2_ALPM_INT_H 10 #define _ESW_TRIDENT2_ALPM_INT_H 11 12 #include <soc/esw/trie.h> 13 #include <soc/tomahawk.h> 14 15 #define SOC_ALPM_MODE_INVALID -1 16 #define SOC_ALPM_MODE_COMBINED 0 17 #define SOC_ALPM_MODE_PARALLEL 1 18 #define SOC_ALPM_MODE_TCAM_ALPM 2 19 20 #define _MAX_KEY_LEN_ 144 21 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 22 #define VRF_ID_LEN (12) 23 #elif defined(BCM_TOMAHAWK_SUPPORT) 24 #define VRF_ID_LEN (11) 25 #else 26 #define VRF_ID_LEN (10) 27 #endif 28 29 30 #define MAX_VRF_ID ((1 << VRF_ID_LEN) + 1) 31 #define _MAX_KEY_WORDS_ (BITS2WORDS(_MAX_KEY_LEN_)) 32 33 #define ALPM_IPV4 0 34 #define ALPM_IPV6 1 35 #define ALPM_IPVERS 2 36 37 #define ALPM_PREFIX_IN_TCAM(u, vrf_id) ((vrf_id == SOC_L3_VRF_OVERRIDE) || \ 38 ((soc_alpm_cmn_mode_get(u) == SOC_ALPM_MODE_TCAM_ALPM) && \ 39 (vrf_id == SOC_L3_VRF_GLOBAL))) 40 41 /* Bucket Management Functions */ 42 /* The Buckets from the shared RAM are assigned to TCAM PIVOTS to store 43 * prefixes. The bucket once assigned to a TCAM PIVOT will be in use till the 44 * PIVOT is active (at least one Prefix is used in the bucket). If no entries 45 * are in the bucket, the bucket can be treated as free. The bucket pointers 46 * follow TCAM entries when the TCAM entires are moved up or down to make 47 * space. 48 */ 49 50 /* Shared bitmap routines are used to track bucket usage 51 * For TH, in Parallel mode with uRPF enable, Global low & Private routes can 52 * share same physical bucket, separate bmap are used for tracking each bucket 53 * usage, for other mode or in TD2, they just point to same memory address */ 54 typedef struct soc_alpm_bucket_s { 55 SHR_BITDCL *alpm_vrf_bucket_bmap[ALPM_IPVERS]; 56 SHR_BITDCL *alpm_glb_bucket_bmap[ALPM_IPVERS]; 57 int alpm_bucket_bmap_size; 58 int bucket_count; 59 int next_free; 60 int v6_resv_bucket_count; 61 } soc_alpm_bucket_t; 62 63 extern soc_alpm_bucket_t soc_alpm_bucket[]; 64 /* For TD2, we just use one bmap, glb bmap is not used */ 65 #define SOC_ALPM_BUCKET_BMAP(u) (soc_alpm_bucket[u].alpm_vrf_bucket_bmap[0]) 66 #define SOC_ALPM_BUCKET_BMAP_BYTE(u,i) (soc_alpm_bucket[u].alpm_bucket_bmap[i]) 67 #define SOC_ALPM_BUCKET_BMAP_SIZE(u) (soc_alpm_bucket[u].alpm_bucket_bmap_size) 68 #define SOC_ALPM_BUCKET_NEXT_FREE(u) (soc_alpm_bucket[u].next_free) 69 #define SOC_ALPM_BUCKET_COUNT(u) (soc_alpm_bucket[u].bucket_count) 70 #define SOC_ALPM_BUCKET_MAX_INDEX(u) (soc_alpm_bucket[u].bucket_count - 1) 71 72 extern int l3_alpm_sw_prefix_lookup[SOC_MAX_NUM_DEVICES]; 73 #define SOC_ALPM_SW_LOOKUP(u) (l3_alpm_sw_prefix_lookup[u]) 74 75 #define SOC_ALPM_RPF_BKT_IDX(u, bkt) \ 76 (bkt + SOC_ALPM_BUCKET_COUNT(u)) 77 78 /* For TH, in Parallel mode, we combine the buckets */ 79 extern soc_alpm_bucket_t soc_th_alpm_bucket[]; 80 81 #define SOC_TH_ALPM_VRF_BUCKET_BMAP(u, ipv) \ 82 (soc_th_alpm_bucket[u].alpm_vrf_bucket_bmap[ipv]) 83 #define SOC_TH_ALPM_GLB_BUCKET_BMAP(u, ipv) \ 84 (soc_th_alpm_bucket[u].alpm_glb_bucket_bmap[ipv]) 85 #define SOC_TH_ALPM_BUCKET_BMAP_BYTE(u,i) \ 86 (soc_th_alpm_bucket[u].alpm_bucket_bmap[i]) 87 #define SOC_TH_ALPM_BUCKET_BMAP_SIZE(u) \ 88 (soc_th_alpm_bucket[u].alpm_bucket_bmap_size) 89 #define SOC_TH_ALPM_BUCKET_NEXT_FREE(u) \ 90 (soc_th_alpm_bucket[u].next_free) 91 #define SOC_TH_ALPM_BUCKET_COUNT(u) \ 92 (soc_th_alpm_bucket[u].bucket_count) 93 #define SOC_TH_ALPM_V6_RESV_BUCKET_COUNT(u) \ 94 (soc_th_alpm_bucket[u].v6_resv_bucket_count) 95 #define SOC_TH_ALPM_BUCKET_MAX_INDEX(u) \ 96 (soc_th_alpm_bucket[u].bucket_count - 1) 97 #define SOC_TH_ALPM_RPF_BKT_IDX(u, bkt) \ 98 (bkt + SOC_TH_ALPM_BUCKET_COUNT(u)) 99 100 #define PRESERVE_HIT TRUE 101 102 typedef struct _payload_s payload_t; 103 struct _payload_s { 104 trie_node_t node; /*trie node */ 105 payload_t *next; /* list node */ 106 unsigned int key[BITS2WORDS(_MAX_KEY_LEN_)]; 107 unsigned int len; 108 int index; /* Memory location */ 109 payload_t *bkt_ptr; 110 }; 111 112 /* 113 * Table Operations for ALPM 114 */ 115 116 /* Generic AUX operation function */ 117 typedef enum _soc_aux_op_s { 118 INSERT_PROPAGATE, 119 DELETE_PROPAGATE, 120 PREFIX_LOOKUP, 121 HITBIT_REPLACE 122 }_soc_aux_op_t; 123 124 extern int _soc_alpm_aux_op(int u, _soc_aux_op_t aux_op, 125 defip_aux_scratch_entry_t *aux_entry, int update_scratch, 126 int *hit, int *tcam_index, int *bucket_index, int aux_flags); 127 extern int _soc_mem_alpm_read(int unit, soc_mem_t mem, int copyno, 128 int index, void *entry_data); 129 extern int _ipmask2pfx(uint32 ipv4m, int *mask_len); 130 131 extern int soc_alpm_assign(int u, int vrf, soc_mem_t mem, int *bucket_pointer, int *shuffled); 132 extern int alpm_bucket_assign(int u, int v6, int *bucket_pointer); 133 extern int alpm_bucket_release(int u, int bucket_pointer, int v6); 134 extern int alpm_bucket_is_assigned(int u, int bucket_ptr, int ipv6, int *used); 135 136 extern int soc_th_alpm_assign(int u, int vrf, soc_mem_t mem, 137 int *log_bkt, int *shuffled, int *free_count); 138 extern int soc_th_alpm_bucket_assign(int u, int vrf, int v6, int *log_bkt); 139 extern int soc_th_alpm_bucket_release(int u, int log_bkt, int vrf, int v6); 140 extern int soc_th_alpm_bucket_is_assigned(int u, int log_bkt, int vrf, int v6, int *used); 141 142 /* Debug counter structure */ 143 typedef struct alpm_vrf_counter_s { 144 uint32 v4; 145 uint32 v6_64; 146 uint32 v6_128; 147 } alpm_vrf_counter_t; 148 149 /* Per VRF PIVOT and Prefix trie. Each VRF will host a trie based on IPv4, IPV6-64 and IPV6-128 150 * This seperation reduces the complexity of trie management. 151 */ 152 typedef struct alpm_vrf_handle_s { 153 trie_t *pivot_trie_ipv4; /* IPV4 Pivot trie */ 154 trie_t *pivot_trie_ipv6; /* IPV6-64 Pivot trie */ 155 trie_t *pivot_trie_ipv6_128; /* IPV6-128 Pivot trie */ 156 trie_t *prefix_trie_ipv4; /* IPV4 Pivot trie */ 157 trie_t *prefix_trie_ipv6; /* IPV6-64 Pivot trie */ 158 trie_t *prefix_trie_ipv6_128; /* IPV6-128 Prefix trie */ 159 defip_entry_t *lpm_entry; /* IPv4 Default LPM entry */ 160 defip_entry_t *lpm_entry_v6; /* IPv6 Default LPM entry */ 161 defip_pair_128_entry_t *lpm_entry_v6_128; /* IPv6-128 Default LPM entry */ 162 int count_v4; /* no. of routes for this vrf */ 163 int count_v6_64; 164 int count_v6_128; 165 166 /* Debug counter */ 167 alpm_vrf_counter_t add; 168 alpm_vrf_counter_t del; 169 alpm_vrf_counter_t bkt_split; 170 alpm_vrf_counter_t pivot_used; 171 alpm_vrf_counter_t lpm_full; 172 alpm_vrf_counter_t lpm_shift; 173 174 int init_done; /* Init for VRF completed */ 175 /* ready to accept route additions */ 176 int flex; /* Programmed with flex counter */ 177 } alpm_vrf_handle_t; 178 179 /* Use MAX_VRF_ID to store VRF_OVERRIDE routes debug info */ 180 extern alpm_vrf_handle_t *alpm_vrf_handle[SOC_MAX_NUM_DEVICES]; 181 182 /* 183 * Bucket Hnadle 184 */ 185 typedef struct alpm_bucket_handle_s { 186 trie_t *bucket_trie; /* trie of Prefix within this bucket */ 187 int bucket_index; /* bucket Pointer */ 188 189 /* Debug counter */ 190 int vrf; 191 uint16 ipv6; 192 uint16 def; 193 uint16 min; 194 uint16 max; 195 196 } alpm_bucket_handle_t; 197 198 /* 199 * Pivot Structure 200 */ 201 typedef struct alpm_pivot_s { 202 trie_node_t node; /*trie node */ 203 /* dq_t listnode;*/ /* list node */ 204 alpm_bucket_handle_t *bucket; /* Bucket trie */ 205 unsigned int key[BITS2WORDS(_MAX_KEY_LEN_)]; /* pivot */ 206 unsigned int len; /* pivot length */ 207 unsigned int bpm_len; /* pivot bpm_len */ 208 int tcam_index; /* TCAM index where the pivot is inserted */ 209 } alpm_pivot_t; 210 211 /* Bucket sharing Data Structure */ 212 213 #define SUB_BKT_SHIFT (3) 214 #define SUB_BKT_MASK ((1U << SUB_BKT_SHIFT) - 1) 215 #define ALPM_LOG_BKT(phy, sub) (((phy) << SUB_BKT_SHIFT) | ((sub) & SUB_BKT_MASK)) 216 #define ALPM_PHY_BKT(u, log) (((log) >> SUB_BKT_SHIFT) & ALPM_CTRL(u).bkt_mask) 217 #define ALPM_SUB_BKT(u, log) ((log) & SUB_BKT_MASK) 218 219 #define SOC_TH_MAX_ALPM_VIEWS (5) /* IPv4, IPv6-64, IPv6-128, IPv4-Flex, IPv6-64-Flex */ 220 #define SOC_TH_MAX_BUCKET_ENTRIES(u) (SOC_IS_TRIDENT3X(u) ? (96+1) : (48+1)) 221 #define SOC_TH_MAX_SUB_BUCKETS (4) /* Max to 4 sub bucket in TH */ 222 223 typedef struct alpm_bkt_usg_s { 224 uint8 count; /* No. of entries in physical bucket */ 225 uint8 sub_bkts; /* Bitmap of logical buckets */ 226 uint8 global; /* 1: Global, 0: Private */ 227 int16 pivots[4]; /* Pivot indices corresponding to logical buckets */ 228 } alpm_bkt_usg_t; 229 230 typedef struct alpm_bkt_bmp_s { 231 uint32 bkt_count; 232 SHR_BITDCL *bkt_bmp; 233 } alpm_bkt_bmp_t; 234 235 #define SOC_ALPM_BU_PTR(u, p) (&(bkt_usage[(u)][(p)])) 236 #define SOC_ALPM_BU_COUNT(u, p) SOC_ALPM_BU_PTR(u, p)->count 237 #define SOC_ALPM_BU_SUB_BKTS(u, p) SOC_ALPM_BU_PTR(u, p)->sub_bkts 238 #define SOC_ALPM_BU_GLOBAL(u, p) SOC_ALPM_BU_PTR(u, p)->global 239 #define SOC_ALPM_BU_PIVOT_IDX(u, p, s) SOC_ALPM_BU_PTR(u, p)->pivots[(s)] 240 #define SOC_ALPM_BU_PIVOT_IDX_UPDATE(u, pivot) \ 241 { \ 242 int phy_bkt, sub_bkt; \ 243 phy_bkt = PIVOT_BUCKET_INDEX(ALPM_TCAM_PIVOT(u, (pivot))); \ 244 sub_bkt = ALPM_SUB_BKT(u, phy_bkt); \ 245 phy_bkt = ALPM_PHY_BKT(u, phy_bkt); \ 246 if (SOC_ALPM_BU_SUB_BKT_IS_SET(u, phy_bkt, sub_bkt)) { \ 247 SOC_ALPM_BU_PIVOT_IDX(u, phy_bkt, sub_bkt) = (pivot); \ 248 } \ 249 } 250 251 #define SOC_ALPM_BU_SUB_BKT_SET(u, p, s) \ 252 (SOC_ALPM_BU_PTR(u, (p))->sub_bkts |= 1U << (s)) 253 #define SOC_ALPM_BU_SUB_BKT_CLR(u, p, s) \ 254 (SOC_ALPM_BU_PTR(u, (p))->sub_bkts &= ~(1U << (s))) 255 #define SOC_ALPM_BU_SUB_BKT_IS_SET(u, p, s) \ 256 (SOC_ALPM_BU_PTR(u, (p))->sub_bkts & (1U << (s))) 257 258 #define SOC_ALPM_GBU_PTR(u, v, c) (&global_bkt_usage[(u)][(v)][(c)]) 259 #define SOC_ALPM_GBU_BKT_BMP(u, v, c) SOC_ALPM_GBU_PTR(u, v, c)->bkt_bmp 260 #define SOC_ALPM_GBU_BKT_COUNT(u, v, c) SOC_ALPM_GBU_PTR(u, v, c)->bkt_count 261 262 263 /* Get available bank based on given bank_disable bitmap 264 * - bank_num : a return value for next available bank id 265 * - bank_count: total bank number 266 * - bank_disable: disabled bank bitmap 267 */ 268 269 #define ALPM_FIRST_AVAIL_BANK(bank_num, bank_count, bank_disable) \ 270 do { \ 271 bank_num = 0;\ 272 while ((bank_disable & (1U << bank_num)) && \ 273 (bank_num < bank_count)) { \ 274 bank_num ++; \ 275 } \ 276 } while (0) 277 #define ALPM_NEXT_AVAIL_BANK(bank_num, bank_count, bank_disable) \ 278 do { \ 279 bank_num ++; \ 280 while ((bank_disable & (1U << bank_num)) && \ 281 (bank_num < bank_count)) { \ 282 bank_num ++; \ 283 } \ 284 } while (0) 285 286 287 /* Used for store returned entry_index in lookup function 288 * defip_index = 289 * ----------------------------------------------------- 290 * | 3 bits (sub bucket index) | 29 bits (entry index) | 291 * ----------------------------------------------------- 292 */ 293 #define ALPM_ENT_INDEX_BITS (32 - SUB_BKT_SHIFT) 294 #define ALPM_ENT_INDEX_MASK ((1 << ALPM_ENT_INDEX_BITS) - 1) 295 #define ALPM_ENT_INDEX(idx) ((idx) & ALPM_ENT_INDEX_MASK) 296 297 /* TH: 13, AP & TH2: 14 */ 298 #define SOC_ALPM_BUCKET_BITS(u) ((SOC_IS_TOMAHAWK(u) || SOC_IS_TRIDENT3X(u)) ? 13 : 14) 299 300 #define SOC_TH_ALPM_AIDX_TO_PHY_BKT(u, aidx) \ 301 (((aidx) >> (ALPM_CTRL(u).bank_bits)) & ALPM_CTRL(u).bkt_mask) 302 303 #define SOC_TH_ALPM_AIDX_TO_SUB_BKT(u, aidx) ((aidx) >> ALPM_ENT_INDEX_BITS) 304 305 #define SOC_TH_ALPM_AIDX_TO_LOG_BKT(u, aidx) \ 306 ALPM_LOG_BKT(SOC_TH_ALPM_AIDX_TO_PHY_BKT(u, aidx), \ 307 SOC_TH_ALPM_AIDX_TO_SUB_BKT(u, aidx)) 308 309 #define SOC_TH_ALPM_AIDX(u, phy, sub, bank, ent) \ 310 ((sub) << ALPM_ENT_INDEX_BITS | \ 311 (ent) << (ALPM_CTRL(u).bkt_bits + ALPM_CTRL(u).bank_bits) | \ 312 (phy) << (ALPM_CTRL(u).bank_bits) | \ 313 (bank)) 314 315 extern alpm_bkt_usg_t *bkt_usage[SOC_MAX_NUM_DEVICES]; 316 extern alpm_bkt_bmp_t *global_bkt_usage[SOC_MAX_NUM_DEVICES][SOC_TH_MAX_ALPM_VIEWS]; 317 318 /* TCAM Pivot management */ 319 320 #define MAX_PIVOT_COUNT (16384) 321 #define TH_MAX_PIVOT_COUNT(u) \ 322 ((SOC_IS_TOMAHAWK2(u) || SOC_IS_TRIDENT3X(u)) ? 32768 : 16384) 323 #define MAX_BANK_COUNT(u) (SOC_IS_TRIDENT3X(u) ? 8 : 4) 324 325 /* Array of Pivots */ 326 extern alpm_pivot_t **tcam_pivot[SOC_MAX_NUM_DEVICES]; 327 328 #define ALPM_TCAM_PIVOT(u, index) tcam_pivot[u][index] 329 330 #define PIVOT_BUCKET_HANDLE(p) (p)->bucket 331 #define PIVOT_BUCKET_TRIE(p) ((p)->bucket)->bucket_trie 332 #define PIVOT_BUCKET_INDEX(p) ((p)->bucket)->bucket_index 333 334 /* Debug counter */ 335 #define PIVOT_BUCKET_VRF(p) ((p)->bucket)->vrf 336 #define PIVOT_BUCKET_IPV6(p) ((p)->bucket)->ipv6 337 #define PIVOT_BUCKET_DEF(p) ((p)->bucket)->def 338 #define PIVOT_BUCKET_MIN(p) ((p)->bucket)->min 339 #define PIVOT_BUCKET_MAX(p) ((p)->bucket)->max 340 #define PIVOT_BUCKET_COUNT(p) PIVOT_BUCKET_TRIE(p)->trie->count 341 342 #define PIVOT_BUCKET_ENT_CNT_UPDATE(p) \ 343 if (PIVOT_BUCKET_TRIE(p)->trie != NULL) { \ 344 int _count = PIVOT_BUCKET_COUNT(p); \ 345 if (((p)->bucket)->min == 0) { \ 346 ((p)->bucket)->min = _count; \ 347 } else if (_count < ((p)->bucket)->min) { \ 348 ((p)->bucket)->min = _count; \ 349 } \ 350 if (_count > ((p)->bucket)->max) { \ 351 ((p)->bucket)->max = _count; \ 352 } \ 353 } 354 355 #define PIVOT_TCAM_INDEX(p) ((p)->tcam_index) 356 #define PIVOT_TCAM_BPMLEN(p) ((p)->bpm_len) 357 358 359 #define VRF_PIVOT_TRIE_IPV4(u, vrf) \ 360 alpm_vrf_handle[u][vrf].pivot_trie_ipv4 361 #define VRF_PIVOT_TRIE_IPV6(u, vrf) \ 362 alpm_vrf_handle[u][vrf].pivot_trie_ipv6 363 #define VRF_PIVOT_TRIE_IPV6_128(u, vrf) \ 364 alpm_vrf_handle[u][vrf].pivot_trie_ipv6_128 365 #define VRF_PREFIX_TRIE_IPV4(u, vrf) \ 366 alpm_vrf_handle[u][vrf].prefix_trie_ipv4 367 #define VRF_PREFIX_TRIE_IPV6(u, vrf) \ 368 alpm_vrf_handle[u][vrf].prefix_trie_ipv6 369 #define VRF_PREFIX_TRIE_IPV6_128(u, vrf) \ 370 alpm_vrf_handle[u][vrf].prefix_trie_ipv6_128 371 372 #define L3_DEFIP_MODE_V4 (0) 373 #define L3_DEFIP_MODE_64 (1) 374 #define L3_DEFIP_MODE_128 (2) 375 #define L3_DEFIP_MODE_MAX (3) 376 377 #define RAW_OLD_BKT_DIP 0 378 #define RAW_OLD_BKT_SIP 1 379 #define RAW_NEW_BKT_DIP 2 380 #define RAW_NEW_BKT_SIP 3 381 #define RAW_RB_BKT_DIP 4 382 #define RAW_RB_BKT_SIP 5 383 #define RAW_BKT_NUM 6 384 385 #define VRF_TRIE_INIT_DONE(u, vrf, v6, val) \ 386 do {\ 387 alpm_vrf_handle[u][vrf].init_done &= ~(1 << (v6));\ 388 alpm_vrf_handle[(u)][(vrf)].init_done |= ((val) & 1) << (v6);\ 389 } while (0) 390 391 #define VRF_TRIE_INIT_COMPLETED(u, vrf, v6) \ 392 ((alpm_vrf_handle[u][vrf].init_done & (1 << (v6))) != 0) 393 394 #define VRF_TRIE_DEFAULT_ROUTE_IPV4(u, vrf) \ 395 alpm_vrf_handle[u][vrf].lpm_entry 396 #define VRF_TRIE_DEFAULT_ROUTE_IPV6(u, vrf) \ 397 alpm_vrf_handle[u][vrf].lpm_entry_v6 398 #define VRF_TRIE_DEFAULT_ROUTE_IPV6_128(u, vrf) \ 399 alpm_vrf_handle[u][vrf].lpm_entry_v6_128 400 401 #define VRF_PIVOT_FULL_INC(u, vrf, v6) \ 402 do { \ 403 if (!(v6)) { \ 404 alpm_vrf_handle[(u)][(vrf)].lpm_full.v4++; \ 405 } else if ((v6) == 1) { \ 406 alpm_vrf_handle[(u)][(vrf)].lpm_full.v6_64++; \ 407 } else { \ 408 alpm_vrf_handle[(u)][(vrf)].lpm_full.v6_128++; \ 409 } \ 410 } while (0) 411 412 #define VRF_PIVOT_SHIFT_INC(u, vrf, v6) \ 413 do { \ 414 if (!(v6)) { \ 415 alpm_vrf_handle[(u)][(vrf)].lpm_shift.v4++; \ 416 } else if ((v6) == 1) { \ 417 alpm_vrf_handle[(u)][(vrf)].lpm_shift.v6_64++; \ 418 } else { \ 419 alpm_vrf_handle[(u)][(vrf)].lpm_shift.v6_128++; \ 420 } \ 421 } while (0) 422 423 #define VRF_PIVOT_REF_CNT(u, vrf_id, vrf, v6) \ 424 (((vrf_id) == SOC_L3_VRF_OVERRIDE) ? \ 425 (((v6) == 0) ? alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v4 : \ 426 (((v6) == 1) ? alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v6_64 : \ 427 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v6_128)) : \ 428 (((v6) == 0) ? alpm_vrf_handle[(u)][(vrf)].pivot_used.v4 : \ 429 (((v6) == 1) ? alpm_vrf_handle[(u)][(vrf)].pivot_used.v6_64 : \ 430 alpm_vrf_handle[(u)][(vrf)].pivot_used.v6_128))) 431 432 433 #define VRF_FLEX_COMPLETED VRF_PIVOT_REF_CNT 434 435 436 #define VRF_FLEX_SET(u, vrf_id, vrf, v6, val) \ 437 do { \ 438 if ((vrf_id) == SOC_L3_VRF_OVERRIDE) { \ 439 alpm_vrf_handle[(u)][MAX_VRF_ID].flex &= ~(1 << (v6)); \ 440 alpm_vrf_handle[(u)][MAX_VRF_ID].flex |= ((!!(val))) << (v6);\ 441 } else { \ 442 alpm_vrf_handle[(u)][(vrf)].flex &= ~(1 << (v6)); \ 443 alpm_vrf_handle[(u)][(vrf)].flex |= ((!!(val))) << (v6); \ 444 } \ 445 } while (0) 446 447 #define VRF_FLEX_IS_SET(u, vrf_id, vrf, v6, add) \ 448 (((add) || VRF_FLEX_COMPLETED(u, vrf_id, vrf, v6)) && \ 449 (((vrf_id) == SOC_L3_VRF_OVERRIDE) ? \ 450 ((alpm_vrf_handle[(u)][MAX_VRF_ID].flex & (1 << (v6))) != 0) : \ 451 ((alpm_vrf_handle[(u)][(vrf)].flex & (1 << (v6))) != 0))) 452 453 454 #define VRF_PIVOT_REF_INC(u, vrf_id, vrf, v6) \ 455 do { \ 456 if ((vrf_id) == SOC_L3_VRF_OVERRIDE) { \ 457 if (!(v6)) { \ 458 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v4++; \ 459 } else if ((v6) == 1) { \ 460 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v6_64++; \ 461 } else { \ 462 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v6_128++; \ 463 } \ 464 } else { \ 465 if (!(v6)) { \ 466 alpm_vrf_handle[(u)][(vrf)].pivot_used.v4++; \ 467 } else if ((v6) == 1) { \ 468 alpm_vrf_handle[(u)][(vrf)].pivot_used.v6_64++; \ 469 } else { \ 470 alpm_vrf_handle[(u)][(vrf)].pivot_used.v6_128++; \ 471 } \ 472 } \ 473 } while (0) 474 475 #define VRF_PIVOT_REF_DEC(u, vrf_id, vrf, v6) \ 476 do { \ 477 if ((vrf_id) == SOC_L3_VRF_OVERRIDE) { \ 478 if (!(v6)) { \ 479 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v4--; \ 480 } else if ((v6) == 1) { \ 481 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v6_64--; \ 482 } else { \ 483 alpm_vrf_handle[(u)][MAX_VRF_ID].pivot_used.v6_128--; \ 484 } \ 485 } else { \ 486 if (!(v6)) { \ 487 alpm_vrf_handle[(u)][(vrf)].pivot_used.v4--; \ 488 } else if ((v6) == 1) { \ 489 alpm_vrf_handle[(u)][(vrf)].pivot_used.v6_64--; \ 490 } else { \ 491 alpm_vrf_handle[(u)][(vrf)].pivot_used.v6_128--; \ 492 } \ 493 } \ 494 } while (0) 495 496 #define VRF_BUCKET_SPLIT_INC(u, vrf, v6) \ 497 do { \ 498 if (!(v6)) { \ 499 alpm_vrf_handle[(u)][(vrf)].bkt_split.v4++; \ 500 } else if ((v6) == L3_DEFIP_MODE_64) { \ 501 alpm_vrf_handle[(u)][(vrf)].bkt_split.v6_64++; \ 502 } else { \ 503 alpm_vrf_handle[(u)][(vrf)].bkt_split.v6_128++; \ 504 } \ 505 } while (0) 506 507 #define VRF_TRIE_ROUTES_INC(u, vrf_id, vrf, v6) \ 508 do { \ 509 if ((vrf_id) == SOC_L3_VRF_OVERRIDE) { \ 510 if (!(v6)) { \ 511 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v4++; \ 512 alpm_vrf_handle[(u)][MAX_VRF_ID].add.v4++; \ 513 } else if ((v6) == L3_DEFIP_MODE_64) { \ 514 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v6_64++; \ 515 alpm_vrf_handle[(u)][MAX_VRF_ID].add.v6_64++; \ 516 } else { \ 517 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v6_128++; \ 518 alpm_vrf_handle[(u)][MAX_VRF_ID].add.v6_128++; \ 519 } \ 520 } else { \ 521 if (!(v6)) { \ 522 alpm_vrf_handle[(u)][(vrf)].count_v4++; \ 523 alpm_vrf_handle[(u)][(vrf)].add.v4++; \ 524 } else if ((v6) == L3_DEFIP_MODE_64) { \ 525 alpm_vrf_handle[(u)][(vrf)].count_v6_64++; \ 526 alpm_vrf_handle[(u)][(vrf)].add.v6_64++; \ 527 } else { \ 528 alpm_vrf_handle[(u)][(vrf)].count_v6_128++; \ 529 alpm_vrf_handle[(u)][(vrf)].add.v6_128++; \ 530 } \ 531 } \ 532 } while (0) 533 534 #define VRF_TRIE_ROUTES_DEC(u, vrf_id, vrf, v6) \ 535 do { \ 536 if ((vrf_id) == SOC_L3_VRF_OVERRIDE) { \ 537 if (!(v6)) { \ 538 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v4--; \ 539 alpm_vrf_handle[(u)][MAX_VRF_ID].del.v4++; \ 540 } else if ((v6) == L3_DEFIP_MODE_64) { \ 541 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v6_64--; \ 542 alpm_vrf_handle[(u)][MAX_VRF_ID].del.v6_64++; \ 543 } else { \ 544 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v6_128--; \ 545 alpm_vrf_handle[(u)][MAX_VRF_ID].del.v6_128++; \ 546 } \ 547 } else { \ 548 if (!(v6)) { \ 549 alpm_vrf_handle[(u)][(vrf)].count_v4--; \ 550 alpm_vrf_handle[(u)][(vrf)].del.v4++; \ 551 } else if ((v6) == L3_DEFIP_MODE_64) { \ 552 alpm_vrf_handle[(u)][(vrf)].count_v6_64--; \ 553 alpm_vrf_handle[(u)][(vrf)].del.v6_64++; \ 554 } else { \ 555 alpm_vrf_handle[(u)][(vrf)].count_v6_128--; \ 556 alpm_vrf_handle[(u)][(vrf)].del.v6_128++; \ 557 } \ 558 } \ 559 } while (0) 560 561 562 #define VRF_TRIE_ROUTES_CNT(u, vrf_id, vrf, v6) \ 563 (((vrf_id) == SOC_L3_VRF_OVERRIDE) ? \ 564 (((v6) == 0) ? alpm_vrf_handle[(u)][MAX_VRF_ID].count_v4 : \ 565 (((v6) == 1) ? alpm_vrf_handle[(u)][MAX_VRF_ID].count_v6_64 : \ 566 alpm_vrf_handle[(u)][MAX_VRF_ID].count_v6_128)) : \ 567 (((v6) == 0) ? alpm_vrf_handle[(u)][(vrf)].count_v4 : \ 568 (((v6) == 1) ? alpm_vrf_handle[(u)][(vrf)].count_v6_64 : \ 569 alpm_vrf_handle[(u)][(vrf)].count_v6_128))) 570 571 572 /* Used to store the list of Prefixes that need to be moved to new bucket */ 573 #define MAX_PREFIX_PER_BUCKET 96 574 #define SOC_ALPM_LPM_LOCK(u) soc_mem_lock(u, L3_DEFIPm) 575 #define SOC_ALPM_LPM_UNLOCK(u) soc_mem_unlock(u, L3_DEFIPm) 576 #define _ALPM_IF_ERROR_GOTO(rv, label, done, doing) {if ((rv) < 0) {goto label;} done=doing;} 577 #define MAX_RAW_COUNT -1 578 #define INVALID_BPM_LEN -1 579 580 #define SOC_ALPM_MEM_VIEW(mem) \ 581 (mem == L3_DEFIP_ALPM_IPV4m ? 0 : \ 582 mem == L3_DEFIP_ALPM_IPV6_64m ? 1 : \ 583 mem == L3_DEFIP_ALPM_IPV6_128m ? 2 : \ 584 mem == L3_DEFIP_ALPM_IPV4_1m ? 3 : \ 585 mem == L3_DEFIP_ALPM_IPV6_64_1m ? 4 : 0) 586 587 #define SOC_ALPM_MEM_V6(mem) \ 588 (mem == L3_DEFIP_ALPM_IPV4m ? L3_DEFIP_MODE_V4 : \ 589 mem == L3_DEFIP_ALPM_IPV6_64m ? L3_DEFIP_MODE_64 : \ 590 mem == L3_DEFIP_ALPM_IPV6_128m ? L3_DEFIP_MODE_128: \ 591 mem == L3_DEFIP_ALPM_IPV4_1m ? L3_DEFIP_MODE_V4 : \ 592 mem == L3_DEFIP_ALPM_IPV6_64_1m ? L3_DEFIP_MODE_64 : 0) 593 594 /* Used for AUX operation */ 595 #define SOC_ALPM_AUX_DEF_ROUTE (1 << 0) 596 #define SOC_ALPM_AUX_SRC_DISCARD (1 << 1) 597 598 typedef enum { 599 MERGE_PHY = 0, 600 MERGE_LOG_CHILD_TO_PARENT, 601 MERGE_LOG_PARENT_TO_CHILD 602 } soc_alpm_merge_type_t; 603 604 #define REPART_THRESHOLD 10 605 #define MERGE_THRESHOLD 10 606 607 typedef struct { 608 int u; 609 int merge_count; 610 int orig_vrf; 611 int vrf; 612 int v6; 613 soc_mem_t mem; 614 int max_count; 615 616 int shuffled; 617 int free_count; /* Max free count as a result of merge or repart */ 618 int log_bkt; /* out */ 619 } soc_alpm_merge_info_t; 620 621 622 typedef struct { 623 payload_t *prefix[MAX_PREFIX_PER_BUCKET]; 624 int count; 625 } alpm_mem_prefix_array_t; 626 627 typedef struct _alpm_pfx_info_s { 628 soc_mem_t mem; 629 void *alpm_data; 630 void *alpm_sip_data; 631 int pivot_idx_from; 632 int log_bkt_from; 633 int log_bkt_to; 634 int vrf; 635 } alpm_pfx_info_t; 636 637 /* Internal Debug counter */ 638 typedef struct _alpm_int_dbg_cnt_s { 639 uint32 bkt_split; 640 uint32 bkt_share; 641 uint32 bkt_merge; 642 uint32 bkt_merge2; 643 uint32 bkt_repart; 644 uint32 ppg_cb_insert; 645 uint32 ppg_cb_delete; 646 uint32 ppg_cb_hitbit; 647 } _alpm_int_dbg_cnt_t; 648 649 typedef struct trie_bpm_cb_user_data_s { 650 int unit; 651 int ipv6; 652 int aux_op; 653 int count; 654 int flags; 655 656 /* carry out data based on aux_op value */ 657 int pfx_len; 658 int old_idx; 659 int new_idx; 660 void *entry; 661 } trie_bpm_cb_user_data_t; 662 663 typedef struct _soc_alpm_fld_s { 664 /* L3_DEFIP */ 665 soc_field_t key_mode0; 666 soc_field_t key_mode1; 667 soc_field_t key_mode_mask0; 668 soc_field_t key_mode_mask1; 669 soc_field_t key_type0; 670 soc_field_t key_type1; 671 soc_field_t key_type_mask0; 672 soc_field_t key_type_mask1; 673 /* L3_DEFIP_PAIR_128 */ 674 soc_field_t key_mode0_upr; 675 soc_field_t key_mode0_lwr; 676 soc_field_t key_mode1_upr; 677 soc_field_t key_mode1_lwr; 678 soc_field_t key_mode_mask0_upr; 679 soc_field_t key_mode_mask0_lwr; 680 soc_field_t key_mode_mask1_upr; 681 soc_field_t key_mode_mask1_lwr; 682 soc_field_t key_type0_upr; 683 soc_field_t key_type0_lwr; 684 soc_field_t key_type1_upr; 685 soc_field_t key_type1_lwr; 686 soc_field_t key_type_mask0_upr; 687 soc_field_t key_type_mask0_lwr; 688 soc_field_t key_type_mask1_upr; 689 soc_field_t key_type_mask1_lwr; 690 /* L3_DEFIP_AUX_SCRATCH */ 691 soc_field_t key_mode; 692 soc_field_t key_type; 693 } _soc_alpm_fld_t; 694 695 typedef struct _soc_alpm_ctrl_s { 696 int alpm_mode; 697 int bkt_sharing; 698 int half_bkt_mode; 699 int sw_prefix_lkup; 700 int num_banks; 701 int bank_bits; 702 int num_bkts; 703 int bkt_bits; 704 uint32 bkt_mask; 705 uint32 bank_disable_bmp[2]; /* 0:Global, 1:Private */ 706 uint32 bank_disable_bmp_8b[2]; /* 0:Global, 1:Private */ 707 int double_wide[L3_DEFIP_MODE_MAX]; 708 int ent_per_bank[L3_DEFIP_MODE_MAX]; 709 int cnt_ent_per_bkt[L3_DEFIP_MODE_MAX]; 710 int gp_zoned; 711 712 int hit_bits_skip; 713 int trie_propagate; 714 int trie_user_ppg; 715 int hit_idx_upd; 716 int force_aux_op; 717 int alpm_scaling; 718 int aux_enable; 719 720 uint8 _alpm_128b; 721 uint8 _alpm_128b_bkt_rsvd; 722 uint32 _alpm_128b_bkt_rsvd_cnt; 723 724 _soc_alpm_fld_t fld; 725 726 int ctrl_inited; 727 } _soc_alpm_ctrl_t; 728 729 extern _alpm_int_dbg_cnt_t _alpm_dbg_cntr[]; 730 extern _soc_alpm_ctrl_t soc_alpm_control[]; 731 732 #define ALPM_CTRL(u) (soc_alpm_control[(u)]) 733 734 #define MODE0_f(u) ALPM_CTRL(u).fld.key_mode0 735 #define MODE1_f(u) ALPM_CTRL(u).fld.key_mode1 736 #define MODE_MASK0_f(u) ALPM_CTRL(u).fld.key_mode_mask0 737 #define MODE_MASK1_f(u) ALPM_CTRL(u).fld.key_mode_mask1 738 #define ENTRY_TYPE0_f(u) ALPM_CTRL(u).fld.key_type0 739 #define ENTRY_TYPE1_f(u) ALPM_CTRL(u).fld.key_type1 740 #define ENTRY_TYPE_MASK0_f(u) ALPM_CTRL(u).fld.key_type_mask0 741 #define ENTRY_TYPE_MASK1_f(u) ALPM_CTRL(u).fld.key_type_mask1 742 #define MODE0_UPR_f(u) ALPM_CTRL(u).fld.key_mode0_upr 743 #define MODE0_LWR_f(u) ALPM_CTRL(u).fld.key_mode0_lwr 744 #define MODE1_UPR_f(u) ALPM_CTRL(u).fld.key_mode1_upr 745 #define MODE1_LWR_f(u) ALPM_CTRL(u).fld.key_mode1_lwr 746 #define MODE_MASK0_UPR_f(u) ALPM_CTRL(u).fld.key_mode_mask0_upr 747 #define MODE_MASK0_LWR_f(u) ALPM_CTRL(u).fld.key_mode_mask0_lwr 748 #define MODE_MASK1_UPR_f(u) ALPM_CTRL(u).fld.key_mode_mask1_upr 749 #define MODE_MASK1_LWR_f(u) ALPM_CTRL(u).fld.key_mode_mask1_lwr 750 #define ENTRY_TYPE0_UPR_f(u) ALPM_CTRL(u).fld.key_type0_upr 751 #define ENTRY_TYPE0_LWR_f(u) ALPM_CTRL(u).fld.key_type0_lwr 752 #define ENTRY_TYPE1_UPR_f(u) ALPM_CTRL(u).fld.key_type1_upr 753 #define ENTRY_TYPE1_LWR_f(u) ALPM_CTRL(u).fld.key_type1_lwr 754 #define ENTRY_TYPE_MASK0_UPR_f(u) ALPM_CTRL(u).fld.key_type_mask0_upr 755 #define ENTRY_TYPE_MASK0_LWR_f(u) ALPM_CTRL(u).fld.key_type_mask0_lwr 756 #define ENTRY_TYPE_MASK1_UPR_f(u) ALPM_CTRL(u).fld.key_type_mask1_upr 757 #define ENTRY_TYPE_MASK1_LWR_f(u) ALPM_CTRL(u).fld.key_type_mask1_lwr 758 #define MODE_f(u) ALPM_CTRL(u).fld.key_mode 759 #define ENTRY_TYPE_f(u) ALPM_CTRL(u).fld.key_type 760 761 extern _alpm_int_dbg_cnt_t soc_alpm_dbg_cnt[SOC_MAX_NUM_DEVICES]; 762 extern void _soc_th_alpm_mask_prefix_create(int u, int mode, uint32 mask_len, 763 uint32 *mask); 764 extern void soc_alpm_db_ent_type_encoding(int u, int vrf, uint32 *db_type, 765 uint32 *ent_type); 766 extern int _soc_alpm_rpf_entry(int u, int idx); 767 extern int _soc_alpm_find_in_bkt(int u, soc_mem_t mem, int bucket_index, 768 int bank_disable, uint32 *e, void *alpm_data, 769 int *key_index, int v6); 770 extern int alpm_mem_prefix_array_cb(trie_node_t *node, void *info); 771 extern int alpm_delete_node_cb(trie_node_t *node, void *info); 772 extern int _soc_alpm_insert_in_bkt(int u, soc_mem_t mem, int bucket_index, 773 int bank_disable, void *alpm_data, void *alpm_sip_data, 774 uint32 *e, int *key_index, int v6); 775 extern int _soc_alpm_delete_in_bkt(int u, soc_mem_t mem, int delete_bucket, 776 int bank_disable, void *bufp2, uint32 *e, 777 int *key_index, int v6); 778 extern int _soc_th_alpm_lpm_entry_view_get(int u, int ipv6, int flex); 779 extern int _soc_th_alpm_lpm_flex_get(int u, int ipv6, int entry_view); 780 extern int soc_alpm_128_init(int u); 781 extern int soc_alpm_128_state_clear(int u); 782 extern int soc_alpm_128_deinit(int u); 783 extern int soc_alpm_128_lpm_init(int u); 784 extern int soc_alpm_128_lpm_deinit(int u); 785 extern int soc_alpm_physical_idx(int u, soc_mem_t mem, int index, int full); 786 extern int soc_alpm_logical_idx(int u, soc_mem_t mem, int index, int full); 787 788 extern int _soc_alpm_mem_index(int u, soc_mem_t mem, int bucket_index, 789 int offset, uint32 bank_disable, int *key_index); 790 extern int _soc_alpm_raw_bucket_read(int u, soc_mem_t mem, int bucket_index, 791 void *raw_entry, void *raw_sip_entry); 792 extern int _soc_alpm_raw_bucket_write(int u, soc_mem_t mem, int bucket_index, 793 uint32 bank_disable, 794 void *raw_entry, void *raw_sip_entry, 795 int entry_cnt); 796 extern void _soc_alpm_raw_mem_read(int unit, soc_mem_t mem, void *raw, 797 int ent_id, void *entry); 798 extern void _soc_alpm_raw_mem_write(int unit, soc_mem_t mem, void *raw, 799 int index, int ent_id, void *entry); 800 extern void _soc_alpm_raw_parity_set(int u, soc_mem_t mem, void *alpm_data); 801 802 extern uint32 soc_alpm_bank_dis(int u, int vrf); 803 extern int _soc_alpm_bkt_entry_cnt(int u, soc_mem_t mem); 804 extern int _soc_alpm_128_lpm_free_entries(int u, int vrf); 805 extern int _soc_alpm_128_bucket_merge(int u, soc_mem_t mem, int pivot_idx_from, 806 int pivot_idx_to, soc_alpm_merge_type_t merge_dir, 807 int *shuffled); 808 extern int _soc_alpm_128_bucket_repartition(int u, soc_mem_t mem, int pivot_idx_from, 809 int pivot_idx_to, trie_node_t **new_trie, 810 int *shuffled); 811 812 /* For TH */ 813 extern void soc_th_alpm_dbg_urpf(int u); 814 extern int _soc_th_alpm_mem_prefix_array_cb(trie_node_t *node, void *info); 815 extern int soc_th_alpm_hit_bits_update(int u, alpm_mem_prefix_array_t *pa, int *new_idx, 816 int ipv6, int vrf); 817 extern int _soc_th_alpm_aux_op(int u, _soc_aux_op_t aux_op, 818 defip_aux_scratch_entry_t *aux_entry, int update_scratch, 819 int *hit, int *tcam_index, int *bktid , int aux_flags); 820 extern int _soc_th_alpm_rpf_entry(int u, int idx); 821 extern int _soc_th_alpm_find_in_bkt(int u, soc_mem_t mem, int bktid, 822 int bank_disable, uint32 *e, void *alpm_data, 823 int *key_index, int v6); 824 extern int _soc_th_alpm_insert_in_bkt(int u, soc_mem_t mem, int bktid, 825 int bank_disable, void *alpm_data, void *alpm_sip_data, 826 uint32 *e, int *key_index, int v6); 827 extern int _soc_th_alpm_delete_in_bkt(int u, soc_mem_t mem, int delete_bucket, 828 int bank_disable, void *bufp2, uint32 *e, 829 int *key_index, int v6); 830 extern int soc_th_alpm_128_init(int u); 831 extern int soc_th_alpm_128_state_clear(int u); 832 extern int soc_th_alpm_128_deinit(int u); 833 extern int soc_th_alpm_128_lpm_init(int u); 834 extern int soc_th_alpm_128_lpm_deinit(int u); 835 extern int soc_th_alpm_physical_idx(int u, soc_mem_t mem, int index, int full); 836 extern int soc_th_alpm_logical_idx(int u, soc_mem_t mem, int index, int full); 837 extern int _soc_th_alpm_mem_index(int u, soc_mem_t mem, int phy_bkt, 838 int offset, uint32 bank_disable, int *key_index); 839 840 extern void soc_th_alpm_bank_dis(int u, int vrf, uint32 *b4, uint32 *b8); 841 extern int _soc_th_alpm_bkt_entry_cnt(int u, soc_mem_t alpm_mem); 842 843 /* For bucket sharing */ 844 extern int _soc_th_alpm_128_bucket_merge(int u, soc_mem_t mem, int log_bkt_from, 845 int log_bkt_to, soc_alpm_merge_type_t merge_dir, 846 int *shuffled); 847 extern int _soc_th_alpm_128_lpm_free_entries(int u, int vrf); 848 extern int _soc_th_alpm_128_bucket_repartition(int u, soc_mem_t mem, int log_bkt_from, 849 int log_bkt_to, int max_count, 850 trie_node_t **new_trie, 851 int *shuffled); 852 extern void soc_th_alpm_bucket_usage_incr(int u, int log_bkt, int pivot_index, int vrf, soc_mem_t mem, int diff); 853 extern void soc_th_alpm_bucket_usage_decr(int u, int log_bkt, int clear, int vrf, soc_mem_t mem, int diff, int log_bkt_to); 854 855 #endif /* _ESW_TRIDENT2_ALPM_INT_H */