ft_field.c (124686B)
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: ft_field.c 8 * Purpose: Flowtracker module specific routines in flowtracker 9 * stage in FP. 10 */ 11 12 #include <soc/defs.h> 13 14 #if defined (BCM_FLOWTRACKER_SUPPORT) && defined (BCM_FIELD_SUPPORT) 15 16 #include <bcm/error.h> 17 #include <bcm/field.h> 18 #include <shared/bsl.h> 19 #include <bcm/flowtracker.h> 20 21 #include <bcm_int/esw/field.h> 22 #include <bcm_int/esw/tomahawk.h> 23 #include <bcm_int/esw/helix5.h> 24 #include <bcm_int/esw/keygen_api.h> 25 #include <bcm_int/esw/flowtracker/ft_group.h> 26 #include <bcm_int/esw/flowtracker/ft_alu.h> 27 #include <bcm_int/esw/flowtracker/ft_field.h> 28 29 30 /* Internal MACRO to goto cleanup. */ 31 #define BCMI_IF_ERROR_CLEANUP(_rv_) \ 32 do { \ 33 if (_rv_ != BCM_E_NONE) { \ 34 goto cleanup; \ 35 } \ 36 } while(0) 37 38 /* Macro to add group tracking elements map to database. */ 39 #define _FP_FT_TRACKING_PARAM_QUAL_MAP_DECL \ 40 _field_ft_tracking_param_qual_map_t _pq_map_ 41 42 #define _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(_unit_, _map_db_, \ 43 _param_, _qual_, _width_, _flags_) \ 44 do { \ 45 _field_ft_tracking_param_qual_map_init((_unit_), &_pq_map_); \ 46 _pq_map_.param = (_param_); \ 47 _pq_map_.qual = (_qual_); \ 48 _pq_map_.width = (_width_); \ 49 _pq_map_.flags = (_flags_); \ 50 rv = _field_ft_tracking_param_qual_map_insert((_unit_), \ 51 (_param_), &(_pq_map_), (_map_db_)); \ 52 BCMI_IF_ERROR_CLEANUP(rv); \ 53 } while(0) 54 55 /* Macro to add alu data tracking information to map database. */ 56 #define _FP_FT_TRACKING_ALU_DATA_MAP_ADD(_unit_, _map_db_, \ 57 _param_, _qual_, _start_, _width_, _flags_) \ 58 do { \ 59 _field_ft_tracking_param_qual_map_init((_unit_), &_pq_map_); \ 60 _pq_map_.param = (_param_); \ 61 _pq_map_.qual = (_qual_); \ 62 _pq_map_.start_loc = (_start_); \ 63 _pq_map_.width = (_width_); \ 64 _pq_map_.flags = (_flags_); \ 65 rv = _field_ft_tracking_param_qual_map_insert((_unit_), \ 66 (_param_), &(_pq_map_), (_map_db_)); \ 67 BCMI_IF_ERROR_CLEANUP(rv); \ 68 } while(0) 69 70 /* Tracking param is not mapped to qualifier. */ 71 #define _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED (1 << 0) 72 73 /* Tracking param requires ALU 16-bit. */ 74 #define _FP_FT_TRACKING_PARAM_F_ALU16_REQ (1 << 1) 75 76 /* Tracking param required ALU 32-bit. */ 77 #define _FP_FT_TRACKING_PARAM_F_ALU32_REQ (1 << 2) 78 79 /* Tracking Param is mapped for ALU Data */ 80 #define _FP_FT_TRACKING_PARAM_F_ALU_DATA (1 << 3) 81 82 /* Tracking Param requires modulo 32 for Key */ 83 #define _FP_FT_TRACKING_PARAM_F_KEY_MODULO_32 (1 << 4) 84 85 /* Tracking Param requires modulo 32 for Data */ 86 #define _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32 (1 << 5) 87 88 /* Tracking Param does not generate Session Key/Data */ 89 #define _FP_FT_TRACKING_PARAM_F_NO_FILL (1 << 6) 90 91 /* Tracking param required ALU. */ 92 #define _FP_FT_TRACKING_PARAM_F_ALU_REQ \ 93 (_FP_FT_TRACKING_PARAM_F_ALU16_REQ | \ 94 _FP_FT_TRACKING_PARAM_F_ALU32_REQ) 95 96 /* Tracking info type is param info. */ 97 #define _FP_FT_TRACKING_INFO_TYPE_PARAM (1 << 0) 98 99 /* Tracking info type is flowcheck info. */ 100 #define _FP_FT_TRACKING_INFO_TYPE_FLOWCHECK (1 << 1) 101 102 /* Tracking info type is Alu data info */ 103 #define _FP_FT_TRACKING_INFO_TYPE_ALU_DATA (1 << 2) 104 105 /* Start Index of ALU Data in param_qual_map db */ 106 #define _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START \ 107 (_FIELD_FT_TRACKING_ELEMENT_TYPE_MAX) 108 /* 109 * Typedef: 110 * _field_ft_tracking_alu_data_info_t 111 * 112 * Purpose: 113 * ALU Data related tracking information. 114 */ 115 typedef struct _field_ft_tracking_alu_data_info_s { 116 uint16 param; 117 118 int offset; 119 120 int width; 121 } _field_ft_tracking_alu_data_info_t; 122 123 /* FT Group Keygen Extraction process States */ 124 #define _FIELD_FT_GROUP_KEYGEN_START 0 125 #define _FIELD_FT_GROUP_KEYGEN_CFG_ALLOC 1 126 #define _FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD 2 127 #define _FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD 3 128 #define _FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD 4 129 #define _FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST 5 130 #define _FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST 6 131 #define _FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT 7 132 #define _FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT 8 133 #define _FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS 9 134 #define _FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS 10 135 #define _FIELD_FT_GROUP_KEYGEN_OPER_SAVE 11 136 #define _FIELD_FT_GROUP_KEYGEN_END 12 137 138 /* 139 * Typedef: 140 * _field_ft_group_keydata_keygen_md_t 141 * 142 * Purpose: 143 * Session key/data extraction related information. 144 */ 145 typedef struct _field_ft_group_keydata_keygen_md_s { 146 /* List of allowed keygen mode for extraction. */ 147 bcmi_keygen_mode_t ext_modes[2]; 148 149 /* Number of valid indices in ext_modes. */ 150 int ext_modes_count; 151 152 /* Keygen_cfg->qual_info_arr. */ 153 bcmi_keygen_qual_info_t *qual_info_arr; 154 155 /* Total memory allocated to qual_info_arr. */ 156 uint16 max_qual_info_alloc; 157 158 /* Actual number of qual info in qual_info_arr. */ 159 uint16 qual_info_count; 160 161 /* Qset of qualifiers in qual_info_arr. */ 162 bcm_field_qset_t qset; 163 164 /* Keygen_oper information after extraction. */ 165 bcmi_keygen_oper_t keygen_oper; 166 167 /* Actual extraction Keygen mode. */ 168 bcmi_keygen_mode_t keygen_mode; 169 170 /* Number of keygen parts. */ 171 uint16 num_parts; 172 173 } _field_ft_group_keydata_keygen_md_t; 174 175 /* 176 * Typedef: 177 * _field_ft_group_keygen_oper_info_t 178 * 179 * Purpose: 180 * Session key/data extraction information 181 * in the form required by FT module. 182 */ 183 typedef struct _field_ft_group_keygen_oper_info_s { 184 /* keygen mode of session key. */ 185 int mode; 186 187 /* Number of Session key info. */ 188 int num_skey_info; 189 190 /* Session key info. */ 191 bcmi_ft_group_alu_info_t *skey_info; 192 193 /* Number of elements in skey_ext_info. */ 194 int skey_ext_count; 195 196 /* Encoded session Key ext codes. */ 197 bcmi_ft_hw_extractor_info_t *skey_ext_info; 198 199 /* Number of Session data info. */ 200 int num_sdata_info; 201 202 /* Session data info. */ 203 bcmi_ft_group_alu_info_t *sdata_info; 204 205 /* Number of elements in sdata_ext_info. */ 206 int sdata_ext_count; 207 208 /* Encoded Session data ext codes. */ 209 bcmi_ft_hw_extractor_info_t *sdata_ext_info; 210 211 } _field_ft_group_keygen_oper_info_t; 212 213 /* 214 * Typedef: 215 * _field_ft_group_keygen_md_t 216 * 217 * Purpose: 218 * metadata for FT group keygen extraction for 219 * session key and session data. 220 */ 221 typedef struct _field_ft_group_keygen_md_s { 222 /* Current processing state in _FIELD_FT_GROUP_KEYGEN_XXX. */ 223 uint16 state; 224 225 /* Previous processing state in _FIELD_FT_GROUP_KEYGEN_XXX. */ 226 uint16 prev_state; 227 228 /* Return code for current processing state. */ 229 int state_rv; 230 231 /* FT information in field stage struct. */ 232 _field_ft_info_t *ft_info; 233 234 /* FT Group Identifier. */ 235 bcm_flowtracker_group_t ft_group_id; 236 237 /* Number of elements in tracking_params_info. */ 238 int num_tracking_params; 239 240 /* List of tracking params info for FT Group. */ 241 bcm_flowtracker_tracking_param_info_t *tracking_params_info; 242 243 /* Number of elements in flowtracker_checks. */ 244 int num_flowchecks; 245 246 /* List of flowcheck Ids for FT Group/ */ 247 bcm_flowtracker_check_t *flowtracker_checks; 248 249 /* Number of ALU data elements. */ 250 int num_alu_data; 251 252 /* Pointer to ALU Data info. */ 253 _field_ft_tracking_alu_data_info_t *alu_data_info; 254 255 /* Metadata for session key keygen. */ 256 _field_ft_group_keydata_keygen_md_t skey_keygen_md; 257 258 /* Metadata for session data keygen. */ 259 _field_ft_group_keydata_keygen_md_t sdata_keygen_md; 260 261 /* Operational info for key/data extraction. */ 262 _field_ft_group_keygen_oper_info_t keydata_oper_info; 263 264 /* Set if output is required to saved to FT Group DB. */ 265 uint8 save_op; 266 267 } _field_ft_group_keygen_md_t; 268 269 /* 270 * Typedef: 271 * _bcm_field_ft_entry_traverse_cb 272 * Purpose: 273 * Callback function pointer per entry in flowtracke stage. 274 */ 275 typedef int (*_bcm_field_ft_entry_traverse_cb)(int unit, 276 bcm_field_entry_t entry, bcm_flowtracker_group_t id, 277 void *user_data1, void *user_data2); 278 279 /* 280 * Function: 281 * _field_ft_tracking_param_qual_map_init 282 * 283 * Purpose: 284 * Initializes group tracking element map 285 * 286 * Parameters: 287 * unit - (IN) BCM device number. 288 * element_map- (IN) group tracking element map 289 * 290 * Returns: 291 */ 292 STATIC void 293 _field_ft_tracking_param_qual_map_init( 294 int unit, 295 _field_ft_tracking_param_qual_map_t *pq_map) 296 { 297 if (pq_map == NULL) { 298 return; 299 } 300 301 sal_memset(pq_map, 0, 302 sizeof(_field_ft_tracking_param_qual_map_t)); 303 304 return; 305 } 306 307 /* 308 * Function: 309 * _field_ft_tracking_param_qual_map_insert 310 * 311 * Purpose: 312 * Insert tracking param-qual map to map database. 313 * 314 * Parameters: 315 * unit - (IN) BCM device number. 316 * param - (IN) tracking param 317 * pq_map - (IN) tracking param-qual map 318 * map_db - (IN/OUT) param and qual Map database 319 * 320 * Returns: 321 * BCM_E_NONE 322 */ 323 STATIC int 324 _field_ft_tracking_param_qual_map_insert( 325 int unit, 326 uint16 param, 327 _field_ft_tracking_param_qual_map_t *pq_map, 328 _field_ft_tracking_param_qual_map_db_t *map_db) 329 { 330 _field_ft_tracking_param_qual_map_t *temp_map = NULL; 331 332 /* Validate input params. */ 333 if ((pq_map == NULL) || (map_db == NULL) || 334 (param >= _FIELD_FT_TRACKING_PARAM_MAX)) { 335 return BCM_E_PARAM; 336 } 337 338 temp_map = map_db->param_qual_map[param]; 339 340 if (temp_map == NULL) { 341 _FP_XGS3_ALLOC(temp_map, 342 sizeof(_field_ft_tracking_param_qual_map_t), 343 "tracking param-qual map"); 344 } else { 345 return BCM_E_INTERNAL; 346 } 347 348 if (temp_map == NULL) { 349 return BCM_E_MEMORY; 350 } 351 352 map_db->param_qual_map[param] = temp_map; 353 sal_memcpy(temp_map, pq_map, 354 sizeof(_field_ft_tracking_param_qual_map_t)); 355 356 return BCM_E_NONE; 357 } 358 359 /* 360 * Function: 361 * _field_ft_tracking_param_qual_map_db_cleanup 362 * 363 * Purpose: 364 * Cleanup tracking param and qualifier map database 365 * 366 * Parameters: 367 * unit - (IN) BCM device number. 368 * ft_info - (IN) Flowtracker specific info 369 * 370 * Returns: 371 * None. 372 */ 373 void 374 _field_ft_tracking_param_qual_map_db_cleanup( 375 int unit, 376 _field_ft_info_t *ft_info) 377 { 378 uint16 param = 0; 379 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 380 381 if ((ft_info == NULL) || 382 (ft_info->param_qual_map_db == NULL)) { 383 return; 384 } 385 386 map_db = ft_info->param_qual_map_db; 387 388 for (param = 0; param < _FIELD_FT_TRACKING_PARAM_MAX; param++) { 389 if (map_db->param_qual_map[param]) { 390 sal_free(map_db->param_qual_map[param]); 391 map_db->param_qual_map[param] = NULL; 392 } 393 } 394 395 sal_free(map_db); 396 ft_info->param_qual_map_db = NULL; 397 } 398 399 /* 400 * Function: 401 * _field_ft_tracking_param_qual_map_db_init 402 * 403 * Purpose: 404 * Initialize tracking params and qualifier map database 405 * 406 * Parameters: 407 * unit - (IN) BCM device number. 408 * ft_info - (IN/OUT) Flowtracker info structure 409 * 410 * Returns: 411 * BCM_E_XXX 412 */ 413 int 414 _field_ft_tracking_param_qual_map_db_init( 415 int unit, 416 _field_ft_info_t *ft_info) 417 { 418 int rv = BCM_E_NONE; 419 uint16 shift = 0; 420 uint32 flags = 0; 421 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 422 _FP_FT_TRACKING_PARAM_QUAL_MAP_DECL; 423 424 if (ft_info == NULL) { 425 return BCM_E_PARAM; 426 } 427 428 _FP_XGS3_ALLOC(map_db, 429 sizeof(_field_ft_tracking_param_qual_map_db_t), 430 "tracking param qual map db"); 431 if (map_db == NULL) { 432 return BCM_E_MEMORY; 433 } 434 435 ft_info->param_qual_map_db = map_db; 436 437 /* Tracking param qualifier map. */ 438 flags = 0; 439 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 440 map_db, bcmFlowtrackerTrackingParamTypeSrcIPv4, 441 bcmFieldQualifySrcIp, 32, flags); 442 443 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 444 map_db, bcmFlowtrackerTrackingParamTypeDstIPv4, 445 bcmFieldQualifyDstIp, 32, flags); 446 447 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 448 map_db, bcmFlowtrackerTrackingParamTypeSrcIPv6, 449 bcmFieldQualifySrcIp6, 128, flags); 450 451 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 452 map_db, bcmFlowtrackerTrackingParamTypeDstIPv6, 453 bcmFieldQualifyDstIp6, 128, flags); 454 455 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 456 map_db, bcmFlowtrackerTrackingParamTypeL4SrcPort, 457 bcmFieldQualifyL4SrcPort, 16, flags); 458 459 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 460 map_db, bcmFlowtrackerTrackingParamTypeL4DstPort, 461 bcmFieldQualifyL4DstPort, 16, flags); 462 463 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 464 map_db, bcmFlowtrackerTrackingParamTypeIPProtocol, 465 bcmFieldQualifyIpProtocol, 8, flags); 466 467 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 468 map_db, bcmFlowtrackerTrackingParamTypeVRF, 469 bcmFieldQualifyVrf, 8, flags); 470 471 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 472 map_db, bcmFlowtrackerTrackingParamTypeTTL, 473 bcmFieldQualifyTtl, 8, flags); 474 475 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 476 map_db, bcmFlowtrackerTrackingParamTypeIPLength, 477 bcmFieldQualifyIp4Length, 16, flags); 478 479 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 480 map_db, bcmFlowtrackerTrackingParamTypeTcpWindowSize, 481 bcmFieldQualifyTcpWindowSize, 16, flags); 482 483 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 484 map_db, bcmFlowtrackerTrackingParamTypeVxlanNetworkId, 485 bcmFieldQualifyVxlanNetworkId, 24, 486 flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32); 487 488 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 489 map_db, bcmFlowtrackerTrackingParamTypeNextHeader, 490 bcmFieldQualifyIp6PktNextHeader, 8, flags); 491 492 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 493 map_db, bcmFlowtrackerTrackingParamTypeHopLimit, 494 bcmFieldQualifyIp6PktHopLimit, 8, flags); 495 496 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 497 map_db, bcmFlowtrackerTrackingParamTypeInnerSrcIPv4, 498 bcmFieldQualifyInnerSrcIp, 32, flags); 499 500 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 501 map_db, bcmFlowtrackerTrackingParamTypeInnerDstIPv4, 502 bcmFieldQualifyInnerDstIp, 32, flags); 503 504 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 505 map_db, bcmFlowtrackerTrackingParamTypeInnerSrcIPv6, 506 bcmFieldQualifyInnerSrcIp6, 128, flags); 507 508 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 509 map_db, bcmFlowtrackerTrackingParamTypeInnerDstIPv6, 510 bcmFieldQualifyInnerDstIp6, 128, flags); 511 512 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 513 map_db, bcmFlowtrackerTrackingParamTypeInnerIPProtocol, 514 bcmFieldQualifyInnerIpProtocol, 8, flags); 515 516 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 517 map_db, bcmFlowtrackerTrackingParamTypeInnerTTL, 518 bcmFieldQualifyInnerTtl, 8, flags); 519 520 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 521 map_db, bcmFlowtrackerTrackingParamTypeInnerNextHeader, 522 bcmFieldQualifyInnerIp6PktNextHeader, 8, flags); 523 524 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 525 map_db, bcmFlowtrackerTrackingParamTypeInnerHopLimit, 526 bcmFieldQualifyInnerIp6PktHopLimit, 8, flags); 527 528 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 529 map_db, bcmFlowtrackerTrackingParamTypeInnerL4SrcPort, 530 bcmFieldQualifyInnerL4SrcPort, 16, flags); 531 532 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 533 map_db, bcmFlowtrackerTrackingParamTypeInnerL4DstPort, 534 bcmFieldQualifyInnerL4DstPort, 16, flags); 535 536 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 537 map_db, bcmFlowtrackerTrackingParamTypeTcpFlags, 538 bcmFieldQualifyTcpControl, 8, flags); 539 540 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 541 map_db, bcmFlowtrackerTrackingParamTypeOuterVlanTag, 542 bcmFieldQualifyOuterVlan, 16, flags); 543 544 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 545 map_db, bcmFlowtrackerTrackingParamTypeIP6Length, 546 bcmFieldQualifyIp6Length, 16, flags); 547 548 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 549 map_db, bcmFlowtrackerTrackingParamTypeInnerIPLength, 550 bcmFieldQualifyTunnelPayloadIp4Length, 16, flags); 551 552 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 553 map_db, bcmFlowtrackerTrackingParamTypeInnerIP6Length, 554 bcmFieldQualifyTunnelPayloadIp6Length, 16, flags); 555 556 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 557 map_db, bcmFlowtrackerTrackingParamTypeTunnelClass, 558 bcmFieldQualifyTunnelId, 24, 559 flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32); 560 561 /* Tracking param with no qualifier, used for counting */ 562 flags = _FP_FT_TRACKING_PARAM_F_ALU32_REQ; 563 564 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 565 map_db, bcmFlowtrackerTrackingParamTypeDosAttack, 566 bcmFieldQualifyDosAttackEvents, 32, 567 flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32); 568 569 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 570 map_db, bcmFlowtrackerTrackingParamTypeInnerDosAttack, 571 bcmFieldQualifyInnerDosAttackEvents, 32, 572 flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32); 573 574 flags |= _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED; 575 576 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 577 map_db, bcmFlowtrackerTrackingParamTypePktCount, 578 0, 32, flags); 579 580 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 581 map_db, bcmFlowtrackerTrackingParamTypeByteCount, 582 0, 32, flags); 583 584 /* Timestamp tracking parameters are not sent to FT group. */ 585 flags = _FP_FT_TRACKING_PARAM_F_NO_FILL; 586 flags |= _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED; 587 588 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 589 map_db, bcmFlowtrackerTrackingParamTypeTimestampNewLearn, 590 0, 0, flags); 591 592 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 593 map_db, bcmFlowtrackerTrackingParamTypeTimestampFlowStart, 594 0, 0, flags); 595 596 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 597 map_db, bcmFlowtrackerTrackingParamTypeTimestampFlowEnd, 598 0, 0, flags); 599 600 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 601 map_db, bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1, 602 0, 0, flags); 603 604 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 605 map_db, bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2, 606 0, 0, flags); 607 608 /* Map Tracking Params to ignore processing. */ 609 flags = _FP_FT_TRACKING_PARAM_F_NO_FILL; 610 flags |= _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED; 611 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 612 map_db, bcmFlowtrackerTrackingParamTypeNone, 613 0, 0, flags); 614 615 _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit, 616 map_db, bcmFlowtrackerTrackingParamTypeFlowtrackerCheck, 617 0, 0, flags); 618 619 /* Tracking ALU Data */ 620 shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START; 621 flags = _FP_FT_TRACKING_PARAM_F_ALU_DATA; 622 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 623 map_db, _bcmFieldFtAluDataTcpFlagsFIN + shift, 624 bcmFieldQualifyTcpControl, 0, 1, flags); 625 626 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 627 map_db, _bcmFieldFtAluDataTcpFlagsSYN + shift, 628 bcmFieldQualifyTcpControl, 1, 1, flags); 629 630 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 631 map_db, _bcmFieldFtAluDataTcpFlagsRST + shift, 632 bcmFieldQualifyTcpControl, 2, 1, flags); 633 634 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 635 map_db, _bcmFieldFtAluDataTcpFlagsPSH + shift, 636 bcmFieldQualifyTcpControl, 3, 1, flags); 637 638 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 639 map_db, _bcmFieldFtAluDataTcpFlagsACK + shift, 640 bcmFieldQualifyTcpControl, 4, 1, flags); 641 642 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 643 map_db, _bcmFieldFtAluDataTcpFlagsURG + shift, 644 bcmFieldQualifyTcpControl, 5, 1, flags); 645 646 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 647 map_db, _bcmFieldFtAluDataTcpFlagsECE + shift, 648 bcmFieldQualifyTcpControl, 6, 1, flags); 649 650 _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit, 651 map_db, _bcmFieldFtAluDataTcpFlagsCWR + shift, 652 bcmFieldQualifyTcpControl, 7, 1, flags); 653 654 cleanup: 655 656 if (rv != BCM_E_NONE) { 657 (void) _field_ft_tracking_param_qual_map_db_cleanup(unit, ft_info); 658 } 659 660 return rv; 661 } 662 663 /* Alu Data info */ 664 static _field_ft_tracking_alu_data_info_t 665 _field_ft_tracking_alu_data_info[] = { 666 {_bcmFieldFtAluDataTcpFlagsFIN, 2, 1}, 667 {_bcmFieldFtAluDataTcpFlagsSYN, 0, 1}, 668 {_bcmFieldFtAluDataTcpFlagsRST, 3, 1}, 669 {_bcmFieldFtAluDataTcpFlagsPSH, 4, 1}, 670 {_bcmFieldFtAluDataTcpFlagsACK, 1, 1}, 671 {_bcmFieldFtAluDataTcpFlagsURG, 5, 1}, 672 {_bcmFieldFtAluDataTcpFlagsECE, 6, 1}, 673 {_bcmFieldFtAluDataTcpFlagsCWR, 7, 1} 674 }; 675 676 /* 677 * Function: 678 * _field_hx5_ftg_alu_data_info_get 679 * 680 * Purpose: 681 * Get pointer to ALU Data info 682 * 683 * Parameters: 684 * unit - (IN) BCM device number. 685 * id - (IN) flowtracker group id. 686 * info - (OUT) Pointer to ALU Data Info. 687 * num_info - (OUT) number of ALU Data info. 688 * 689 * Returns: 690 * BCM_E_NONE 691 */ 692 STATIC int 693 _field_hx5_ftg_alu_data_info_get( 694 int unit, 695 bcm_flowtracker_group_t id, 696 _field_ft_tracking_alu_data_info_t **info, 697 int *num_info) 698 { 699 /* 700 * ALU Data info is fixed to extract TCP Flags. 701 * If ALU data needs to be extracted from other source 702 * flowtracker group need to convey it. 703 * This function set the pointer to fixed ALU Data info 704 * and no memory allocated is required for now. 705 */ 706 if (num_info != NULL) { 707 *num_info = COUNTOF(_field_ft_tracking_alu_data_info); 708 } 709 710 if (info != NULL) { 711 *info = &_field_ft_tracking_alu_data_info[0]; 712 } 713 714 return BCM_E_NONE; 715 } 716 717 /* 718 * Function: 719 * _field_hx5_ftg_keygen_cfg_qual_alloc 720 * 721 * Purpose: 722 * Allocate memory for qual_info_arr for session key and 723 * session data. 724 * 725 * Parameters: 726 * unit - (IN) BCM device number. 727 * ftg_keygen_md - (IN) Ft group Keygen metadata 728 * 729 * Returns: 730 * None. 731 */ 732 733 STATIC int 734 _field_hx5_ftg_keygen_cfg_qual_alloc( 735 int unit, 736 _field_ft_group_keygen_md_t *ftg_keygen_md) 737 { 738 int rv = BCM_E_NONE; 739 int idx = 0, shift = 0; 740 int num_key_params = 0; 741 int num_data_params = 0; 742 int num_tracking_params = 0; 743 int num_flowchecks = 0; 744 int total_data_quals = 0; 745 int num_alu_data = 0; 746 bcm_field_qualify_t qual; 747 bcm_field_qset_t qset; 748 bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL; 749 _field_ft_tracking_alu_data_info_t *alu_data = NULL; 750 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 751 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 752 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 753 754 if (ftg_keygen_md == NULL) { 755 return (BCM_E_PARAM); 756 } 757 758 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 759 num_tracking_params = ftg_keygen_md->num_tracking_params; 760 num_flowchecks = ftg_keygen_md->num_flowchecks; 761 num_alu_data = ftg_keygen_md->num_alu_data; 762 763 /* Calculate number of keys and data */ 764 for (idx = 0; idx < num_tracking_params; idx++) { 765 tracking_param_info = &ftg_keygen_md->tracking_params_info[idx]; 766 if (tracking_param_info->flags & 767 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) { 768 num_key_params++; 769 } else { 770 num_data_params++; 771 } 772 } 773 774 /* Validate number of key and data */ 775 if ((num_key_params == 0) || (num_data_params == 0)) { 776 LOG_DEBUG(BSL_LS_BCM_FP, 777 (BSL_META_U(unit, "FT Group=%d - Tracking Key and/or" 778 " Data not specified\n\r"), 779 ftg_keygen_md->ft_group_id)); 780 return BCM_E_CONFIG; 781 } 782 783 /* Calculate number of session data qualifiers */ 784 total_data_quals = 0; 785 786 /* Qualifiers for ALU Data */ 787 BCM_FIELD_QSET_INIT(qset); 788 shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START; 789 for (idx = 0; idx < num_alu_data; idx++) { 790 alu_data = &ftg_keygen_md->alu_data_info[idx]; 791 pq_map = map_db->param_qual_map[alu_data->param + shift]; 792 qual = pq_map->qual; 793 794 if (!(BCM_FIELD_QSET_TEST(qset, qual))) { 795 total_data_quals++; 796 BCM_FIELD_QSET_ADD(qset, qual); 797 } 798 } 799 800 /* 801 * Qualifiers in Flowtracker checks 802 * Primary flowcheck can have action params also. 803 * So, need to allocate memory for them too. 804 */ 805 total_data_quals += (2 * num_flowchecks); 806 807 /* Qualifiers in Tracking params fo session data */ 808 total_data_quals += num_data_params; 809 810 /* Allocate qual_info_arr for session Key */ 811 _FP_XGS3_ALLOC(qual_info_arr, 812 num_key_params * sizeof(bcmi_keygen_qual_info_t), 813 "skey qual info arr"); 814 if (qual_info_arr == NULL) { 815 rv = BCM_E_MEMORY; 816 } else { 817 ftg_keygen_md->skey_keygen_md.qual_info_arr = qual_info_arr; 818 ftg_keygen_md->skey_keygen_md.max_qual_info_alloc = num_key_params; 819 } 820 821 /* Allocate qual_info_arr for session Data */ 822 if (BCM_SUCCESS(rv)) { 823 qual_info_arr = NULL; 824 _FP_XGS3_ALLOC(qual_info_arr, 825 total_data_quals * sizeof(bcmi_keygen_qual_info_t), 826 "sdata qual info arr"); 827 if (qual_info_arr == NULL) { 828 rv = BCM_E_MEMORY; 829 } else { 830 ftg_keygen_md->sdata_keygen_md.qual_info_arr = qual_info_arr; 831 ftg_keygen_md->sdata_keygen_md.max_qual_info_alloc = total_data_quals; 832 } 833 } 834 835 return rv; 836 } 837 838 /* 839 * Function: 840 * _field_hx5_ftg_qual_ext_hw_info_get 841 * 842 * Purpose: 843 * Convert keygen_oper to qual_ext_offset_info and ext_codes. 844 * 845 * Parameters: 846 * unit - (IN) BCM device number. 847 * key_or_data - (IN) Conversion of session key or data. 848 * ftg_keygen_md - (IN) FT Group Keygen metadata. 849 * qual_ext_offset_info - (OUT) Pointer to qual-extractor info. 850 * ext_codes - (OUT) Pointer to extraction codes. 851 * 852 * Returns: 853 * BCM_E_XXX 854 */ 855 STATIC int 856 _field_hx5_ftg_qual_ext_hw_info_get( 857 int unit, 858 int key_or_data, 859 _field_ft_group_keygen_md_t *ftg_keygen_md, 860 _field_ft_qual_ext_offset_info_t **qual_ext_offset_info, 861 _field_ft_keygen_ext_codes_t *ext_codes) 862 { 863 int rv = BCM_E_NONE; 864 int keygen_profile = 0; 865 int num_keygen_parts = 0; 866 uint16 ext_ctrl_sel_info_count = 0; 867 bcmi_keygen_oper_t *keygen_oper = NULL; 868 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info = NULL; 869 870 if ((ftg_keygen_md == NULL) || 871 (ext_codes == NULL) || 872 (qual_ext_offset_info == NULL)) { 873 return BCM_E_PARAM; 874 } 875 876 if (key_or_data == 1) { 877 keygen_oper = &ftg_keygen_md->skey_keygen_md.keygen_oper; 878 num_keygen_parts = ftg_keygen_md->skey_keygen_md.num_parts; 879 keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB; 880 } else { 881 keygen_oper = &ftg_keygen_md->sdata_keygen_md.keygen_oper; 882 num_keygen_parts = ftg_keygen_md->sdata_keygen_md.num_parts; 883 keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AB; 884 } 885 886 /* Get qual_ext_offset_info */ 887 ext_ctrl_sel_info = keygen_oper->ext_ctrl_sel_info; 888 ext_ctrl_sel_info_count = keygen_oper->ext_ctrl_sel_info_count; 889 890 /* Dump Qualifiers and Extractors info from Keygen_oper */ 891 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 892 "FT Group=%d Keygen Info for %s\r\n"), 893 ftg_keygen_md->ft_group_id, 894 ((key_or_data == 1) ? "SESSION KEY" : "SESSION DATA"))); 895 (void) _bcm_field_keygen_qual_offset_info_dump(unit, 896 num_keygen_parts, keygen_oper); 897 898 (void) _bcm_field_ft_keygen_extractors_init(ext_codes); 899 rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile, 900 ext_ctrl_sel_info_count, ext_ctrl_sel_info, ext_codes); 901 BCMI_IF_ERROR_CLEANUP(rv); 902 903 /* Process extracted qualifiers and extractors */ 904 if (ext_ctrl_sel_info != NULL) { 905 rv = _field_hx5_ft_qual_ext_offset_info_get(unit, 906 num_keygen_parts, 907 keygen_oper, qual_ext_offset_info); 908 BCMI_IF_ERROR_CLEANUP(rv); 909 910 /* Update Mask of extractors */ 911 rv = _bcm_field_hx5_ft_keygen_extractors_mask_set(unit, 912 *qual_ext_offset_info, ext_codes); 913 BCMI_IF_ERROR_CLEANUP(rv); 914 915 rv = _field_hx5_ft_qual_offset_ext_shift_apply(unit, 916 0, ext_codes, *qual_ext_offset_info); 917 BCMI_IF_ERROR_CLEANUP(rv); 918 } 919 920 /* Dump Hardware Extraction codes */ 921 (void) _bcm_field_hx5_ft_keygen_hw_extractors_dump(unit, ext_codes); 922 923 cleanup: 924 925 if (BCM_FAILURE(rv)) { 926 if (*qual_ext_offset_info != NULL) { 927 sal_free(*qual_ext_offset_info); 928 *qual_ext_offset_info = NULL; 929 } 930 } 931 932 return rv; 933 } 934 935 /* 936 * Function: 937 * _field_hx5_ftg_qual_offset_width_get 938 * 939 * Purpose: 940 * Get start and width from offset_arr for a qualifier. 941 * 942 * Parameters: 943 * unit - (IN) BCM device number. 944 * offset_arr - (IN) Offset arr. 945 * start_bit - (OUT) Start bit position. 946 * width - (OUT) Number of bits. 947 * 948 * Returns: 949 * BCM_E_XXX 950 */ 951 STATIC int 952 _field_hx5_ftg_qual_offset_width_get(int unit, 953 bcmi_keygen_qual_offset_t *offset_arr, 954 int *start_bit, 955 int *width) 956 { 957 int offset = 0; 958 int part_width = 0; 959 int total_width = 0; 960 int num_offsets = 0; 961 962 for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) { 963 part_width = offset_arr->width[offset]; 964 if (!part_width) { 965 continue; 966 } 967 total_width += part_width; 968 num_offsets += 1; 969 if (num_offsets == offset_arr->num_offsets) { 970 break; 971 } 972 } 973 974 *start_bit = offset_arr->offset[0]; 975 *width = total_width; 976 977 return BCM_E_NONE; 978 } 979 980 /* 981 * Function: 982 * _field_hx5_ftg_keygen_oper_dump 983 * 984 * Purpose: 985 * Dump session key/data extraction information. 986 * 987 * Parameters: 988 * unit - (IN) BCM device number. 989 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 990 * 991 * Returns: 992 * BCM_E_XXX 993 */ 994 STATIC void 995 _field_hx5_ftg_keygen_oper_dump( 996 int unit, 997 _field_ft_group_keygen_md_t *ftg_keygen_md) 998 { 999 uint32 idx = 0; 1000 bcmi_ft_group_alu_info_t *keydata_info = NULL; 1001 _field_ft_group_keygen_oper_info_t *oper_info = NULL; 1002 1003 oper_info = &ftg_keygen_md->keydata_oper_info; 1004 1005 LOG_VERBOSE(BSL_LS_BCM_FP, 1006 (BSL_META_U(unit, "===Extraction Operation Info===\r\n"))); 1007 LOG_VERBOSE(BSL_LS_BCM_FP, 1008 (BSL_META_U(unit, "---Session Keys---\r\n"))); 1009 LOG_VERBOSE(BSL_LS_BCM_FP, 1010 (BSL_META_U(unit, " Session Key Mode = %d\r\n"), 1011 oper_info->mode)); 1012 LOG_VERBOSE(BSL_LS_BCM_FP, 1013 (BSL_META_U(unit, " Number of Session Keys = %d\r\n"), 1014 oper_info->num_skey_info)); 1015 LOG_VERBOSE(BSL_LS_BCM_FP, 1016 (BSL_META_U(unit, "|%5s |%10s |%10s |%10s |\r\n"), 1017 "Idx", "Element", "Offset", "Length")); 1018 for (idx = 0; idx < oper_info->num_skey_info; idx++) { 1019 keydata_info = &oper_info->skey_info[idx]; 1020 LOG_VERBOSE(BSL_LS_BCM_FP, 1021 (BSL_META_U(unit, "|%5d |%10d |%10d |%10d |\r\n"), 1022 idx, 1023 keydata_info->element_type1, 1024 keydata_info->key1.location, 1025 keydata_info->key1.length)); 1026 } 1027 LOG_VERBOSE(BSL_LS_BCM_FP, 1028 (BSL_META_U(unit, "---Session Data---\r\n"))); 1029 LOG_VERBOSE(BSL_LS_BCM_FP, 1030 (BSL_META_U(unit, " Number of Session Data = %d\r\n"), 1031 oper_info->num_sdata_info)); 1032 LOG_VERBOSE(BSL_LS_BCM_FP, 1033 (BSL_META_U(unit, "|%5s |%10s |%10s |"), 1034 "Idx", "FlowCheck", "Type")); 1035 LOG_VERBOSE(BSL_LS_BCM_FP, 1036 (BSL_META_U(unit, "%10s |%10s |%10s |%10s |\r\n"), 1037 "Element", "Offset", "Length", "ALU Req")); 1038 for (idx = 0; idx < oper_info->num_sdata_info; idx++) { 1039 keydata_info = &oper_info->sdata_info[idx]; 1040 LOG_VERBOSE(BSL_LS_BCM_FP, 1041 (BSL_META_U(unit, "|%5d |%10x |%10s |"), 1042 idx, 1043 keydata_info->flowchecker_id, 1044 "Primary")); 1045 LOG_VERBOSE(BSL_LS_BCM_FP, 1046 (BSL_META_U(unit, "%10d |" 1047 "%10d |%10d |%10d |\r\n"), 1048 keydata_info->element_type1, 1049 keydata_info->key1.location, 1050 keydata_info->key1.length, 1051 keydata_info->key1.is_alu)); 1052 1053 /* Print secondary and Action key */ 1054 if (keydata_info->flowchecker_id != 0) { 1055 if (keydata_info->action_element_type != 1056 bcmFlowtrackerTrackingParamTypeNone) { 1057 LOG_VERBOSE(BSL_LS_BCM_FP, 1058 (BSL_META_U(unit, "|%5d |%10x |%10s |"), 1059 idx, 1060 keydata_info->flowchecker_id, 1061 "Action")); 1062 LOG_VERBOSE(BSL_LS_BCM_FP, 1063 (BSL_META_U(unit, "%10d |" 1064 "%10d |%10d |%10d |\r\n"), 1065 keydata_info->action_element_type, 1066 keydata_info->action_key.location, 1067 keydata_info->action_key.length, 1068 keydata_info->key1.is_alu)); 1069 } 1070 if (keydata_info->element_type2 != 1071 bcmFlowtrackerTrackingParamTypeNone) { 1072 LOG_VERBOSE(BSL_LS_BCM_FP, 1073 (BSL_META_U(unit, "|%5d |%10x |%10s |"), 1074 idx, 1075 BCMI_FT_FLOWCHECKER_INDEX_SET(keydata_info->flowchecker_id, 1076 BCM_FT_IDX_TYPE_2ND_CHECK), 1077 "Second")); 1078 LOG_VERBOSE(BSL_LS_BCM_FP, 1079 (BSL_META_U(unit, "%10d |" 1080 "%10d |%10d |%10d |\r\n"), 1081 keydata_info->element_type2, 1082 keydata_info->key2.location, 1083 keydata_info->key2.length, 1084 keydata_info->key2.is_alu)); 1085 } 1086 } 1087 } 1088 } 1089 1090 /* 1091 * Function: 1092 * _field_hx5_ftg_keygen_initialize 1093 * 1094 * Purpose: 1095 * Initialize ft group keygen metadata struct. 1096 * 1097 * Parameters: 1098 * unit - (IN) BCM device number. 1099 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1100 * 1101 * Returns: 1102 * BCM_E_XXX 1103 */ 1104 STATIC int 1105 _field_hx5_ftg_keygen_initialize( 1106 int unit, 1107 _field_ft_group_keygen_md_t *ftg_keygen_md) 1108 { 1109 int rv = BCM_E_NONE; 1110 _field_stage_t *stage_fc = NULL; 1111 1112 if (ftg_keygen_md == NULL) { 1113 return (BCM_E_PARAM); 1114 } 1115 1116 /* Validate Flowtracker group */ 1117 rv = bcmi_ft_group_is_invalid(unit, ftg_keygen_md->ft_group_id); 1118 1119 /* Get Flowtracker Stage info */ 1120 if (BCM_SUCCESS(rv)) { 1121 rv = _field_stage_control_get(unit, 1122 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc); 1123 } 1124 1125 if (BCM_SUCCESS(rv)) { 1126 /* Ft info from stage */ 1127 ftg_keygen_md->ft_info = stage_fc->ft_info; 1128 } 1129 1130 /* Move to next state */ 1131 ftg_keygen_md->state_rv = rv; 1132 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1133 if (BCM_FAILURE(rv)) { 1134 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1135 } else { 1136 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_ALLOC; 1137 } 1138 1139 return rv; 1140 } 1141 1142 /* 1143 * Function: 1144 * _field_hx5_ftg_keygen_cfg_alloc 1145 * 1146 * Purpose: 1147 * Read FT group tracking param and flowchecks info and allocate 1148 * memories to qual_info_arr for input to Keygen algo. 1149 * 1150 * Parameters: 1151 * unit - (IN) BCM device number. 1152 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1153 * 1154 * Returns: 1155 * BCM_E_XXX 1156 */ 1157 STATIC int 1158 _field_hx5_ftg_keygen_cfg_alloc( 1159 int unit, 1160 _field_ft_group_keygen_md_t *ftg_keygen_md) 1161 { 1162 int rv = BCM_E_NONE; 1163 int num_tracking_params = 0; 1164 int num_flowchecks = 0; 1165 int num_alu_data = 0; 1166 bcm_flowtracker_group_t ft_group_id; 1167 1168 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1169 ft_group_id = ftg_keygen_md->ft_group_id; 1170 1171 /* Get number of tracking params from group template */ 1172 rv = bcm_esw_flowtracker_group_tracking_params_get(unit, 1173 ft_group_id, 0, NULL, &num_tracking_params); 1174 1175 /* Get number of flowcheck info from flowtracker group */ 1176 if (BCM_SUCCESS(rv)) { 1177 rv = bcmi_flowtracker_check_get_all(unit, 1178 ft_group_id, 0, 0, NULL, &num_flowchecks); 1179 } 1180 1181 /* Get number of Alu Data */ 1182 if (BCM_SUCCESS(rv)) { 1183 rv = _field_hx5_ftg_alu_data_info_get(unit, 1184 ft_group_id, NULL, &num_alu_data); 1185 } 1186 1187 /* Allocate memory for tracking params info */ 1188 if (BCM_SUCCESS(rv)) { 1189 ftg_keygen_md->num_tracking_params = num_tracking_params; 1190 _FP_XGS3_ALLOC(ftg_keygen_md->tracking_params_info, 1191 num_tracking_params * sizeof(bcm_flowtracker_tracking_param_info_t), 1192 "tracking params info"); 1193 if (ftg_keygen_md->tracking_params_info == NULL) { 1194 rv = BCM_E_MEMORY; 1195 } 1196 } 1197 1198 /* Allocate memory for flowchecks */ 1199 if (BCM_SUCCESS(rv)) { 1200 ftg_keygen_md->num_flowchecks = num_flowchecks; 1201 _FP_XGS3_ALLOC(ftg_keygen_md->flowtracker_checks, 1202 num_flowchecks * sizeof(bcm_flowtracker_check_t), 1203 "flowtracker checks"); 1204 if (ftg_keygen_md->flowtracker_checks == NULL) { 1205 rv = BCM_E_MEMORY; 1206 } 1207 } 1208 1209 /* Read tracking params info */ 1210 if (BCM_SUCCESS(rv)) { 1211 rv = bcm_esw_flowtracker_group_tracking_params_get(unit, 1212 ft_group_id, num_tracking_params, 1213 &ftg_keygen_md->tracking_params_info[0], 1214 &num_tracking_params); 1215 } 1216 1217 /* Read flowtracker checks */ 1218 if (BCM_SUCCESS(rv)) { 1219 rv = bcmi_flowtracker_check_get_all(unit, 1220 ft_group_id, 0, num_flowchecks, 1221 &ftg_keygen_md->flowtracker_checks[0], 1222 &num_flowchecks); 1223 } 1224 1225 /* Read ALU Data */ 1226 if (BCM_SUCCESS(rv)) { 1227 rv = _field_hx5_ftg_alu_data_info_get(unit, ft_group_id, 1228 &ftg_keygen_md->alu_data_info, 1229 &ftg_keygen_md->num_alu_data); 1230 } 1231 1232 /* Allocate memory for qual_info arr of session key/Data */ 1233 if (BCM_SUCCESS(rv)) { 1234 rv = _field_hx5_ftg_keygen_cfg_qual_alloc(unit, ftg_keygen_md); 1235 } 1236 1237 /* Move to next state */ 1238 ftg_keygen_md->state_rv = rv; 1239 if (BCM_FAILURE(rv)) { 1240 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1241 } else { 1242 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD; 1243 } 1244 1245 return rv; 1246 } 1247 1248 /* 1249 * Function: 1250 * _field_hx5_ftg_keygen_cfg_alu_qual_add 1251 * 1252 * Purpose: 1253 * Read FT group Alu data info and populate qual_info_arr 1254 * for session data extraction. 1255 * 1256 * Parameters: 1257 * unit - (IN) BCM device number. 1258 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1259 * 1260 * Returns: 1261 * BCM_E_XXX 1262 */ 1263 STATIC int 1264 _field_hx5_ftg_keygen_cfg_alu_qual_add( 1265 int unit, 1266 _field_ft_group_keygen_md_t *ftg_keygen_md) 1267 { 1268 int rv = BCM_E_NONE; 1269 int new_idx = 0; 1270 int idx = 0; 1271 int shift = 0; 1272 uint16 param; 1273 uint16 allocated_quals = 0; 1274 bcm_field_qualify_t qual; 1275 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 1276 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 1277 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 1278 _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL; 1279 1280 /* Check if ALU data is required */ 1281 if (ftg_keygen_md->num_alu_data == 0) { 1282 goto cleanup; 1283 } 1284 1285 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1286 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 1287 shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START; 1288 1289 /* Add to Session Data qual_info_arr */ 1290 sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md; 1291 allocated_quals = sdata_keygen_md->qual_info_count; 1292 qual_info_arr = sdata_keygen_md->qual_info_arr; 1293 1294 for (idx = 0; idx < ftg_keygen_md->num_alu_data; idx++) { 1295 param = ftg_keygen_md->alu_data_info[idx].param; 1296 pq_map = map_db->param_qual_map[param + shift]; 1297 qual = pq_map->qual; 1298 1299 if (BCM_FIELD_QSET_TEST(sdata_keygen_md->qset, qual)) { 1300 continue; 1301 } 1302 1303 new_idx = allocated_quals; 1304 qual_info_arr[new_idx].qual_id = qual; 1305 qual_info_arr[new_idx].flags = 1306 BCMI_KEYGEN_QUAL_F_STICKY_CONTAINERS | 1307 BCMI_KEYGEN_QUAL_F_USE_FINFO_NEW | 1308 BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN16; 1309 allocated_quals++; 1310 BCM_FIELD_QSET_ADD(sdata_keygen_md->qset, qual); 1311 } 1312 1313 sdata_keygen_md->qual_info_count = allocated_quals; 1314 1315 cleanup: 1316 1317 /* Move to next state */ 1318 ftg_keygen_md->state_rv = rv; 1319 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD; 1320 1321 return rv; 1322 } 1323 1324 /* 1325 * Function: 1326 * _field_hx5_ftg_keygen_cfg_flowcheck_qual_add 1327 * 1328 * Purpose: 1329 * Read FT group Flowcheck info and populate qual_info_arr 1330 * for session data extraction. 1331 * 1332 * Parameters: 1333 * unit - (IN) BCM device number. 1334 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1335 * 1336 * Returns: 1337 * BCM_E_XXX 1338 */ 1339 STATIC int 1340 _field_hx5_ftg_keygen_cfg_flowcheck_qual_add( 1341 int unit, 1342 _field_ft_group_keygen_md_t *ftg_keygen_md) 1343 { 1344 int rv = BCM_E_NONE; 1345 int idx = 0; 1346 int p_idx = 0; 1347 int new_idx = 0; 1348 int num_params = 0; 1349 uint16 param; 1350 uint16 param_list[2]; 1351 uint16 allocated_quals = 0; 1352 bcm_field_qualify_t qual; 1353 bcm_flowtracker_check_t check_id; 1354 bcm_flowtracker_check_info_t fc_info; 1355 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 1356 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 1357 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 1358 _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL; 1359 bcm_flowtracker_check_action_info_t action_info; 1360 1361 /* validate inputs */ 1362 if (ftg_keygen_md == NULL) { 1363 return (BCM_E_PARAM); 1364 } 1365 1366 /* Check if Flowcheck is required */ 1367 if (ftg_keygen_md->num_flowchecks == 0) { 1368 goto cleanup; 1369 } 1370 1371 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1372 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 1373 1374 /* Add to Session Data qual_info_arr */ 1375 sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md; 1376 allocated_quals = sdata_keygen_md->qual_info_count; 1377 qual_info_arr = sdata_keygen_md->qual_info_arr; 1378 1379 for (idx = 0; idx < ftg_keygen_md->num_flowchecks; idx++) { 1380 num_params = 0; 1381 check_id = ftg_keygen_md->flowtracker_checks[idx]; 1382 1383 sal_memset(&fc_info, 0, sizeof(bcm_flowtracker_check_info_t)); 1384 rv = bcmi_ft_check_get(unit, check_id, &fc_info); 1385 if (BCM_FAILURE(rv)) { 1386 goto cleanup; 1387 } 1388 param_list[0] = fc_info.param; 1389 num_params++; 1390 1391 /* If primary flowcheck, get action info */ 1392 if (BCMI_FT_IDX_IS_PRIMARY_CHECK(check_id)) { 1393 bcm_flowtracker_check_action_info_t_init(&action_info); 1394 rv = bcm_esw_flowtracker_check_action_info_get(unit, 1395 check_id, &action_info); 1396 BCMI_IF_ERROR_CLEANUP(rv); 1397 1398 if (action_info.param != bcmFlowtrackerTrackingParamTypeNone) { 1399 param_list[1] = action_info.param; 1400 num_params++; 1401 } 1402 } 1403 1404 for (p_idx = 0; p_idx < num_params; p_idx++) { 1405 param = param_list[p_idx]; 1406 pq_map = map_db->param_qual_map[param]; 1407 1408 if ((param > _FIELD_FT_TRACKING_PARAM_MAX) || (pq_map == NULL)) { 1409 rv = BCM_E_PARAM; 1410 BCMI_IF_ERROR_CLEANUP(rv); 1411 } 1412 if (pq_map->flags & 1413 _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) { 1414 continue; 1415 } 1416 1417 qual = pq_map->qual; 1418 if (!BCM_FIELD_QSET_TEST(sdata_keygen_md->qset, qual)) { 1419 new_idx = allocated_quals; 1420 qual_info_arr[new_idx].qual_id = qual; 1421 qual_info_arr[new_idx].flags = 1422 BCMI_KEYGEN_QUAL_F_STICKY_CONTAINERS | 1423 BCMI_KEYGEN_QUAL_F_USE_FINFO_NEW | 1424 BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN16; 1425 1426 if (pq_map->flags & 1427 _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32) { 1428 qual_info_arr[new_idx].flags |= 1429 BCMI_KEYGEN_QUAL_F_EXTRACT_TO_MODULO_32_OFFSET; 1430 } 1431 allocated_quals++; 1432 BCM_FIELD_QSET_ADD(sdata_keygen_md->qset, qual); 1433 } 1434 } 1435 } 1436 1437 sdata_keygen_md->qual_info_count = allocated_quals; 1438 1439 cleanup: 1440 1441 /* Move to next state */ 1442 ftg_keygen_md->state_rv = rv; 1443 if (BCM_FAILURE(rv)) { 1444 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1445 } else { 1446 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD; 1447 } 1448 1449 return rv; 1450 } 1451 1452 /* 1453 * Function: 1454 * _field_hx5_ftg_keygen_cfg_data_key_qual_add 1455 * 1456 * Purpose: 1457 * Read FT group Tracking param info and populate qual_info_arr 1458 * for session key and session data extraction. 1459 * 1460 * Parameters: 1461 * unit - (IN) BCM device number. 1462 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1463 * 1464 * Returns: 1465 * BCM_E_XXX 1466 */ 1467 STATIC int 1468 _field_hx5_ftg_keygen_cfg_data_key_qual_add( 1469 int unit, 1470 _field_ft_group_keygen_md_t *ftg_keygen_md) 1471 { 1472 int rv = BCM_E_NONE; 1473 int idx = 0; 1474 int new_idx = 0; 1475 int is_key = FALSE; 1476 int num_tracking_params = 0; 1477 uint16 param; 1478 uint16 *allocated_quals = NULL; 1479 bcm_field_qualify_t qual; 1480 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 1481 bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL; 1482 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 1483 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 1484 _field_ft_group_keydata_keygen_md_t *skey_keygen_md = NULL; 1485 _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL; 1486 1487 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 1488 num_tracking_params = ftg_keygen_md->num_tracking_params; 1489 1490 skey_keygen_md = &ftg_keygen_md->skey_keygen_md; 1491 sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md; 1492 1493 /* Loop through tracking params */ 1494 for (idx = 0; idx < num_tracking_params; idx++) { 1495 tracking_param_info = &ftg_keygen_md->tracking_params_info[idx]; 1496 1497 if (tracking_param_info->flags & 1498 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) { 1499 is_key = TRUE; 1500 qual_info_arr = skey_keygen_md->qual_info_arr; 1501 allocated_quals = &skey_keygen_md->qual_info_count; 1502 } else { 1503 is_key = FALSE; 1504 qual_info_arr = sdata_keygen_md->qual_info_arr; 1505 allocated_quals = &sdata_keygen_md->qual_info_count; 1506 } 1507 1508 /* Handling tracking param FlowtrackerCheck */ 1509 if (tracking_param_info->param == 1510 bcmFlowtrackerTrackingParamTypeFlowtrackerCheck) { 1511 rv = bcmi_ft_group_check_validate(unit, 1512 BCMI_FT_GROUP_CHECK_MATCH_GROUP, 1513 ftg_keygen_md->ft_group_id, tracking_param_info->check_id); 1514 if ((rv != BCM_E_NONE) || (is_key == TRUE)) { 1515 rv = BCM_E_PARAM; 1516 BCMI_IF_ERROR_CLEANUP(rv); 1517 } 1518 } 1519 1520 param = tracking_param_info->param; 1521 pq_map = map_db->param_qual_map[param]; 1522 1523 if ((param > _FIELD_FT_TRACKING_PARAM_MAX) || (pq_map == NULL)) { 1524 rv = BCM_E_PARAM; 1525 BCMI_IF_ERROR_CLEANUP(rv); 1526 } 1527 if (pq_map->flags & 1528 _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) { 1529 continue; 1530 } 1531 1532 qual = pq_map->qual; 1533 if (((is_key == TRUE) && BCM_FIELD_QSET_TEST(skey_keygen_md->qset, qual)) || 1534 ((is_key == FALSE) && BCM_FIELD_QSET_TEST(sdata_keygen_md->qset, qual))) { 1535 continue; 1536 } 1537 1538 new_idx = *allocated_quals; 1539 qual_info_arr[new_idx].qual_id = qual; 1540 qual_info_arr[new_idx].flags = 1541 BCMI_KEYGEN_QUAL_F_STICKY_CONTAINERS | 1542 BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN16; 1543 1544 if (is_key == TRUE) { 1545 qual_info_arr[new_idx].flags |= 1546 BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN8; 1547 if (pq_map->flags & 1548 _FP_FT_TRACKING_PARAM_F_KEY_MODULO_32) { 1549 qual_info_arr[new_idx].flags |= 1550 BCMI_KEYGEN_QUAL_F_EXTRACT_TO_MODULO_32_OFFSET; 1551 } 1552 } else { 1553 qual_info_arr[new_idx].flags |= 1554 BCMI_KEYGEN_QUAL_F_USE_FINFO_NEW; 1555 if (pq_map->flags & 1556 _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32) { 1557 qual_info_arr[new_idx].flags |= 1558 BCMI_KEYGEN_QUAL_F_EXTRACT_TO_MODULO_32_OFFSET; 1559 } 1560 } 1561 1562 (*allocated_quals)++; 1563 if (is_key == TRUE) { 1564 BCM_FIELD_QSET_ADD(skey_keygen_md->qset, qual); 1565 } else { 1566 BCM_FIELD_QSET_ADD(sdata_keygen_md->qset, qual); 1567 } 1568 } 1569 1570 cleanup: 1571 1572 ftg_keygen_md->state_rv = rv; 1573 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1574 1575 if (BCM_FAILURE(rv)) { 1576 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1577 } else { 1578 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST; 1579 } 1580 1581 return rv; 1582 } 1583 1584 /* 1585 * Function: 1586 * _field_hx5_ftg_keygen_qual_info_shift 1587 * 1588 * Purpose: 1589 * Shift qual info in qual_info_arr downward. 1590 * 1591 * Parameters: 1592 * unit - (IN) BCM device number. 1593 * start_idx - (IN) Start index (lower number) 1594 * end_idx - (IN) End Index (higher number) 1595 * qual_info_arr - (IN/OUT) Qual info array. 1596 * qual_size_arr - (IN/OUT) Qual size array. 1597 * 1598 * Returns: 1599 * BCM_E_XXX 1600 */ 1601 int 1602 _field_hx5_ftg_keygen_qual_info_shift(int unit, 1603 int start_idx, 1604 int end_idx, 1605 bcmi_keygen_qual_info_t *qual_info_arr, 1606 uint16 *qual_size_arr) 1607 { 1608 int idx = 0; 1609 int qual_size = 0; 1610 bcmi_keygen_qual_info_t temp_qual_info; 1611 1612 qual_size = qual_size_arr[end_idx]; 1613 sal_memcpy(&temp_qual_info, &qual_info_arr[end_idx], 1614 sizeof(bcmi_keygen_qual_info_t)); 1615 1616 for (idx = end_idx; idx > start_idx; idx--) { 1617 qual_size_arr[idx] = qual_size_arr[idx - 1]; 1618 sal_memcpy(&qual_info_arr[idx], &qual_info_arr[idx - 1], 1619 sizeof(bcmi_keygen_qual_info_t)); 1620 } 1621 1622 qual_size_arr[start_idx] = qual_size; 1623 sal_memcpy(&qual_info_arr[start_idx], &temp_qual_info, 1624 sizeof(bcmi_keygen_qual_info_t)); 1625 1626 return BCM_E_NONE; 1627 } 1628 1629 /* 1630 * Function: 1631 * _field_hx5_ftg_keygen_cfg_data_qual_adjust 1632 * 1633 * Purpose: 1634 * Re-arrange, if required, qual_info_arr for session data extraction. 1635 * 1636 * Parameters: 1637 * unit - (IN) BCM device number. 1638 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1639 * 1640 * Returns: 1641 * BCM_E_XXX 1642 */ 1643 STATIC int 1644 _field_hx5_ftg_keygen_cfg_data_qual_adjust( 1645 int unit, 1646 _field_ft_group_keygen_md_t *ftg_keygen_md) 1647 { 1648 int rv = BCM_E_NONE; 1649 int idx = 0; 1650 int rank1_idx = 0; 1651 uint16 qual_size = 0; 1652 uint16 qual_info_count = 0; 1653 uint16 qual_size_arr[20]; 1654 bcmi_keygen_cfg_t keygen_cfg; 1655 _field_ft_info_t *ft_info = NULL; 1656 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 1657 1658 if (ftg_keygen_md == NULL) { 1659 return (BCM_E_PARAM); 1660 } 1661 1662 qual_info_arr = ftg_keygen_md->sdata_keygen_md.qual_info_arr; 1663 qual_info_count = ftg_keygen_md->sdata_keygen_md.qual_info_count; 1664 if ((qual_info_arr == NULL) || (qual_info_count <= 1)) { 1665 goto cleanup; 1666 } 1667 1668 ft_info = ftg_keygen_md->ft_info; 1669 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg; 1670 1671 /* Create list of qualifier sizes */ 1672 for (idx = 0; idx < qual_info_count; idx++) { 1673 rv = bcmi_keygen_qual_cfg_max_size_get(unit, 1674 &keygen_cfg, qual_info_arr[idx].qual_id, &qual_size); 1675 BCM_IF_ERROR_RETURN(rv); 1676 1677 qual_size_arr[idx] = qual_size; 1678 } 1679 1680 /* Sort qualifiers based on size and usage. Mask is not considered */ 1681 /* Set rank1_idx after ALU_DATA qualifier. */ 1682 rank1_idx = 1; 1683 for (idx = rank1_idx; idx < qual_info_count; idx++) { 1684 1685 if ((qual_size_arr[idx] % 8) != 0) { 1686 /* If qual_size is not multiple of 8, Rank 1 */ 1687 1688 rv = _field_hx5_ftg_keygen_qual_info_shift(unit, 1689 rank1_idx, idx, qual_info_arr, qual_size_arr); 1690 BCMI_IF_ERROR_CLEANUP(rv); 1691 rank1_idx++; 1692 } 1693 } 1694 1695 cleanup: 1696 1697 ftg_keygen_md->state_rv = rv; 1698 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1699 1700 if (BCM_FAILURE(rv)) { 1701 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1702 } else { 1703 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST; 1704 } 1705 1706 return rv; 1707 } 1708 1709 /* 1710 * Function: 1711 * _field_hx5_ftg_keygen_cfg_key_qual_adjust 1712 * 1713 * Purpose: 1714 * Re-arrange, if required, qual_info_arr for session key extraction. 1715 * 1716 * Parameters: 1717 * unit - (IN) BCM device number. 1718 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1719 * 1720 * Returns: 1721 * BCM_E_XXX 1722 */ 1723 STATIC int 1724 _field_hx5_ftg_keygen_cfg_key_qual_adjust( 1725 int unit, 1726 _field_ft_group_keygen_md_t *ftg_keygen_md) 1727 { 1728 int rv = BCM_E_NONE; 1729 int idx = 0; 1730 int rank1_idx = 0; 1731 int rank2_idx = 0; 1732 int rank3_idx = 0; 1733 uint16 qual_size = 0; 1734 uint16 qual_info_count = 0; 1735 uint16 qual_size_arr[20]; 1736 bcmi_keygen_cfg_t keygen_cfg; 1737 _field_ft_info_t *ft_info = NULL; 1738 bcmi_keygen_qual_info_t *qual_info_arr = NULL; 1739 1740 if (ftg_keygen_md == NULL) { 1741 return (BCM_E_PARAM); 1742 } 1743 1744 qual_info_arr = ftg_keygen_md->skey_keygen_md.qual_info_arr; 1745 qual_info_count = ftg_keygen_md->skey_keygen_md.qual_info_count; 1746 if ((qual_info_arr == NULL) || (qual_info_count <= 1)) { 1747 goto cleanup; 1748 } 1749 1750 ft_info = ftg_keygen_md->ft_info; 1751 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg; 1752 1753 /* Create list of qualifier sizes */ 1754 for (idx = 0; idx < qual_info_count; idx++) { 1755 rv = bcmi_keygen_qual_cfg_max_size_get(unit, 1756 &keygen_cfg, qual_info_arr[idx].qual_id, &qual_size); 1757 BCM_IF_ERROR_RETURN(rv); 1758 1759 qual_size_arr[idx] = qual_size; 1760 } 1761 1762 /* Shuffle qualifiers based on size and usage. Mask is not considered */ 1763 rank1_idx = rank2_idx = rank3_idx = 0; 1764 for (idx = 0; idx < qual_info_count; idx++) { 1765 1766 if (qual_size_arr[idx] > 104) { 1767 /* If qual_size is greater than 104 bits, Rank 1 */ 1768 1769 rv = _field_hx5_ftg_keygen_qual_info_shift(unit, 1770 rank1_idx, idx, qual_info_arr, qual_size_arr); 1771 BCMI_IF_ERROR_CLEANUP(rv); 1772 rank1_idx++; rank2_idx++; rank3_idx++; 1773 1774 } else if ((qual_size_arr[idx] > 16) && 1775 (qual_size_arr[idx] % 16) != 0) { 1776 /* If qual_size > 16 but not multiple of 16, rank 2. */ 1777 1778 rv = _field_hx5_ftg_keygen_qual_info_shift(unit, 1779 rank2_idx, idx, qual_info_arr, qual_size_arr); 1780 BCMI_IF_ERROR_CLEANUP(rv); 1781 rank2_idx++; rank3_idx++; 1782 } else if ((qual_size_arr[idx] % 8) != 0) { 1783 /* If qual_size is not multiple of 8, rank 3. */ 1784 1785 rv = _field_hx5_ftg_keygen_qual_info_shift(unit, 1786 rank3_idx, idx, qual_info_arr, qual_size_arr); 1787 BCMI_IF_ERROR_CLEANUP(rv); 1788 rank3_idx++; 1789 } 1790 } 1791 1792 cleanup: 1793 1794 ftg_keygen_md->state_rv = rv; 1795 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1796 1797 if (BCM_FAILURE(rv)) { 1798 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1799 } else { 1800 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT; 1801 } 1802 1803 return rv; 1804 } 1805 1806 /* 1807 * Function: 1808 * _field_hx5_ftg_keygen_data_oper_extract 1809 * 1810 * Purpose: 1811 * Call keygen algo to extract session data. 1812 * 1813 * Parameters: 1814 * unit - (IN) BCM device number. 1815 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1816 * 1817 * Returns: 1818 * BCM_E_XXX 1819 */ 1820 STATIC int 1821 _field_hx5_ftg_keygen_data_oper_extract( 1822 int unit, 1823 _field_ft_group_keygen_md_t *ftg_keygen_md) 1824 { 1825 int rv = BCM_E_NONE; 1826 int mode_idx = 0; 1827 int ext_modes_count = 0; 1828 _field_ft_info_t *ft_info = NULL; 1829 bcmi_keygen_mode_t ext_modes[2]; 1830 bcmi_keygen_cfg_t keygen_cfg; 1831 bcmi_keygen_oper_t *keygen_oper = NULL; 1832 bcmi_keygen_mode_t keygen_mode = BCMI_KEYGEN_MODE_SINGLE; 1833 bcmi_keygen_mode_t keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE; 1834 _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL; 1835 1836 ft_info = ftg_keygen_md->ft_info; 1837 sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md; 1838 1839 /* If valid ext modes list is not provided, error. */ 1840 if (sdata_keygen_md->ext_modes_count == 0) { 1841 rv = BCM_E_INTERNAL; 1842 } 1843 1844 /* Session data extraction modes */ 1845 ext_modes_count = 1; 1846 ext_modes[0] = BCMI_KEYGEN_MODE_SINGLE; 1847 1848 for (mode_idx = 0; mode_idx < ext_modes_count; mode_idx++) { 1849 1850 switch(ext_modes[mode_idx]) { 1851 case BCMI_KEYGEN_MODE_SINGLE: 1852 1853 keygen_mode = BCMI_KEYGEN_MODE_SINGLE; 1854 keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE; 1855 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t)); 1856 keygen_cfg.qual_info_arr = sdata_keygen_md->qual_info_arr; 1857 keygen_cfg.qual_info_count = sdata_keygen_md->qual_info_count; 1858 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg; 1859 keygen_cfg.ext_cfg_db = ft_info->flow_key_ext_cfg_arr[keygen_ext_mode]; 1860 keygen_cfg.mode = keygen_mode; 1861 keygen_cfg.num_parts = 2; 1862 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_SERIAL_MUX_ALLOC; 1863 1864 keygen_oper = &sdata_keygen_md->keygen_oper; 1865 sal_memset(keygen_oper, 0, sizeof(bcmi_keygen_oper_t)); 1866 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, keygen_oper); 1867 break; 1868 default: 1869 rv = BCM_E_INTERNAL; 1870 } 1871 if (BCM_SUCCESS(rv)) { 1872 break; 1873 } 1874 } 1875 1876 /* Move to next state */ 1877 ftg_keygen_md->state_rv = rv; 1878 ftg_keygen_md->prev_state = ftg_keygen_md->state; 1879 if (BCM_FAILURE(rv)) { 1880 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 1881 } else { 1882 sdata_keygen_md->keygen_mode = keygen_mode; 1883 sdata_keygen_md->num_parts = keygen_cfg.num_parts; 1884 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT; 1885 } 1886 1887 return rv; 1888 } 1889 1890 /* 1891 * Function: 1892 * _field_hx5_ftg_keygen_qual_skip_check 1893 * 1894 * Purpose: 1895 * Check if it is required to skip first qualifier. 1896 * In case there are two qualifiers which ar 128 bits, 1897 * rest of qualifiers cannot be masked as all Type A 1898 * are exhausted. This could be a problem with IPv6 1899 * 5-tuple. To prevent it, if 2 such qualifiers are 1900 * present if is better to skip one qualifier and 1901 * extract it statically at the end of Key. 1902 * 1903 * Parameters: 1904 * unit - (IN) BCM device number. 1905 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1906 * 1907 * Returns: 1908 * BCM_E_XXX 1909 * 1910 * Notes: 1911 * In function _field_hx5_ftg_keygen_cfg_key_qual_adjust(), we 1912 * sort qualifiers are place 128-bit extractors in the front. 1913 * It is pre-requisite to this function to work properly. 1914 */ 1915 STATIC int 1916 _field_hx5_ftg_keygen_qual_skip_check( 1917 int unit, 1918 _field_ft_group_keydata_keygen_md_t *skey_keygen_md, 1919 int *skip_qual_extract) 1920 { 1921 int idx = 0; 1922 bcm_field_qualify_t qual; 1923 int qual_skip_req = 0; 1924 1925 for (idx = 0; idx < 2; idx++) { 1926 if (skey_keygen_md->qual_info_count > idx) { 1927 qual = skey_keygen_md->qual_info_arr[idx].qual_id; 1928 1929 if ((qual == bcmFieldQualifySrcIp6) || 1930 (qual == bcmFieldQualifyDstIp6) || 1931 (qual == bcmFieldQualifyInnerSrcIp6) || 1932 (qual == bcmFieldQualifyInnerDstIp6)) { 1933 qual_skip_req++; 1934 } 1935 } 1936 } 1937 if (qual_skip_req == 2) { 1938 *skip_qual_extract = TRUE; 1939 } else { 1940 *skip_qual_extract = FALSE; 1941 } 1942 return BCM_E_NONE; 1943 } 1944 1945 /* 1946 * Function: 1947 * _field_hx5_ftg_keygen_key_oper_extract 1948 * 1949 * Purpose: 1950 * Call keygen algo to extract session key. 1951 * 1952 * Parameters: 1953 * unit - (IN) BCM device number. 1954 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 1955 * 1956 * Returns: 1957 * BCM_E_XXX 1958 */ 1959 STATIC int 1960 _field_hx5_ftg_keygen_key_oper_extract( 1961 int unit, 1962 _field_ft_group_keygen_md_t *ftg_keygen_md) 1963 { 1964 int rv = BCM_E_NONE; 1965 int mode_idx = 0; 1966 int ext_modes_count = 0; 1967 int skip_qual_extract = FALSE; 1968 _field_ft_info_t *ft_info = NULL; 1969 bcmi_keygen_mode_t ext_modes[2]; 1970 bcmi_keygen_cfg_t keygen_cfg; 1971 bcmi_keygen_oper_t *keygen_oper = NULL; 1972 bcm_field_qualify_t skipped_qual = bcmFieldQualifySrcIp6; 1973 bcmi_keygen_mode_t keygen_mode = BCMI_KEYGEN_MODE_SINGLE; 1974 bcmi_keygen_mode_t keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE; 1975 _field_ft_group_keydata_keygen_md_t *skey_keygen_md = NULL; 1976 1977 ft_info = ftg_keygen_md->ft_info; 1978 skey_keygen_md = &ftg_keygen_md->skey_keygen_md; 1979 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t)); 1980 1981 /* Check if static qualifier extraction is required */ 1982 rv = _field_hx5_ftg_keygen_qual_skip_check(unit, 1983 skey_keygen_md, &skip_qual_extract); 1984 BCMI_IF_ERROR_CLEANUP(rv); 1985 1986 if (skip_qual_extract == TRUE) { 1987 skipped_qual = skey_keygen_md->qual_info_arr[0].qual_id; 1988 ext_modes[0] = BCMI_KEYGEN_MODE_DBLINTRA; 1989 ext_modes_count = 1; 1990 } else { 1991 ext_modes[0] = BCMI_KEYGEN_MODE_SINGLE; 1992 ext_modes[1] = BCMI_KEYGEN_MODE_DBLINTRA; 1993 ext_modes_count = 2; 1994 } 1995 1996 for (mode_idx = 0; mode_idx < ext_modes_count; mode_idx++) { 1997 1998 switch(ext_modes[mode_idx]) { 1999 case BCMI_KEYGEN_MODE_SINGLE: 2000 2001 keygen_mode = BCMI_KEYGEN_MODE_SINGLE; 2002 keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE; 2003 2004 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t)); 2005 keygen_cfg.qual_info_arr = skey_keygen_md->qual_info_arr; 2006 keygen_cfg.qual_info_count = skey_keygen_md->qual_info_count; 2007 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg; 2008 keygen_cfg.ext_cfg_db = ft_info->flow_key_ext_cfg_arr[keygen_ext_mode]; 2009 keygen_cfg.mode = keygen_mode; 2010 keygen_cfg.num_parts = 2; 2011 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_SERIAL_MUX_ALLOC; 2012 2013 keygen_oper = &skey_keygen_md->keygen_oper; 2014 sal_memset(keygen_oper, 0, sizeof(bcmi_keygen_oper_t)); 2015 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, keygen_oper); 2016 break; 2017 2018 case BCMI_KEYGEN_MODE_DBLINTRA: 2019 2020 keygen_mode = BCMI_KEYGEN_MODE_DBLINTRA; 2021 keygen_ext_mode = BCMI_KEYGEN_MODE_DBLINTRA; 2022 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t)); 2023 2024 if (skip_qual_extract == TRUE) { 2025 /* Remove static qual/extractor from qual_info_arr */ 2026 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_QSET_UPDATE; 2027 rv = _field_hx5_ft_keygen_cfg_qual_ext_ctrl_skip(unit, 2028 &keygen_cfg, skipped_qual, NULL); 2029 BCMI_IF_ERROR_CLEANUP(rv); 2030 keygen_cfg.qual_info_arr = &skey_keygen_md->qual_info_arr[1]; 2031 keygen_cfg.qual_info_count = skey_keygen_md->qual_info_count - 1; 2032 } else { 2033 keygen_cfg.qual_info_arr = &skey_keygen_md->qual_info_arr[0]; 2034 keygen_cfg.qual_info_count = skey_keygen_md->qual_info_count; 2035 } 2036 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg; 2037 keygen_cfg.ext_cfg_db = ft_info->flow_key_ext_cfg_arr[keygen_ext_mode]; 2038 keygen_cfg.mode = keygen_mode; 2039 keygen_cfg.num_parts = 3; 2040 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_SERIAL_MUX_ALLOC; 2041 2042 keygen_oper = &skey_keygen_md->keygen_oper; 2043 sal_memset(keygen_oper, 0, sizeof(bcmi_keygen_oper_t)); 2044 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, keygen_oper); 2045 break; 2046 2047 default: 2048 rv = BCM_E_INTERNAL; 2049 BCMI_IF_ERROR_CLEANUP(rv); 2050 } 2051 if (BCM_FAILURE(rv)) { 2052 /* Free Keygen_cfg */ 2053 if (keygen_cfg.ext_ctrl_sel_info != NULL) { 2054 sal_free(keygen_cfg.ext_ctrl_sel_info); 2055 keygen_cfg.ext_ctrl_sel_info = NULL; 2056 } 2057 } else if (BCM_SUCCESS(rv) && (skip_qual_extract == TRUE)) { 2058 /* Update keygen_oper with static extraction info */ 2059 rv = _field_hx5_ft_keygen_oper_qual_ext_ctrl_apply(unit, 2060 &keygen_cfg, skipped_qual, keygen_oper); 2061 } 2062 /* Break if extraction is successful */ 2063 if (BCM_SUCCESS(rv)) { 2064 break; 2065 } 2066 } 2067 2068 cleanup: 2069 2070 /* Free Keygen_cfg */ 2071 if (keygen_cfg.ext_ctrl_sel_info != NULL) { 2072 sal_free(keygen_cfg.ext_ctrl_sel_info); 2073 keygen_cfg.ext_ctrl_sel_info = NULL; 2074 } 2075 2076 /* Move to next state */ 2077 ftg_keygen_md->state_rv = rv; 2078 ftg_keygen_md->prev_state = ftg_keygen_md->state; 2079 if (BCM_FAILURE(rv)) { 2080 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 2081 } else { 2082 skey_keygen_md->keygen_mode = keygen_mode; 2083 skey_keygen_md->num_parts = keygen_cfg.num_parts; 2084 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS; 2085 } 2086 2087 return rv; 2088 } 2089 2090 /* 2091 * Function: 2092 * _field_hx5_ftg_flowcheck_oper_process 2093 * 2094 * Purpose: 2095 * Process Session data keygen_oper for flowcheck info. 2096 * 2097 * Parameters: 2098 * unit - (IN) BCM device number. 2099 * qual_ext_offset_info - (IN) Qual-Extractor info 2100 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2101 * 2102 * Returns: 2103 * BCM_E_XXX 2104 */ 2105 STATIC int 2106 _field_hx5_ftg_flowcheck_oper_process( 2107 int unit, 2108 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info, 2109 _field_ft_group_keygen_md_t *ftg_keygen_md) 2110 { 2111 int rv = BCM_E_NONE; 2112 int idx = 0; 2113 int sd_idx = 0; 2114 int data_idx = 0; 2115 int q_idx = 0; 2116 int width = 0; 2117 int start_loc = 0; 2118 int temp_fc_idx = 0; 2119 int fc_idx = 0; 2120 bcmi_ft_alu_key_t *sdata_info_key = NULL; 2121 bcm_field_qualify_t qual; 2122 bcm_flowtracker_check_t check_id; 2123 bcmi_ft_group_alu_info_t *sdata_info = NULL; 2124 bcm_flowtracker_check_info_t fc_info; 2125 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 2126 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 2127 bcm_flowtracker_check_action_info_t action_info; 2128 2129 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 2130 sdata_info = ftg_keygen_md->keydata_oper_info.sdata_info; 2131 data_idx = ftg_keygen_md->keydata_oper_info.num_sdata_info; 2132 2133 for (idx = 0; idx < ftg_keygen_md->num_flowchecks; idx++) { 2134 2135 check_id = ftg_keygen_md->flowtracker_checks[idx]; 2136 bcm_flowtracker_check_info_t_init(&fc_info); 2137 rv = bcmi_ft_check_get(unit, check_id, &fc_info); 2138 BCM_IF_ERROR_RETURN(rv); 2139 2140 fc_idx = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id); 2141 2142 /* Search if flowcheck is already added in sdata_info */ 2143 for (sd_idx = 0; sd_idx < data_idx; sd_idx++) { 2144 temp_fc_idx = 2145 BCMI_FT_FLOWCHECKER_INDEX_GET(sdata_info[sd_idx].flowchecker_id); 2146 2147 if (temp_fc_idx == fc_idx) { 2148 break; 2149 } 2150 } 2151 /* If not found, use last and increment data_idx */ 2152 if (sd_idx == data_idx) { 2153 data_idx++; 2154 } 2155 2156 sdata_info[sd_idx].flowchecker_id = 2157 BCMI_FT_FLOWCHECKER_INDEX_SET(fc_idx, BCM_FT_IDX_TYPE_CHECK); 2158 2159 if (BCMI_FT_IDX_IS_2ND_CHECK(check_id)) { 2160 sdata_info[sd_idx].element_type2 = fc_info.param; 2161 sdata_info_key = &sdata_info[sd_idx].key2; 2162 } else { 2163 sdata_info[sd_idx].element_type1 = fc_info.param; 2164 sdata_info_key = &sdata_info[sd_idx].key1; 2165 } 2166 2167 pq_map = map_db->param_qual_map[fc_info.param]; 2168 2169 if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_FILL) { 2170 continue; 2171 } 2172 2173 if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) { 2174 sdata_info_key->location = 0; 2175 sdata_info_key->length = pq_map->width; 2176 sdata_info_key->is_alu = 2177 ((pq_map->flags & _FP_FT_TRACKING_PARAM_F_ALU_REQ) ? 1 : 0); 2178 } else { 2179 qual = pq_map->qual; 2180 for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) { 2181 if (qual_ext_offset_info->qid_arr[q_idx] != qual) { 2182 continue; 2183 } 2184 if (q_idx == qual_ext_offset_info->size) { 2185 BCM_IF_ERROR_RETURN(BCM_E_INTERNAL); 2186 } 2187 start_loc = width = 0; 2188 rv = _field_hx5_ftg_qual_offset_width_get(unit, 2189 &qual_ext_offset_info->offset_arr[q_idx], 2190 &start_loc, &width); 2191 BCM_IF_ERROR_RETURN(rv); 2192 2193 sdata_info_key->location = start_loc; 2194 sdata_info_key->length = width; 2195 sdata_info_key->is_alu = 1; 2196 } 2197 } 2198 2199 /* Set action key from primary flowcheck */ 2200 if (!BCMI_FT_IDX_IS_2ND_CHECK(check_id)) { 2201 bcm_flowtracker_check_action_info_t_init(&action_info); 2202 rv = bcm_esw_flowtracker_check_action_info_get(unit, 2203 check_id, &action_info); 2204 BCM_IF_ERROR_RETURN(rv); 2205 2206 if (action_info.param == bcmFlowtrackerTrackingParamTypeNone) { 2207 continue; 2208 } 2209 pq_map = map_db->param_qual_map[action_info.param]; 2210 if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) { 2211 continue; 2212 } 2213 2214 qual = pq_map->qual; 2215 for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) { 2216 if (qual_ext_offset_info->qid_arr[q_idx] != qual) { 2217 continue; 2218 } 2219 start_loc = width = 0; 2220 rv = _field_hx5_ftg_qual_offset_width_get(unit, 2221 &qual_ext_offset_info->offset_arr[q_idx], 2222 &start_loc, &width); 2223 BCM_IF_ERROR_RETURN(rv); 2224 2225 sdata_info[sd_idx].action_element_type = action_info.param; 2226 sdata_info[sd_idx].action_key.location = start_loc; 2227 sdata_info[sd_idx].action_key.length = width; 2228 sdata_info[sd_idx].action_key.is_alu = 1; 2229 } 2230 } 2231 } 2232 2233 ftg_keygen_md->keydata_oper_info.num_sdata_info = data_idx; 2234 2235 return rv; 2236 } 2237 2238 /* 2239 * Function: 2240 * _field_hx5_ftg_tracking_params_oper_process 2241 * 2242 * Purpose: 2243 * Process Session data keygen_oper for tracking params.. 2244 * 2245 * Parameters: 2246 * unit - (IN) BCM device number. 2247 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2248 * 2249 * Returns: 2250 * BCM_E_XXX 2251 */ 2252 STATIC int 2253 _field_hx5_ftg_tracking_params_oper_process( 2254 int unit, 2255 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info, 2256 _field_ft_group_keygen_md_t *ftg_keygen_md) 2257 { 2258 int rv = BCM_E_NONE; 2259 int width = 0; 2260 int idx = 0; 2261 int data_idx = 0; 2262 int q_idx = 0; 2263 int start_bit = 0; 2264 uint16 param = 0; 2265 bcm_field_qualify_t qual; 2266 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 2267 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 2268 _field_ft_group_keygen_oper_info_t *oper_info = NULL; 2269 bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL; 2270 2271 oper_info = &ftg_keygen_md->keydata_oper_info; 2272 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 2273 2274 data_idx = oper_info->num_sdata_info; 2275 idx = 0; 2276 while(idx < ftg_keygen_md->num_tracking_params) { 2277 2278 tracking_param_info = &ftg_keygen_md->tracking_params_info[idx]; 2279 2280 if (tracking_param_info->flags & 2281 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) { 2282 idx++; 2283 continue; 2284 } 2285 2286 param = tracking_param_info->param; 2287 pq_map = map_db->param_qual_map[param]; 2288 2289 if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_FILL) { 2290 idx++; 2291 continue; 2292 } 2293 2294 if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) { 2295 oper_info->sdata_info[data_idx].key1.location = 0; 2296 oper_info->sdata_info[data_idx].key1.is_alu = 2297 ((pq_map->flags & _FP_FT_TRACKING_PARAM_F_ALU_REQ) ? 1 : 0); 2298 oper_info->sdata_info[data_idx].key1.length = pq_map->width; 2299 oper_info->sdata_info[data_idx].element_type1 = param; 2300 oper_info->sdata_info[data_idx].flowchecker_id = 0; 2301 data_idx++; 2302 } else { 2303 2304 qual = pq_map->qual; 2305 for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) { 2306 if (qual_ext_offset_info->qid_arr[q_idx] != qual) { 2307 continue; 2308 } 2309 start_bit = width = 0; 2310 rv = _field_hx5_ftg_qual_offset_width_get(unit, 2311 &qual_ext_offset_info->offset_arr[q_idx], 2312 &start_bit, &width); 2313 BCMI_IF_ERROR_CLEANUP(rv); 2314 2315 oper_info->sdata_info[data_idx].key1.location = start_bit; 2316 oper_info->sdata_info[data_idx].key1.is_alu = 0; 2317 oper_info->sdata_info[data_idx].key1.length = width; 2318 oper_info->sdata_info[data_idx].element_type1 = param; 2319 oper_info->sdata_info[data_idx].flowchecker_id = 0; 2320 data_idx++; 2321 } 2322 } 2323 idx++; 2324 } 2325 2326 oper_info->num_sdata_info = data_idx; 2327 2328 cleanup: 2329 2330 return rv; 2331 } 2332 2333 /* 2334 * Function: 2335 * _field_hx5_ftg_alu_data_oper_process 2336 * 2337 * Purpose: 2338 * Output of session data keygen is processed for ALU data 2339 * and results are saved in extractors codes. 2340 * 2341 * Parameters: 2342 * unit - (IN) BCM device number. 2343 * qual_ext_offset_info - (IN) Qual-Extractor info. 2344 * ext_codes - (OUT) extractor codes. 2345 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2346 * 2347 * Returns: 2348 * BCM_E_XXX 2349 */ 2350 STATIC int 2351 _field_hx5_ftg_alu_data_oper_process( 2352 int unit, 2353 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info, 2354 _field_ft_keygen_ext_codes_t *ext_codes, 2355 _field_ft_group_keygen_md_t *ftg_keygen_md) 2356 { 2357 int rv = BCM_E_NONE; 2358 int bit = 0; 2359 int q_idx = 0; 2360 int index = 0; 2361 int shift = 0; 2362 int width = 0; 2363 int offset = 0; 2364 int location = 0; 2365 int start_loc = 0; 2366 int qual_width = 0; 2367 uint16 param = 0; 2368 uint32 type_mask[1] = {0}; 2369 bcm_field_qualify_t qual; 2370 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 2371 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 2372 _field_ft_tracking_alu_data_info_t *alu_data_info = NULL; 2373 _field_ft_keygen_type_c_ext_t *type_c_extractors = NULL; 2374 2375 if ((qual_ext_offset_info == NULL) || 2376 (ext_codes == NULL) || (ftg_keygen_md == NULL)) { 2377 return BCM_E_PARAM; 2378 } 2379 2380 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 2381 type_c_extractors = &ext_codes->type_c_extractors; 2382 shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START; 2383 2384 for (index = 0; index < ftg_keygen_md->num_alu_data; index++) { 2385 alu_data_info = &ftg_keygen_md->alu_data_info[index]; 2386 param = alu_data_info->param; 2387 offset = alu_data_info->offset; 2388 width = alu_data_info->width; 2389 pq_map = map_db->param_qual_map[param + shift]; 2390 qual = pq_map->qual; 2391 2392 for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) { 2393 if (qual_ext_offset_info->qid_arr[q_idx] != qual) { 2394 continue; 2395 } 2396 start_loc = qual_width = 0; 2397 rv = _field_hx5_ftg_qual_offset_width_get(unit, 2398 &qual_ext_offset_info->offset_arr[q_idx], 2399 &start_loc, &qual_width); 2400 BCM_IF_ERROR_RETURN(rv); 2401 2402 if ((start_loc + width) > qual_width) { 2403 return BCM_E_INTERNAL; 2404 } 2405 location = start_loc + pq_map->start_loc; 2406 2407 for (bit = 0; bit < width; bit++) { 2408 type_c_extractors->l1_e1_sel[offset + bit] = location + bit; 2409 } 2410 SHR_BITSET_RANGE(&type_mask[0], offset, width); 2411 } 2412 } 2413 2414 ext_codes->type_c_mask.mask = type_mask[0]; 2415 2416 return BCM_E_NONE; 2417 } 2418 2419 /* 2420 * Function: 2421 * _field_hx5_ftg_keygen_data_oper_process 2422 * 2423 * Purpose: 2424 * Process Session data keygen_oper. 2425 * 2426 * Parameters: 2427 * unit - (IN) BCM device number. 2428 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2429 * 2430 * Returns: 2431 * BCM_E_XXX 2432 */ 2433 STATIC int 2434 _field_hx5_ftg_keygen_data_oper_process( 2435 int unit, 2436 _field_ft_group_keygen_md_t *ftg_keygen_md) 2437 { 2438 int rv = BCM_E_NONE; 2439 int num_sdata_info = 0; 2440 _field_ft_keygen_ext_codes_t ext_codes; 2441 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info = NULL; 2442 _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL; 2443 _field_ft_group_keygen_oper_info_t *oper_info = NULL; 2444 2445 /* Get qualifier/extractors hw info from keygen_oper */ 2446 rv = _field_hx5_ftg_qual_ext_hw_info_get(unit, 2447 0, ftg_keygen_md, &qual_ext_offset_info, &ext_codes); 2448 2449 if (BCM_FAILURE(rv) || (qual_ext_offset_info == NULL)) { 2450 goto cleanup; 2451 } 2452 2453 oper_info = &ftg_keygen_md->keydata_oper_info; 2454 sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md; 2455 2456 /* Allocate memory for flowtracker group session data db */ 2457 num_sdata_info = sdata_keygen_md->max_qual_info_alloc; 2458 _FP_XGS3_ALLOC(oper_info->sdata_info, 2459 num_sdata_info * sizeof(bcmi_ft_group_alu_info_t), 2460 "session data info"); 2461 if (oper_info->sdata_info == NULL) { 2462 BCMI_IF_ERROR_CLEANUP(BCM_E_MEMORY); 2463 } 2464 2465 /* Prepare Session data from flowchecks */ 2466 if (BCM_SUCCESS(rv)) { 2467 rv = _field_hx5_ftg_flowcheck_oper_process(unit, 2468 qual_ext_offset_info, ftg_keygen_md); 2469 } 2470 2471 /* Prepare Session data from tracking params */ 2472 if (BCM_SUCCESS(rv)) { 2473 rv = _field_hx5_ftg_tracking_params_oper_process(unit, 2474 qual_ext_offset_info, ftg_keygen_md); 2475 } 2476 2477 /* Process alu data oper info */ 2478 if (BCM_SUCCESS(rv)) { 2479 rv = _field_hx5_ftg_alu_data_oper_process(unit, 2480 qual_ext_offset_info, &ext_codes, ftg_keygen_md); 2481 } 2482 2483 /* Encode Session Data extractors. */ 2484 if (BCM_SUCCESS(rv)) { 2485 rv = _bcm_field_hx5_ft_extractors_encode(unit, &ext_codes, 2486 &oper_info->sdata_ext_count, &oper_info->sdata_ext_info); 2487 } 2488 2489 cleanup: 2490 2491 if (qual_ext_offset_info != NULL) { 2492 (void) _field_hx5_ft_qual_ext_offset_info_free(unit, 2493 &qual_ext_offset_info); 2494 } 2495 2496 /* Move to next state */ 2497 ftg_keygen_md->state_rv = rv; 2498 ftg_keygen_md->prev_state = ftg_keygen_md->state; 2499 if (BCM_FAILURE(rv)) { 2500 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 2501 } else { 2502 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS; 2503 } 2504 2505 return rv; 2506 } 2507 2508 /* 2509 * Function: 2510 * _field_hx5_ftg_keygen_key_oper_process 2511 * 2512 * Purpose: 2513 * Process Session data keygen_oper. 2514 * 2515 * Parameters: 2516 * unit - (IN) BCM device number. 2517 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2518 * 2519 * Returns: 2520 * BCM_E_XXX 2521 */ 2522 STATIC int 2523 _field_hx5_ftg_keygen_key_oper_process( 2524 int unit, 2525 _field_ft_group_keygen_md_t *ftg_keygen_md) 2526 { 2527 int rv = BCM_E_NONE; 2528 int idx = 0; 2529 int key_idx = 0; 2530 int qual_idx = 0; 2531 int start_bit = 0; 2532 int width = 0; 2533 int num_skey_info = 0; 2534 uint16 param = 0; 2535 bcm_field_qualify_t qual; 2536 _field_ft_keygen_ext_codes_t ext_codes; 2537 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 2538 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 2539 _field_ft_group_keygen_oper_info_t *oper_info = NULL; 2540 _field_ft_group_keydata_keygen_md_t *skey_keygen_md = NULL; 2541 _field_ft_qual_ext_offset_info_t *qual_ext_offset_info = NULL; 2542 bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL; 2543 2544 /* Get qualifier/extractors hw info from keygen_oper */ 2545 rv = _field_hx5_ftg_qual_ext_hw_info_get(unit, 2546 1, ftg_keygen_md, &qual_ext_offset_info, &ext_codes); 2547 2548 if (BCM_FAILURE(rv) || (qual_ext_offset_info == NULL)) { 2549 goto cleanup; 2550 } 2551 2552 oper_info = &ftg_keygen_md->keydata_oper_info; 2553 map_db = ftg_keygen_md->ft_info->param_qual_map_db; 2554 skey_keygen_md = &ftg_keygen_md->skey_keygen_md; 2555 2556 /* Allocate memory for flowtracker group session key db */ 2557 num_skey_info = skey_keygen_md->max_qual_info_alloc; 2558 _FP_XGS3_ALLOC(oper_info->skey_info, 2559 num_skey_info * sizeof(bcmi_ft_group_alu_info_t), 2560 "session key info"); 2561 if (oper_info->skey_info == NULL) { 2562 BCMI_IF_ERROR_CLEANUP(BCM_E_MEMORY); 2563 } 2564 2565 key_idx = 0; 2566 while(idx < ftg_keygen_md->num_tracking_params) { 2567 2568 tracking_param_info = &ftg_keygen_md->tracking_params_info[idx]; 2569 2570 /* Skip if tracking param is not Key. */ 2571 if (!(tracking_param_info->flags & 2572 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY)) { 2573 idx++; 2574 continue; 2575 } 2576 2577 param = tracking_param_info->param; 2578 pq_map = map_db->param_qual_map[param]; 2579 qual = pq_map->qual; 2580 2581 for (qual_idx = 0; qual_idx < qual_ext_offset_info->size; qual_idx++) { 2582 if (qual_ext_offset_info->qid_arr[qual_idx] != qual) { 2583 continue; 2584 } 2585 start_bit = width = 0; 2586 rv = _field_hx5_ftg_qual_offset_width_get(unit, 2587 &qual_ext_offset_info->offset_arr[qual_idx], 2588 &start_bit, &width); 2589 BCMI_IF_ERROR_CLEANUP(rv); 2590 2591 oper_info->skey_info[key_idx].key1.location = start_bit; 2592 oper_info->skey_info[key_idx].key1.is_alu = 0; 2593 oper_info->skey_info[key_idx].key1.length = width; 2594 oper_info->skey_info[key_idx].element_type1 = param; 2595 oper_info->skey_info[key_idx].flowchecker_id = 0; 2596 key_idx++; 2597 } 2598 idx++; 2599 } 2600 oper_info->num_skey_info = key_idx; 2601 if (skey_keygen_md->keygen_mode == BCMI_KEYGEN_MODE_SINGLE) { 2602 oper_info->mode = bcmiFtGroupModeSingle; 2603 } else { 2604 oper_info->mode = bcmiFtGroupModeDouble; 2605 } 2606 2607 /* Encode Session Key extractors. */ 2608 rv = _bcm_field_hx5_ft_extractors_encode(unit, &ext_codes, 2609 &oper_info->skey_ext_count, &oper_info->skey_ext_info); 2610 2611 cleanup: 2612 2613 if (qual_ext_offset_info != NULL) { 2614 (void) _field_hx5_ft_qual_ext_offset_info_free(unit, 2615 &qual_ext_offset_info); 2616 } 2617 2618 /* Move to next state */ 2619 ftg_keygen_md->state_rv = rv; 2620 ftg_keygen_md->prev_state = ftg_keygen_md->state; 2621 if (BCM_FAILURE(rv)) { 2622 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 2623 } else { 2624 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_OPER_SAVE; 2625 } 2626 2627 return rv; 2628 } 2629 2630 /* 2631 * Function: 2632 * _field_hx5_ftg_keygen_oper_save 2633 * 2634 * Purpose: 2635 * Save FT Group Session Key/Data to FT Group DB. 2636 * 2637 * Parameters: 2638 * unit - (IN) BCM device number. 2639 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2640 * 2641 * Returns: 2642 * BCM_E_PARAM - Invalid inputs. 2643 * BCM_E_MEMORY - Failed to allocate memory. 2644 * BCM_E_NONE - Success. 2645 */ 2646 STATIC int 2647 _field_hx5_ftg_keygen_oper_save( 2648 int unit, 2649 _field_ft_group_keygen_md_t *ftg_keygen_md) 2650 { 2651 int rv = BCM_E_NONE; 2652 bcm_flowtracker_group_t ft_group_id; 2653 _field_ft_group_keygen_oper_info_t *oper_info = NULL; 2654 2655 /* Dump Session Key and Session Data */ 2656 _field_hx5_ftg_keygen_oper_dump(unit, ftg_keygen_md); 2657 2658 if (ftg_keygen_md->save_op == FALSE) { 2659 rv = BCM_E_NONE; 2660 goto cleanup; 2661 } 2662 2663 ft_group_id = ftg_keygen_md->ft_group_id; 2664 oper_info = &ftg_keygen_md->keydata_oper_info; 2665 2666 rv = bcmi_esw_ft_group_extraction_mode_set(unit, 2667 1, ft_group_id, oper_info->mode); 2668 2669 if (BCM_SUCCESS(rv)) { 2670 rv = bcmi_esw_ft_group_extraction_mode_set(unit, 2671 0, ft_group_id, oper_info->mode); 2672 } 2673 2674 if (BCM_SUCCESS(rv) && (oper_info->skey_info != NULL)) { 2675 rv = bcmi_esw_ft_group_extraction_alu_info_set(unit, ft_group_id, 2676 1, oper_info->num_skey_info, oper_info->skey_info); 2677 } 2678 2679 if (BCM_SUCCESS(rv) && (oper_info->skey_ext_info != NULL)) { 2680 rv = bcmi_esw_ft_group_extraction_hw_info_set(unit, ft_group_id, 2681 1, oper_info->skey_ext_count, oper_info->skey_ext_info); 2682 } 2683 2684 if (BCM_SUCCESS(rv) && (oper_info->sdata_info != NULL)) { 2685 rv = bcmi_esw_ft_group_extraction_alu_info_set(unit, ft_group_id, 2686 0, oper_info->num_sdata_info, oper_info->sdata_info); 2687 } 2688 2689 if (BCM_SUCCESS(rv) && (oper_info->sdata_ext_info != NULL)) { 2690 rv = bcmi_esw_ft_group_extraction_hw_info_set(unit, ft_group_id, 2691 0, oper_info->sdata_ext_count, oper_info->sdata_ext_info); 2692 } 2693 2694 cleanup: 2695 2696 ftg_keygen_md->state_rv = rv; 2697 ftg_keygen_md->prev_state = ftg_keygen_md->state; 2698 ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END; 2699 2700 return rv; 2701 } 2702 2703 /* 2704 * Function: 2705 * _field_hx5_ftg_keygen_end 2706 * 2707 * Purpose: 2708 * Deallocate memories in FT Group Keygen metadata. 2709 * 2710 * Parameters: 2711 * unit - (IN) BCM device number. 2712 * ftg_keygen_md - (INOUT) FT Group Keygen metadata. 2713 * 2714 * Returns: 2715 * BCM_E_PARAM - Invalid inputs. 2716 * BCM_E_MEMORY - Failed to allocate memory. 2717 * BCM_E_NONE - Success. 2718 */ 2719 STATIC int 2720 _field_hx5_ftg_keygen_end( 2721 int unit, 2722 _field_ft_group_keygen_md_t *ftg_keygen_md) 2723 { 2724 if (ftg_keygen_md->tracking_params_info != NULL) { 2725 sal_free(ftg_keygen_md->tracking_params_info); 2726 ftg_keygen_md->tracking_params_info = NULL; 2727 } 2728 2729 if (ftg_keygen_md->flowtracker_checks != NULL) { 2730 sal_free(ftg_keygen_md->flowtracker_checks); 2731 ftg_keygen_md->flowtracker_checks = NULL; 2732 } 2733 2734 if (ftg_keygen_md->skey_keygen_md.qual_info_arr != NULL) { 2735 sal_free(ftg_keygen_md->skey_keygen_md.qual_info_arr); 2736 ftg_keygen_md->skey_keygen_md.qual_info_arr = NULL; 2737 } 2738 2739 if (ftg_keygen_md->sdata_keygen_md.qual_info_arr != NULL) { 2740 sal_free(ftg_keygen_md->sdata_keygen_md.qual_info_arr); 2741 ftg_keygen_md->sdata_keygen_md.qual_info_arr = NULL; 2742 } 2743 2744 (void) bcmi_keygen_oper_free(unit, 2745 ftg_keygen_md->skey_keygen_md.num_parts, 2746 &ftg_keygen_md->skey_keygen_md.keygen_oper); 2747 2748 (void) bcmi_keygen_oper_free(unit, 2749 ftg_keygen_md->sdata_keygen_md.num_parts, 2750 &ftg_keygen_md->sdata_keygen_md.keygen_oper); 2751 2752 if (ftg_keygen_md->keydata_oper_info.sdata_info != NULL) { 2753 sal_free(ftg_keygen_md->keydata_oper_info.sdata_info); 2754 ftg_keygen_md->keydata_oper_info.sdata_info = NULL; 2755 } 2756 2757 if (ftg_keygen_md->keydata_oper_info.skey_info != NULL) { 2758 sal_free(ftg_keygen_md->keydata_oper_info.skey_info); 2759 ftg_keygen_md->keydata_oper_info.skey_info = NULL; 2760 } 2761 2762 if (ftg_keygen_md->keydata_oper_info.skey_ext_info != NULL) { 2763 sal_free(ftg_keygen_md->keydata_oper_info.skey_ext_info); 2764 ftg_keygen_md->keydata_oper_info.skey_ext_info = NULL; 2765 } 2766 2767 if (ftg_keygen_md->keydata_oper_info.sdata_ext_info != NULL) { 2768 sal_free(ftg_keygen_md->keydata_oper_info.sdata_ext_info); 2769 ftg_keygen_md->keydata_oper_info.sdata_ext_info = NULL; 2770 } 2771 2772 return (ftg_keygen_md->state_rv); 2773 } 2774 2775 /* 2776 * Function: 2777 * _field_hx5_ftg_keygen_process 2778 * 2779 * Purpose: 2780 * Gernerate session key, session data and alu data extractions 2781 * corresponding to FT Group tracking params and flowchecks. 2782 * 2783 * Parameters: 2784 * unit - (IN) BCM device number. 2785 * ftg_keygen_md - (IN) FT Group Keygen metadata. 2786 * 2787 * Returns: 2788 * BCM_E_XXX 2789 */ 2790 STATIC int 2791 _field_hx5_ftg_keygen_process( 2792 int unit, 2793 _field_ft_group_keygen_md_t *ftg_keygen_md) 2794 { 2795 int rv = BCM_E_NONE; 2796 2797 do { 2798 switch(ftg_keygen_md->state) { 2799 case _FIELD_FT_GROUP_KEYGEN_START: 2800 rv = _field_hx5_ftg_keygen_initialize(unit, ftg_keygen_md); 2801 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2802 "Completed state->" 2803 "_FIELD_FT_GROUP_KEYGEN_START ret=%d\r\n"), 2804 ftg_keygen_md->state_rv)); 2805 break; 2806 case _FIELD_FT_GROUP_KEYGEN_CFG_ALLOC: 2807 rv = _field_hx5_ftg_keygen_cfg_alloc(unit, ftg_keygen_md); 2808 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2809 "Completed state->" 2810 "_FIELD_FT_GROUP_KEYGEN_CFG_ALLOC ret=%d\r\n"), 2811 ftg_keygen_md->state_rv)); 2812 break; 2813 case _FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD: 2814 rv = _field_hx5_ftg_keygen_cfg_alu_qual_add(unit, ftg_keygen_md); 2815 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2816 "Completed state->" 2817 "_FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD ret=%d\r\n"), 2818 ftg_keygen_md->state_rv)); 2819 break; 2820 case _FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD: 2821 rv = _field_hx5_ftg_keygen_cfg_flowcheck_qual_add(unit, ftg_keygen_md); 2822 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2823 "Completed state->" 2824 "_FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD ret=%d\r\n"), 2825 ftg_keygen_md->state_rv)); 2826 break; 2827 case _FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD: 2828 rv = _field_hx5_ftg_keygen_cfg_data_key_qual_add(unit, ftg_keygen_md); 2829 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2830 "Completed state->" 2831 "_FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD ret=%d\r\n"), 2832 ftg_keygen_md->state_rv)); 2833 break; 2834 case _FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST: 2835 rv = _field_hx5_ftg_keygen_cfg_data_qual_adjust(unit, ftg_keygen_md); 2836 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2837 "Completed state->" 2838 "_FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST ret=%d\r\n"), 2839 ftg_keygen_md->state_rv)); 2840 break; 2841 case _FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST: 2842 rv = _field_hx5_ftg_keygen_cfg_key_qual_adjust(unit, ftg_keygen_md); 2843 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2844 "Completed state->" 2845 "_FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST ret=%d\r\n"), 2846 ftg_keygen_md->state_rv)); 2847 break; 2848 case _FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT: 2849 rv = _field_hx5_ftg_keygen_data_oper_extract(unit, ftg_keygen_md); 2850 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2851 "Completed state->" 2852 "_FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT ret=%d\r\n"), 2853 ftg_keygen_md->state_rv)); 2854 break; 2855 case _FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT: 2856 rv = _field_hx5_ftg_keygen_key_oper_extract(unit, ftg_keygen_md); 2857 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2858 "Completed state->" 2859 "_FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT ret=%d\r\n"), 2860 ftg_keygen_md->state_rv)); 2861 break; 2862 case _FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS: 2863 rv = _field_hx5_ftg_keygen_data_oper_process(unit, ftg_keygen_md); 2864 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2865 "Completed state->" 2866 "_FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS ret=%d\r\n"), 2867 ftg_keygen_md->state_rv)); 2868 break; 2869 case _FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS: 2870 rv = _field_hx5_ftg_keygen_key_oper_process(unit, ftg_keygen_md); 2871 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2872 "Completed state->" 2873 "_FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS ret=%d\r\n"), 2874 ftg_keygen_md->state_rv)); 2875 break; 2876 case _FIELD_FT_GROUP_KEYGEN_OPER_SAVE: 2877 rv = _field_hx5_ftg_keygen_oper_save(unit, ftg_keygen_md); 2878 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2879 "Completed state->" 2880 "_FIELD_FT_GROUP_KEYGEN_OPER_SAVE ret=%d\r\n"), 2881 ftg_keygen_md->state_rv)); 2882 break; 2883 case _FIELD_FT_GROUP_KEYGEN_END: 2884 rv = _field_hx5_ftg_keygen_end(unit, ftg_keygen_md); 2885 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2886 "Completed state->" 2887 "_FIELD_FT_GROUP_KEYGEN_END ret=%d\r\n"), 2888 ftg_keygen_md->state_rv)); 2889 return rv; 2890 default: 2891 /* Not a valid case */ 2892 return rv; 2893 } 2894 } while(1); 2895 2896 return rv; 2897 } 2898 2899 2900 /* 2901 * Function: 2902 * _bcm_field_ft_entry_traverse 2903 * 2904 * Purpose: 2905 * Traverse fp entries in flowtracker stage and 2906 * call callback to process the entry. 2907 * 2908 * Parameters: 2909 * unit - (IN) BCM device number. 2910 * id - (IN) Flowtracekr group. 2911 * cb_f - (IN) Callback function pointer 2912 * user_data1 - (IN) user data 1 2913 * user_data2 - (IN) user data 2 2914 * 2915 * Returns: 2916 * BCM_E_XXX 2917 */ 2918 STATIC int 2919 _bcm_field_ftfp_entry_traverse( 2920 int unit, 2921 bcm_flowtracker_group_t id, 2922 _bcm_field_ft_entry_traverse_cb cb_f, 2923 void *user_data1, 2924 void *user_data2) 2925 { 2926 int rv = BCM_E_NONE; 2927 int eidx = 0; 2928 int entries = 0; 2929 _field_group_t *fg = NULL; 2930 _field_control_t *fc = NULL; 2931 bcm_field_entry_t *entry_ids = NULL; 2932 2933 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 2934 2935 /* Iterate FTFP Groups */ 2936 for (fg = fc->groups; fg != NULL; fg = fg->next) { 2937 if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 2938 continue; 2939 } 2940 2941 rv = bcm_esw_field_entry_multi_get(unit, fg->gid, 0, NULL, &entries); 2942 2943 if (BCM_SUCCESS(rv)) { 2944 entry_ids = sal_alloc(entries * sizeof (bcm_field_entry_t), 2945 "Entry ID array"); 2946 2947 if (entry_ids == NULL) { 2948 rv = BCM_E_MEMORY; 2949 break; 2950 } else { 2951 rv = bcm_esw_field_entry_multi_get(unit, 2952 fg->gid, entries, entry_ids, &entries); 2953 2954 if (BCM_SUCCESS(rv)) { 2955 /* Iterate FTFP Entries */ 2956 for (eidx = 0; eidx < entries; eidx++) { 2957 /* Call callback */ 2958 rv = cb_f(unit, entry_ids[eidx], 2959 id, user_data1, user_data2); 2960 if (BCM_FAILURE(rv)) { 2961 break; 2962 } 2963 } 2964 } 2965 sal_free(entry_ids); 2966 entry_ids = NULL; 2967 } 2968 } 2969 } 2970 2971 return (rv); 2972 } 2973 2974 /* 2975 * Function: 2976 * _bcm_field_ft_qual_config_get 2977 * 2978 * Purpose: 2979 * Get Qualifier config info from Qual Cfg Info Db. 2980 * 2981 * Parameters: 2982 * unit - (IN) BCM device number. 2983 * qual_cfg_info_db - (IN) Qualifier cfg info db 2984 * qual - (IN) Qualifier 2985 * offset - (OUT) Offset of Qualifier in L0 Bus 2986 * Width - (OUT) Width of Qualifier in L0 Bus 2987 * 2988 * Returns: 2989 * BCM_E_INTERNAL - Incoreect Input 2990 * BCM_E_NONE - Success. 2991 * Notes: 2992 * This function is only valid if all offets of qualifier 2993 * are consecutive and only one instance. 2994 */ 2995 STATIC int 2996 _bcm_field_ft_qual_config_get(int unit, 2997 bcmi_keygen_qual_cfg_info_db_t *db, 2998 bcm_field_qualify_t qual, 2999 uint32 *offset, 3000 uint32 *width) 3001 { 3002 uint8 num_chunks; 3003 uint8 chunk = 0; 3004 uint16 temp_width = 0; 3005 uint16 temp_offset = 0; 3006 bcmi_keygen_qual_offset_cfg_t *e_params = NULL; 3007 bcmi_keygen_qual_cfg_t *qual_cfg_arr = NULL; 3008 bcmi_keygen_qual_cfg_info_t *qual_cfg_info = NULL; 3009 3010 if (db == NULL) { 3011 return BCM_E_INTERNAL; 3012 } 3013 3014 qual_cfg_info = db->qual_cfg_info[qual]; 3015 qual_cfg_arr = qual_cfg_info->qual_cfg_arr; 3016 3017 if (qual_cfg_arr == NULL) { 3018 return BCM_E_INTERNAL; 3019 } 3020 3021 num_chunks = qual_cfg_arr->num_chunks; 3022 3023 for (chunk = 0; chunk < num_chunks; chunk++) { 3024 e_params = &qual_cfg_arr->e_params[chunk]; 3025 3026 if (chunk == 0) { 3027 temp_offset = e_params->offset; 3028 } 3029 3030 temp_width += e_params->width; 3031 } 3032 3033 *offset = temp_offset; 3034 *width = temp_width; 3035 3036 return BCM_E_NONE; 3037 } 3038 3039 /* 3040 * Function: 3041 * _field_hx5_ft_normalize_format_set 3042 * 3043 * Purpose: 3044 * Set normalization format for given qualifier-pair. 3045 * 3046 * Parameters: 3047 * unit - (IN) BCM device number. 3048 * index - (IN) Index in norm_qualifiers. 3049 * norm_qualifier - (IN) Normalization qualifiers list. 3050 * max_norm_commands - (IN) Maximum norm commands that can be 3051 * configured in hw memory. 3052 * norm_cmds_buf - (IN/OUT) Buffer for norm commands format. 3053 * valid_commands - (IN/OUT) valid commands in norm_cmds_bufs. 3054 * 3055 * Returns: 3056 * BCM_E_XXX 3057 */ 3058 int 3059 _field_hx5_ft_normalize_format_set(int unit, 3060 bcm_flowtracker_tracking_param_info_t **norm_tracking_params_info, 3061 int max_norm_commands, 3062 uint32 *norm_cmds_buf, 3063 int *valid_commands) 3064 { 3065 uint32 comm_idx = 0; 3066 uint32 src_offset = 0; 3067 uint32 dst_offset = 0; 3068 uint32 src_width = 0; 3069 uint32 dst_width = 0; 3070 bcm_field_qualify_t src_qual; 3071 bcm_field_qualify_t dst_qual; 3072 _field_stage_t *stage_fc = NULL; 3073 bcm_flowtracker_tracking_param_type_t param; 3074 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 3075 bcmi_keygen_qual_cfg_info_db_t *qual_cfg_info_db = NULL; 3076 3077 if (*valid_commands >= max_norm_commands) { 3078 LOG_ERROR(BSL_LS_BCM_FP, 3079 (BSL_META_U(unit, "All Keys in tracking params" 3080 " of flowtracker group cannot be" 3081 " normalized\n\r"))); 3082 return BCM_E_CONFIG; 3083 } 3084 3085 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 3086 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 3087 3088 map_db = stage_fc->ft_info->param_qual_map_db; 3089 qual_cfg_info_db = stage_fc->ft_info->flow_key_qual_cfg; 3090 3091 /* Get Field Qualifiers */ 3092 param = norm_tracking_params_info[0]->param; 3093 src_qual = map_db->param_qual_map[param]->qual; 3094 param = norm_tracking_params_info[1]->param; 3095 dst_qual = map_db->param_qual_map[param]->qual; 3096 3097 BCM_IF_ERROR_RETURN(_bcm_field_ft_qual_config_get(unit, 3098 qual_cfg_info_db, src_qual, &src_offset, &src_width)); 3099 BCM_IF_ERROR_RETURN(_bcm_field_ft_qual_config_get(unit, 3100 qual_cfg_info_db, dst_qual, &dst_offset, &dst_width)); 3101 3102 /* Validate alignemnt */ 3103 if (((src_offset % 16) != 0) || ((dst_offset % 16) != 0) || 3104 ((src_width % 16) != 0) || (dst_width != src_width) || 3105 (src_width == 0) || (dst_width == 0)) { 3106 return BCM_E_CONFIG; 3107 } 3108 src_offset /= 16; 3109 dst_offset /= 16; 3110 /* Formula for size is (n + 1)*2B */ 3111 src_width = (src_width - 1) / 16; 3112 3113 comm_idx = *valid_commands; 3114 3115 soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt, 3116 &norm_cmds_buf[comm_idx], NORMALIZE_ENABLEf, 1); 3117 3118 soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt, 3119 &norm_cmds_buf[comm_idx], NORMALIZE_SRC_START_OFFSETf, 3120 src_offset); 3121 3122 soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt, 3123 &norm_cmds_buf[comm_idx], NORMALIZE_DST_START_OFFSETf, 3124 dst_offset); 3125 3126 soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt, 3127 &norm_cmds_buf[comm_idx], NORMALIZE_SIZEf, src_width); 3128 3129 *valid_commands = comm_idx + 1; 3130 3131 return BCM_E_NONE; 3132 } 3133 3134 /* 3135 * Function: 3136 * _field_hx5_ft_normalize_controls_set 3137 * 3138 * Purpose: 3139 * Set normalize controls of FTFP policy table. 3140 * 3141 * Parameters: 3142 * unit - (IN) BCM device number. 3143 * id - (IN) Flowtracker Group Id 3144 * policy_mem - (IN) Policy Memory 3145 * enable - (IN) Normalization Enable/Disable 3146 * data_buf - (IN/OUT) Policy memory buffer 3147 * 3148 * Returns: 3149 * BCM_E_XXX 3150 */ 3151 int 3152 _field_hx5_ft_normalize_controls_set( 3153 int unit, 3154 bcm_flowtracker_group_t id, 3155 soc_mem_t policy_mem, 3156 uint32 enable, 3157 uint32 *data_buf) 3158 { 3159 int idx = 0; 3160 int rv = BCM_E_NONE; 3161 int valid_commands = 0; 3162 int num_tracking_params = 0; 3163 uint32 norm_cmds_buf[4] = {0}; 3164 bcm_flowtracker_tracking_param_info_t *tracking_params_info = NULL; 3165 bcm_flowtracker_tracking_param_info_t 3166 *norm_tracking_params_info[BCMI_FT_GROUP_NORM_TRACKING_PARAMS] = {NULL}; 3167 3168 /* Normalize Commands */ 3169 soc_field_t normalize_cmds_f[] = { 3170 NORMALIZE_0_COMMANDf, NORMALIZE_1_COMMANDf, 3171 NORMALIZE_2_COMMANDf, NORMALIZE_3_COMMANDf 3172 }; 3173 3174 /* If enable=FALSE, reset Normalize commands */ 3175 if (enable == 0) { 3176 for (idx = 0; idx < COUNTOF(normalize_cmds_f); idx++) { 3177 if (SOC_MEM_FIELD_VALID(unit, policy_mem, normalize_cmds_f[idx])) { 3178 soc_mem_field_set(unit, policy_mem, (void *) data_buf, 3179 normalize_cmds_f[idx], &norm_cmds_buf[idx]); 3180 } 3181 } 3182 goto cleanup; 3183 } 3184 3185 /* Get number of tracking params from group template */ 3186 rv = bcm_esw_flowtracker_group_tracking_params_get(unit, 3187 id, 0, NULL, &num_tracking_params); 3188 BCMI_IF_ERROR_CLEANUP(rv); 3189 3190 /* Allocate memory for tracking params info */ 3191 _FP_XGS3_ALLOC(tracking_params_info, (num_tracking_params * \ 3192 sizeof(bcm_flowtracker_tracking_param_info_t)), 3193 "tracking params info"); 3194 if (tracking_params_info == NULL) { 3195 rv = BCM_E_MEMORY; 3196 BCMI_IF_ERROR_CLEANUP(rv); 3197 } 3198 3199 /* Read tracking params info */ 3200 rv = bcm_esw_flowtracker_group_tracking_params_get(unit, 3201 id, num_tracking_params, &tracking_params_info[0], 3202 &num_tracking_params); 3203 BCMI_IF_ERROR_CLEANUP(rv); 3204 3205 /* Get tracking params for normalization */ 3206 rv = bcmi_ft_group_norm_tracking_params_info_get(unit, 3207 id, &norm_tracking_params_info[0]); 3208 BCMI_IF_ERROR_CLEANUP(rv); 3209 3210 /* Normalize if both param in the pair are present */ 3211 for (idx = 0; idx < BCMI_FT_GROUP_NORM_TRACKING_PARAMS; idx += 2) { 3212 if ((norm_tracking_params_info[idx] != NULL) && 3213 (norm_tracking_params_info[idx + 1] != NULL)) { 3214 rv = _field_hx5_ft_normalize_format_set(unit, 3215 &norm_tracking_params_info[idx], COUNTOF(normalize_cmds_f), 3216 norm_cmds_buf, &valid_commands); 3217 BCMI_IF_ERROR_CLEANUP(rv); 3218 } 3219 } 3220 3221 /* Set to policy table */ 3222 for (idx = 0; idx < valid_commands; idx++) { 3223 if (SOC_MEM_FIELD_VALID(unit, policy_mem, normalize_cmds_f[idx])) { 3224 soc_mem_field_set(unit, policy_mem, (void *) data_buf, 3225 normalize_cmds_f[idx], &norm_cmds_buf[idx]); 3226 } 3227 } 3228 3229 cleanup: 3230 3231 if (tracking_params_info != NULL) { 3232 sal_free(tracking_params_info); 3233 } 3234 3235 return rv; 3236 } 3237 3238 /* 3239 * Function: 3240 * _field_ftfp_entry_control_set 3241 * 3242 * Purpose: 3243 * Apply flowtracker group control to given entry if associated 3244 * action is given flowtracker group. 3245 * 3246 * Parameters: 3247 * unit - (IN) BCM device number. 3248 * entry - (IN) Field entry. 3249 * id - (IN) Flowtracker group Id 3250 * user_data1 - (IN) user data 1 3251 * user_data2 - (IN) user data 2 3252 * 3253 * Returns: 3254 * BCM_E_PARAM - If input parameters are not valid 3255 * BCM_E_MEMORY - If Failed to allocate required memory 3256 * BCM_E_NONE - Success. 3257 */ 3258 STATIC int 3259 _field_ftfp_entry_control_set( 3260 int unit, 3261 bcm_field_entry_t entry, 3262 bcm_flowtracker_group_t id, 3263 void *user_data1, 3264 void *user_data2) 3265 { 3266 int rv = BCM_E_NONE; 3267 int tcam_idx = 0; 3268 int param = 0; 3269 uint32 val = 0; 3270 uint32 ft_group_id_set = 0; 3271 uint32 action_ft_set = 0; 3272 uint32 ent_action_ft = 0; 3273 uint32 action_new_learn_set = 0; 3274 uint32 ent_action_new_learn = 0; 3275 uint32 cur_param = 0; 3276 _field_action_t *fa = NULL; 3277 _field_entry_t *f_ent = NULL; 3278 soc_field_t field = INVALIDf; 3279 soc_mem_t tcam_mem = INVALIDm; 3280 soc_mem_t policy_mem = INVALIDm; 3281 bcm_flowtracker_group_control_type_t control_type; 3282 bcm_flowtracker_group_t ent_flow_group_id = -1; 3283 uint32 data_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3284 3285 if ((user_data1 == NULL) || (user_data2 == NULL)) { 3286 return BCM_E_PARAM; 3287 } 3288 3289 control_type = *((bcm_flowtracker_group_control_type_t *) user_data1); 3290 param = *((int *)user_data2); 3291 3292 FP_LOCK(unit); 3293 3294 rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent); 3295 if (BCM_FAILURE(rv)) { 3296 FP_UNLOCK(unit); 3297 return (rv); 3298 } 3299 3300 /* Loop through all actions */ 3301 for (fa = f_ent->actions; 3302 (fa != NULL) && (fa->flags & _FP_ACTION_VALID); 3303 fa = fa->next) { 3304 switch(fa->action) { 3305 case bcmFieldActionFlowtrackerGroupId: 3306 if (!(fa->flags & _FP_ACTION_DIRTY)) { 3307 ft_group_id_set = TRUE; 3308 ent_flow_group_id = fa->param[0]; 3309 } 3310 break; 3311 case bcmFieldActionFlowtrackerEnable: 3312 if (!(fa->flags & _FP_ACTION_DIRTY)) { 3313 action_ft_set = TRUE; 3314 ent_action_ft = fa->param[0]; 3315 } 3316 break; 3317 case bcmFieldActionFlowtrackerNewLearnEnable: 3318 if (!(fa->flags & _FP_ACTION_DIRTY)) { 3319 action_new_learn_set = 1; 3320 ent_action_new_learn = fa->param[0]; 3321 } 3322 break; 3323 default: 3324 break; 3325 } 3326 } 3327 3328 if ((ft_group_id_set == FALSE) || (ent_flow_group_id != id)) { 3329 FP_UNLOCK(unit); 3330 return rv; 3331 } 3332 3333 /* Get Policy Index */ 3334 rv = _bcm_field_entry_tcam_idx_get(unit, f_ent, &tcam_idx); 3335 if (BCM_FAILURE(rv)) { 3336 FP_UNLOCK(unit); 3337 return rv; 3338 } 3339 3340 /* Get Policy Mem */ 3341 rv = _bcm_field_th_tcam_policy_mem_get(unit, 3342 f_ent, &tcam_mem, &policy_mem); 3343 if (BCM_FAILURE(rv)) { 3344 FP_UNLOCK(unit); 3345 return rv; 3346 } 3347 3348 rv = soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, 3349 tcam_idx, data_buf); 3350 if (BCM_FAILURE(rv)) { 3351 FP_UNLOCK(unit); 3352 return rv; 3353 } 3354 3355 /* Supported ft_group Controls are DO_NOT_FT and LEARN_DISABLE */ 3356 switch(control_type) { 3357 case bcmFlowtrackerGroupControlFlowtrackerEnable: 3358 field = DO_NOT_FTf; 3359 /* if Field Action is present, it takes priority. */ 3360 if (action_ft_set == TRUE) { 3361 val = (ent_action_ft) ? 0 : 1; 3362 } else { 3363 val = (param) ? 0 : 1; 3364 } 3365 break; 3366 case bcmFlowtrackerGroupControlNewLearnEnable: 3367 field = LEARN_DISABLEf; 3368 /* if Field Action is present, it takes priority. */ 3369 if (action_new_learn_set == TRUE) { 3370 val = (ent_action_new_learn) ? 0 : 1; 3371 } else { 3372 val = (param) ? 0 : 1; 3373 } 3374 break; 3375 case bcmFlowtrackerGroupControlFlowDirection: 3376 field = BIDIRECTIONAL_FLOWf; 3377 val= ((param == bcmFlowtrackerFlowDirectionBidirectional) ? 1 : 0); 3378 3379 rv = _field_hx5_ft_normalize_controls_set(unit, 3380 id, policy_mem, val, data_buf); 3381 break; 3382 default: 3383 rv = BCM_E_PARAM; 3384 break; 3385 } 3386 3387 if (BCM_FAILURE(rv)) { 3388 FP_UNLOCK(unit); 3389 return rv; 3390 } 3391 3392 if (SOC_MEM_FIELD_VALID(unit, policy_mem, field)) { 3393 cur_param = soc_mem_field32_get(unit, 3394 policy_mem, data_buf, field); 3395 3396 if (cur_param != val) { 3397 soc_mem_field32_set(unit, 3398 policy_mem, data_buf, field, val); 3399 3400 rv = soc_mem_write(unit, policy_mem, 3401 MEM_BLOCK_ALL, tcam_idx, data_buf); 3402 } 3403 } 3404 3405 FP_UNLOCK(unit); 3406 3407 return rv; 3408 } 3409 3410 /* 3411 * Function: 3412 * _field_ftfp_entry_action_stale_set 3413 * 3414 * Purpose: 3415 * Mark flowtracker group id action in ftfp entries as 3416 * staled out. 3417 * 3418 * Parameters: 3419 * unit - (IN) BCM device number. 3420 * entry - (IN) Field entry. 3421 * id - (IN) Flowtracker group Id 3422 * user_data1 - (IN) user data 1 3423 * user_data2 - (IN) user data 2 3424 * 3425 * Returns: 3426 * BCM_E_PARAM - If input parameters are not valid 3427 * BCM_E_NONE - Success. 3428 * BCM_E_XXX 3429 */ 3430 STATIC int 3431 _field_ftfp_entry_action_stale_set( 3432 int unit, 3433 bcm_field_entry_t entry, 3434 bcm_flowtracker_group_t id, 3435 void *user_data1, 3436 void *user_data2) 3437 { 3438 int rv = BCM_E_NONE; 3439 _field_entry_t *f_ent = NULL; 3440 3441 FP_LOCK(unit); 3442 3443 rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent); 3444 if (BCM_FAILURE(rv)) { 3445 FP_UNLOCK(unit); 3446 return (rv); 3447 } 3448 3449 rv = _bcm_field_hx5_ft_group_hw_free(unit, f_ent, 3450 _FP_ACTION_HW_FREE | _BCM_FIELD_ACTION_REF_STALE); 3451 3452 FP_UNLOCK(unit); 3453 3454 return rv; 3455 } 3456 3457 /* Public Interfaces */ 3458 3459 /* 3460 * Function: 3461 * _bcm_field_ft_alu_data_config_get 3462 * 3463 * Purpose: 3464 * Get ALU Data config info 3465 * 3466 * Parameters: 3467 * unit - (IN) BCM device number. 3468 * id - (IN) flowtracker group id. 3469 * alu_data - (IN) Alu Data param 3470 * offset - (OUT) Offset in ALU Data vector. 3471 * width - (OUT) Number of bits in ALU Data vector. 3472 * 3473 * Returns: 3474 * BCM_E_NOT_FOUND - If given alu_data is not found. 3475 * BCM_E_NONE 3476 */ 3477 int 3478 _bcm_field_ft_alu_data_config_get( 3479 int unit, 3480 bcm_flowtracker_group_t id, 3481 _bcm_field_ft_alu_data_t alu_data, 3482 int *offset, 3483 int *width) 3484 { 3485 int rv = BCM_E_NONE; 3486 int index = 0; 3487 int num_alu_data = 0; 3488 uint8 found = FALSE; 3489 uint16 param = 0; 3490 _field_ft_tracking_alu_data_info_t *alu_data_info = NULL; 3491 3492 alu_data_info = &_field_ft_tracking_alu_data_info[0]; 3493 num_alu_data = COUNTOF(_field_ft_tracking_alu_data_info); 3494 3495 for (index = 0; index < num_alu_data; index++) { 3496 param = alu_data_info[index].param; 3497 if (param == alu_data) { 3498 found = TRUE; 3499 if (offset != NULL) { 3500 *offset = alu_data_info[index].offset; 3501 } 3502 3503 if (width != NULL) { 3504 *width = alu_data_info[index].width; 3505 } 3506 } 3507 } 3508 3509 if (found == FALSE) { 3510 rv = BCM_E_NOT_FOUND; 3511 } 3512 3513 return rv; 3514 } 3515 3516 /* 3517 * Function: 3518 * _bcm_field_ft_group_tracking_info_process 3519 * 3520 * Purpose: 3521 * Process FT group tracking information and update FT group 3522 * database, if required 3523 * 3524 * Parameters: 3525 * unit - (IN) BCM device number. 3526 * id - (IN) flowtracker group id. 3527 * save_output- (IN) TRUE if output is required to be saved to 3528 * FT Group DB. 3529 * 3530 * Returns: 3531 * BCM_E_XXX 3532 */ 3533 int 3534 _bcm_field_ft_group_tracking_info_process( 3535 int unit, 3536 bcm_flowtracker_group_t id, 3537 uint8 save_output) 3538 { 3539 _field_ft_group_keygen_md_t ftg_keygen_md; 3540 3541 sal_memset(&ftg_keygen_md, 0, sizeof(_field_ft_group_keygen_md_t)); 3542 3543 ftg_keygen_md.state_rv = BCM_E_NONE; 3544 ftg_keygen_md.ft_group_id = id; 3545 ftg_keygen_md.state = _FIELD_FT_GROUP_KEYGEN_START; 3546 ftg_keygen_md.prev_state = _FIELD_FT_GROUP_KEYGEN_START; 3547 ftg_keygen_md.save_op = save_output; 3548 3549 return _field_hx5_ftg_keygen_process(unit, &ftg_keygen_md); 3550 } 3551 3552 /* 3553 * Function: 3554 * _bcm_field_ft_group_extraction_clear 3555 * 3556 * Purpose: 3557 * Cleanup FT group tracking params extraction information 3558 * from FT group database 3559 * 3560 * Parameters: 3561 * unit - (IN) BCM device number. 3562 * id - (IN) flowtracker group id. 3563 * 3564 * Returns: 3565 * BCM_E_XXX 3566 */ 3567 int 3568 _bcm_field_ft_group_extraction_clear( 3569 int unit, 3570 bcm_flowtracker_group_t id) 3571 { 3572 int rv = BCM_E_NONE; 3573 3574 /* Clear session key params extraction info */ 3575 rv = bcmi_esw_ft_group_extraction_alu_info_set(unit, 3576 id, 1, 0, NULL); 3577 BCM_IF_ERROR_RETURN(rv); 3578 3579 /* Clear session key hw extractors info */ 3580 rv = bcmi_esw_ft_group_extraction_hw_info_set(unit, 3581 id, 1, 0, NULL); 3582 BCM_IF_ERROR_RETURN(rv); 3583 3584 /* Clear session data params extraction info */ 3585 rv = bcmi_esw_ft_group_extraction_alu_info_set(unit, 3586 id, 0, 0, NULL); 3587 BCM_IF_ERROR_RETURN(rv); 3588 3589 /* Clear session data hw extractors info */ 3590 rv = bcmi_esw_ft_group_extraction_hw_info_set(unit, 3591 id, 0, 0, NULL); 3592 3593 return rv; 3594 } 3595 3596 /* 3597 * Function: 3598 * _bcm_field_ft_group_control_set 3599 * 3600 * Purpose: 3601 * Apply flowtracker group controls to each entry in which 3602 * action is given flowtracker group.. 3603 * 3604 * Parameters: 3605 * unit - (IN) BCM device number. 3606 * id - (IN) Flowtracker group 3607 * control_type- (IN) control to apply 3608 * param - (IN) Parameter associated with control 3609 * 3610 * Returns: 3611 * BCM_E_PARAM - Null field stage control structure. 3612 * BCM_E_NONE - Success. 3613 */ 3614 int 3615 _bcm_field_ft_group_control_set( 3616 int unit, 3617 bcm_flowtracker_group_t id, 3618 bcm_flowtracker_group_control_type_t control_type, 3619 int param) 3620 { 3621 return _bcm_field_ftfp_entry_traverse(unit, id, 3622 _field_ftfp_entry_control_set, 3623 (void *) &control_type, (void *) ¶m); 3624 } 3625 3626 3627 /* 3628 * Function: 3629 * _bcm_field_ft_group_invalidate 3630 * 3631 * Purpose: 3632 * Mark flowtracker group Id action in ftfp entries 3633 * stale. 3634 * 3635 * Parameters: 3636 * unit - (IN) BCM device number. 3637 * 3638 * Returns: 3639 * BCM_E_XXX 3640 */ 3641 int 3642 _bcm_field_ft_group_invalidate(int unit) 3643 { 3644 return _bcm_field_ftfp_entry_traverse(unit, -1, 3645 _field_ftfp_entry_action_stale_set, 3646 NULL, NULL); 3647 } 3648 3649 /* 3650 * Function: 3651 * _bcm_field_ft_tracking_param_range_get 3652 * 3653 * Purpose: 3654 * Returns minimum and maximum values of tracking params. 3655 * 3656 * Parameters: 3657 * unit - (IN) BCM device number. 3658 * param - (IN) Tracking param. 3659 * min_value - (OUT) Minimum value. 3660 * max_value - (OUT) Maximum value. 3661 * 3662 * Returns: 3663 * BCM_E_XXX 3664 */ 3665 int 3666 _bcm_field_ft_tracking_param_range_get( 3667 int unit, 3668 bcm_flowtracker_tracking_param_type_t param, 3669 uint32 *min_value, 3670 uint32 *max_value) 3671 { 3672 int rv = BCM_E_NONE; 3673 uint16 max_bits; 3674 bcmi_keygen_cfg_t keygen_cfg; 3675 _field_stage_t *stage_fc = NULL; 3676 _field_ft_info_t *ft_info = NULL; 3677 _field_ft_tracking_param_qual_map_t *pq_map = NULL; 3678 _field_ft_tracking_param_qual_map_db_t *map_db = NULL; 3679 3680 if (param >= _FIELD_FT_TRACKING_PARAM_MAX) { 3681 return BCM_E_PARAM; 3682 } 3683 3684 rv = _field_stage_control_get(unit, 3685 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc); 3686 BCM_IF_ERROR_RETURN(rv); 3687 3688 ft_info = stage_fc->ft_info; 3689 map_db = ft_info->param_qual_map_db; 3690 pq_map = map_db->param_qual_map[param]; 3691 if (pq_map == NULL) { 3692 return BCM_E_PARAM; 3693 } 3694 if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) { 3695 return BCM_E_PARAM; 3696 } 3697 3698 /* Get number of bits required to represent qualifier. */ 3699 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg; 3700 rv = bcmi_keygen_qual_cfg_max_size_get(unit, 3701 &keygen_cfg, pq_map->qual, &max_bits); 3702 BCM_IF_ERROR_RETURN(rv); 3703 3704 *min_value = 0; 3705 if (max_bits == 32) { 3706 *max_value = 0xFFFFFFFF; 3707 } else { 3708 *max_value = (1 << max_bits) - 1; 3709 } 3710 3711 return rv; 3712 } 3713 3714 /* 3715 * Function: 3716 * _bcm_field_ft_session_profiles_install 3717 * 3718 * Purpose: 3719 * Install session profiles for ftfp policy 3720 * 3721 * Parameters: 3722 * unit - (IN) BCM device number. 3723 * id - (IN) Flowtracker Group Id. 3724 * profiles - (OUT) Session Profiles. 3725 * 3726 * Returns: 3727 * BCM_E_XXX 3728 */ 3729 int _bcm_field_ft_session_profiles_install( 3730 int unit, 3731 bcm_flowtracker_group_t id) 3732 { 3733 int rv = BCM_E_NONE; 3734 bcmi_ft_session_profiles_t profiles; 3735 3736 sal_memset(&profiles, 0, sizeof (bcmi_ft_session_profiles_t)); 3737 rv = _field_hx5_ft_session_profiles_install(unit, id, &profiles); 3738 3739 if (BCM_SUCCESS(rv)) { 3740 rv = bcmi_ft_group_ftfp_profiles_set(unit, id, &profiles); 3741 } 3742 3743 if (BCM_SUCCESS(rv)) { 3744 rv = bcmi_ft_group_session_key_type_set(unit, 3745 id, profiles.session_key_profile_idx - 1); 3746 } 3747 3748 return rv; 3749 } 3750 3751 /* 3752 * Function: 3753 * _bcm_field_ft_session_profiles_uninstall 3754 * 3755 * Purpose: 3756 * Un-install session profiles for ftfp policy 3757 * 3758 * Parameters: 3759 * unit - (IN) BCM device number. 3760 * id - (IN) Flowtracker Group Id. 3761 * profiles - (IN) Session Profiles. 3762 * 3763 * Returns: 3764 * BCM_E_XXX 3765 */ 3766 int _bcm_field_ft_session_profiles_uninstall( 3767 int unit, 3768 bcm_flowtracker_group_t id) 3769 { 3770 int rv = BCM_E_NONE; 3771 bcmi_ft_session_profiles_t profiles; 3772 3773 sal_memset(&profiles, 0, sizeof (bcmi_ft_session_profiles_t)); 3774 3775 rv = bcmi_ft_group_ftfp_profiles_get(unit, id, &profiles); 3776 BCM_IF_ERROR_RETURN(rv); 3777 3778 return _field_hx5_ft_session_profiles_remove(unit, id, &profiles); 3779 } 3780 3781 /* 3782 * Function: 3783 * _bcm_field_ft_session_profiles_recover 3784 * 3785 * Purpose: 3786 * Recover session profiles indices. 3787 * 3788 * Parameters: 3789 * unit - (IN) BCM device number. 3790 * id - (IN) Flowtracker Group Id. 3791 * 3792 * Returns: 3793 * BCM_E_XXX 3794 */ 3795 int 3796 _bcm_field_ft_session_profiles_recover( 3797 int unit, 3798 bcm_flowtracker_group_t id) 3799 { 3800 bcmi_ft_session_profiles_t profiles; 3801 3802 BCM_IF_ERROR_RETURN(bcmi_ft_group_ftfp_profiles_get(unit, 3803 id, &profiles)); 3804 3805 BCM_IF_ERROR_RETURN(_field_hx5_ft_session_profiles_reference( 3806 unit, id, &profiles)); 3807 3808 BCM_IF_ERROR_RETURN(bcmi_ft_group_session_key_type_set(unit, 3809 id, profiles.session_key_profile_idx - 1)); 3810 3811 return BCM_E_NONE; 3812 } 3813 3814 /* 3815 * Function: 3816 * _bcm_field_ft_group_checkbmp_get 3817 * 3818 * Purpose: 3819 * Get flowtracker check in ALU16 bitmap. 3820 * 3821 * Parameters: 3822 * unit - (IN) BCM device number. 3823 * id - (IN) Flowtracker Group Id. 3824 * num_checks - (IN) Number of flowchecks. 3825 * check_list - (IN) List of Flowchecks 3826 * check_bmp_data - (OUT) Data bitmap 3827 * check_bmp_mask - (OUT) Mask bitmap. 3828 * 3829 * Returns: 3830 * BCM_E_XXX 3831 */ 3832 int _bcm_field_ft_group_checkbmp_get( 3833 int unit, 3834 bcm_flowtracker_group_t id, 3835 uint32 num_checks, 3836 bcm_field_flowtrackercheck_t *check_list, 3837 uint32 *check_bmp_data, 3838 uint32 *check_bmp_mask) 3839 { 3840 int rv = BCM_E_NONE; 3841 int bit = 0; 3842 int iter = 0; 3843 int flags = 0; 3844 uint32 found = 0; 3845 uint32 value = 0; 3846 bcm_flowtracker_check_t check_id; 3847 bcm_flowtracker_check_t check_map[8] = {0}; 3848 3849 rv = bcmi_ft_group_is_invalid(unit, id); 3850 BCM_IF_ERROR_RETURN(rv); 3851 3852 /* Get List of Flowcheck for flowtracker group */ 3853 rv = bcmi_ft_alu_check16_mapping_get(unit, id, check_map); 3854 BCM_IF_ERROR_RETURN(rv); 3855 3856 flags = BCMI_FT_GROUP_CHECK_MATCH_PRIMARY; 3857 3858 for (iter = 0; iter < num_checks; iter++) { 3859 check_id = check_list[iter].flow_check_id; 3860 value = check_list[iter].value; 3861 3862 rv = bcmi_ft_group_check_validate(unit, 3863 flags, id, check_id); 3864 BCM_IF_ERROR_RETURN(rv); 3865 3866 for (bit = 0; bit < 8; bit++) { 3867 if (check_map[bit] == check_id) { 3868 *check_bmp_mask |= (1 << bit); 3869 if (value == TRUE) { 3870 *check_bmp_data |= (1 << bit); 3871 } 3872 found++; 3873 break; 3874 } 3875 } 3876 } 3877 3878 if (found != num_checks) { 3879 return BCM_E_PARAM; 3880 } 3881 3882 return BCM_E_NONE; 3883 } 3884 3885 /* 3886 * Function: 3887 * _bcm_field_ft_group_checklist_get 3888 * 3889 * Purpose: 3890 * Get list of flowtracker check from ALU16 bitmap. 3891 * 3892 * Parameters: 3893 * unit - (IN) BCM device number. 3894 * id - (IN) Flowtracker Group Id. 3895 * check_bmp_data - (IN) Data bitmap. 3896 * check_bmp_mask - (IN) Mask bitmap. 3897 * num_checks - (IN) Number of flowchecks. 3898 * check_list - (OUT) List of Flowchecks. 3899 * actual_num_checks - (OUT) actual number of flowchecks. 3900 * 3901 * Returns: 3902 * BCM_E_XXX 3903 */ 3904 int _bcm_field_ft_group_checklist_get( 3905 int unit, 3906 bcm_flowtracker_group_t id, 3907 uint32 check_bmp_data, 3908 uint32 check_bmp_mask, 3909 uint32 num_checks, 3910 bcm_field_flowtrackercheck_t *check_list, 3911 uint32 *actual_num_checks) 3912 { 3913 int rv = BCM_E_NONE; 3914 int i = 0, check_idx = 0; 3915 bcm_flowtracker_check_t check_map[8] = {0}; 3916 3917 if (actual_num_checks == NULL) { 3918 return BCM_E_PARAM; 3919 } 3920 3921 rv = bcmi_ft_group_is_invalid(unit, id); 3922 BCM_IF_ERROR_RETURN(rv); 3923 3924 rv = bcmi_ft_alu_check16_mapping_get(unit, id, check_map); 3925 BCM_IF_ERROR_RETURN(rv); 3926 3927 if (check_list == NULL) { 3928 *actual_num_checks = _shr_popcount(check_bmp_mask); 3929 return BCM_E_NONE; 3930 } 3931 3932 for (i = 0; (i < 8) && (check_idx < num_checks); i++) { 3933 3934 if ((check_bmp_data) & (1 << i)) { 3935 check_list[check_idx].value = 1; 3936 } 3937 if ((check_bmp_mask) & (1 << i)) { 3938 check_list[check_idx].flow_check_id = check_map[i]; 3939 check_idx++; 3940 3941 if (check_idx >= num_checks) { 3942 break; 3943 } 3944 } 3945 } 3946 3947 *actual_num_checks = check_idx; 3948 3949 return BCM_E_NONE; 3950 } 3951 3952 #endif /* BCM_FLOWTRACKER_SUPPORT */