field.c (134592B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: field.c 8 * Purpose: Field Processor routines Specific to Helix5. 9 */ 10 11 #include <soc/defs.h> 12 13 #if defined (BCM_HELIX5_SUPPORT) && defined(BCM_FIELD_SUPPORT) 14 15 #include <bcm/error.h> 16 #include <bcm/field.h> 17 #include <shared/bsl.h> 18 19 #include <bcm_int/esw/field.h> 20 #include <bcm_int/esw/tomahawk.h> 21 #include <bcm_int/esw/helix5.h> 22 #include <bcm_int/esw/keygen_api.h> 23 #include <bcm_int/esw/flowtracker/ft_group.h> 24 25 /* 26 * Typedef : 27 * _field_ft_group_qual_part_info_t 28 * Purpose: 29 * Temporary structure used to convert keygen qualifiers and 30 * offsets information to field group qual_arr member field. 31 */ 32 typedef struct _field_ft_group_qual_part_info_s { 33 int count; 34 bcm_field_qset_t qset; 35 } _field_ft_group_qual_part_info_t; 36 37 /* 38 * Function: 39 * _field_hx5_ft_stage_extractors_init 40 * 41 * Purpose: 42 * Initializes flowtracker stage extractors information. 43 * 44 * Parameters: 45 * unit - (IN) BCM device number. 46 * stage_fc - (IN) Field stage control structure. 47 * 48 * Returns: 49 * BCM_E_PARAM - Null field stage control structure. 50 * BCM_E_INTERNAL - Invalid CAP Stage ID. 51 * BCM_E_NONE - Success. 52 */ 53 STATIC int 54 _field_hx5_ft_stage_extractors_init(int unit, 55 _field_stage_t *stage_fc) 56 { 57 int rv = BCM_E_NONE; 58 int mode = 0; 59 bcmi_keygen_ext_cfg_db_t **ext_cfg_db_arr = NULL; 60 61 /* Validate input params */ 62 if (stage_fc == NULL) { 63 return BCM_E_PARAM; 64 } 65 66 if (stage_fc->ext_cfg_db_arr != NULL) { 67 return BCM_E_NONE; 68 } 69 70 _FP_XGS3_ALLOC(ext_cfg_db_arr, 71 sizeof(bcmi_keygen_ext_cfg_db_t *) * BCMI_KEYGEN_MODE_COUNT, 72 " ft stage ext cfg db"); 73 74 if (ext_cfg_db_arr == NULL) { 75 return BCM_E_MEMORY; 76 } 77 78 for (mode = BCMI_KEYGEN_MODE_SINGLE; 79 mode < BCMI_KEYGEN_MODE_COUNT; mode++) { 80 switch(mode) { 81 case BCMI_KEYGEN_MODE_SINGLE: 82 case BCMI_KEYGEN_MODE_DBLINTRA: 83 _FP_XGS3_ALLOC(ext_cfg_db_arr[mode], 84 sizeof(bcmi_keygen_ext_cfg_db_t), 85 " ft ext db"); 86 if (ext_cfg_db_arr[mode] == NULL) { 87 rv = BCM_E_MEMORY; 88 } 89 if (BCM_SUCCESS(rv)) { 90 rv = _field_ft_keygen_profile_aab_extractors_db_create(unit, 91 ext_cfg_db_arr[mode], mode); 92 } 93 break; 94 default: 95 continue; 96 } 97 if (BCM_FAILURE(rv)) { 98 break; 99 } 100 } 101 102 if (BCM_FAILURE(rv)) { 103 if (ext_cfg_db_arr != NULL) { 104 for (mode = BCMI_KEYGEN_MODE_SINGLE; 105 mode < BCMI_KEYGEN_MODE_COUNT; mode++) { 106 if (ext_cfg_db_arr[mode] != NULL) { 107 (void) bcmi_keygen_ext_cfg_db_free(unit, 108 ext_cfg_db_arr[mode]); 109 ext_cfg_db_arr[mode] = NULL; 110 } 111 } 112 sal_free(ext_cfg_db_arr); 113 } 114 } else { 115 stage_fc->ext_cfg_db_arr = ext_cfg_db_arr; 116 } 117 118 return BCM_E_NONE; 119 } 120 121 /* 122 * Function: 123 * _field_hx5_ft_session_keygen_profiles_init 124 * 125 * Purpose: 126 * Initializes flowtracker stage session keygen profiles. 127 * 128 * Parameters: 129 * unit - (IN) BCM device number. 130 * stage_fc - (IN) Field stage control structure. 131 * 132 * Returns: 133 * BCM_E_PARAM - Null field stage control structure. 134 * BCM_E_INTERNAL - Invalid CAP Stage ID. 135 * BCM_E_NONE - Success. 136 */ 137 STATIC int 138 _field_hx5_ft_session_keygen_profiles_init(int unit, 139 _field_stage_t *stage_fc) 140 { 141 int rv = BCM_E_NONE; 142 soc_mem_t mem[5] = {INVALIDm}; 143 int entry_words[5] = {0}; 144 int min_idx[5] = {0}; 145 int max_idx[5] = {0}; 146 int idx_min, idx_max; 147 int user_entry_profiles; 148 _field_ft_info_t *ft_info = NULL; 149 150 /* Valid only for Flowtracker */ 151 if (stage_fc->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 152 return rv; 153 } 154 155 ft_info = stage_fc->ft_info; 156 157 user_entry_profiles = soc_property_get(unit, 158 spn_FLOWTRACKER_NUM_UNIQUE_USER_ENTRY_KEYS, 0); 159 if ((user_entry_profiles < 0) || (user_entry_profiles > 128)) { 160 user_entry_profiles = 128; 161 } 162 163 /* Session Key keygen profile */ 164 soc_profile_mem_t_init(&(ft_info->session_key_profile)); 165 166 mem[0] = BSK_SESSION_KEY_LTS_MUX_CTRL_0m; 167 entry_words[0] = BYTES2WORDS(sizeof(bsk_session_key_lts_mux_ctrl_0_entry_t)); 168 mem[1] = BSK_SESSION_KEY_LTS_MASK_0m; 169 entry_words[1] = BYTES2WORDS(sizeof(bsk_session_key_lts_mask_0_entry_t)); 170 mem[2] = BSK_SESSION_KEY_LTS_MUX_CTRL_1m; 171 entry_words[2] = BYTES2WORDS(sizeof(bsk_session_key_lts_mux_ctrl_1_entry_t)); 172 mem[3] = BSK_SESSION_KEY_LTS_MASK_1m; 173 entry_words[3] = BYTES2WORDS(sizeof(bsk_session_key_lts_mask_1_entry_t)); 174 mem[4] = BSK_SESSION_KEY_LTS_MUX_CTRL_2_PLUS_MASKm; 175 entry_words[4] = BYTES2WORDS(sizeof(bsk_session_key_lts_mux_ctrl_2_plus_mask_entry_t)); 176 177 idx_min = soc_mem_index_min(unit, mem[0]); 178 idx_max = (soc_mem_index_max(unit, mem[0]) - user_entry_profiles); 179 180 min_idx[0] = min_idx[1] = min_idx[2] = min_idx[3] = min_idx[4] = idx_min; 181 max_idx[0] = max_idx[1] = max_idx[2] = max_idx[3] = max_idx[4] = idx_max; 182 183 if (idx_min <= idx_max) { 184 rv = soc_profile_mem_index_create(unit, mem, 185 entry_words, min_idx, max_idx, 186 NULL, 5, &(ft_info->session_key_profile)); 187 if (BCM_FAILURE(rv)) { 188 LOG_ERROR(BSL_LS_BCM_FP, 189 (BSL_META_U(unit, 190 "Flowtracker FP Error: Session key" 191 " Keygen profile - Failed.\n"))); 192 return (rv); 193 } 194 } 195 196 /* Session Key keygen profile for user installed flows. */ 197 if (user_entry_profiles > 0) { 198 soc_profile_mem_t_init(&(ft_info->session_key_user_profile)); 199 200 idx_min = (soc_mem_index_max(unit, mem[0]) - user_entry_profiles + 1); 201 idx_max = (soc_mem_index_max(unit, mem[0])); 202 203 min_idx[0] = min_idx[1] = min_idx[2] = min_idx[3] = min_idx[4] = idx_min; 204 max_idx[0] = max_idx[1] = max_idx[2] = max_idx[3] = max_idx[4] = idx_max; 205 206 if (idx_min <= idx_max) { 207 rv = soc_profile_mem_index_create(unit, mem, 208 entry_words, min_idx, max_idx, 209 NULL, 5, &(ft_info->session_key_user_profile)); 210 if (BCM_FAILURE(rv)) { 211 LOG_ERROR(BSL_LS_BCM_FP, 212 (BSL_META_U(unit, 213 "Flowtracker FP Error: Session key Keygen" 214 " profile for user flows - Failed.\n"))); 215 return (rv); 216 } 217 } 218 } 219 220 221 /* Session Data keygen profile */ 222 soc_profile_mem_t_init(&(ft_info->session_data_profile)); 223 mem[0] = BSK_SESSION_DATA_LTS_MUX_CTRL_0m; 224 entry_words[0] = BYTES2WORDS(sizeof(bsk_session_data_lts_mux_ctrl_0_entry_t)); 225 mem[1] = BSK_SESSION_DATA_LTS_MASK_0m; 226 entry_words[1] = BYTES2WORDS(sizeof(bsk_session_data_lts_mask_0_entry_t)); 227 mem[2] = BSK_SESSION_DATA_LTS_MUX_CTRL_1_PLUS_MASKm; 228 entry_words[2] = BYTES2WORDS(sizeof(bsk_session_data_lts_mux_ctrl_1_plus_mask_entry_t)); 229 230 rv = soc_profile_mem_create(unit, mem, 231 entry_words, 3, &(ft_info->session_data_profile)); 232 if (BCM_FAILURE(rv)) { 233 soc_profile_mem_destroy(unit, &(ft_info->session_key_profile)); 234 LOG_ERROR(BSL_LS_BCM_FP, 235 (BSL_META_U(unit, 236 "Flowtracker FP Error: Session Data" 237 " Keygen profile - Failed.\n"))); 238 return (rv); 239 } 240 241 /* Alu data keygen profile */ 242 soc_profile_mem_t_init(&(ft_info->alu_data_profile)); 243 mem[0] = BSK_ALU_DATA_LTS_MUX_CTRL_PLUS_MASKm; 244 entry_words[0] = BYTES2WORDS(sizeof(bsk_alu_data_lts_mux_ctrl_plus_mask_entry_t)); 245 246 rv = soc_profile_mem_create(unit, mem, 247 entry_words, 1, &(ft_info->alu_data_profile)); 248 if (BCM_FAILURE(rv)) { 249 soc_profile_mem_destroy(unit, &(ft_info->session_data_profile)); 250 soc_profile_mem_destroy(unit, &(ft_info->session_key_profile)); 251 LOG_ERROR(BSL_LS_BCM_FP, 252 (BSL_META_U(unit, 253 "Flowtracker FP Error: Alu Data " 254 "Keygen profile - Failed.\n"))); 255 return (rv); 256 } 257 258 return rv; 259 } 260 261 /* 262 * Function: 263 * _field_hx5_ft_stage_ftinfo_init 264 * 265 * Purpose: 266 * Initializes strucutures and databases for flowtracker core module 267 * which is maintained/used by flowtracker stage. 268 * 269 * Parameters: 270 * unit - (IN) BCM device number. 271 * stage_fc - (IN) Field stage control structure. 272 * 273 * Returns: 274 * BCM_E_XXX 275 */ 276 STATIC int 277 _field_hx5_ft_stage_ftinfo_init(int unit, 278 _field_stage_t *stage_fc) 279 { 280 int rv = BCM_E_NONE; 281 _field_ft_info_t *ft_info = NULL; 282 283 if (stage_fc == NULL) { 284 return BCM_E_PARAM; 285 } 286 287 _FP_XGS3_ALLOC(ft_info, sizeof (_field_ft_info_t), "FT core info"); 288 if (ft_info == NULL) { 289 return BCM_E_MEMORY; 290 } 291 292 stage_fc->ft_info = ft_info; 293 294 /* Initialize session keygen profiles */ 295 rv = _field_hx5_ft_session_keygen_profiles_init(unit, stage_fc); 296 if (BCM_FAILURE(rv)) { 297 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 298 "FP(unit %d) Error: _field_hx5_ft_session_keygen_profiles_init=%d\n"), 299 unit, rv)); 300 sal_free(stage_fc->ft_info); 301 stage_fc->ft_info = NULL; 302 return (rv); 303 } 304 305 /* Tracking param-flowcheck qualifier map db init */ 306 rv = _field_ft_tracking_param_qual_map_db_init(unit, ft_info); 307 if (rv != BCM_E_NONE) { 308 (void) _field_ft_tracking_param_qual_map_db_cleanup(unit, ft_info); 309 sal_free(stage_fc->ft_info); 310 stage_fc->ft_info = NULL; 311 return rv; 312 } 313 314 /* Flow key Qualifiers cfg is same as stage qualifers */ 315 ft_info->flow_key_qual_cfg = stage_fc->qual_cfg_info_db; 316 317 /* Flow key Extractors cfg is same as stage extractors cfg */ 318 ft_info->flow_key_ext_cfg_arr = stage_fc->ext_cfg_db_arr; 319 320 /* Flow data Qualifiers cfg is same as stage qualifiers */ 321 ft_info->flow_data_qual_cfg = stage_fc->qual_cfg_info_db; 322 323 /* Flow data Extractors cfg is profile AB - 256 bits */ 324 _FP_XGS3_ALLOC(ft_info->flow_data_ext_cfg, 325 sizeof(bcmi_keygen_ext_cfg_db_t), 326 "flow data extr cfg"); 327 if (ft_info->flow_data_ext_cfg == NULL) { 328 (void) _field_ft_tracking_param_qual_map_db_cleanup(unit, ft_info); 329 sal_free(stage_fc->ft_info); 330 stage_fc->ft_info = NULL; 331 return BCM_E_MEMORY; 332 } 333 334 rv = _field_ft_keygen_profile_ab_extractors_db_create(unit, 335 ft_info->flow_data_ext_cfg, BCMI_KEYGEN_MODE_SINGLE); 336 337 if (rv != BCM_E_NONE) { 338 if (stage_fc->ft_info != NULL) { 339 if (stage_fc->ft_info->flow_data_ext_cfg != NULL) { 340 sal_free(stage_fc->ft_info->flow_data_ext_cfg); 341 } 342 (void) _field_ft_tracking_param_qual_map_db_cleanup(unit, ft_info); 343 sal_free(stage_fc->ft_info); 344 stage_fc->ft_info = NULL; 345 } 346 } 347 return rv; 348 } 349 350 /* 351 * Function: 352 * _field_hx5_ft_stage_ftinfo_deinit 353 * 354 * Purpose: 355 * De-initializes strucutures and databases for flowtracker core module 356 * which is maintained/used by flowtracker stage. 357 * 358 * Parameters: 359 * unit - (IN) BCM device number. 360 * stage_fc - (IN) Stage field control structure. 361 * 362 * Returns: 363 * BCM_E_XXX 364 */ 365 STATIC int 366 _field_hx5_ft_stage_ftinfo_deinit(int unit, 367 _field_stage_t *stage_fc) 368 { 369 _field_ft_info_t *ft_info =NULL; 370 371 if (stage_fc == NULL) { 372 return BCM_E_NONE; 373 } 374 375 if (stage_fc->ft_info == NULL) { 376 return BCM_E_NONE; 377 } 378 ft_info = stage_fc->ft_info; 379 380 /* destroy session keygen profiles */ 381 soc_profile_mem_destroy(unit, &(ft_info->session_key_profile)); 382 soc_profile_mem_destroy(unit, &(ft_info->session_data_profile)); 383 soc_profile_mem_destroy(unit, &(ft_info->alu_data_profile)); 384 385 ft_info->flow_key_qual_cfg = NULL; 386 ft_info->flow_key_ext_cfg_arr = NULL; 387 ft_info->flow_data_qual_cfg = NULL; 388 389 /* Flow data Extractors cfg */ 390 if (ft_info->flow_data_ext_cfg != NULL) { 391 bcmi_keygen_ext_cfg_db_free(unit, ft_info->flow_data_ext_cfg); 392 ft_info->flow_data_ext_cfg = NULL; 393 } 394 395 (void) _field_ft_tracking_param_qual_map_db_cleanup(unit, ft_info); 396 397 sal_free(stage_fc->ft_info); 398 stage_fc->ft_info = NULL; 399 400 return BCM_E_NONE; 401 } 402 403 /* 404 * Function: 405 * _field_hx5_ft_stage_quals_ibus_map_init 406 * 407 * Purpose: 408 * Initializes flowtracker stage qualifiers ingress field bus mapping. 409 * 410 * Parameters: 411 * unit - (IN) BCM device number. 412 * stage_fc - (IN) Stage field control structure. 413 * 414 * Returns: 415 * BCM_E_PARAM - Null field stage control structure. 416 * BCM_E_INTERNAL - Invalid CAP Stage ID. 417 * BCM_E_NONE - Success. 418 */ 419 STATIC int 420 _field_hx5_ft_stage_quals_ibus_map_init(int unit, 421 _field_stage_t *stage_fc) 422 { 423 uint32 pp_ports = 0; 424 bcmi_keygen_qual_flags_bmp_t qual_flags; 425 bcmi_keygen_qual_cfg_info_db_t *db = NULL; 426 BCMI_KEYGEN_FUNC_ENTER(unit); 427 BCMI_KEYGEN_QUAL_CFG_DECL; 428 429 /* validate input params */ 430 if (stage_fc == NULL) { 431 return BCM_E_PARAM; 432 } 433 434 _FP_XGS3_ALLOC(stage_fc->qual_cfg_info_db, 435 sizeof(bcmi_keygen_qual_cfg_info_db_t), 436 "flowtracker qualifiers"); 437 if (NULL == stage_fc->qual_cfg_info_db) { 438 return (BCM_E_MEMORY); 439 } 440 441 db = stage_fc->qual_cfg_info_db; 442 sal_memset(&qual_flags, 0, sizeof(bcmi_keygen_qual_flags_bmp_t)); 443 444 /* Dummy Qualifiers */ 445 /* Stage */ 446 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 447 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyStage, qual_flags); 448 449 /* Stage Flowtracker */ 450 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 451 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyStageIngressFlowtracker, qual_flags); 452 453 /* Underlay Packet fields - PARSER1_FIELD_BUS */ 454 /* Source MAC Address */ 455 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 456 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 0, 0, 16); 457 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 1, 16, 16); 458 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 2, 32, 16); 459 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcMac, qual_flags); 460 461 /* Destination MAC Address */ 462 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 463 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 3, 48, 16); 464 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 4, 64, 16); 465 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 5, 80, 16); 466 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDstMac, qual_flags); 467 468 /* Outer Vlan */ 469 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 470 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 10, 160, 16); 471 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyOuterVlan, qual_flags); 472 473 /* Outer Vlan Identifier */ 474 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 475 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 10, 160, 12); 476 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyOuterVlanId, qual_flags); 477 478 /* Outer Vlan CFI */ 479 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 480 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 10, 172, 1); 481 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyOuterVlanCfi, qual_flags); 482 483 /* Outer Vlan Priority */ 484 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 485 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 10, 173, 3); 486 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyOuterVlanPri, qual_flags); 487 488 /* Inner Vlan */ 489 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 490 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 11, 176, 16); 491 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerVlan, qual_flags); 492 493 /* Inner Vlan Identifier */ 494 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 495 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 11, 176, 12); 496 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerVlanId, qual_flags); 497 498 /* Inner Vlan CFI */ 499 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 500 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 11, 188, 1); 501 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerVlanCfi, qual_flags); 502 503 /* Inner Vlan Priority */ 504 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 505 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 11, 189, 3); 506 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerVlanPri, qual_flags); 507 508 /* Outer Ethertype */ 509 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 510 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 13, 208, 16); 511 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyEtherType, qual_flags); 512 513 /* IPv4 Source Address */ 514 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 515 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 14, 224, 16); 516 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 15, 240, 16); 517 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcIp, qual_flags); 518 519 /* IPv4 IP Protocol */ 520 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 521 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 17, 272, 8); 522 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIpProtocol, qual_flags); 523 524 /* IPv4 TTL */ 525 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 526 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 17, 280, 8); 527 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTtl, qual_flags); 528 529 /* IPv4 Total Length */ 530 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 531 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 20, 320, 16); 532 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIp4Length, qual_flags); 533 534 /* IPv4 TOS / DSCP */ 535 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 536 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 21, 336, 8); 537 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTos, qual_flags); 538 539 /* IPv6 Source Address */ 540 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 541 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 14, 224, 16); 542 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 15, 240, 16); 543 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 16, 256, 16); 544 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 17, 272, 16); 545 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(4, BCMI_KEYGEN_EXT_SECTION_L1E16, 18, 288, 16); 546 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(5, BCMI_KEYGEN_EXT_SECTION_L1E16, 19, 304, 16); 547 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(6, BCMI_KEYGEN_EXT_SECTION_L1E16, 20, 320, 16); 548 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(7, BCMI_KEYGEN_EXT_SECTION_L1E16, 21, 336, 16); 549 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcIp6, qual_flags); 550 551 /* IPv6 LSB 64-bit Source Address */ 552 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 553 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 14, 224, 16); 554 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 15, 240, 16); 555 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 16, 256, 16); 556 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 17, 272, 16); 557 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcIp6Low, qual_flags); 558 559 /* IPv6 MSB 64-bit Source Address */ 560 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 561 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 18, 288, 16); 562 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 19, 304, 16); 563 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 20, 320, 16); 564 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 21, 336, 16); 565 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcIp6High, qual_flags); 566 567 /* IPv4 Destination Address */ 568 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 569 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 22, 352, 16); 570 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 23, 368, 16); 571 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDstIp, qual_flags); 572 573 /* IPv6 Flow Label */ 574 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 575 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 22, 352, 16); 576 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 23, 368, 4); 577 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIp6FlowLabel, qual_flags); 578 579 /* IPv6 Traffic class */ 580 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 581 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 23, 372, 8); 582 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIp6PktTrafficClass, qual_flags); 583 584 /* IPv6 Destination Address */ 585 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 586 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 24, 384, 16); 587 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 25, 400, 16); 588 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 26, 416, 16); 589 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 27, 432, 16); 590 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(4, BCMI_KEYGEN_EXT_SECTION_L1E16, 28, 448, 16); 591 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(5, BCMI_KEYGEN_EXT_SECTION_L1E16, 29, 464, 16); 592 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(6, BCMI_KEYGEN_EXT_SECTION_L1E16, 30, 480, 16); 593 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(7, BCMI_KEYGEN_EXT_SECTION_L1E16, 31, 496, 16); 594 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDstIp6, qual_flags); 595 596 /* IPv6 LSB 64-bit Destination Address */ 597 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 598 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 24, 384, 16); 599 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 25, 400, 16); 600 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 26, 416, 16); 601 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 27, 432, 16); 602 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDstIp6Low, qual_flags); 603 604 /* IPv6 MSB 64-bit Destination Address */ 605 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 606 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 28, 448, 16); 607 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 29, 464, 16); 608 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 30, 480, 16); 609 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 31, 496, 16); 610 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDstIp6High, qual_flags); 611 612 /* IPv6 Hop limit */ 613 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 614 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 32, 512, 8); 615 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIp6PktHopLimit, qual_flags); 616 617 /* IPv6 Next Header */ 618 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 619 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 32, 520, 8); 620 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIp6PktNextHeader, qual_flags); 621 622 /* IPv6 Payload Length */ 623 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 624 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 33, 528, 16); 625 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIp6Length, qual_flags); 626 627 /* L4 Destination Port */ 628 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 629 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 34, 544, 16); 630 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyL4DstPort, qual_flags); 631 632 /* L4 Source Port */ 633 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 634 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 35, 560, 16); 635 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyL4SrcPort, qual_flags); 636 637 /* TCP Window Size */ 638 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 639 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 36, 576, 16); 640 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTcpWindowSize, qual_flags); 641 642 /* TCP Control Flags */ 643 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 644 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 37, 592, 8); 645 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTcpControl, qual_flags); 646 647 /* VxLan Reserved 56-63 bits */ 648 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 649 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 38, 608, 8); 650 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVxlanHeaderBits56_63, qual_flags); 651 652 /* VxLan Identifier */ 653 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 654 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 38, 616, 8); 655 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 39, 624, 16); 656 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVxlanNetworkId, qual_flags); 657 658 /* VxLan Reserved 8-31 bits */ 659 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 660 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 40, 640, 16); 661 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 41, 656, 8); 662 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVxlanHeaderBits8_31, qual_flags); 663 664 /* VxLan Flags */ 665 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 666 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 41, 664, 8); 667 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVxlanFlags, qual_flags); 668 669 /* Overlay packet fields - PARSER2_FIELD_BUS */ 670 /* Tunneled Payload / Inner IPv4 Source Address */ 671 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 672 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 78, 1248, 16); 673 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 79, 1264, 16); 674 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerSrcIp, qual_flags); 675 676 /* Tunneled Payload / Inner IPv4 Ip Protocol */ 677 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 678 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 81, 1296, 8); 679 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerIpProtocol, qual_flags); 680 681 /* Inner IPv4 TTL */ 682 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 683 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 81, 1304, 8); 684 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerTtl, qual_flags); 685 686 /* Tunnel Payload / Inner IPv4 Total Length */ 687 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 688 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 84, 1344, 16); 689 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTunnelPayloadIp4Length, qual_flags); 690 691 /* Inner IPv4 TOS / DSCP */ 692 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 693 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 85, 1360, 8); 694 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerTos, qual_flags); 695 696 /* Inner IPv6 Source Address */ 697 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 698 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 78, 1248, 16); 699 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 79, 1264, 16); 700 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 80, 1280, 16); 701 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 81, 1296, 16); 702 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(4, BCMI_KEYGEN_EXT_SECTION_L1E16, 82, 1312, 16); 703 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(5, BCMI_KEYGEN_EXT_SECTION_L1E16, 83, 1328, 16); 704 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(6, BCMI_KEYGEN_EXT_SECTION_L1E16, 84, 1344, 16); 705 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(7, BCMI_KEYGEN_EXT_SECTION_L1E16, 85, 1360, 16); 706 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerSrcIp6, qual_flags); 707 708 /* Inner IPv6 MSB 64-bit Source Address */ 709 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 710 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 82, 1312, 16); 711 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 83, 1328, 16); 712 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 84, 1344, 16); 713 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 85, 1360, 16); 714 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerSrcIp6High, qual_flags); 715 716 /* Inner IPv4 Destination Address */ 717 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 718 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 86, 1376, 16); 719 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 87, 1392, 16); 720 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerDstIp, qual_flags); 721 722 /* Inner IPv6 Flow Label */ 723 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 724 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 86, 1376, 16); 725 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 87, 1392, 4); 726 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerIp6FlowLabel, qual_flags); 727 728 /* Inner IPv6 Traffic class */ 729 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 730 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 87, 1396, 8); 731 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerIp6PktTrafficClass, qual_flags); 732 733 /* Inner IPv6 Destination Address */ 734 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 735 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 88, 1408, 16); 736 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 89, 1424, 16); 737 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 90, 1440, 16); 738 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 91, 1456, 16); 739 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(4, BCMI_KEYGEN_EXT_SECTION_L1E16, 92, 1472, 16); 740 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(5, BCMI_KEYGEN_EXT_SECTION_L1E16, 93, 1488, 16); 741 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(6, BCMI_KEYGEN_EXT_SECTION_L1E16, 94, 1504, 16); 742 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(7, BCMI_KEYGEN_EXT_SECTION_L1E16, 95, 1520, 16); 743 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerDstIp6, qual_flags); 744 745 /* Inner IPv6 MSB 64-bit Destination Address */ 746 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 747 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 92, 1472, 16); 748 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 93, 1488, 16); 749 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(2, BCMI_KEYGEN_EXT_SECTION_L1E16, 94, 1504, 16); 750 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(3, BCMI_KEYGEN_EXT_SECTION_L1E16, 95, 1520, 16); 751 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerDstIp6High, qual_flags); 752 753 /* Inner IPv6 Hop limit */ 754 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 755 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 96, 1536, 8); 756 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerIp6PktHopLimit, qual_flags); 757 758 /* Inner IPv6 Next Header */ 759 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 760 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 96, 1544, 8); 761 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerIp6PktNextHeader, qual_flags); 762 763 /* Tunnel Payload / Inner IPv6 Payload Length */ 764 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 765 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 97, 1552, 16); 766 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTunnelPayloadIp6Length, qual_flags); 767 768 /* Inner L4 Destination Port */ 769 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 770 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 98, 1568, 16); 771 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerL4DstPort, qual_flags); 772 773 /* Inner L4 Source Port */ 774 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 775 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 99, 1584, 16); 776 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerL4SrcPort, qual_flags); 777 778 /* OBJECT BUS */ 779 /* Module Header SGPP - Module Id + Port */ 780 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 781 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 129, 2064, 16); 782 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyHiGigSrcModPortGport, qual_flags); 783 784 /* Module Header SGPP - Module Id */ 785 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 786 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 129, 2072, 8); 787 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyHiGigSrcModuleGport, qual_flags); 788 789 /* Module Header SGPP - Port */ 790 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 791 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 129, 2064, 8); 792 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyHiGigSrcPortGport, qual_flags); 793 794 /* SGLP Module Id + Port */ 795 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 796 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 130, 2080, 16); 797 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcModPortGport, qual_flags); 798 799 /* SGLP Module Id */ 800 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 801 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 130, 2088, 8); 802 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcModuleGport, qual_flags); 803 804 /*INGRESS_PP_PORT */ 805 pp_ports = 7; 806 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 807 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 133, 2128, pp_ports); 808 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInPort, qual_flags); 809 810 /* Source Trunk Map class ID */ 811 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 812 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 135, 2160, 12); 813 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInterfaceClassPort, qual_flags); 814 815 /* VFP_CLASSID HI */ 816 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 817 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 136, 2176, 10); 818 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifySrcClassField, qual_flags); 819 820 /* VFP_CLASSID LO */ 821 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 822 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 137, 2192, 10); 823 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDstClassField, qual_flags); 824 825 /* VPN */ 826 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 827 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 138, 2208, 10); 828 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVpn, qual_flags); 829 830 /* Virtual Routing forwarding object */ 831 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 832 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 139, 2224, 16); 833 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVrf, qual_flags); 834 835 /* Incoming L3 Interface */ 836 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 837 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 140, 2240, 13); 838 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyL3Ingress, qual_flags); 839 840 /* Higig Dst Module + Port */ 841 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 842 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 143, 2288, 16); 843 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyHiGigDstModPortGport, qual_flags); 844 845 /* Source VP Class Id */ 846 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 847 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 153, 2448, 12); 848 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInterfaceClassVPort, qual_flags); 849 850 /* L3_IIF Class ID */ 851 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 852 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 154, 2464, 12); 853 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInterfaceClassL3, qual_flags); 854 855 /* HVE1_DOS_ATTACK_RESULTS_BUS */ 856 /* DOS Attack Events */ 857 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 858 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 173, 2768, 16); 859 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 174, 2784, 16); 860 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyDosAttackEvents, qual_flags); 861 862 /* HVE2_DOS_ATTACK_RESULTS_BUS */ 863 /* Inner DOS Attack Events */ 864 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 865 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 175, 2800, 16); 866 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 176, 2816, 16); 867 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerDosAttackEvents, qual_flags); 868 869 /* PARSER1_HVE_BUS */ 870 /* Vlan Format */ 871 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 872 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 178, 2849, 2); 873 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyVlanFormat, qual_flags); 874 875 /* L2 Format */ 876 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 877 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 178, 2857, 2); 878 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyL2Format, qual_flags); 879 880 /* L2/L3 Unicast/Multicast/Broadcast */ 881 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 882 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 179, 2866, 2); 883 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 179, 2876, 2); 884 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyPktDstAddrType, qual_flags); 885 886 /* Outer Priority tagged */ 887 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 888 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 179, 2873, 1); 889 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyOuterPriTaggedPkt, qual_flags); 890 891 /* IP with TTL=0 */ 892 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 893 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 179, 2878, 1); 894 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIpTtlZeroPkt, qual_flags); 895 896 /* IP Flags */ 897 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 898 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 181, 2899, 2); 899 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyIpFlags, qual_flags); 900 901 /* L4 Valid */ 902 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 903 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 181, 2908, 1); 904 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyL4Ports, qual_flags); 905 906 /* Inner Tpid */ 907 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 908 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 182, 2928, 2); 909 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerTpid, qual_flags); 910 911 /* Outer Tpid */ 912 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 913 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 183, 2942, 2); 914 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyOuterTpid, qual_flags); 915 916 /* PARSER2_HVE_BUS */ 917 /* Inner L2/L3 Unicast/Multicast/Broadcast */ 918 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 919 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 193, 3090, 2); 920 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 193, 3099, 2); 921 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyPktInnerDstAddrType, qual_flags); 922 923 /* Inner L4 Valid */ 924 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 925 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 195, 3132, 1); 926 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyInnerL4Ports, qual_flags); 927 928 /* Tunnel Class for Flowtracker usage */ 929 BCMI_KEYGEN_QUAL_CFG_INIT(unit); 930 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(0, BCMI_KEYGEN_EXT_SECTION_L1E16, 157, 2512, 16); 931 BCMI_KEYGEN_QUAL_CFG_OFFSET_ADD(1, BCMI_KEYGEN_EXT_SECTION_L1E16, 158, 2528, 8); 932 BCMI_KEYGEN_QUAL_CFG_INSERT(unit, db, bcmFieldQualifyTunnelId, qual_flags); 933 934 exit: 935 936 BCMI_KEYGEN_FUNC_EXIT(); 937 } 938 939 /* 940 * Function: 941 * _bcm_field_hx5_ft_tcam_policy_mem_get 942 * 943 * Purpose: 944 * Get tcam+policy combo memory 945 * 946 * Parameters: 947 * unit - (IN) BCM device number. 948 * tcam_mem - (OUT) tcam table 949 * policy_mem - (OUT) policy table 950 * 951 * Returns: 952 * BCM_E_XXX 953 */ 954 STATIC int 955 _bcm_field_hx5_ft_tcam_policy_mem_get(int unit, 956 soc_mem_t *tcam_mem, 957 soc_mem_t *policy_mem) 958 { 959 *tcam_mem = BSK_FTFP_TCAMm; 960 *policy_mem = BSK_FTFP_POLICYm; 961 962 return BCM_E_NONE; 963 } 964 965 /* 966 * Function: 967 * _field_hx5_ft_entry_qual_tcam_set 968 * 969 * Purpose: 970 * Sets tcam key and mask information to buffer 971 * 972 * Parameters: 973 * unit - (IN) BCM device number. 974 * f_ent - (IN) Field entry structure. 975 * tcam_mem - (IN) tcam hw table. 976 * tcam_idx - (IN) tcam hw index 977 * entry_buf - (IN/OUT) Entry buffer. 978 * 979 * Returns: 980 * BCM_E_XXX 981 */ 982 STATIC int 983 _field_hx5_ft_entry_qual_tcam_set(int unit, 984 _field_entry_t *f_ent, 985 soc_mem_t tcam_mem, 986 int tcam_idx, 987 uint32 *entry_buf) 988 { 989 _field_tcam_t *tcam = NULL; 990 991 if ((f_ent == NULL) || (entry_buf == NULL)) { 992 return BCM_E_PARAM; 993 } 994 995 tcam = &f_ent->tcam; 996 if (tcam == NULL) { 997 return (BCM_E_INTERNAL); 998 } 999 1000 soc_mem_field_set(unit, tcam_mem, entry_buf, KEYf, tcam->key); 1001 soc_mem_field_set(unit, tcam_mem, entry_buf, MASKf, tcam->mask); 1002 soc_mem_field32_set(unit, tcam_mem, entry_buf, VALIDf, 3); 1003 1004 return BCM_E_NONE; 1005 } 1006 1007 /* 1008 * Function: 1009 * _field_hx5_ft_entry_policy_set 1010 * 1011 * Purpose: 1012 * Sets policy data information to buffer 1013 * 1014 * Parameters: 1015 * unit - (IN) BCM device number. 1016 * f_ent - (IN) Field entry structure. 1017 * policy_mem - (IN) Policy hw table. 1018 * e_buf - (IN/OUT) Entry buffer. 1019 * 1020 * Returns: 1021 * BCM_E_PARAM - Null field stage control structure. 1022 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1023 * BCM_E_NONE - Success. 1024 */ 1025 STATIC int 1026 _field_hx5_ft_entry_policy_set(int unit, 1027 _field_entry_t *f_ent, 1028 soc_mem_t policy_mem, 1029 uint32 *e_buf) 1030 { 1031 int rv = BCM_E_NONE; 1032 _field_action_t *fa = NULL; 1033 uint32 value = 0; 1034 uint32 do_not_ft_def = 1; 1035 uint32 action_ft = 0, action_ft_set = FALSE; 1036 uint32 action_new_learn = 0, action_new_learn_set = FALSE; 1037 bcm_flowtracker_group_t ft_group_id = -1; 1038 bcmi_ft_group_ftfp_data_t ftfp_data; 1039 bcmi_ft_session_profiles_t *profiles = NULL; 1040 1041 if ((f_ent ==NULL) || (policy_mem == INVALIDm) || (e_buf == NULL)) { 1042 return (BCM_E_PARAM); 1043 } 1044 1045 /* policy install is needed only for Entry part 0 */ 1046 if (f_ent->flags & _FP_ENTRY_SECOND_HALF) { 1047 return BCM_E_NONE; 1048 } 1049 1050 /* Loop through all actions */ 1051 for (fa = f_ent->actions; 1052 (fa != NULL) && (fa->flags & _FP_ACTION_VALID); 1053 fa = fa->next) { 1054 switch(fa->action) { 1055 case bcmFieldActionFlowtrackerGroupId: 1056 ft_group_id = fa->param[0]; 1057 break; 1058 case bcmFieldActionFlowtrackerEnable: 1059 action_ft_set = TRUE; 1060 action_ft = fa->param[0]; 1061 break; 1062 case bcmFieldActionFlowtrackerNewLearnEnable: 1063 action_new_learn_set = TRUE; 1064 action_new_learn = fa->param[0]; 1065 break; 1066 default: 1067 return (BCM_E_INTERNAL); 1068 } 1069 } 1070 1071 if (ft_group_id != -1) { 1072 /* Read all relevent information from FT module */ 1073 BCM_IF_ERROR_RETURN(bcmi_ft_group_ftfp_data_get(unit, 1074 ft_group_id, &ftfp_data)); 1075 profiles = &ftfp_data.profiles; 1076 1077 /* Set Group Id */ 1078 if(SOC_MEM_FIELD_VALID(unit, policy_mem, GROUP_IDf)) { 1079 value = ft_group_id; 1080 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1081 GROUP_IDf, &(value)); 1082 } 1083 1084 /* Set bi-directional flow */ 1085 if (SOC_MEM_FIELD_VALID(unit, policy_mem, BIDIRECTIONAL_FLOWf)) { 1086 value = 0; 1087 if (ftfp_data.direction == bcmFlowtrackerFlowDirectionBidirectional) { 1088 value = 1; 1089 } 1090 BCM_IF_ERROR_RETURN(_field_hx5_ft_normalize_controls_set(unit, 1091 ft_group_id, policy_mem, value, e_buf)); 1092 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1093 BIDIRECTIONAL_FLOWf, &(value)); 1094 } 1095 1096 /* Set Do not FT */ 1097 if (SOC_MEM_FIELD_VALID(unit, policy_mem, DO_NOT_FTf)) { 1098 if (action_ft_set == TRUE) { 1099 value = (action_ft) ? 0 : 1; 1100 } else { 1101 value = (ftfp_data.flowtrack) ? 0 : 1; 1102 } 1103 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1104 DO_NOT_FTf, &(value)); 1105 } 1106 1107 /* Set New Learn Disable */ 1108 if (SOC_MEM_FIELD_VALID(unit, policy_mem, LEARN_DISABLEf)) { 1109 if (action_new_learn_set == TRUE) { 1110 value = (action_new_learn) ? 0 : 1; 1111 } else { 1112 value = (ftfp_data.new_learn) ? 0: 1; 1113 } 1114 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1115 LEARN_DISABLEf, &(value)); 1116 } 1117 1118 /* Set Session Key Profile index */ 1119 if ((SOC_MEM_FIELD_VALID(unit, 1120 policy_mem, SESSION_KEY_LTS_PROFILEf)) && 1121 (profiles->session_key_profile_idx != 0)) { 1122 value = profiles->session_key_profile_idx - 1; 1123 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1124 SESSION_KEY_LTS_PROFILEf, &(value)); 1125 } 1126 1127 /* Set Session Data Profile index */ 1128 if ((SOC_MEM_FIELD_VALID(unit, 1129 policy_mem, SESSION_DATA_LTS_PROFILEf)) && 1130 (profiles->session_data_profile_idx != 0)) { 1131 value = profiles->session_data_profile_idx - 1; 1132 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1133 SESSION_DATA_LTS_PROFILEf, &(value)); 1134 } 1135 1136 /* Set Alu Data Profile index */ 1137 if ((SOC_MEM_FIELD_VALID(unit, 1138 policy_mem, ALU_DATA_LTS_PROFILEf)) && 1139 (profiles->alu_data_profile_idx != 0)) { 1140 value = profiles->alu_data_profile_idx - 1; 1141 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1142 ALU_DATA_LTS_PROFILEf, &(value)); 1143 } 1144 1145 /* Set Key Type */ 1146 if (SOC_MEM_FIELD_VALID(unit, policy_mem, SESSION_KEY_TYPEf)) { 1147 /* Set this value to Profile_id of Session_key */ 1148 value = ftfp_data.session_key_type; 1149 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1150 SESSION_KEY_TYPEf, &(value)); 1151 } 1152 1153 /* Session Key Mode */ 1154 if (SOC_MEM_FIELD_VALID(unit, policy_mem, SESSION_KEY_MODEf)) { 1155 value = 1156 (ftfp_data.session_key_mode == bcmiFtGroupModeDouble) ? 1 : 0; 1157 1158 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1159 SESSION_KEY_MODEf, &(value)); 1160 } 1161 } else { 1162 /* Group is not associated, set do not Ft */ 1163 if (SOC_MEM_FIELD_VALID(unit, policy_mem, DO_NOT_FTf)) { 1164 soc_mem_field_set(unit, policy_mem, (void *) e_buf, 1165 DO_NOT_FTf, &do_not_ft_def); 1166 } 1167 } 1168 /* Reset DIRTY flag */ 1169 for (fa = f_ent->actions; 1170 (fa != NULL) && (fa->flags & _FP_ACTION_VALID); 1171 fa = fa->next) { 1172 fa->flags &= (~_FP_ACTION_DIRTY); 1173 } 1174 1175 return rv; 1176 } 1177 1178 /* 1179 * Function: 1180 * _field_hx5_ft_tcam_policy_init 1181 * 1182 * Purpose: 1183 * Fill Tcam/Policy memories with default entries. 1184 * Default entries are required to handle broadscan port. 1185 * 1186 * Parameters: 1187 * unit - (IN) BCM device number. 1188 * stage_fc - (IN) Field stage control structure. 1189 * 1190 * Returns: 1191 * BCM_E_PARAM - Wrong Input params 1192 * BCM_E_NONE - Success. 1193 */ 1194 int 1195 _field_hx5_ft_tcam_policy_init(int unit, 1196 _field_stage_t *stage_fc) 1197 { 1198 int rv = 0; 1199 uint32 do_not_ft_def = 1; 1200 uint32 broadscan_port = 0; 1201 uint32 e_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1202 uint32 policy_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1203 uint32 key_key_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1204 uint32 mask_key_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1205 soc_mem_t tcam_mem = INVALIDf; 1206 soc_mem_t policy_mem = INVALIDf; 1207 1208 /* If user wants to flowtrack ipfix packets coming from FAE Port */ 1209 if (!soc_feature(unit, soc_feature_bscan_fae_port_flow_exclude)) { 1210 return BCM_E_NONE; 1211 } 1212 1213 /* Decrease tcam_sz by 4 */ 1214 /* 1 for Single-wide, 2 for Double-wide and 1 Reserved */ 1215 stage_fc->tcam_sz -= 4; 1216 /* Move tcam stat Idx up by 2 */ 1217 stage_fc->slices[0]->start_tcam_idx +=4; 1218 /* Reduce number of Free Entry in the slice by 2 */ 1219 stage_fc->slices[0]->free_count -= 4; 1220 /* Reduce number of entries in the slice by 2 */ 1221 stage_fc->slices[0]->entry_count -= 4; 1222 1223 /* Get FAE Port */ 1224 broadscan_port = FAE_PORT(unit); 1225 1226 /* Disable Ingress Filtering */ 1227 rv = bcm_esw_port_control_set(unit, broadscan_port, 1228 bcmPortControlFilterIngress, FALSE); 1229 BCM_IF_ERROR_RETURN(rv); 1230 1231 /* 1232 * Modify Combo table to disard traffic coming from broadscan port. 1233 * Single-Wide default entry 1234 * 1235 * mod BSK_FTFP_COMBO_TCAM_POLICY 0 1 VALID=3 MASK_KEY=0x7F KEY_KEY=0x47 \ 1236 * MASK_MODE=1 KEY_MODE=0 DO_NOT_FT=1 1237 * 1238 * Double-Wide default entry 1239 * mod BSK_FTFP_COMBO_TCAM_POLICY 2 1 VALID=3 MASK_MODE=1 KEY_MODE=1 \ 1240 MASK_KEY=0x7F KEY_KEY=0x47 DO_NOT_FT=1 1241 * mod BSK_FTFP_COMBO_TCAM_POLICY 3 1 VALID=3 MASK_MODE=1 KEY_MODE=1 1242 */ 1243 1244 rv = _bcm_field_hx5_ft_tcam_policy_mem_get(unit, &tcam_mem, &policy_mem); 1245 BCM_IF_ERROR_RETURN(rv); 1246 1247 /* Init Tcam+Policy at Index=0 */ 1248 sal_memset(e_buf, 0, sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1249 sal_memset(policy_buf, 0, sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1250 1251 /* Set fields in policy */ 1252 soc_mem_field32_set(unit, policy_mem, 1253 (void *) policy_buf, DO_NOT_FTf, do_not_ft_def); 1254 1255 /* Set fields in Tcam */ 1256 key_key_buf[0] = broadscan_port; 1257 mask_key_buf[0]=0x7f; 1258 soc_mem_field_set(unit, tcam_mem, 1259 e_buf, KEY_KEYf, &key_key_buf[0]); 1260 soc_mem_field_set(unit, tcam_mem, 1261 e_buf, MASK_KEYf, &mask_key_buf[0]); 1262 soc_mem_field32_set(unit, tcam_mem, 1263 (void *) e_buf, KEY_MODEf, 0); 1264 soc_mem_field32_set(unit, tcam_mem, 1265 (void *) e_buf, MASK_MODEf, 1); 1266 soc_mem_field32_set(unit, tcam_mem, 1267 (void *) e_buf, VALIDf, 3); 1268 1269 /* Write to hardware */ 1270 rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, 0, policy_buf); 1271 BCM_IF_ERROR_RETURN(rv); 1272 rv = soc_mem_write(unit, tcam_mem, MEM_BLOCK_ALL, 0, e_buf); 1273 BCM_IF_ERROR_RETURN(rv); 1274 1275 /* Init Tcam+Policy at Index=2 */ 1276 sal_memset(e_buf, 0, sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1277 sal_memset(policy_buf, 0, sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1278 1279 /* Set fields in policy */ 1280 soc_mem_field32_set(unit, policy_mem, 1281 (void *) policy_buf, DO_NOT_FTf, do_not_ft_def); 1282 1283 /* Set fields in Tcam */ 1284 key_key_buf[0] = broadscan_port; 1285 mask_key_buf[0]=0x7f; 1286 soc_mem_field_set(unit, tcam_mem, 1287 (void *) e_buf, KEY_KEYf, &key_key_buf[0]); 1288 soc_mem_field_set(unit, tcam_mem, 1289 (void *) e_buf, MASK_KEYf, &mask_key_buf[0]); 1290 soc_mem_field32_set(unit, tcam_mem, 1291 (void *) e_buf, KEY_MODEf, 1); 1292 soc_mem_field32_set(unit, tcam_mem, 1293 (void *) e_buf, MASK_MODEf, 1); 1294 soc_mem_field32_set(unit, tcam_mem, 1295 (void *) e_buf, VALIDf, 3); 1296 1297 /* Write to hardware */ 1298 rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, 2, policy_buf); 1299 BCM_IF_ERROR_RETURN(rv); 1300 rv = soc_mem_write(unit, tcam_mem, MEM_BLOCK_ALL, 2, e_buf); 1301 BCM_IF_ERROR_RETURN(rv); 1302 1303 /* Init Tcam+Policy at Index=3 */ 1304 sal_memset(e_buf, 0, sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1305 1306 /* Set fields in Tcam */ 1307 soc_mem_field32_set(unit, tcam_mem, 1308 (void *) e_buf, KEY_MODEf, 1); 1309 soc_mem_field32_set(unit, tcam_mem, 1310 (void *) e_buf, MASK_MODEf, 1); 1311 soc_mem_field32_set(unit, tcam_mem, 1312 (void *) e_buf, VALIDf, 3); 1313 1314 /* Write to hardware */ 1315 rv = soc_mem_write(unit, tcam_mem, MEM_BLOCK_ALL, 3, e_buf); 1316 BCM_IF_ERROR_RETURN(rv); 1317 1318 return rv; 1319 } 1320 1321 /* 1322 * Function: 1323 * _field_hx5_ftstage_init 1324 * 1325 * Purpose: 1326 * Initializes flowtracker stage related information. 1327 * 1328 * Parameters: 1329 * unit - (IN) BCM device number. 1330 * fc - (IN) Field control structure. 1331 * stage_fc - (IN) Field stage control structure. 1332 * 1333 * Returns: 1334 * BCM_E_PARAM - Null field stage control structure. 1335 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1336 * BCM_E_NONE - Success. 1337 */ 1338 int 1339 _field_hx5_ftstage_init(int unit, 1340 _field_control_t *fc, 1341 _field_stage_t *stage_fc) 1342 { 1343 int rv = BCM_E_NONE; 1344 1345 /* Input parameter Check */ 1346 if ((fc == NULL) || (stage_fc == NULL)) { 1347 return (BCM_E_PARAM); 1348 } 1349 1350 /* Applicable only for flowtracker stage */ 1351 if (stage_fc->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 1352 return (BCM_E_NONE); 1353 } 1354 1355 /* Initialize stage's extractor configuration */ 1356 rv = _field_hx5_ft_stage_extractors_init(unit, stage_fc); 1357 if (BCM_FAILURE(rv)) { 1358 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 1359 "FP(unit %d) Error: _field_hx5_ft_stage_extractors_init=%d\n"), 1360 unit, rv)); 1361 return (rv); 1362 } 1363 1364 /* Initializing supported Qset */ 1365 sal_memset(&stage_fc->_field_supported_qset, 0, sizeof(bcm_field_qset_t)); 1366 1367 /* Initialize stage Preselector information for Lt slices and entries */ 1368 rv = _bcm_field_th_stage_preselector_init(unit, fc, stage_fc); 1369 if (BCM_FAILURE(rv)) { 1370 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 1371 "FP(unit %d) Error: _bcm_field_th_stage_preselector_init=%d" 1372 "\n"), unit, rv)); 1373 return (rv); 1374 } 1375 1376 /* Qualifiers ingress field bus map */ 1377 rv = _field_hx5_ft_stage_quals_ibus_map_init(unit, stage_fc); 1378 if (BCM_FAILURE(rv)) { 1379 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 1380 "FP(unit %d) Error: _field_hx5_ft_stage_quals_ibus_map_init=%d" 1381 "\n"), unit, rv)); 1382 return (rv); 1383 } 1384 1385 /* Init information used by FT core module */ 1386 rv = _field_hx5_ft_stage_ftinfo_init(unit, stage_fc); 1387 if (BCM_FAILURE(rv)) { 1388 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 1389 "FP(unit %d) Error: _field_hx5_ft_stage_ftinfo_init=%d" 1390 "\n"), unit, rv)); 1391 return (rv); 1392 } 1393 1394 return (rv); 1395 } 1396 1397 /* 1398 * Function: 1399 * _field_hx5_ftstage_deinit 1400 * 1401 * Purpose: 1402 * De-initializes flowtracker stage. 1403 * 1404 * Parameters: 1405 * unit - (IN) BCM device number. 1406 * stage_fc - (IN) Stage field control structure. 1407 * 1408 * Returns: 1409 * BCM_E_PARAM - Null field stage control structure. 1410 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1411 * BCM_E_NONE - Success. 1412 */ 1413 int 1414 _field_hx5_ftstage_deinit(int unit, 1415 _field_stage_t *stage_fc) 1416 { 1417 /* Input parameter check. */ 1418 if (NULL == stage_fc) { 1419 return (BCM_E_NONE); 1420 } 1421 1422 if (stage_fc->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 1423 return BCM_E_NONE; 1424 } 1425 1426 /* De-init ft related info */ 1427 (void) _field_hx5_ft_stage_ftinfo_deinit(unit, stage_fc); 1428 1429 /* Rest of allocations freed in common code */ 1430 1431 return BCM_E_NONE; 1432 } 1433 1434 /* 1435 * Function: 1436 * _field_hx5_ft_slice_validate 1437 * 1438 * Purpose: 1439 * Validates if field group can be allowed to create in given slice. 1440 * 1441 * Parameters: 1442 * unit - (IN) BCM device number. 1443 * stage_fc - (IN) Stage field control structure. 1444 * fg - (IN) Field group control structure. 1445 * slice_id - (IN) Slice number 1446 * 1447 * Returns: 1448 * BCM_E_PARAM - Null field stage control structure. 1449 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1450 * BCM_E_NONE - Success. 1451 */ 1452 int 1453 _field_hx5_ft_slice_validate(int unit, 1454 _field_stage_t *stage_fc, 1455 _field_group_t *fg, 1456 int slice_id) 1457 { 1458 int rv = BCM_E_NONE; 1459 1460 /* Validate lt slice */ 1461 rv = _field_th_group_lt_slice_validate(unit, stage_fc, fg, slice_id, NULL); 1462 1463 return rv; 1464 } 1465 1466 /* 1467 * Function: 1468 * _field_hx5_ft_group_key_type_clear 1469 * 1470 * Purpose: 1471 * Clears group key type assignment in field group in flowtracker stage. 1472 * 1473 * Parameters: 1474 * unit - (IN) BCM device number. 1475 * stage_fc - (IN) Stage field control structure. 1476 * fg - (IN) Field group control structure. 1477 * 1478 * Returns: 1479 * BCM_E_PARAM - Null field stage control structure. 1480 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1481 * BCM_E_NONE - Success. 1482 */ 1483 int 1484 _field_hx5_ft_group_keytype_clear(int unit, 1485 _field_stage_t *stage_fc, 1486 _field_group_t *fg) 1487 { 1488 int keytype = 0; 1489 _field_ft_info_t *ft_info = NULL; 1490 1491 if ((stage_fc == NULL) || (fg == NULL)) { 1492 return BCM_E_PARAM;; 1493 } 1494 1495 if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 1496 return (BCM_E_NONE); 1497 } 1498 1499 if (stage_fc->ft_info == NULL) { 1500 return BCM_E_INTERNAL; 1501 } 1502 1503 ft_info = stage_fc->ft_info; 1504 1505 keytype = (fg->lt_id >> _FP_GROUP_FT_KEYTYPE_SHIFT) & 1506 (_FP_GROUP_FT_KEYTYPE_MASK); 1507 SHR_BITCLR(ft_info->key_type_bmp, keytype); 1508 1509 return BCM_E_NONE; 1510 } 1511 1512 /* 1513 * Function: 1514 * _field_hx5_ft_group_keytype_assign 1515 * 1516 * Purpose: 1517 * Group key type to field group in flowtracker stage. 1518 * 1519 * Parameters: 1520 * unit - (IN) BCM device number. 1521 * stage_fc - (IN) Stage field control structure. 1522 * fg - (IN) Field group control structure. 1523 * 1524 * Returns: 1525 * BCM_E_PARAM - Null field stage control structure. 1526 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1527 * BCM_E_NONE - Success. 1528 */ 1529 int 1530 _field_hx5_ft_group_keytype_assign(int unit, 1531 _field_stage_t *stage_fc, 1532 _field_group_t *fg) 1533 { 1534 int keytype = 0; 1535 int double_wide = 0; 1536 _field_ft_info_t *ft_info = NULL; 1537 1538 /* Validate input params */ 1539 if ((stage_fc == NULL) || (fg == NULL)) { 1540 return BCM_E_PARAM; 1541 } 1542 1543 /* Applicable only in flowtracker stage. */ 1544 if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 1545 return (BCM_E_NONE); 1546 } 1547 1548 ft_info = stage_fc->ft_info; 1549 if (ft_info == NULL) { 1550 return BCM_E_INTERNAL; 1551 } 1552 1553 /* Unique value for each group */ 1554 for (keytype = 0; 1555 keytype < _BCM_FIELD_FT_GROUP_KEY_TYPE_MAX; 1556 keytype++) { 1557 if (!SHR_BITGET(stage_fc->ft_info->key_type_bmp, keytype)) { 1558 SHR_BITSET(stage_fc->ft_info->key_type_bmp, keytype); 1559 break; 1560 } 1561 } 1562 if (keytype == _BCM_FIELD_FT_GROUP_KEY_TYPE_MAX) { 1563 return BCM_E_INTERNAL; 1564 } 1565 1566 if (fg->flags & _FP_GROUP_DW_DEPTH_EXPANDED) { 1567 double_wide = 1; 1568 } 1569 1570 fg->lt_id = (keytype << _FP_GROUP_FT_KEYTYPE_SHIFT) | double_wide; 1571 1572 return BCM_E_NONE; 1573 } 1574 1575 /* 1576 * Function: 1577 * _field_hx5_ft_entries_free_get 1578 * 1579 * Purpose: 1580 * Return number of free entries in slice for given group. 1581 * 1582 * Parameters: 1583 * unit - (IN) BCM device number. 1584 * fs - (IN) field slice structure. 1585 * fg - (IN) Field group control structure. 1586 * free_cnt - (OUT) Out argument for number of free entries. 1587 * 1588 * Returns: 1589 * BCM_E_PARAM - Null field stage control structure. 1590 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1591 * BCM_E_NONE - Success. 1592 */ 1593 int 1594 _field_hx5_ft_entries_free_get(int unit, 1595 _field_slice_t *fs, 1596 _field_group_t *fg, 1597 int *free_cnt) 1598 { 1599 /* Input Paramter Check. */ 1600 if ((fg == NULL) || (fs == NULL) || (free_cnt == NULL)) { 1601 return (BCM_E_PARAM); 1602 } 1603 1604 /* Initialize free entry count. */ 1605 *free_cnt = 0; 1606 1607 /* Calculate free entry count. */ 1608 if (fg->flags & _FP_GROUP_DW_DEPTH_EXPANDED) { 1609 *free_cnt = fs->free_count >> 1; 1610 } else { 1611 *free_cnt = fs->free_count; 1612 } 1613 1614 return (BCM_E_NONE); 1615 } 1616 1617 /* 1618 * Function: 1619 * _bcm_field_hx5_ft_entry_keytype_set 1620 * 1621 * Purpose: 1622 * Qualify entry in flowtracker stage with group keytype 1623 * 1624 * Parameters: 1625 * unit - (IN) BCM device number. 1626 * f_ent - (IN) Field entry structure. 1627 * 1628 * Returns: 1629 * BCM_E_PARAM - Null field stage control structure. 1630 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1631 * BCM_E_NONE - Success. 1632 */ 1633 int 1634 _bcm_field_hx5_ft_entry_keytype_set(int unit, 1635 _field_entry_t *f_ent) 1636 { 1637 int rv = BCM_E_NONE; 1638 uint32 lt_id_mask = 0xFF; 1639 _bcm_field_qual_offset_t q_offset; 1640 1641 if (f_ent == NULL) { 1642 return BCM_E_PARAM; 1643 } 1644 1645 if (f_ent->group->lt_id == -1) { 1646 return BCM_E_INTERNAL; 1647 } 1648 1649 sal_memset(&q_offset, 0, 1650 sizeof (_bcm_field_qual_offset_t)); 1651 1652 q_offset.field = KEYf; 1653 q_offset.num_offsets = 1; 1654 q_offset.offset[0] = 0; 1655 q_offset.width[0] = 8; 1656 q_offset.qual_width = 8; 1657 1658 BCM_IF_ERROR_RETURN(_bcm_field_qual_value_set(unit, &q_offset, 1659 f_ent, (uint32 *)&f_ent->group->lt_id, <_id_mask)); 1660 1661 return rv; 1662 } 1663 1664 /* 1665 * Function: 1666 * _field_hx5_ft_entry_policy_mem_install 1667 * 1668 * Purpose: 1669 * Installs policy hw table for entry. 1670 * 1671 * Parameters: 1672 * unit - (IN) BCM device number. 1673 * f_ent - (IN) field entry structure. 1674 * policy_mem - (IN) policy hw table 1675 * tcam_idx - (IN) Index in policy table 1676 * 1677 * Returns: 1678 * BCM_E_PARAM - Null field stage control structure. 1679 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1680 * BCM_E_NONE - Success. 1681 */ 1682 int 1683 _field_hx5_ft_entry_policy_mem_install(int unit, 1684 _field_entry_t *f_ent, 1685 soc_mem_t policy_mem, 1686 int tcam_idx) 1687 { 1688 int rv = BCM_E_NONE; 1689 uint32 e_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1690 1691 /* Validate input params */ 1692 if ((f_ent == NULL) || (policy_mem == INVALIDm) || (tcam_idx == -1)) { 1693 return BCM_E_PARAM; 1694 } 1695 1696 /* Read policy memory */ 1697 rv = soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, tcam_idx, e_buf); 1698 BCM_IF_ERROR_RETURN(rv); 1699 1700 /* Set policy buffer */ 1701 rv = _field_hx5_ft_entry_policy_set(unit, f_ent, policy_mem, e_buf); 1702 BCM_IF_ERROR_RETURN(rv); 1703 1704 /* Write to hardware */ 1705 rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, tcam_idx, e_buf); 1706 return rv; 1707 1708 } 1709 1710 /* 1711 * Function: 1712 * _field_ft_entry_tcam_policy_install 1713 * 1714 * Purpose: 1715 * Installs tcam + policy hw tables for entry. 1716 * 1717 * Parameters: 1718 * unit - (IN) BCM device number. 1719 * f_ent - (IN) field entry structure. 1720 * tcam_idx - (IN) Index in tcam table 1721 * 1722 * Returns: 1723 * BCM_E_PARAM - Null field stage control structure. 1724 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1725 * BCM_E_NONE - Success. 1726 */ 1727 int 1728 _field_hx5_ft_entry_tcam_policy_install(int unit, 1729 _field_entry_t *f_ent, 1730 int tcam_idx) 1731 { 1732 int rv = BCM_E_NONE; 1733 soc_mem_t tcam_mem = INVALIDm; 1734 soc_mem_t policy_mem = INVALIDm; 1735 uint32 entry_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1736 1737 if (f_ent == NULL) { 1738 return (BCM_E_PARAM); 1739 } 1740 1741 /* Get the combo TCAM+Policy */ 1742 rv = _bcm_field_hx5_ft_tcam_policy_mem_get(unit, &tcam_mem, &policy_mem); 1743 BCM_IF_ERROR_RETURN(rv); 1744 1745 if ((tcam_idx < soc_mem_index_min(unit, tcam_mem)) || 1746 (tcam_idx > soc_mem_index_max(unit, tcam_mem))) { 1747 return (BCM_E_PARAM); 1748 } 1749 1750 rv = soc_mem_read(unit, tcam_mem, MEM_BLOCK_ANY, 1751 tcam_idx, entry_buf); 1752 BCM_IF_ERROR_RETURN(rv); 1753 1754 /* Set Policy data buffer */ 1755 rv = _field_hx5_ft_entry_policy_mem_install(unit, f_ent, policy_mem, tcam_idx); 1756 if (BCM_FAILURE(rv)) { 1757 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META( 1758 "Failed to Install Policy Table for Entry[%d]" 1759 " tcam_idx:[%d].\n\r"), 1760 f_ent->eid, tcam_idx)); 1761 return rv; 1762 } 1763 1764 /* Set Qualifier for TCAM Table */ 1765 rv = _field_hx5_ft_entry_qual_tcam_set(unit, f_ent, tcam_mem, 1766 tcam_idx, entry_buf); 1767 1768 /* Write to h/w Table */ 1769 if (BCM_SUCCESS(rv)) { 1770 soc_mem_write(unit, tcam_mem, MEM_BLOCK_ALL, 1771 tcam_idx, entry_buf); 1772 1773 /* Increment the HW Slice entry count */ 1774 f_ent->fs->hw_ent_count++; 1775 1776 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 1777 "==> %s(): Entry[%d] Installed - mem:%d tcam_idx:%d slice:%d\n\r"), 1778 __func__, f_ent->eid, tcam_mem, tcam_idx, f_ent->fs->slice_number)); 1779 } else { 1780 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META( 1781 "Failed to Install the TCAM Entry[%d] tcam_idx:[%d].\n\r"), 1782 f_ent->eid, tcam_idx)); 1783 } 1784 1785 return rv; 1786 } 1787 1788 /* 1789 * Function: 1790 * _bcm_field_hx5_ft_entry_move 1791 * 1792 * Purpose: 1793 * Move tcam entry to new index 1794 * 1795 * Parameters: 1796 * unit - (IN) BCM device number. 1797 * f_ent - (IN) field entry structure. 1798 * parts_count- (IN) Number of parts of entry. 1799 * tcam_idx_old- (IN) Old tcam Indices of entry 1800 * tcam_idx_new- (IN) New tcam Indices of entry 1801 * 1802 * Returns: 1803 * BCM_E_PARAM - Null field stage control structure. 1804 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1805 * BCM_E_NONE - Success. 1806 */ 1807 int 1808 _bcm_field_hx5_ft_entry_move(int unit, 1809 _field_entry_t *f_ent, 1810 int parts_count, 1811 int *tcam_idx_old, 1812 int *tcam_idx_new) 1813 { 1814 int rv = BCM_E_NONE; 1815 int part = 0; 1816 int is_backup_entry = 0; 1817 soc_mem_t tcam_mem = INVALIDm; 1818 soc_mem_t policy_mem = INVALIDm; 1819 int new_slice_numb = 0; 1820 int new_slice_idx = 0; 1821 int tcam_idx_min = 0, tcam_idx_max = 0; 1822 uint32 entry_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1823 _field_slice_t *fs = NULL; 1824 _field_stage_t *stage_fc = NULL; 1825 1826 if ((f_ent == NULL) || (tcam_idx_old == NULL) || (tcam_idx_new == NULL)) { 1827 return (BCM_E_PARAM); 1828 } 1829 1830 rv = _field_stage_control_get(unit, f_ent->group->stage_id, &stage_fc); 1831 BCM_IF_ERROR_RETURN(rv); 1832 1833 /* Get entry tcam and actions. */ 1834 rv = _bcm_field_hx5_ft_tcam_policy_mem_get(unit, &tcam_mem, &policy_mem); 1835 BCM_IF_ERROR_RETURN(rv); 1836 1837 /* Sanity check for index */ 1838 tcam_idx_max = soc_mem_index_max(unit, tcam_mem); 1839 tcam_idx_min = soc_mem_index_min(unit, tcam_mem); 1840 1841 for (part = 0; part < parts_count; part++) { 1842 if ((tcam_idx_old[part] > tcam_idx_max) || 1843 (tcam_idx_old[part] < tcam_idx_min) || 1844 (tcam_idx_new[part] > tcam_idx_max) || 1845 (tcam_idx_new[part] < tcam_idx_min)) { 1846 return (BCM_E_PARAM); 1847 } 1848 } 1849 1850 if ((NULL != f_ent->ent_copy) && 1851 (f_ent->ent_copy->eid == _FP_INTERNAL_RESERVED_ID)) { 1852 is_backup_entry = 1; 1853 } 1854 1855 /* Write to destination */ 1856 for (part = parts_count - 1; part >= 0; part--) { 1857 if (part == 0) { 1858 sal_memset(entry_buf, 0 , sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1859 1860 rv = soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, 1861 tcam_idx_old[part], entry_buf); 1862 BCM_IF_ERROR_RETURN(rv); 1863 1864 /* Write duplicate tcam entry to new tcam index. */ 1865 rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, 1866 tcam_idx_new[part], entry_buf); 1867 BCM_IF_ERROR_RETURN(rv); 1868 } 1869 1870 sal_memset(entry_buf, 0 , sizeof(uint32) * SOC_MAX_MEM_FIELD_WORDS); 1871 1872 rv = soc_mem_read(unit, tcam_mem, MEM_BLOCK_ANY, 1873 tcam_idx_old[part], entry_buf); 1874 BCM_IF_ERROR_RETURN(rv); 1875 1876 /* Write duplicate tcam entry to new tcam index. */ 1877 rv = soc_mem_write(unit, tcam_mem, MEM_BLOCK_ALL, 1878 tcam_idx_new[part], entry_buf); 1879 BCM_IF_ERROR_RETURN(rv); 1880 } 1881 1882 for (part = 0; part < parts_count; part++) { 1883 /* Calculate entry new slice & offset in the slice. */ 1884 rv = _bcm_field_tcam_idx_to_slice_offset (unit, stage_fc, 1885 f_ent->group->instance, 1886 tcam_idx_new[part], 1887 &new_slice_numb, 1888 &new_slice_idx); 1889 BCM_IF_ERROR_RETURN(rv); 1890 fs = &stage_fc->slices[f_ent->group->instance][new_slice_numb]; 1891 fs->hw_ent_count++; 1892 1893 /* 1894 * fp_entry_move is invoked even for backup entry create 1895 * to copy TCAM and FP_POLICY_TABLE tables. In this case 1896 * TCAM and FP_POLICY_TABLEs should not be erased for 1897 * original entry. 1898 */ 1899 if (1 != is_backup_entry) { 1900 /* 1901 * Clear old location 1902 */ 1903 rv = _bcm_field_th_tcam_policy_clear(unit, f_ent, 1904 tcam_idx_old[part]); 1905 BCM_IF_ERROR_RETURN(rv); 1906 } 1907 } 1908 1909 return rv; 1910 } 1911 1912 /* 1913 * Function: 1914 * _bcm_field_hx5_ft_tcam_policy_clear 1915 * 1916 * Purpose: 1917 * Clears hw table at given index. 1918 * 1919 * Parameters: 1920 * unit - (IN) BCM device number. 1921 * f_ent - (IN) field entry structure. 1922 * tcam_idx - (IN) tcam index. 1923 * 1924 * Returns: 1925 * BCM_E_PARAM - Null field stage control structure. 1926 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1927 * BCM_E_NONE - Success. 1928 */ 1929 int 1930 _bcm_field_hx5_ft_tcam_policy_clear(int unit, 1931 _field_entry_t *f_ent, 1932 int tcam_idx) 1933 { 1934 int rv = BCM_E_NONE; 1935 soc_mem_t tcam_mem = INVALIDm; 1936 soc_mem_t policy_mem = INVALIDm; 1937 uint32 null_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1938 1939 rv = _bcm_field_hx5_ft_tcam_policy_mem_get(unit, &tcam_mem, &policy_mem); 1940 BCM_IF_ERROR_RETURN(rv); 1941 1942 if (tcam_idx > soc_mem_index_max(unit, tcam_mem)) { 1943 return BCM_E_PARAM; 1944 } 1945 1946 SOC_IF_ERROR_RETURN(soc_mem_write(unit, tcam_mem, 1947 MEM_BLOCK_ALL, tcam_idx, null_buf)); 1948 1949 SOC_IF_ERROR_RETURN(soc_mem_write(unit, policy_mem, 1950 MEM_BLOCK_ALL, tcam_idx, null_buf)); 1951 return rv; 1952 } 1953 1954 /* 1955 * Function: 1956 * _field_hx5_ft_stage_entry_enable_set 1957 * 1958 * Purpose: 1959 * Enable/Disable an entry from the hardware tables. 1960 * 1961 * Parameters: 1962 * unit - (IN) BCM device number 1963 * f_ent - (IN) Reference to Entry structure 1964 * enable_flag - (IN) Flag to enable or disable 1965 * 1966 * Returns: 1967 * BCM_E_XXX 1968 * 1969 * Notes: 1970 * This does not destroy the entry, nor deallocate any related resources; 1971 * it only enables/disables a rule from hardware table using VALIDf of the 1972 * corresponding hardware entry. To deallocate the memory used by the entry 1973 * call bcm_field_entry_destroy. 1974 */ 1975 int 1976 _field_hx5_ft_stage_entry_enable_set(int unit, 1977 _field_entry_t *f_ent, 1978 int enable_flag) 1979 { 1980 int rv = BCM_E_NONE; 1981 int part = 0, parts_count = 0; 1982 _field_group_t *fg = NULL; 1983 1984 fg = f_ent->group; 1985 1986 /* Get number of parts */ 1987 rv = _bcm_field_entry_tcam_parts_count (unit, fg->stage_id, 1988 fg->flags, &parts_count); 1989 for (part = 0; part < parts_count; part++) { 1990 rv = _field_th_stage_entry_enable_set(unit, &f_ent[part], enable_flag); 1991 } 1992 1993 return rv; 1994 } 1995 1996 /* 1997 * Function: 1998 * _bcm_field_hx5_ft_action_params_check 1999 * 2000 * Purpose: 2001 * Verifies action to be associated with entry. 2002 * 2003 * Parameters: 2004 * unit - (IN) BCM device number. 2005 * f_ent - (IN) field entry structure. 2006 * fa - (IN) field action structure. 2007 * 2008 * Returns: 2009 * BCM_E_PARAM - Null field stage control structure. 2010 * BCM_E_INTERNAL - Invalid CAP Stage ID. 2011 * BCM_E_NONE - Success. 2012 */ 2013 int 2014 _bcm_field_hx5_ft_action_params_check(int unit, 2015 _field_entry_t *f_ent, 2016 _field_action_t *fa) 2017 { 2018 int rv = BCM_E_NONE; 2019 bcm_flowtracker_group_t id = 0; 2020 _field_action_t *fa_iter = NULL; 2021 2022 if (f_ent->group->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 2023 return BCM_E_NONE; 2024 } 2025 2026 fa_iter = f_ent->actions; 2027 while(fa_iter != NULL) { 2028 if (fa_iter->flags & _FP_ACTION_VALID) { 2029 if ((fa->action == bcmFieldActionFlowtrackerNewLearnEnable) && 2030 (fa_iter->action == bcmFieldActionFlowtrackerGroupId)) { 2031 id = fa_iter->param[0]; 2032 if (BCMI_FT_GROUP(unit, id)->flags 2033 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 2034 return BCM_E_CONFIG; 2035 } 2036 } else if ((fa->action == bcmFieldActionFlowtrackerGroupId) && 2037 (fa_iter->action == bcmFieldActionFlowtrackerNewLearnEnable)) { 2038 id = fa->param[0]; 2039 if (BCMI_FT_GROUP(unit, id)->flags 2040 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 2041 return BCM_E_CONFIG; 2042 } 2043 } 2044 } 2045 fa_iter = fa_iter->next; 2046 } 2047 2048 switch(fa->action) { 2049 case bcmFieldActionFlowtrackerGroupId: 2050 id = fa->param[0]; 2051 2052 /* Check FT module compliance */ 2053 rv = bcmi_ft_group_entry_add_check(unit, id); 2054 break; 2055 2056 case bcmFieldActionFlowtrackerEnable: 2057 case bcmFieldActionFlowtrackerNewLearnEnable: 2058 if (fa->param[0] > 1) { 2059 LOG_ERROR(BSL_LS_BCM_FP, 2060 (BSL_META_U(unit, "FP(unit %d) Error: Incorrect" 2061 " argument passed.\r\n"), unit)); 2062 rv = BCM_E_PARAM; 2063 } 2064 break; 2065 default: 2066 break; 2067 } 2068 2069 return rv; 2070 } 2071 2072 /* 2073 * Function: 2074 * _bcm_field_hx5_ft_group_aset_update 2075 * 2076 * Purpose: 2077 * Updates aset of field group. 2078 * 2079 * Parameters: 2080 * unit - (IN) BCM device number. 2081 * fg - (IN) field group structure. 2082 * aset - (IN) New action set structure. 2083 * 2084 * Returns: 2085 * BCM_E_PARAM - Wrong input argument. 2086 * BCM_E_UNAVAIL - Incoming Action is not supported. 2087 * BCM_E_NONE - Success. 2088 */ 2089 int 2090 _bcm_field_hx5_ft_group_aset_update(int unit, 2091 _field_group_t *fg, 2092 bcm_field_aset_t *aset) 2093 { 2094 int a_idx = 0; 2095 int aset_diff = FALSE; 2096 _bcm_field_aset_t aset_modified; 2097 2098 if ((fg == NULL) || (aset == NULL)) { 2099 return BCM_E_PARAM; 2100 } 2101 2102 /* Copy original aset of field group */ 2103 sal_memcpy(&aset_modified, &fg->aset, sizeof(_bcm_field_aset_t)); 2104 2105 /* Set new actions to aset */ 2106 for (a_idx = 0; a_idx < bcmFieldActionCount; a_idx++) { 2107 if (BCM_FIELD_ASET_TEST(*aset, a_idx)) { 2108 if (!_field_stage_action_support_check(unit, fg, a_idx)) { 2109 LOG_ERROR(BSL_LS_BCM_FP, 2110 (BSL_META_U(unit, "FP(unit %d) Error: action =%s is" 2111 " not supported for given group stage.\n"), 2112 unit, _field_action_name(a_idx))); 2113 return BCM_E_UNAVAIL; 2114 } 2115 if (!BCM_FIELD_ASET_TEST(fg->aset, a_idx)) { 2116 BCM_FIELD_ASET_ADD(aset_modified, a_idx); 2117 aset_diff = TRUE; 2118 } 2119 } 2120 } 2121 2122 /* Copy modified aset to field group aset */ 2123 if (aset_diff == TRUE) { 2124 sal_memcpy(&fg->aset, &aset_modified, sizeof(_bcm_field_aset_t)); 2125 } 2126 2127 return BCM_E_NONE; 2128 } 2129 2130 /* 2131 * Function: 2132 * _bcm_field_hx5_ft_group_hw_alloc 2133 * 2134 * Purpose: 2135 * If flowtracker group id is associated with the entry, 2136 * flowtracker APIs are called to install SESSION_KEY/DATA, 2137 * flowtracker ALUs and other hardware tables. 2138 * 2139 * Parameters: 2140 * unit - (IN) BCM device number. 2141 * f_ent - (In) Field entry structure. 2142 * 2143 * Returns: 2144 * BCM_E_XXX 2145 */ 2146 int 2147 _bcm_field_hx5_ft_group_hw_alloc(int unit, 2148 _field_entry_t *f_ent) 2149 { 2150 int rv = BCM_E_NONE; 2151 int num_key_info = 0; 2152 bcm_flowtracker_group_t id = -1; 2153 int ref_count = 0; 2154 _field_action_t *fa = NULL; 2155 bcmi_ft_session_profiles_t profiles; 2156 2157 if (f_ent->group->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 2158 return BCM_E_NONE; 2159 } 2160 2161 sal_memset(&profiles, 0, sizeof(bcmi_ft_session_profiles_t)); 2162 2163 for (fa = f_ent->actions; 2164 (fa != NULL) && (fa->flags & _FP_ACTION_VALID); 2165 fa = fa->next) { 2166 if (fa->action != bcmFieldActionFlowtrackerGroupId) { 2167 continue; 2168 } 2169 if (!(fa->flags & _FP_ACTION_DIRTY)) { 2170 continue; 2171 } 2172 2173 fa->old_index = fa->hw_index; 2174 id = fa->param[0]; 2175 2176 /* Get reference count */ 2177 BCM_IF_ERROR_RETURN( 2178 bcmi_esw_ft_group_param_retrieve(unit, id, 2179 bcmiFtGroupParamFtfpEntryNum, &ref_count)); 2180 if (ref_count == 0) { 2181 /* Check Ft Group tracking params extraction */ 2182 rv = bcmi_esw_ft_group_extraction_alu_info_get(unit, 2183 id, 1, 0, NULL, &num_key_info); 2184 if ((rv != BCM_E_NONE) || (num_key_info == 0)) { 2185 return BCM_E_CONFIG; 2186 } 2187 } 2188 /* Increment reference count */ 2189 if (BCM_SUCCESS(rv)) { 2190 rv = bcmi_esw_ft_group_param_update(unit, id, 2191 bcmiFtGroupParamFtfpEntryNum, 2192 bcmiFtGroupParamsOprInc, 1); 2193 } 2194 fa->hw_index = id; 2195 } 2196 2197 return (rv); 2198 } 2199 2200 /* 2201 * Function: 2202 * _bcm_field_hx5_ft_group_hw_free 2203 * 2204 * Purpose: 2205 * If flowtracker group id is dis-associated from the entry, 2206 * flowtracker APIs are called to clear SESSION_KEY/DATA, 2207 * flowtracker ALUs and other hardware tables. 2208 * 2209 * Parameters: 2210 * unit - (IN) BCM device number. 2211 * f_ent - (In) Field entry structure. 2212 * 2213 * Returns: 2214 * BCM_E_XXX 2215 */ 2216 int 2217 _bcm_field_hx5_ft_group_hw_free(int unit, 2218 _field_entry_t *f_ent, 2219 int flags) 2220 { 2221 uint16 id = 0; 2222 _field_action_t *fa = NULL; 2223 bcmi_ft_session_profiles_t profiles; 2224 2225 if (f_ent->group->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 2226 return BCM_E_NONE; 2227 } 2228 2229 sal_memset(&profiles, 0, sizeof(bcmi_ft_session_profiles_t)); 2230 2231 for (fa = f_ent->actions; NULL != fa; fa = fa->next) { 2232 if (bcmFieldActionFlowtrackerGroupId != fa->action) { 2233 continue; 2234 } 2235 if (fa->flags & _BCM_FIELD_ACTION_REF_STALE) { 2236 /* Flowtracker Group is Stale */ 2237 continue; 2238 } 2239 if ((flags & _FP_ACTION_OLD_RESOURCE_FREE) && 2240 (fa->old_index != _FP_INVALID_INDEX)) { 2241 id = fa->old_index; 2242 /* Decrement reference count */ 2243 BCM_IF_ERROR_RETURN( 2244 bcmi_esw_ft_group_param_update(unit, 2245 id, bcmiFtGroupParamFtfpEntryNum, 2246 bcmiFtGroupParamsOprDec, 1)); 2247 fa->old_index = _FP_INVALID_INDEX; 2248 } 2249 if ((flags & _FP_ACTION_RESOURCE_FREE) && 2250 (fa->hw_index != _FP_INVALID_INDEX)) { 2251 id = fa->hw_index; 2252 /* Decrement reference count */ 2253 BCM_IF_ERROR_RETURN( 2254 bcmi_esw_ft_group_param_update(unit, id, 2255 bcmiFtGroupParamFtfpEntryNum, 2256 bcmiFtGroupParamsOprDec, 1)); 2257 if (!(flags & _BCM_FIELD_ACTION_REF_STALE)) { 2258 fa->hw_index = _FP_INVALID_INDEX; 2259 } 2260 } 2261 if (flags & _BCM_FIELD_ACTION_REF_STALE) { 2262 fa->flags |= _BCM_FIELD_ACTION_REF_STALE; 2263 } 2264 } 2265 2266 return (BCM_E_NONE); 2267 } 2268 2269 /* 2270 * Function: 2271 * _bcm_field_hx5_hint_dosattack_event_flags 2272 * 2273 * Purpose: 2274 * Update qual_info for dos attack events when hint 2275 * is provided. 2276 * 2277 * Parameters: 2278 * unit - (IN) BCM device number. 2279 * hint_node - (IN) hint structure. 2280 * qual_info - (IN/OUT) Qualifier information for extraction. 2281 * 2282 * Returns: 2283 * BCM_E_XXX 2284 */ 2285 int 2286 _bcm_field_hx5_dosattack_event_qual_bitmap(int unit, 2287 _field_hint_t *hint_node, 2288 bcmi_keygen_qual_info_t *qual_info) 2289 { 2290 uint32 event_flags[1]; 2291 uint32 event_bit = 0, bit_pos = 0; 2292 soc_field_t field = INVALIDf; 2293 soc_format_t fmt = INVALIDfmt; 2294 soc_field_info_t *field_info = NULL; 2295 2296 if ((qual_info == NULL) || (hint_node == NULL)) { 2297 return BCM_E_PARAM; 2298 } 2299 2300 event_flags[0] = hint_node->hint->dosattack_event_flags; 2301 2302 SHR_BIT_ITER(event_flags, 32, event_bit) { 2303 field = INVALIDf; 2304 switch((1 << event_bit)) { 2305 case BCM_FIELD_DOSATTACK_MACSA_DA_SAME: 2306 field = MACSA_EQ_MACDAf; 2307 break; 2308 case BCM_FIELD_DOSATTACK_IPFRAG_OFFSET: 2309 field = IP_FRAG_OFFSET_VALUE_OF_1f; 2310 break; 2311 case BCM_FIELD_DOSATTACK_V6_TYPE0_ROUTING_HDR: 2312 field = TYPE_ZERO_ROUTING_HDR_PRESENTf; 2313 break; 2314 case BCM_FIELD_DOSATTACK_V6_NON_LAST_FRAG_LT_1280: 2315 field = V6_NON_LAST_FRAGMENT_SIZE_TOO_SMALLf; 2316 break; 2317 case BCM_FIELD_DOSATTACK_FIRST_TCPIP_FRAG_SMALL: 2318 field = TCP_HDR_TOO_SMALLf; 2319 break; 2320 case BCM_FIELD_DOSATTACK_TCP_OFFSET: 2321 field = TCP_FRAG_OFFSET_EQ_ONEf; 2322 break; 2323 case BCM_FIELD_DOSATTACK_SYN_FRAG: 2324 field = TCP_FLAGS_SYN_EQ_ONE_ACK_EQ_ZERO_AND_SRC_PORT_LT_1024f; 2325 break; 2326 case BCM_FIELD_DOSATTACK_FLAGZERO_SEQZERO: 2327 field = TCP_ALL_FLAGS_EQ_ZERO_AND_SEQNUM_EQ_ZEROf; 2328 break; 2329 case BCM_FIELD_DOSATTACK_TCPFLAGS_FUP: 2330 field = TCP_FLAGS_FIN_URG_AND_PSH_EQ_ONE_AND_SEQNUM_EQ_ZEROf; 2331 break; 2332 case BCM_FIELD_DOSATTACK_TCPFLAGS_SF: 2333 field = TCP_FLAGS_FIN_AND_SYN_EQ_ONEf; 2334 break; 2335 case BCM_FIELD_DOSATTACK_TCPPORTS_EQUAL: 2336 field = TCP_SPORT_EQ_DPORTf; 2337 break; 2338 case BCM_FIELD_DOSATTACK_UDPPORTS_EQUAL: 2339 field = UDP_SPORT_EQ_DPORTf; 2340 break; 2341 case BCM_FIELD_DOSATTACK_ICMP: 2342 field = ICMP_ECHO_PKT_SIZE_TOO_BIGf; 2343 break; 2344 case BCM_FIELD_DOSATTACK_ICMPFRAGMENTS: 2345 field = ICMP_FRAGMENTED_PKTf; 2346 break; 2347 case BCM_FIELD_DOSATTACK_TCPFLAGS_SR: 2348 field = TCP_SYN_RSTf; 2349 break; 2350 case BCM_FIELD_DOSATTACK_TCPFLAGS_SYN_FIRSTFRAG: 2351 field = TCP_SYN_FIRST_FRAGMENTf; 2352 break; 2353 case BCM_FIELD_DOSATTACK_TCPFLAGS_FIN_NOACK: 2354 field = TCP_FIN_NO_ACKf; 2355 break; 2356 case BCM_FIELD_DOSATTACK_TCPFLAGS_RST_NOACK: 2357 field = TCP_RST_NO_ACKf; 2358 break; 2359 case BCM_FIELD_DOSATTACK_TCPFLAGS_NOSFRA: 2360 field = TCP_NO_SYN_FIN_RST_ACKf; 2361 break; 2362 case BCM_FIELD_DOSATTACK_TCP_DSTPORT_ZERO: 2363 field = TCP_DPORT_ZEROf; 2364 break; 2365 case BCM_FIELD_DOSATTACK_TCP_SRCPORT_ZERO: 2366 field = TCP_DPORT_ZEROf; 2367 break; 2368 case BCM_FIELD_DOSATTACK_TCP_DST_IP_BCAST: 2369 field = TCP_IP_BROADCAST_CHECKf; 2370 break; 2371 case BCM_FIELD_DOSATTACK_TCPFLAGS_ZERO: 2372 field = TCP_FLAG_ZEROf; 2373 break; 2374 case BCM_FIELD_DOSATTACK_TCPFLAGS_RESVD_NONZERO: 2375 field = TCP_RESERVED_NON_ZEROf; 2376 break; 2377 case BCM_FIELD_DOSATTACK_TCPFLAGS_ACK: 2378 field = TCP_ACK_ACKNUMBER_ZEROf; 2379 break; 2380 case BCM_FIELD_DOSATTACK_TCPFLAGS_URG_NOURGPTR: 2381 field = TCP_URG_NO_URG_POINTERf; 2382 break; 2383 case BCM_FIELD_DOSATTACK_TCPFLAGS_NOURG_URGPTR: 2384 field = TCP_NO_URG_URG_POINTERf; 2385 break; 2386 case BCM_FIELD_DOSATTACK_TCPFLAGS_SYNOPTION: 2387 field = TCP_SYN_WITH_DATA_PAYLOADf; 2388 break; 2389 default: 2390 return BCM_E_PARAM; 2391 } 2392 2393 fmt = HVE_DOS_ATTACK_RESULTS_FORMATfmt; 2394 if (soc_format_field_valid(unit, fmt, field) == FALSE) { 2395 return BCM_E_PARAM; 2396 } 2397 field_info = soc_format_fieldinfo_get(unit, fmt, field); 2398 bit_pos = field_info->bp; 2399 2400 SHR_BITSET(qual_info->bitmap, bit_pos); 2401 } 2402 qual_info->partial = TRUE; 2403 2404 return BCM_E_NONE; 2405 } 2406 2407 /******************* Extraction *****************************/ 2408 /* 2409 * Function: 2410 * _field_offset_part_get 2411 * 2412 * Purpose: 2413 * Returns group part number for given offset in keygen context. 2414 * 2415 * Parameters: 2416 * offset_arr - (IN) Offset array in keygen context. 2417 * index - (IN) Index in offset array. 2418 * part - (OUT) pointer to part. 2419 * 2420 * Returns: 2421 * BCM_E_INTERNAL - Incorrect arguments. 2422 * BCM_E_NONE - Success. 2423 */ 2424 STATIC int 2425 _field_offset_part_get(bcmi_keygen_qual_offset_t *offset_arr, 2426 uint8 index, int *part) 2427 { 2428 int rv = BCM_E_NONE; 2429 2430 if ((offset_arr == NULL) || (part == NULL)) { 2431 return BCM_E_PARAM; 2432 } 2433 2434 if (index < BCMI_KEYGEN_QUAL_OFFSETS_MAX) { 2435 *part = offset_arr->offset[index] / 180; 2436 } else { 2437 rv = BCM_E_INTERNAL; 2438 } 2439 2440 return rv; 2441 } 2442 2443 /* 2444 * Function: 2445 * _field_hx5_ft_qual_offset_split_req 2446 * 2447 * Purpose: 2448 * Checks if spliting is required in given offset_info 2449 * at given offset. 2450 * 2451 * Parameters: 2452 * uint - (IN) Device Unit. 2453 * offset_arr - (IN) Offset array in keygen context. 2454 * offset - (IN) Offset to verify 2455 * split_pos - (OUT) Split bit position 2456 * 2457 * Returns: 2458 * TRUE - Splitting is required. 2459 * FALSE - Splitting is not required. 2460 */ 2461 STATIC int 2462 _field_hx5_ft_qual_offset_split_req(int unit, 2463 bcmi_keygen_qual_offset_t *offset_arr, 2464 int offset, 2465 int *split_pos) 2466 { 2467 int q_offset = 0; 2468 int width = 0; 2469 2470 q_offset = offset_arr->offset[offset]; 2471 width = offset_arr->width[offset]; 2472 2473 if ((q_offset < 180) && (q_offset + width) > 180) { 2474 if (split_pos != NULL) { 2475 *split_pos = 180; 2476 } 2477 return TRUE; 2478 } 2479 2480 return FALSE; 2481 } 2482 2483 /* 2484 * Function: 2485 * _field_hx5_ft_qual_offset_arr_split 2486 * 2487 * Purpose: 2488 * Split offset info info 2 parts if group_part boundary 2489 * lies in-between the qualifier offsets. 2490 * 2491 * Parameters: 2492 * uint - (IN) Unit 2493 * split_idx - (IN) Qualifier offset which requires splitting. 2494 * qual_offset_info - (IN/OUT) qualifier offset info 2495 * 2496 * Returns: 2497 * BCM_E_XXX 2498 * 2499 * Notes: 2500 * In Flowtracker, keygen types A/A/B are 128 bits in size. But, 2501 * double-wide group mode is 360 bits with 180 bits in either 2502 * parts. Due to this unsymmetry in keygen type bit size and 2503 * group parts size, it can happen that 180 bit part boundary 2504 * lies in-between offset info in at max 1 qualifier. So, it 2505 * is required to split that offset_arr into 2 parts for 2506 * correct population of group_qual info. 2507 */ 2508 STATIC int 2509 _field_hx5_ft_qual_offset_arr_split(int unit, 2510 int split_idx, 2511 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info) 2512 { 2513 int rv = BCM_E_NONE; 2514 int width = 0; 2515 int offset = 0; 2516 int q_offset = 0; 2517 int ext_num = 0; 2518 int split_offset = 0; 2519 int num_offsets = 0; 2520 int split_pos = 0; 2521 _field_ft_qual_sel_t *sel_offset_arr = NULL; 2522 bcmi_keygen_qual_offset_t *offset_arr = NULL; 2523 2524 offset_arr = qual_ext_offset_info->offset_arr; 2525 sel_offset_arr = qual_ext_offset_info->sel_offset_arr; 2526 2527 /* Search for split offset */ 2528 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 2529 if (!offset_arr[split_idx].width[offset]) { 2530 continue; 2531 } 2532 if (_field_hx5_ft_qual_offset_split_req(unit, 2533 &offset_arr[split_idx], offset, &split_pos) == TRUE) { 2534 split_offset = offset; 2535 width = offset_arr[split_idx].width[offset]; 2536 q_offset = offset_arr[split_idx].offset[offset]; 2537 ext_num = sel_offset_arr[split_idx].ext_num[offset]; 2538 break; 2539 } 2540 num_offsets++; 2541 if (num_offsets == offset_arr[split_idx].num_offsets) { 2542 break; 2543 } 2544 } 2545 2546 /* Split */ 2547 if (num_offsets < offset_arr[split_idx].num_offsets) { 2548 if (((split_offset + 1) >= BCMI_KEYGEN_QUAL_OFFSETS_MAX) || 2549 (offset_arr[split_idx].width[BCMI_KEYGEN_QUAL_OFFSETS_MAX - 1])) { 2550 /* Cannot split, not enough free indices */ 2551 return BCM_E_INTERNAL; 2552 } 2553 for (offset = (BCMI_KEYGEN_QUAL_OFFSETS_MAX - 1); 2554 offset > split_offset; offset--) { 2555 offset_arr[split_idx].offset[offset] = 2556 offset_arr[split_idx].offset[offset - 1]; 2557 offset_arr[split_idx].width[offset] = 2558 offset_arr[split_idx].width[offset - 1]; 2559 sel_offset_arr[split_idx].ext_num[offset] = 2560 sel_offset_arr[split_idx].ext_num[offset - 1]; 2561 } 2562 2563 width = (q_offset + width) - split_pos; 2564 offset_arr[split_idx].offset[split_offset] = q_offset; 2565 offset_arr[split_idx].width[split_offset] = split_pos - q_offset; 2566 sel_offset_arr[split_idx].ext_num[split_offset] = ext_num; 2567 offset_arr[split_idx].offset[split_offset + 1] = split_pos; 2568 offset_arr[split_idx].width[split_offset + 1] = width; 2569 sel_offset_arr[split_idx].ext_num[split_offset + 1] = ext_num; 2570 2571 offset_arr[split_idx].num_offsets += 1; 2572 sel_offset_arr[split_idx].num_offsets += 1; 2573 } 2574 2575 return rv; 2576 } 2577 2578 /* 2579 * Function: 2580 * _bcm_field_hx5_ft_keygen_extractors_mask_set 2581 * 2582 * Purpose: 2583 * Extractor mask memory are calculated based on 2584 * extractors codes and qualifier offsets/width. 2585 * 2586 * Parameters: 2587 * uint - (IN) Unit 2588 * qual_ext_offset_info - (IN) qualifier offset info 2589 * ext_codes - (IN/OUT) Extractors code. 2590 * 2591 * Returns: 2592 * BCM_E_XXX 2593 * 2594 * Notes: 2595 * In flowtracker, keygen type A has 128 bits of mask. This mask 2596 * needs to be calculated based onn extractor codes and qualifier 2597 * offset/width pair. 2598 * Shift_offsets are first calculated to get correct shifted 2599 * offsets of qualifier offsets. 2600 */ 2601 int 2602 _bcm_field_hx5_ft_keygen_extractors_mask_set(int unit, 2603 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info, 2604 _field_ft_keygen_ext_codes_t *ext_codes) 2605 { 2606 int rv = BCM_E_NONE; 2607 int qual_idx = 0; 2608 int q_offset = 0; 2609 int q_width = 0; 2610 int ext_num = 0; 2611 int num_offsets = 0; 2612 int offset = 0; 2613 int shift_offsets_arr[30] = {0}; 2614 2615 (void) _field_hx5_ft_keygen_ext_shift_offsets_get(unit, 2616 ext_codes, &shift_offsets_arr[0]); 2617 2618 while(qual_idx < qual_ext_offset_info->size) { 2619 num_offsets = 0; 2620 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 2621 if (!qual_ext_offset_info->offset_arr[qual_idx].width[offset]) { 2622 continue; 2623 } 2624 2625 q_offset = qual_ext_offset_info->offset_arr[qual_idx].offset[offset]; 2626 q_width = qual_ext_offset_info->offset_arr[qual_idx].width[offset]; 2627 ext_num = qual_ext_offset_info->sel_offset_arr[qual_idx].ext_num[offset]; 2628 2629 BCM_IF_ERROR_RETURN( 2630 _bcm_field_ft_keygen_profile_extractors_mask_set(unit, 2631 q_offset, q_width, ext_num, shift_offsets_arr, ext_codes)); 2632 2633 num_offsets++; 2634 if (num_offsets == 2635 qual_ext_offset_info->offset_arr[qual_idx].num_offsets) { 2636 break; 2637 } 2638 } 2639 qual_idx++; 2640 } 2641 2642 return rv; 2643 } 2644 2645 /* 2646 * Function: 2647 * _field_hx5_ft_qual_offset_ext_shift_apply 2648 * 2649 * Purpose: 2650 * Updates offset values in qual_offset_info based on extractors 2651 * shift logic and group parts. 2652 * 2653 * Parameters: 2654 * uint - (IN) Unit. 2655 * split_allowed - (IN) Check if we need to do split 2656 * ext_codes - (IN) Extractors code. 2657 * qual_offset_info - (IN/OUT) qualifier offset info 2658 * 2659 * Returns: 2660 * BCM_E_XXX 2661 */ 2662 int 2663 _field_hx5_ft_qual_offset_ext_shift_apply(int unit, 2664 int split_allowed, 2665 _field_ft_keygen_ext_codes_t *ext_codes, 2666 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info) 2667 { 2668 int idx = 0; 2669 int rv = BCM_E_NONE; 2670 int offset = 0; 2671 int q_offset = 0; 2672 int shift_idx = 0; 2673 int num_offsets = 0; 2674 int offset_arr_split = FALSE; 2675 int shift_offsets_arr[30] = {0}; 2676 2677 (void) _field_hx5_ft_keygen_ext_shift_offsets_get(unit, 2678 ext_codes, &shift_offsets_arr[0]); 2679 2680 idx = 0; 2681 while (idx < qual_ext_offset_info->size) { 2682 num_offsets = 0; 2683 offset_arr_split = FALSE; 2684 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 2685 if (!qual_ext_offset_info->offset_arr[idx].width[offset]) { 2686 continue; 2687 } 2688 q_offset = qual_ext_offset_info->offset_arr[idx].offset[offset]; 2689 shift_idx = q_offset / 16; 2690 q_offset = (q_offset % 16) + shift_offsets_arr[shift_idx]; 2691 qual_ext_offset_info->offset_arr[idx].offset[offset] = q_offset; 2692 2693 if (_field_hx5_ft_qual_offset_split_req(unit, &qual_ext_offset_info-> 2694 offset_arr[idx], offset, NULL) == TRUE) { 2695 offset_arr_split = TRUE; 2696 } 2697 num_offsets++; 2698 if (num_offsets == 2699 qual_ext_offset_info->offset_arr[idx].num_offsets) { 2700 break; 2701 } 2702 } 2703 if ((split_allowed) && (offset_arr_split)) { 2704 BCM_IF_ERROR_RETURN(_field_hx5_ft_qual_offset_arr_split(unit, 2705 idx, qual_ext_offset_info)); 2706 } 2707 idx++; 2708 } 2709 2710 return rv; 2711 } 2712 2713 /* 2714 * Function: 2715 * _field_hx5_ft_group_keygen_ext_codes_set 2716 * 2717 * Purpose: 2718 * Extract flowtracker stage field group keygen extractor codes. 2719 * 2720 * Parameters: 2721 * unit - (IN) BCM device number 2722 * fg - (IN) Field group structure. 2723 * keygen_oper- (IN) Kegen operational structure. 2724 * 2725 * Returns: 2726 * BCM_E_MEMEORY - Failed to allocate memory. 2727 * BCM_E_PARAM - Input params is wrong. 2728 * BCM_E_NONE - Success. 2729 */ 2730 STATIC int 2731 _field_hx5_ft_group_keygen_ext_codes_set(int unit, 2732 _field_group_t *fg, 2733 bcmi_keygen_oper_t *keygen_oper) 2734 { 2735 int rv = BCM_E_NONE; 2736 int keygen_profile; 2737 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info; 2738 uint16 ext_ctrl_sel_info_count; 2739 _field_ft_keygen_ext_codes_t *ext_codes = NULL; 2740 2741 /* Validate input params. */ 2742 if ((fg == NULL) || (keygen_oper == NULL)) { 2743 return BCM_E_PARAM; 2744 } 2745 2746 if (fg->ft_ext_codes == NULL) { 2747 /* Allocate memory */ 2748 _FP_XGS3_ALLOC(ext_codes, sizeof(_field_ft_keygen_ext_codes_t), 2749 "field group ext codes"); 2750 if (ext_codes == NULL) { 2751 return BCM_E_MEMORY; 2752 } 2753 (void) _bcm_field_ft_keygen_extractors_init(ext_codes); 2754 keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB; 2755 } else { 2756 ext_codes = fg->ft_ext_codes; 2757 keygen_profile = ext_codes->keygen_profile; 2758 } 2759 2760 ext_ctrl_sel_info_count = keygen_oper->ext_ctrl_sel_info_count; 2761 ext_ctrl_sel_info = keygen_oper->ext_ctrl_sel_info; 2762 2763 rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile, 2764 ext_ctrl_sel_info_count, ext_ctrl_sel_info, ext_codes); 2765 2766 if (BCM_SUCCESS(rv)) { 2767 fg->ft_ext_codes = ext_codes; 2768 } else { 2769 fg->ft_ext_codes = NULL; 2770 sal_free(ext_codes); 2771 } 2772 2773 return rv; 2774 } 2775 2776 /* 2777 * Function: 2778 * _field_hx5_ft_qual_offset_info_merge 2779 * 2780 * Purpose: 2781 * Create single offset_arr/qid_arr from output of Keygen_oper 2782 * 2783 * Parameters: 2784 * uint - (IN) Unit. 2785 * keygen_oper - (IN) Output from Keygen algorithm. 2786 * keygen_parts_count - (IN) Number of Parts in Keygen output. 2787 * qual_offset_info - (OUT) qualifier offset info 2788 * 2789 * Returns: 2790 * BCM_E_XXX 2791 */ 2792 int 2793 _field_hx5_ft_qual_offset_info_merge(int unit, 2794 bcmi_keygen_oper_t *keygen_oper, 2795 int keygen_parts_count, 2796 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info) 2797 { 2798 int rv = BCM_E_NONE; 2799 int q_idx = 0, idx = 0; 2800 int keygen_part = 0; 2801 int offset = 0; 2802 int sel_offset = 0; 2803 int new_qual_idx = 0; 2804 uint16 num_offsets = 0; 2805 bcm_field_qset_t qset; 2806 bcmi_keygen_qual_offset_info_t *info = NULL; 2807 2808 new_qual_idx = 0; 2809 BCM_FIELD_QSET_INIT(qset); 2810 /* Loop through all keygen parts */ 2811 for (keygen_part = 0; keygen_part < keygen_parts_count; keygen_part++) { 2812 info = &(keygen_oper->qual_offset_info[keygen_part]); 2813 sel_offset = 160 * keygen_part; 2814 2815 /* Loop through qual info in the keygen part */ 2816 for (idx = 0; idx < info->size; idx++, q_idx++) { 2817 /* Check if qual is also allocated, use that index */ 2818 if (BCM_FIELD_QSET_TEST(qset, info->qid_arr[idx])) { 2819 for (q_idx = 0; q_idx < new_qual_idx; q_idx++) { 2820 if (qual_ext_offset_info->qid_arr[q_idx] == 2821 info->qid_arr[idx]) { 2822 break; 2823 } 2824 } 2825 if (q_idx == new_qual_idx) { 2826 return BCM_E_INTERNAL; 2827 } 2828 } else { 2829 /* Assign new index */ 2830 q_idx = new_qual_idx; 2831 new_qual_idx++; 2832 } 2833 num_offsets = 0; 2834 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 2835 if (!info->offset_arr[idx].width[offset]) { 2836 continue; 2837 } 2838 if (qual_ext_offset_info->offset_arr[q_idx].width[offset]) { 2839 return (BCM_E_INTERNAL); 2840 } 2841 qual_ext_offset_info->offset_arr[q_idx].offset[offset] = 2842 info->offset_arr[idx].offset[offset] + sel_offset; 2843 qual_ext_offset_info->offset_arr[q_idx].width[offset] = 2844 info->offset_arr[idx].width[offset]; 2845 qual_ext_offset_info->sel_offset_arr[q_idx].ext_num[offset] = 2846 (info->offset_arr[idx].offset[offset] + sel_offset) / 16; 2847 num_offsets++; 2848 if (num_offsets == info->offset_arr[idx].num_offsets) { 2849 break; 2850 } 2851 } 2852 qual_ext_offset_info->qid_arr[q_idx] = info->qid_arr[idx]; 2853 qual_ext_offset_info->offset_arr[q_idx].num_offsets += num_offsets; 2854 qual_ext_offset_info->sel_offset_arr[q_idx].num_offsets += num_offsets; 2855 /* Add qual to Qset */ 2856 BCM_FIELD_QSET_ADD(qset, info->qid_arr[idx]); 2857 } 2858 } 2859 qual_ext_offset_info->size = new_qual_idx; 2860 2861 return rv; 2862 } 2863 2864 /* 2865 * Function: 2866 * _field_hx5_ft_qual_ext_offset_info_free 2867 * 2868 * Purpose: 2869 * Free qual_ext_offset_info 2870 * 2871 * Parameters: 2872 * uint - (IN) Unit. 2873 * qual_ext_offset_info - (OUT) qualifier ext offset info 2874 * 2875 * Returns: 2876 * None 2877 * Notes: 2878 * Double pointes is passed as input. So, memory for 2879 * qual_ext_offset_info is also freed. 2880 */ 2881 void 2882 _field_hx5_ft_qual_ext_offset_info_free(int unit, 2883 _field_ft_qual_ext_offset_info_t **qual_ext_offset_info) 2884 { 2885 _field_ft_qual_ext_offset_info_t *temp_info = NULL; 2886 2887 if (*qual_ext_offset_info == NULL) { 2888 return; 2889 } 2890 2891 temp_info = *qual_ext_offset_info; 2892 2893 if (temp_info->qid_arr != NULL) { 2894 sal_free(temp_info->qid_arr); 2895 temp_info->qid_arr = NULL; 2896 } 2897 if (temp_info->offset_arr != NULL) { 2898 sal_free(temp_info->offset_arr); 2899 temp_info->offset_arr = NULL; 2900 } 2901 if (temp_info->sel_offset_arr != NULL) { 2902 sal_free(temp_info->sel_offset_arr); 2903 temp_info->sel_offset_arr = NULL; 2904 } 2905 2906 sal_free(temp_info); 2907 *qual_ext_offset_info = NULL; 2908 } 2909 2910 /* 2911 * Function: 2912 * _field_hx5_ft_qual_ext_offset_info_get 2913 * 2914 * Purpose: 2915 * Create a temporary structure to work on keygen_oper 2916 * 2917 * Parameters: 2918 * uint - (IN) Unit. 2919 * keygen_parts_count - (IN) Number of Parts in Keygen output. 2920 * keygen_oper - (IN) Output from Keygen algorithm. 2921 * qual_ext_offset_info - (OUT) qualifier ext offset info 2922 * 2923 * Returns: 2924 * BCM_E_XXX 2925 * Notes: 2926 * Double pointer is passed as input. So, memory for 2927 * qual_ext_offset_info is also allocated. 2928 */ 2929 int 2930 _field_hx5_ft_qual_ext_offset_info_get(int unit, 2931 int keygen_parts_count, 2932 bcmi_keygen_oper_t *keygen_oper, 2933 _field_ft_qual_ext_offset_info_t **qual_ext_offset_info) 2934 { 2935 int rv = BCM_E_NONE; 2936 int keygen_part = 0; 2937 int qual_offset_info_count = 0; 2938 _field_ft_qual_ext_offset_info_t *temp_info = NULL; 2939 bcmi_keygen_qual_offset_info_t *qual_offset_info = NULL; 2940 2941 if ((keygen_oper == NULL) || 2942 (keygen_oper->qual_offset_info == NULL) || 2943 (keygen_oper->ext_ctrl_sel_info == NULL)) { 2944 return BCM_E_PARAM; 2945 } 2946 2947 /* Get number of qualifiers offset info */ 2948 for (keygen_part = 0; keygen_part < keygen_parts_count; keygen_part++) { 2949 qual_offset_info = &(keygen_oper->qual_offset_info[keygen_part]); 2950 qual_offset_info_count += qual_offset_info->size; 2951 } 2952 2953 _FP_XGS3_ALLOC(temp_info, 2954 sizeof(_field_ft_qual_ext_offset_info_t), 2955 " Qual Ext offset info"); 2956 if (temp_info == NULL) { 2957 return BCM_E_MEMORY; 2958 } 2959 2960 /* Allocate joint memory for all qual offset infos. */ 2961 temp_info->size = qual_offset_info_count; 2962 _FP_XGS3_ALLOC(temp_info->qid_arr, 2963 qual_offset_info_count * sizeof(bcm_field_qualify_t), 2964 "Group Qualifier Info"); 2965 _FP_XGS3_ALLOC(temp_info->offset_arr, 2966 qual_offset_info_count * sizeof(bcmi_keygen_qual_offset_t), 2967 "Group Qualifier Offset Info"); 2968 _FP_XGS3_ALLOC(temp_info->sel_offset_arr, 2969 qual_offset_info_count * sizeof(_field_ft_qual_sel_t), 2970 "Group Qualifier Offset Info"); 2971 2972 if ((temp_info->qid_arr == NULL) || 2973 (temp_info->offset_arr == NULL) || 2974 (temp_info->sel_offset_arr == NULL)) { 2975 rv = BCM_E_MEMORY; 2976 } 2977 2978 if (BCM_SUCCESS(rv)) { 2979 *qual_ext_offset_info = temp_info; 2980 2981 /* Merge all keygen_parts to joint memory. */ 2982 rv = _field_hx5_ft_qual_offset_info_merge(unit, 2983 keygen_oper, keygen_parts_count, *qual_ext_offset_info); 2984 } 2985 2986 if (BCM_FAILURE(rv)) { 2987 if (temp_info != NULL) { 2988 *qual_ext_offset_info = temp_info; 2989 (void) _field_hx5_ft_qual_ext_offset_info_free(unit, 2990 qual_ext_offset_info); 2991 } 2992 *qual_ext_offset_info = NULL; 2993 } 2994 2995 return rv; 2996 } 2997 2998 /* 2999 * Function: 3000 * _field_hx5_ft_group_qual_offset_info_make 3001 * 3002 * Purpose: 3003 * Create group Qual info for given group part 3004 * 3005 * Parameters: 3006 * uint - (IN) Unit. 3007 * fg - (IN/OUT) Structure to field group. 3008 * qual_ext_offset_info - (IN) qualifier offset info. 3009 * 3010 * Returns: 3011 * BCM_E_XXX 3012 */ 3013 STATIC int 3014 _field_hx5_ft_group_qual_offset_info_make(int unit, 3015 _field_group_t *fg, 3016 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info) 3017 { 3018 int rv = BCM_E_NONE; 3019 int idx = 0; 3020 int part = 0; 3021 int info_idx = 0; 3022 int offset = 0; 3023 int parts_count = 0; 3024 int qual_offset_info_count = 0; 3025 uint16 qual = 0; 3026 uint16 num_offsets = 0; 3027 uint8 part_offset_found[2]; 3028 uint8 new_idx_allocated[2]; 3029 bcm_field_qualify_t *qid_arr = NULL; 3030 _bcm_field_group_qual_t *fg_qual_arr = NULL; 3031 bcmi_keygen_qual_offset_t *offset_arr = NULL; 3032 _field_ft_group_qual_part_info_t grp_part_info[2]; 3033 3034 /* Validate input params. */ 3035 if ((fg == NULL) || (qual_ext_offset_info == NULL)) { 3036 return BCM_E_INTERNAL; 3037 } 3038 3039 qid_arr = qual_ext_offset_info->qid_arr; 3040 offset_arr = qual_ext_offset_info->offset_arr; 3041 qual_offset_info_count = qual_ext_offset_info->size; 3042 3043 /* Get number of entry parts. */ 3044 BCM_IF_ERROR_RETURN(_bcm_field_entry_tcam_parts_count(unit, 3045 fg->stage_id, fg->flags, &parts_count)); 3046 3047 for (part = 0; part < parts_count; part++) { 3048 grp_part_info[part].count = 0; 3049 BCM_FIELD_QSET_INIT(grp_part_info[part].qset); 3050 } 3051 3052 /* Step 1: Loop through all info and get count in multiple group parts */ 3053 for (info_idx = 0; info_idx < qual_offset_info_count; info_idx++) { 3054 qual = qid_arr[info_idx]; 3055 num_offsets = 0; 3056 part_offset_found[0] = part_offset_found[1] = FALSE; 3057 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 3058 if (offset_arr[info_idx].width[offset] == 0) { 3059 continue; 3060 } 3061 rv = _field_offset_part_get(&offset_arr[info_idx], offset, &part); 3062 if ((rv != BCM_E_NONE) || (part >= parts_count)) { 3063 rv = BCM_E_INTERNAL; 3064 goto cleanup; 3065 } 3066 part_offset_found[part] = TRUE; 3067 num_offsets++; 3068 if (num_offsets == offset_arr[info_idx].num_offsets) { 3069 break; 3070 } 3071 } 3072 for (part = 0; part < parts_count; part++) { 3073 if (part_offset_found[part] == TRUE) { 3074 if (!BCM_FIELD_QSET_TEST(grp_part_info[part].qset, qual)) { 3075 grp_part_info[part].count++; 3076 BCM_FIELD_QSET_ADD(grp_part_info[part].qset, qual); 3077 } 3078 } 3079 } 3080 } 3081 3082 /* Step 2: Allocate memory to each group parts */ 3083 for (part = 0; part < parts_count; part++) { 3084 fg_qual_arr = &(fg->qual_arr[0][part]); 3085 fg_qual_arr->size = grp_part_info[part].count; 3086 3087 if (fg_qual_arr->size != 0) { 3088 _FP_XGS3_ALLOC(fg_qual_arr->qid_arr, 3089 fg_qual_arr->size * sizeof(uint16), 3090 "Group Qualifier Array"); 3091 _FP_XGS3_ALLOC(fg_qual_arr->offset_arr, 3092 fg_qual_arr->size * sizeof(_bcm_field_qual_offset_t), 3093 "Group Qualifier Offset Info"); 3094 if ((fg_qual_arr->qid_arr == NULL) || 3095 (fg_qual_arr->offset_arr == NULL)) { 3096 rv = BCM_E_MEMORY; 3097 goto cleanup; 3098 } 3099 } else { 3100 fg_qual_arr->qid_arr = NULL; 3101 fg_qual_arr->offset_arr = NULL; 3102 } 3103 grp_part_info[part].count = 0; 3104 BCM_FIELD_QSET_INIT(grp_part_info[part].qset); 3105 } 3106 3107 /* Step 3: Fill up group qual parts */ 3108 for (info_idx = 0; info_idx < qual_offset_info_count; info_idx++) { 3109 qual = qid_arr[info_idx]; 3110 num_offsets = 0; 3111 new_idx_allocated[0] = new_idx_allocated[1] = FALSE; 3112 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 3113 if (offset_arr[info_idx].width[offset] == 0) { 3114 continue; 3115 } 3116 (void) _field_offset_part_get(&offset_arr[info_idx], offset, &part); 3117 fg_qual_arr = &(fg->qual_arr[0][part]); 3118 if (new_idx_allocated[part] == TRUE) { 3119 idx = grp_part_info[part].count; 3120 } else { 3121 if (BCM_FIELD_QSET_TEST(grp_part_info[part].qset, qual)) { 3122 for (idx = (grp_part_info[part].count - 1); idx >= 0; idx--) { 3123 if (fg_qual_arr->qid_arr[idx] == qual) { 3124 break; 3125 } 3126 } 3127 if (idx < 0) { 3128 rv = BCM_E_INTERNAL; 3129 goto cleanup; 3130 } 3131 } else { 3132 new_idx_allocated[part] = TRUE; 3133 idx = grp_part_info[part].count; 3134 BCM_FIELD_QSET_ADD(grp_part_info[part].qset, qual); 3135 } 3136 } 3137 if ((idx >= fg_qual_arr->size) || 3138 (fg_qual_arr->offset_arr[idx].width[offset] != 0)) { 3139 rv = BCM_E_INTERNAL; 3140 goto cleanup; 3141 } 3142 fg_qual_arr->qid_arr[idx] = qual; 3143 fg_qual_arr->offset_arr[idx].offset[offset] = 3144 offset_arr[info_idx].offset[offset]; 3145 fg_qual_arr->offset_arr[idx].width[offset] = 3146 offset_arr[info_idx].width[offset]; 3147 fg_qual_arr->offset_arr[idx].field = KEYf; 3148 if (fg_qual_arr->offset_arr[idx].num_offsets <= offset) { 3149 fg_qual_arr->offset_arr[idx].num_offsets = (offset + 1); 3150 } 3151 3152 num_offsets++; 3153 if (num_offsets == offset_arr[info_idx].num_offsets) { 3154 break; 3155 } 3156 } 3157 for (part = 0; part < parts_count; part++) { 3158 if (new_idx_allocated[part] == TRUE) { 3159 grp_part_info[part].count++; 3160 } 3161 } 3162 } 3163 3164 cleanup: 3165 3166 if(BCM_FAILURE(rv)) { 3167 for (part = 0; part < parts_count; part++) { 3168 fg_qual_arr = &(fg->qual_arr[0][part]); 3169 if (fg_qual_arr->qid_arr != NULL) { 3170 sal_free(fg_qual_arr->qid_arr); 3171 fg_qual_arr->qid_arr = NULL; 3172 } 3173 if (fg_qual_arr->offset_arr != NULL) { 3174 sal_free(fg_qual_arr->offset_arr); 3175 fg_qual_arr->offset_arr = NULL; 3176 } 3177 } 3178 } 3179 3180 return (rv); 3181 } 3182 3183 /* 3184 * Function: 3185 * _field_hx5_ft_group_keygen_oper_insert 3186 * 3187 * Purpose: 3188 * Convert and save output of keygen algorithm. 3189 * 3190 * Parameters: 3191 * unit - (IN) Unit. 3192 * fg - (IN) Field Group structure. 3193 * keygen_parts_count - (IN) Number of keygen parts 3194 * keygen_oper - (IN) Output from Keygen algorithm. 3195 * 3196 * Returns: 3197 * BCM_E_XXX 3198 */ 3199 STATIC int 3200 _field_hx5_ft_group_keygen_oper_insert(int unit, 3201 _field_group_t *fg, 3202 int keygen_parts_count, 3203 bcmi_keygen_oper_t *keygen_oper) 3204 { 3205 int rv = BCM_E_NONE; 3206 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info = NULL; 3207 3208 if ((fg == NULL) || (keygen_oper == NULL)) { 3209 return BCM_E_INTERNAL; 3210 } 3211 3212 /* Verify if atleast one qualifier is extracted */ 3213 if (keygen_oper->ext_ctrl_sel_info_count == 0) { 3214 return BCM_E_NONE; 3215 } 3216 3217 /* Dump Keygen Oper Qual Offsets and Extractors codes */ 3218 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 3219 "fp_group=%d Keygen Oper Info \n"),fg->gid)); 3220 (void) _bcm_field_keygen_qual_offset_info_dump(unit, 3221 keygen_parts_count, keygen_oper); 3222 3223 rv = _field_hx5_ft_group_keygen_ext_codes_set(unit, fg, keygen_oper); 3224 BCM_IF_ERROR_RETURN(rv); 3225 3226 rv = _field_hx5_ft_qual_ext_offset_info_get(unit, keygen_parts_count, 3227 keygen_oper, &qual_ext_offset_info); 3228 if (BCM_FAILURE(rv)) { 3229 goto cleanup; 3230 } 3231 3232 /* Update Mask of extractors */ 3233 rv = _bcm_field_hx5_ft_keygen_extractors_mask_set(unit, 3234 qual_ext_offset_info, fg->ft_ext_codes); 3235 if (BCM_FAILURE(rv)) { 3236 goto cleanup; 3237 } 3238 3239 /* 3240 * Apply shifts on qualifier offsets due to hw extractors shift logic. 3241 * This will also split offsets to multiple group parts, if required. 3242 */ 3243 rv = _field_hx5_ft_qual_offset_ext_shift_apply(unit, 3244 1, fg->ft_ext_codes, qual_ext_offset_info); 3245 if (rv != BCM_E_NONE) { 3246 goto cleanup; 3247 } 3248 /* Save qualifiers per group part */ 3249 rv = _field_hx5_ft_group_qual_offset_info_make(unit, 3250 fg, qual_ext_offset_info); 3251 if (BCM_FAILURE(rv)) { 3252 goto cleanup; 3253 } 3254 3255 /* Dump Hardware extractor information */ 3256 (void) _bcm_field_hx5_ft_keygen_hw_extractors_dump(unit, fg->ft_ext_codes); 3257 3258 cleanup: 3259 3260 if (qual_ext_offset_info != NULL) { 3261 (void) _field_hx5_ft_qual_ext_offset_info_free(unit, 3262 &qual_ext_offset_info); 3263 } 3264 3265 return rv; 3266 } 3267 3268 /* 3269 * Function: 3270 * _field_hx5_ft_keygen_oper_qual_add 3271 * 3272 * Purpose: 3273 * Add skipped qualifier Inport and its extractor codes to keygen_oper 3274 * info. Before calling keygen algorithm, qualifier InPort and corres- 3275 * ponding extractors are skipped from keygen algo processing as it is 3276 * required to be extracted with same extractors for all groups. Once 3277 * keygen_oper is formed qual InPort is added back to it for generating 3278 * final qual_arr info for the field group. Qual InPort is added to 3279 * part-0 of keygen output. 3280 * 3281 * Parameters: 3282 * unit - (IN) Unit. 3283 * keygen_cfg - (IN) Keygen config 3284 * keygen_oper- (IN/OUT) Output from Keygen algorithm. 3285 * 3286 * Returns: 3287 * BCM_E_XXX 3288 */ 3289 3290 STATIC int 3291 _field_hx5_ft_keygen_oper_qual_add(int unit, 3292 bcmi_keygen_cfg_t *keygen_cfg, 3293 bcmi_keygen_oper_t *keygen_oper) 3294 { 3295 uint16 idx = 0; 3296 uint16 offset = 0, num_offsets = 0; 3297 uint16 ext_ctrl_info_count = 0, skipped_sz = 0; 3298 uint16 qual_offset_info_size = 0; 3299 uint16 qual_offset_info_alloc = FALSE; 3300 bcm_field_qualify_t *qid_arr = NULL; 3301 bcmi_keygen_qual_offset_t *offset_arr = NULL; 3302 bcmi_keygen_qual_offset_info_t *qual_offset_info = NULL; 3303 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info = NULL; 3304 3305 if ((keygen_cfg == NULL) || (keygen_oper == NULL)) { 3306 return BCM_E_PARAM; 3307 } 3308 3309 /* No qualifiers/extractors were skipped */ 3310 if (keygen_cfg->ext_ctrl_sel_info_count == 0) { 3311 return BCM_E_NONE; 3312 } 3313 3314 /* Get total qual info size at part-0 of keygen_oper */ 3315 qual_offset_info = &(keygen_oper->qual_offset_info[0]); 3316 if (qual_offset_info != NULL) { 3317 qual_offset_info_size = qual_offset_info->size; 3318 } 3319 qual_offset_info_size++; 3320 3321 /* Get total extractors */ 3322 ext_ctrl_info_count = keygen_oper->ext_ctrl_sel_info_count; 3323 ext_ctrl_info_count += keygen_cfg->ext_ctrl_sel_info_count; 3324 3325 /* Allocate memories */ 3326 if (qual_offset_info == NULL) { 3327 qual_offset_info_alloc = TRUE; 3328 _FP_XGS3_ALLOC(qual_offset_info, 3329 keygen_cfg->num_parts * sizeof(bcmi_keygen_qual_offset_info_t), 3330 "Qual Offset Info"); 3331 } 3332 _FP_XGS3_ALLOC(qid_arr, 3333 qual_offset_info_size * sizeof(bcm_field_qualify_t), 3334 "Keygen oper qid arr"); 3335 _FP_XGS3_ALLOC(offset_arr, 3336 qual_offset_info_size * sizeof(bcmi_keygen_qual_offset_t), 3337 "Keygen oper offset arr"); 3338 _FP_XGS3_ALLOC(ext_ctrl_sel_info, 3339 ext_ctrl_info_count * sizeof(bcmi_keygen_ext_ctrl_sel_info_t), 3340 "Ext Ctrl Offset Info"); 3341 if ((qual_offset_info == NULL) || (qid_arr == NULL) || 3342 (offset_arr == NULL) || (ext_ctrl_sel_info == NULL)) { 3343 if ((qual_offset_info != NULL) && (qual_offset_info_alloc == TRUE)) { 3344 sal_free(qual_offset_info); 3345 } 3346 if (qid_arr != NULL) { 3347 sal_free(qid_arr); 3348 } 3349 if (offset_arr != NULL) { 3350 sal_free(offset_arr); 3351 } 3352 if (ext_ctrl_sel_info != NULL) { 3353 sal_free(ext_ctrl_sel_info); 3354 } 3355 return BCM_E_MEMORY; 3356 } 3357 /* Add InPort Qual info */ 3358 qid_arr[0] = bcmFieldQualifyInPort; 3359 offset_arr[0].num_offsets = 1; 3360 offset_arr[0].offset[0] = 0; 3361 offset_arr[0].width[0] = 7; 3362 for (idx = 0; idx < qual_offset_info->size; idx++) { 3363 num_offsets = 0; 3364 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 3365 if (qual_offset_info->offset_arr[idx].width[offset] == 0) { 3366 continue; 3367 } 3368 num_offsets++; 3369 offset_arr[idx + 1].offset[offset] = 3370 qual_offset_info->offset_arr[idx].offset[offset]; 3371 offset_arr[idx + 1].width[offset] = 3372 qual_offset_info->offset_arr[idx].width[offset]; 3373 if (num_offsets == qual_offset_info->offset_arr[idx].num_offsets) { 3374 break; 3375 } 3376 } 3377 offset_arr[idx + 1].num_offsets = num_offsets; 3378 qid_arr[idx + 1] = qual_offset_info->qid_arr[idx]; 3379 } 3380 3381 /* Copy ext ctrl sel info */ 3382 skipped_sz = keygen_cfg->ext_ctrl_sel_info_count; 3383 sal_memcpy(&ext_ctrl_sel_info[0], keygen_cfg->ext_ctrl_sel_info, 3384 skipped_sz * sizeof(bcmi_keygen_ext_ctrl_sel_info_t)); 3385 if (keygen_oper->ext_ctrl_sel_info_count != 0) { 3386 sal_memcpy(&ext_ctrl_sel_info[skipped_sz], 3387 keygen_oper->ext_ctrl_sel_info, 3388 keygen_oper->ext_ctrl_sel_info_count * 3389 sizeof(bcmi_keygen_ext_ctrl_sel_info_t)); 3390 } 3391 3392 /* Free modified members in keygen_oper */ 3393 if (keygen_oper->ext_ctrl_sel_info != NULL) { 3394 sal_free(keygen_oper->ext_ctrl_sel_info); 3395 keygen_oper->ext_ctrl_sel_info = NULL; 3396 } 3397 if (qual_offset_info_alloc == FALSE) { 3398 if (keygen_oper->qual_offset_info[0].qid_arr != NULL) { 3399 sal_free(keygen_oper->qual_offset_info[0].qid_arr); 3400 keygen_oper->qual_offset_info[0].qid_arr = NULL; 3401 } 3402 if (keygen_oper->qual_offset_info[0].offset_arr != NULL) { 3403 sal_free(keygen_oper->qual_offset_info[0].offset_arr); 3404 keygen_oper->qual_offset_info[0].offset_arr = NULL; 3405 } 3406 } 3407 3408 /* Update keygen_oper with modified members */ 3409 keygen_oper->ext_ctrl_sel_info_count = ext_ctrl_info_count; 3410 keygen_oper->ext_ctrl_sel_info = ext_ctrl_sel_info; 3411 if (qual_offset_info_alloc == TRUE) { 3412 keygen_oper->qual_offset_info = qual_offset_info; 3413 } 3414 keygen_oper->qual_offset_info[0].qid_arr = qid_arr; 3415 keygen_oper->qual_offset_info[0].offset_arr = offset_arr; 3416 keygen_oper->qual_offset_info[0].size = qual_offset_info_size; 3417 3418 return BCM_E_NONE; 3419 } 3420 3421 /* 3422 * Function: 3423 * _field_hx5_ft_ext_code_assign 3424 * 3425 * Purpose: 3426 * Calculate extractors values and qualifiers offsets in 3427 * final key. 3428 * 3429 * Parameters: 3430 * unit - (IN) BCM device number. 3431 * fsm_ptr - (IN) Field group creation state machine. 3432 * stage_fc - (IN) Field stage control structure. 3433 * 3434 * Returns: 3435 * BCM_E_XXX 3436 */ 3437 int _field_hx5_ft_ext_code_assign(int unit, 3438 int selcode_clear, 3439 _field_group_add_fsm_t *fsm_ptr) 3440 { 3441 int rv = BCM_E_NONE; 3442 uint16 rkey_size = 0; 3443 uint16 skipped_size = 0; 3444 uint16 qual_info_count = 0; 3445 uint16 keygen_parts_count = 0; 3446 uint16 qual_inport_excluded = FALSE; 3447 bcm_field_qset_t qset_req; 3448 bcmi_keygen_cfg_t keygen_cfg; 3449 bcmi_keygen_oper_t keygen_oper; 3450 bcmi_keygen_mode_t keygen_mode; 3451 bcmi_keygen_mode_t keygen_ext_mode; 3452 _field_group_t *fg = NULL; 3453 _field_stage_t *stage_fc = NULL; 3454 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 3455 3456 /* Input parameters check. */ 3457 if (NULL == fsm_ptr) { 3458 return (BCM_E_PARAM); 3459 } 3460 3461 fg = fsm_ptr->fg; 3462 stage_fc = fsm_ptr->stage_fc; 3463 3464 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t)); 3465 sal_memset(&keygen_oper, 0, sizeof(bcmi_keygen_oper_t)); 3466 sal_memcpy(&qset_req, &(fg->qset), sizeof(bcm_field_qset_t)); 3467 3468 /* Need to remove Qual InPort from the qset */ 3469 if ((BCM_FIELD_QSET_TEST(qset_req, bcmFieldQualifyInPort) && 3470 (soc_feature(unit, soc_feature_bscan_fae_port_flow_exclude)))) { 3471 qual_inport_excluded = TRUE; 3472 BCM_FIELD_QSET_REMOVE(qset_req, bcmFieldQualifyInPort); 3473 } 3474 3475 /* Remove dummy qualifiers. */ 3476 BCM_FIELD_QSET_REMOVE(qset_req, bcmFieldQualifyStage); 3477 BCM_FIELD_QSET_REMOVE(qset_req, bcmFieldQualifyStageIngressFlowtracker); 3478 3479 /* Get Group Qualifiers info array. */ 3480 rv = _field_th_group_qual_info_get(unit, stage_fc, fg, 3481 &(qset_req), &qual_info_arr, &qual_info_count); 3482 BCM_IF_ERROR_RETURN(rv); 3483 3484 if (fg->flags & _FP_GROUP_SPAN_SINGLE_SLICE && 3485 !(fg->flags & _FP_GROUP_DW_DEPTH_EXPANDED)) { 3486 keygen_mode = BCMI_KEYGEN_MODE_SINGLE; 3487 keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE; 3488 keygen_parts_count = 2; 3489 } else if (fg->flags & _FP_GROUP_SPAN_SINGLE_SLICE && 3490 fg->flags & _FP_GROUP_DW_DEPTH_EXPANDED) { 3491 keygen_mode = BCMI_KEYGEN_MODE_DBLINTRA; 3492 keygen_ext_mode = BCMI_KEYGEN_MODE_DBLINTRA; 3493 keygen_parts_count = 3; 3494 } else { 3495 rv = BCM_E_INTERNAL; 3496 keygen_parts_count = 0; 3497 goto cleanup; 3498 } 3499 3500 keygen_cfg.qual_info_arr = qual_info_arr; 3501 keygen_cfg.qual_info_count = qual_info_count; 3502 keygen_cfg.qual_cfg_info_db = stage_fc->qual_cfg_info_db; 3503 keygen_cfg.ext_cfg_db = stage_fc->ext_cfg_db_arr[keygen_ext_mode]; 3504 keygen_cfg.mode = keygen_mode; 3505 keygen_cfg.num_parts = keygen_parts_count; 3506 3507 if (fsm_ptr->flags & _FP_GROUP_CONFIG_VALIDATE) { 3508 keygen_cfg.flags = BCMI_KEYGEN_CFG_FLAGS_VALIDATE_ONLY; 3509 } 3510 if ((fg->ft_ext_codes != NULL) && 3511 (fsm_ptr->flags & _FP_GROUP_QSET_UPDATE)) { 3512 /* Create keygen ext codes to exclude already extracted qualifiers. */ 3513 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_QSET_UPDATE; 3514 rv = _field_hx5_ft_keygen_ext_ctrl_info_get(unit, 3515 fg->ft_ext_codes, &keygen_cfg.ext_ctrl_sel_info, 3516 &keygen_cfg.ext_ctrl_sel_info_count); 3517 if (BCM_FAILURE(rv)) { 3518 goto cleanup; 3519 } 3520 } else { 3521 if (soc_feature(unit, soc_feature_bscan_fae_port_flow_exclude) && 3522 (qual_inport_excluded == TRUE)) { 3523 /* Create keygen ext codes to skip extractors for InPort */ 3524 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_QSET_UPDATE; 3525 rv = _field_hx5_ft_keygen_ext_ctrl_info_skip(unit, 3526 &keygen_cfg, &skipped_size); 3527 if (BCM_FAILURE(rv)) { 3528 goto cleanup; 3529 } 3530 } 3531 } 3532 3533 if (!(fsm_ptr->flags & _FP_GROUP_QSET_UPDATE)) { 3534 rv = bcmi_keygen_keysize_get(unit, &keygen_cfg, &rkey_size); 3535 if (BCM_FAILURE(rv)) { 3536 goto cleanup; 3537 } 3538 if (((keygen_mode == BCMI_KEYGEN_MODE_SINGLE) 3539 && ((rkey_size + skipped_size) > 180)) || 3540 ((keygen_mode == BCMI_KEYGEN_MODE_DBLINTRA) 3541 && ((rkey_size + skipped_size) > 360))) { 3542 rv = BCM_E_CONFIG; 3543 goto cleanup; 3544 } 3545 } 3546 3547 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, &keygen_oper); 3548 if (BCM_FAILURE(rv)) { 3549 goto cleanup; 3550 } 3551 3552 /* Update keygen_oper with InPort Qual Info */ 3553 if (soc_feature(unit, soc_feature_bscan_fae_port_flow_exclude) && 3554 (qual_inport_excluded == TRUE)) { 3555 rv = _field_hx5_ft_keygen_oper_qual_add(unit, 3556 &keygen_cfg, &keygen_oper); 3557 if (BCM_FAILURE(rv)) { 3558 goto cleanup; 3559 } 3560 } 3561 3562 if ((fsm_ptr->flags & _FP_GROUP_CONFIG_VALIDATE) == 0) { 3563 rv = _field_hx5_ft_group_keygen_oper_insert(unit, 3564 fsm_ptr->fg, keygen_parts_count, &keygen_oper); 3565 } 3566 3567 cleanup: 3568 3569 (void)bcmi_keygen_oper_free(unit, keygen_parts_count, &keygen_oper); 3570 if (qual_info_arr != NULL) { 3571 sal_free(qual_info_arr); 3572 } 3573 if (keygen_cfg.ext_ctrl_sel_info != NULL) { 3574 sal_free(keygen_cfg.ext_ctrl_sel_info); 3575 keygen_cfg.ext_ctrl_sel_info = NULL; 3576 } 3577 3578 return rv; 3579 } 3580 3581 /* 3582 * Function: 3583 * _bcm_field_hx5_ft_group_update 3584 * 3585 * Purpose: 3586 * Extract group ext codes again with new qualifiers and update 3587 * qualifier info per part. 3588 * 3589 * Parameters: 3590 * unit - (IN) Unit number 3591 * group - (IN) Group Id 3592 * qset - (IN) New qualifiers qset 3593 * 3594 * Returns: 3595 * BCM_E_NONE - Success. 3596 */ 3597 int 3598 _bcm_field_hx5_ft_group_update(int unit, 3599 bcm_field_group_t group, bcm_field_qset_t *qset) 3600 { 3601 int rv = BCM_E_NONE; /* Return status. */ 3602 int idx = 0; /* Index Variable. */ 3603 int pidx = 0; /* Index Variable. */ 3604 int qid_index = 0; /* Index Variable. */ 3605 int qid; /* Qualifier ID. */ 3606 int parts_count = 0; /* number of slices allocated for the group. */ 3607 uint8 part; /* Group Partition. */ 3608 uint8 has_ft_ext_codes = FALSE; /* If original field group has extractors */ 3609 uint16 *qid_array[_FP_MAX_ENTRY_WIDTH] = { NULL }; 3610 /* Array of qualifiers. */ 3611 uint16 size = 0; /* Total number of qualifiers in 3612 each partition of the group. */ 3613 _field_group_t *fg = NULL; /* Field group operational Structure. */ 3614 _field_group_t *temp_fg = NULL; /* Temp field group operational structure. */ 3615 _field_stage_t *stage_fc = NULL; /* Field Stage operational structure. */ 3616 bcm_field_qset_t temp_qset; /* Temporary qset information. */ 3617 _bcm_field_qual_offset_t *offset_array[_FP_MAX_ENTRY_WIDTH] = { NULL }; 3618 /* Array of qualifiers offset information. */ 3619 _field_group_add_fsm_t fsm_ptr; 3620 3621 BCM_IF_ERROR_RETURN(_field_group_get(unit, group, &fg)); 3622 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 3623 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 3624 3625 sal_memcpy(&temp_qset, qset, sizeof(bcm_field_qset_t)); 3626 3627 for (qid = 0; qid < _bcmFieldQualifyCount; qid++) { 3628 if (BCM_FIELD_QSET_TEST(fg->qset, qid)) { 3629 BCM_FIELD_QSET_REMOVE(temp_qset, qid); 3630 } 3631 } 3632 3633 _FP_XGS3_ALLOC(temp_fg, sizeof(_field_group_t), "Temp group for update"); 3634 if (NULL == temp_fg) { 3635 return BCM_E_MEMORY; 3636 } 3637 3638 temp_fg->gid = fg->gid; 3639 temp_fg->flags = fg->flags; 3640 sal_memcpy(&temp_fg->qset, &temp_qset, sizeof(bcm_field_qset_t)); 3641 sal_memset(&fsm_ptr, 0, sizeof(_field_group_add_fsm_t)); 3642 3643 fsm_ptr.fg = temp_fg; 3644 fsm_ptr.stage_fc = stage_fc; 3645 fsm_ptr.flags = _FP_GROUP_QSET_UPDATE; 3646 3647 /* Allocate memory for ext codes */ 3648 if (fg->ft_ext_codes != NULL) { 3649 _FP_XGS3_ALLOC(temp_fg->ft_ext_codes, 3650 sizeof(_field_ft_keygen_ext_codes_t), 3651 "field group ext codes"); 3652 if (temp_fg->ft_ext_codes == NULL) { 3653 sal_free(temp_fg); 3654 return BCM_E_MEMORY; 3655 } 3656 3657 has_ft_ext_codes = TRUE; 3658 sal_memcpy(temp_fg->ft_ext_codes, fg->ft_ext_codes, 3659 sizeof(_field_ft_keygen_ext_codes_t)); 3660 } 3661 rv = _field_hx5_ft_ext_code_assign(unit, 0, &fsm_ptr); 3662 3663 if (BCM_FAILURE(rv)) { 3664 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 3665 "FP(unit %d) Verb: Processing group QSET.\n"), unit)); 3666 goto cleanup; 3667 } 3668 3669 for (part = 0; part < _FP_MAX_ENTRY_WIDTH; part++) { 3670 /* If no new qualifier is extracted in the part, skip the part. */ 3671 size = temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].size; 3672 if (size == 0) { 3673 continue; 3674 } 3675 size += fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].size; 3676 if (size != 0) { 3677 _FP_XGS3_ALLOC(qid_array[part], size * sizeof(uint16), "Qid Array"); 3678 if (NULL == qid_array[part]) { 3679 rv = BCM_E_MEMORY; 3680 goto cleanup; 3681 } 3682 _FP_XGS3_ALLOC(offset_array[part], size * sizeof(_bcm_field_qual_offset_t), 3683 "Qualifier Offset Array"); 3684 if (NULL == offset_array[part]) { 3685 rv = BCM_E_MEMORY; 3686 goto cleanup; 3687 } 3688 3689 qid_index = 0; 3690 for (idx = 0; idx < fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].size; idx++) { 3691 3692 sal_memcpy(&qid_array[part][qid_index], 3693 &(fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr[idx]), 3694 sizeof(uint16)); 3695 3696 sal_memcpy(&offset_array[part][qid_index], 3697 &(fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr[idx]), 3698 sizeof(_bcm_field_qual_offset_t)); 3699 3700 qid_index++; 3701 3702 } 3703 3704 fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].size = size; 3705 3706 /* Copy qualifier array and offset array of new 3707 * qualifiers in this partition. 3708 */ 3709 size = temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].size; 3710 sal_memcpy(&qid_array[part][qid_index], 3711 temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr, 3712 size * sizeof(uint16)); 3713 3714 sal_memcpy(&offset_array[part][qid_index], 3715 temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr, 3716 size * sizeof(_bcm_field_qual_offset_t)); 3717 3718 if (NULL != fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr) { 3719 sal_free(fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr); 3720 } 3721 3722 if (NULL != fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr) { 3723 sal_free(fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr); 3724 } 3725 3726 if (NULL != temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr) { 3727 sal_free(temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr); 3728 } 3729 3730 if (NULL != temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr) { 3731 sal_free(temp_fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr); 3732 } 3733 3734 fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].qid_arr = qid_array[part]; 3735 fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part].offset_arr = offset_array[part]; 3736 } 3737 } 3738 3739 rv = _bcm_field_th_entry_tcam_parts_count(unit, fg->flags, &parts_count); 3740 if (BCM_FAILURE(rv)) { 3741 goto cleanup; 3742 } 3743 3744 for (part = 0; part < _FP_MAX_ENTRY_WIDTH; part++) { 3745 offset_array[part] = NULL; 3746 qid_array[part] = NULL; 3747 } 3748 3749 if (has_ft_ext_codes == TRUE) { 3750 sal_memcpy(fg->ft_ext_codes, temp_fg->ft_ext_codes, 3751 (sizeof(_field_ft_keygen_ext_codes_t))); 3752 } else { 3753 fg->ft_ext_codes = temp_fg->ft_ext_codes; 3754 } 3755 3756 /* Install entry parts in hardware. Loop through all presels */ 3757 for (pidx = 0; pidx < _FP_PRESEL_ENTRIES_MAX_PER_GROUP; pidx++) { 3758 if (fg->presel_ent_arr[pidx] != NULL) { 3759 rv = _field_hx5_ft_group_keygen_install(unit, 3760 fg->presel_ent_arr[pidx]); 3761 } 3762 if (BCM_FAILURE(rv)) { 3763 goto cleanup; 3764 } 3765 } 3766 3767 for (qid = 0; qid < _bcmFieldQualifyCount; qid++) { 3768 if (BCM_FIELD_QSET_TEST(*qset, qid)) { 3769 BCM_FIELD_QSET_ADD(fg->qset, qid); 3770 } 3771 } 3772 3773 cleanup: 3774 for (part = 0; part < _FP_MAX_ENTRY_WIDTH; part++) { 3775 if (NULL != qid_array[part]) { 3776 sal_free(qid_array[part]); 3777 qid_array[part] = NULL; 3778 } 3779 3780 if(NULL != offset_array[part]) { 3781 sal_free(offset_array[part]); 3782 offset_array[part] = NULL; 3783 } 3784 } 3785 3786 if (NULL != temp_fg) { 3787 if ((temp_fg->ft_ext_codes != NULL) && 3788 (has_ft_ext_codes == TRUE)) { 3789 sal_free(temp_fg->ft_ext_codes); 3790 } 3791 sal_free(temp_fg); 3792 } 3793 3794 return (rv); 3795 } 3796 3797 /****** Extraction ends ***************************************/ 3798 3799 /* 3800 * Function: 3801 * _bcm_field_keygen_qual_offset_info_dump 3802 * 3803 * Purpose: 3804 * Dump the output of keygen for qualifiers and extractor 3805 * codes. 3806 * 3807 * Parameters: 3808 * unit - (IN) Unit number 3809 * keygen_parts_count - (IN) Keygen parts 3810 * keygen_oper - (IN) Keygen operation info 3811 * 3812 * Returns: 3813 * BCM_E_NONE - Success. 3814 */ 3815 int 3816 _bcm_field_keygen_qual_offset_info_dump(int unit, 3817 int keygen_parts_count, 3818 bcmi_keygen_oper_t *keygen_oper) 3819 { 3820 int idx = 0; 3821 int part = 0; 3822 int offset = 0; 3823 int num_offsets = 0; 3824 bcm_field_qualify_t qid; 3825 bcmi_keygen_qual_offset_info_t *q_info = NULL; 3826 bcmi_keygen_ext_ctrl_sel_info_t *e_info = NULL; 3827 3828 if (keygen_oper == NULL) { 3829 return BCM_E_NONE; 3830 } 3831 if (keygen_oper->ext_ctrl_sel_info_count == 0) { 3832 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 3833 " Extraction info not available\n\r"))); 3834 return BCM_E_NONE; 3835 } 3836 3837 /* Qualifiers offsets and widths */ 3838 for (part = 0; part < keygen_parts_count; part++) { 3839 q_info = &(keygen_oper->qual_offset_info[part]); 3840 3841 for (idx = 0; idx < q_info->size; idx++) { 3842 qid = q_info->qid_arr[idx]; 3843 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 3844 "qi[p=%d][%d] %s ->"), part, idx, 3845 _field_qual_name(qid))); 3846 num_offsets = 0; 3847 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 3848 if (!q_info->offset_arr[idx].width[offset]) { 3849 continue; 3850 } 3851 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 3852 " {[%d] offset:%d, width:%d}"), 3853 offset, q_info->offset_arr[idx].offset[offset], 3854 q_info->offset_arr[idx].width[offset])); 3855 num_offsets++; 3856 if (num_offsets == q_info->offset_arr[idx].num_offsets) { 3857 break; 3858 } 3859 if (((num_offsets + 1) % 3) == 0) { 3860 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "\n\r\t\t"))); 3861 } 3862 } 3863 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "\n\r"))); 3864 } 3865 } 3866 3867 /* Extractors */ 3868 for (idx = 0; idx < keygen_oper->ext_ctrl_sel_info_count; idx++) { 3869 e_info = &keygen_oper->ext_ctrl_sel_info[idx]; 3870 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 3871 "ei[p=%d][%d] -> ext_Id=0x%x ctrl_sel=%d "), 3872 e_info->part, idx, e_info->ext_num, e_info->ctrl_sel)); 3873 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,"val=%d l=%d g=%d\n\r"), 3874 e_info->ctrl_sel_val, e_info->level, e_info->gran)); 3875 } 3876 3877 return (BCM_E_NONE); 3878 } 3879 3880 #endif