field_em.c (141295B)
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 * All Rights Reserved.$ 7 * 8 * File: field_em.c 9 * Purpose: BCM56960 Field Processor Exact Match functions. 10 */ 11 12 #include <soc/defs.h> 13 #if defined(BCM_TOMAHAWK_SUPPORT) && defined(BCM_FIELD_SUPPORT) 14 #include <shared/bsl.h> 15 #include <soc/mem.h> 16 #include <soc/drv.h> 17 #include <bcm_int/esw/tomahawk.h> 18 #if defined(BCM_TOMAHAWK3_SUPPORT) 19 #include <soc/tomahawk3.h> 20 #include <bcm_int/esw/tomahawk3.h> 21 #endif 22 #include <bcm/field.h> 23 #include <bcm_int/esw/field.h> 24 25 /* Local functions prototypes. */ 26 STATIC 27 int _field_th_action_profiles_init(int unit, _field_stage_t *stage_fc, 28 _field_control_t *fc); 29 30 STATIC 31 int _field_th_qos_action_profiles_init(int unit, _field_stage_t *stage_fc, 32 _field_control_t *fc); 33 34 int 35 _field_th_em_entry_set(int unit, 36 _field_entry_t *f_ent, 37 soc_mem_t mem, 38 uint32 *bufp, int search_entry); 39 int 40 _field_td3_em_entry_set(int unit, 41 _field_entry_t *f_ent, 42 soc_mem_t mem, 43 uint32 *bufp, int search_entry); 44 45 /*Action sets array as per bit positions in Action profile */ 46 uint8 em_action_profile_bitmap[17] = { 47 _FieldActionMeterSet, 48 _FieldActionGreenToPidSet, 49 _FieldActionMirrorOverrideSet, 50 _FieldActionNatOverrideSet, 51 _FieldActionSflowSet, 52 _FieldActionCutThrOverrideSet, 53 _FieldActionUrpfOverrideSet, 54 _FieldActionTtlOverrideSet, 55 _FieldActionLbControlSet, 56 _FieldActionDropSet, 57 _FieldActionChangeCpuCosSet, 58 _FieldActionMirrorSet, 59 _FieldActionNatSet, 60 _FieldActionCopyToCpuSet, 61 _FieldActionL3SwChangeL2Set, 62 _FieldActionRedirectSet, 63 _FieldActionCounterSet 64 }; 65 uint8 ifp_td3_action_profile_bitmap[44] = { 66 _FieldActionProtectionSwitchingDropOverrideSet, 67 _FieldActionIfpDlbAlternatePathControlSet, 68 _FieldActionEcmpDlbActionSet, 69 _FieldActionHgtLagDlbActionSet, 70 _FieldActionEcmp2RhActionSet, 71 _FieldActionEcmp1RhActionSet, 72 _FieldActionLagRhActionSet, 73 _FieldActionHgtRhActionSet, 74 _FieldActionLoopbackProfileActionSet, 75 _FieldActionExtractionCtrlIdActionSet, 76 _FieldActionOpaque4ActionSet, 77 _FieldActionOpaque3ActionSet, 78 _FieldActionOpaque2ActionSet, 79 _FieldActionOpaque1ActionSet, 80 _FieldActionTxTimestampInsertionSet, 81 _FieldActionRxTimestampInsertionSet, 82 _FieldActionIgnoreFcoEZoneCheckSet, 83 _FieldActionGreenToPidSet, 84 _FieldActionMirrorOverrideSet, 85 _FieldActionNatOverrideSet, 86 _FieldActionSflowSet, 87 _FieldActionCutThrOverrideSet, 88 _FieldActionUrpfOverrideSet, 89 _FieldActionTtlOverrideSet, 90 _FieldActionLbControlSet, 91 _FieldActionDropSet, 92 _FieldActionChangeCpuCosSet, 93 _FieldActionMirrorSet, 94 _FieldActionNatSet, 95 _FieldActionCopyToCpuSet, 96 _FieldActionL3SwChangeL2Set, 97 _FieldActionRedirectSet, 98 _FieldActionCounterSet, 99 _FieldActionChangeEcnSet, 100 _FieldActionChangePktPriSet, 101 _FieldActionChangeDscpTosSet, 102 _FieldActionChangeDropPrecendenceSet, 103 _FieldActionChangeCosOrIntPriSet, 104 _FieldActionChangeIntCNSet, 105 _FieldActionChangeInputPrioritySet, 106 _FieldActionInstrumentationSet, 107 _FieldActionEditCtrlIdSet, 108 _FieldActionFcoEVsanSet, 109 _FieldActionMeterSet 110 }; 111 uint8 em_td3_action_profile_bitmap[37] = { 112 _FieldActionProtectionSwitchingDropOverrideSet, 113 _FieldActionIfpDlbAlternatePathControlSet, 114 _FieldActionEcmpDlbActionSet, 115 _FieldActionHgtLagDlbActionSet, 116 _FieldActionEcmp2RhActionSet, 117 _FieldActionEcmp1RhActionSet, 118 _FieldActionLagRhActionSet, 119 _FieldActionHgtRhActionSet, 120 _FieldActionLoopbackProfileActionSet, 121 _FieldActionExtractionCtrlIdActionSet, 122 _FieldActionOpaque4ActionSet, 123 _FieldActionOpaque3ActionSet, 124 _FieldActionOpaque2ActionSet, 125 _FieldActionOpaque1ActionSet, 126 _FieldActionTxTimestampInsertionSet, 127 _FieldActionRxTimestampInsertionSet, 128 _FieldActionIgnoreFcoEZoneCheckSet, 129 _FieldActionGreenToPidSet, 130 _FieldActionMirrorOverrideSet, 131 _FieldActionNatOverrideSet, 132 _FieldActionSflowSet, 133 _FieldActionCutThrOverrideSet, 134 _FieldActionUrpfOverrideSet, 135 _FieldActionTtlOverrideSet, 136 _FieldActionLbControlSet, 137 _FieldActionDropSet, 138 _FieldActionChangeCpuCosSet, 139 _FieldActionMirrorSet, 140 _FieldActionNatSet, 141 _FieldActionCopyToCpuSet, 142 _FieldActionL3SwChangeL2Set, 143 _FieldActionRedirectSet, 144 _FieldActionCounterSet, 145 _FieldActionInstrumentationSet, 146 _FieldActionEditCtrlIdSet, 147 _FieldActionFcoEVsanSet, 148 _FieldActionMeterSet 149 }; 150 uint8 em_th2_action_profile_bitmap[23] = { 151 _FieldActionMeterSet, 152 _FieldActionGreenToPidSet, 153 _FieldActionMirrorOverrideSet, 154 _FieldActionNatOverrideSet, 155 _FieldActionSflowSet, 156 _FieldActionCutThrOverrideSet, 157 _FieldActionUrpfOverrideSet, 158 _FieldActionTtlOverrideSet, 159 _FieldActionLbControlSet, 160 _FieldActionDropSet, 161 _FieldActionChangeCpuCosSet, 162 _FieldActionMirrorSet, 163 _FieldActionNatSet, 164 _FieldActionCopyToCpuSet, 165 _FieldActionL3SwChangeL2Set, 166 _FieldActionRedirectSet, 167 _FieldActionCounterSet, 168 _FieldActionIfpDlbAlternatePathControlSet, 169 _FieldActionEcmpDlbActionSet, 170 _FieldActionHgtLagDlbActionSet, 171 _FieldActionTimestampInsertionSet, 172 _FieldActionInstrumentationSet, 173 _FieldActionProtectionSwitchingDropOverrideSet, 174 }; 175 176 uint8 em_th3_action_profile_bitmap[24] = { 177 _FieldActionMeterSet, 178 _FieldActionChangeCpuCosSet, 179 _FieldActionCopyToCpuSet, 180 _FieldActionCounterSet, 181 _FieldActionCutThrOverrideSet, 182 _FieldActionDelayedDropSet, 183 _FieldActionDelayedRedirectSet, 184 _FieldActionIfpDlbAlternatePathControlSet, 185 _FieldActionEcmpDlbMonitorSet, 186 _FieldActionEcmpDlbActionSet, 187 _FieldActionDropSet, 188 _FieldActionElephantTrapSet, 189 _FieldActionRedirectSet, 190 _FieldActionGreenToPidSet, 191 _FieldActionInbandTelemetrySet, 192 _FieldActionInstrumentationSet, 193 _FieldActionL3SwChangeL2Set, 194 _FieldActionLbControlSet, 195 _FieldActionMirrorOverrideSet, 196 _FieldActionMirrorSet, 197 _FieldActionProtectionSwitchingDropOverrideSet, 198 _FieldActionSflowSet, 199 _FieldActionTimestampInsertionSet, 200 _FieldActionTtlOverrideSet, 201 }; 202 203 /* 204 * Function: 205 * _field_th_emstage_init 206 * Purpose: 207 * Initialize Exact Match Stage. 208 * Parameters: 209 * unit - (IN) BCM device number. 210 * fc - (IN) Field control structure. 211 * stage_fc - (IN) Stage field control structure. 212 * Returns: 213 * BCM_E_XXX 214 * Notes: 215 * Exact Match Stage in Tomahawk is almost same as IFP stage. Hence there 216 * is no need to make separate database for extractor and ibus. Instead IFP 217 * database is created first and then exact match stage pointers just use 218 * same database instead of creating it's own database. 219 */ 220 int 221 _field_th_emstage_init(int unit, _field_control_t *fc, 222 _field_stage_t *stage_fc) 223 { 224 int rv = BCM_E_NONE; /* Operation Return Status */ 225 _field_stage_t *stage_ing; /* Ingress Stage Control Struct */ 226 227 /* Input parameter Check */ 228 if ((fc == NULL) || (stage_fc == NULL)) { 229 return (BCM_E_PARAM); 230 } 231 232 /* Applicable only for exact match stage */ 233 if (stage_fc->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 234 return (BCM_E_NONE); 235 } 236 237 /* Get Ingress Stage Control Structure */ 238 stage_ing = fc->stages; 239 while (stage_ing) { 240 if (stage_ing->stage_id == _BCM_FIELD_STAGE_INGRESS) { 241 break; 242 } 243 stage_ing = stage_ing->next; 244 } 245 246 /* Ingress stage check */ 247 if (NULL == stage_ing) { 248 return (BCM_E_PARAM); 249 } 250 stage_fc->qual_cfg_info_db = stage_ing->qual_cfg_info_db; 251 stage_fc->ext_cfg_db_arr = stage_ing->ext_cfg_db_arr; 252 253 /* Initialise Keygen Profile */ 254 rv = _field_th_keygen_profiles_init(unit, stage_fc, fc); 255 if (BCM_FAILURE(rv)) { 256 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 257 "FP(unit %d) Error: _field_th_keygen_profiles_init=%d\n"), 258 unit, rv)); 259 return (rv); 260 } 261 262 /* Initialise Action Profile */ 263 rv = _field_th_action_profiles_init(unit, stage_fc, fc); 264 if (BCM_FAILURE(rv)) { 265 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 266 "FP(unit %d) Error: _field_th_action_profiles_init=%d\n"), 267 unit, rv)); 268 return (rv); 269 } 270 271 /* Initialise Qos Action Profile */ 272 rv = _field_th_qos_action_profiles_init(unit, stage_fc, fc); 273 if (BCM_FAILURE(rv)) { 274 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 275 "FP(unit %d) Error: _field_th_qos_action_profiles_init=%d\n"), 276 unit, rv)); 277 return (rv); 278 } 279 /* Initializing supported Qset*/ 280 sal_memset(&stage_fc->_field_supported_qset, 0, sizeof(bcm_field_qset_t)); 281 282 /* Initialize stage Preselector information. */ 283 rv = _bcm_field_th_stage_preselector_init(unit, fc, stage_fc); 284 if (BCM_FAILURE(rv)) { 285 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 286 "FP(unit %d) Error: _bcm_field_th_stage_preselector_init=%d" 287 "\n"), unit, rv)); 288 return (rv); 289 } 290 #if defined(BCM_TRIDENT3_SUPPORT) 291 if(soc_feature(unit, soc_feature_td3_style_fp)) { 292 rv = _bcm_field_td3_em_key_attributes_init(unit, stage_fc); 293 if (BCM_FAILURE(rv)) { 294 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 295 "FP(unit %d) Error:_bcm_field_td3_em_key_attributes_init =%d" 296 "\n"), unit, rv)); 297 return (rv); 298 } 299 } 300 #endif 301 #if defined(BCM_TOMAHAWK3_SUPPORT) 302 if(soc_feature(unit, soc_feature_th3_style_fp)) { 303 rv = _bcm_field_th3_em_key_attributes_init(unit, stage_fc, fc); 304 if (BCM_FAILURE(rv)) { 305 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 306 "FP(unit %d) Error:_bcm_field_th3_em_key_attributes_init =%d" 307 "\n"), unit, rv)); 308 return (rv); 309 } 310 } 311 #endif 312 313 return (rv); 314 } 315 316 /* 317 * Function: 318 * _field_th_emstage_update 319 * Purpose: 320 * Update Exact Match Stage. 321 * Parameters: 322 * unit - (IN) BCM device number. 323 * stage_fc - (IN) Stage field control structure. 324 * Returns: 325 * BCM_E_XXX 326 * Notes: 327 * This call is required as exact match uses ext and input 328 * data bus same as ingress stage. During oper mode set 329 * ingress stage delete and add back database leading 330 * to exact match pointing to freed information. 331 * Hence whenever ingress oper mode is changed, these 332 * database pointers should be updated in exact match stage. 333 */ 334 int 335 _field_th_emstage_update(int unit, _field_stage_t *stage_fc) 336 { 337 int rv = BCM_E_NONE; /* Operation Return Status */ 338 _field_stage_t *stage_em; /* Ingress Stage Control Struct */ 339 340 /* Input parameter Check */ 341 if (stage_fc == NULL) { 342 return (BCM_E_PARAM); 343 } 344 345 /* Applicable only for ingress stage */ 346 if (stage_fc->stage_id != _BCM_FIELD_STAGE_INGRESS) { 347 return (BCM_E_NONE); 348 } 349 350 /* Get Exact match stage structure. */ 351 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 352 _BCM_FIELD_STAGE_EXACTMATCH, &stage_em)); 353 stage_em->qual_cfg_info_db = stage_fc->qual_cfg_info_db; 354 stage_em->ext_cfg_db_arr = stage_fc->ext_cfg_db_arr; 355 356 return (rv); 357 } 358 /* 359 * Function: 360 * _field_th_action_profiles_init 361 * Purpose: 362 * Initialize keygen program profiles based on group operational mode. 363 * Parameters: 364 * unit - (IN) BCM device number. 365 * stage_fc - (IN/OUT) Stage field control structure. 366 * 367 * Returns: 368 * BCM_E_PARAM - Null field control structure or stage control parameter. 369 * BCM_E_INTERNAL - Null stage slice control structure. 370 * BCM_E_MEMORY - Allocation failure. 371 * BCM_E_NONE - Success. 372 */ 373 STATIC int 374 _field_th_action_profiles_init(int unit, _field_stage_t *stage_fc, 375 _field_control_t *fc) 376 { 377 soc_mem_t mem; /* SOC memory names. */ 378 int entry_words; /* Entry size in words. */ 379 int inst; /* Instance iterator. */ 380 int rv; /* Operation return status. */ 381 382 /* Input parameter check. */ 383 if (NULL == stage_fc) { 384 return (BCM_E_PARAM); 385 } 386 387 /* Applicable only for Exact Match Stage */ 388 if (stage_fc->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 389 return (BCM_E_NONE); 390 } 391 392 switch (stage_fc->oper_mode) { 393 394 /* Field Groups operational in Global mode. */ 395 case bcmFieldGroupOperModeGlobal: 396 397 /* Initialize action profile memory name. */ 398 mem = EXACT_MATCH_ACTION_PROFILEm; 399 400 /* Determine action profile entry size in number of words. */ 401 entry_words = soc_mem_entry_words(unit, mem); 402 403 /* Create action program profile table. */ 404 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 405 &stage_fc->action_profile[_FP_DEF_INST]); 406 407 if (BCM_FAILURE(rv)) { 408 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 409 "FP(unit %d) Error: action profile creation failed." 410 "=%d\n"), unit, rv)); 411 return (rv); 412 } 413 break; 414 415 /* Field Groups operational in Per-Pipe mode. */ 416 case bcmFieldGroupOperModePipeLocal: 417 418 /* Determine action profiles entry size in number of words. */ 419 entry_words = soc_mem_entry_words(unit, 420 EXACT_MATCH_ACTION_PROFILE_PIPE0m); 421 422 for (inst = 0; inst < stage_fc->num_instances; inst++) { 423 if (!(fc->pipe_map & (1 << inst))) { 424 continue; 425 } 426 /* Initialize action program profile memory name. */ 427 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 428 EXACT_MATCH_ACTION_PROFILEm, 429 inst, &mem)); 430 431 /* Create action program profile table. */ 432 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 433 &stage_fc->action_profile[inst]); 434 435 if (BCM_FAILURE(rv)) { 436 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 437 "FP(unit %d) Error: action profile creation failed." 438 "=%d\n"), unit, rv)); 439 return (rv); 440 } 441 } 442 break; 443 444 default: 445 /* 446 * Invalid Group Operational mode, should never hit this condition. 447 */ 448 return (BCM_E_INTERNAL); 449 } 450 451 return (BCM_E_NONE); 452 } 453 454 /* 455 * Function: 456 * _field_th_qos_action_profiles_init 457 * Purpose: 458 * Initialize qos action profiles based on group operational mode. 459 * Parameters: 460 * unit - (IN) BCM device number. 461 * stage_fc - (IN/OUT) Stage field control structure. 462 * 463 * Returns: 464 * BCM_E_PARAM - Null field control structure or stage control parameter. 465 * BCM_E_INTERNAL - Null stage slice control structure. 466 * BCM_E_MEMORY - Allocation failure. 467 * BCM_E_NONE - Success. 468 */ 469 STATIC int 470 _field_th_qos_action_profiles_init(int unit, _field_stage_t *stage_fc, 471 _field_control_t *fc) 472 { 473 int entry_words; /* Entry size in words. */ 474 int inst; /* Instance iterator. */ 475 int rv; /* Operation return status. */ 476 soc_mem_t mem; /* SOC memory names. */ 477 478 /* Input parameter check. */ 479 if (NULL == stage_fc) { 480 return (BCM_E_PARAM); 481 } 482 483 /* Applicable only for Exact Match Stage */ 484 if (stage_fc->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 485 return (BCM_E_NONE); 486 } 487 488 switch (stage_fc->oper_mode) { 489 490 /* Field Groups operational in Global mode. */ 491 case bcmFieldGroupOperModeGlobal: 492 493 /* Initialize profile1 memory name. */ 494 mem = EXACT_MATCH_QOS_ACTIONS_PROFILEm; 495 496 /* Determine qos action profile entry size in number of words. */ 497 entry_words = soc_mem_entry_words(unit, mem); 498 499 /* Create qos action program profile table. */ 500 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 501 &stage_fc->qos_action_profile[_FP_DEF_INST]); 502 503 if (BCM_FAILURE(rv)) { 504 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 505 "FP(unit %d) Error: qos action " 506 "profile creation failed." 507 "=%d\n"), unit, rv)); 508 return (rv); 509 } 510 break; 511 512 /* Field Groups operational in Per-Pipe mode. */ 513 case bcmFieldGroupOperModePipeLocal: 514 515 /* Determine qos action profiles entry size in number of words. */ 516 entry_words = soc_mem_entry_words(unit, 517 EXACT_MATCH_QOS_ACTIONS_PROFILE_PIPE0m); 518 519 for (inst = 0; inst < stage_fc->num_instances; inst++) { 520 if (!(fc->pipe_map & (1 << inst))) { 521 continue; 522 } 523 /* Initialize qos action program profile memory name. */ 524 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 525 EXACT_MATCH_QOS_ACTIONS_PROFILEm, 526 inst, &mem)); 527 528 /* Create qos action program profile table. */ 529 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 530 &stage_fc->qos_action_profile[inst]); 531 if (BCM_FAILURE(rv)) { 532 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 533 "FP(unit %d) Error: qos action " 534 "profile creation failed." 535 "=%d\n"), unit, rv)); 536 return (rv); 537 } 538 } 539 break; 540 541 default: 542 /* 543 * Invalid Group Operational mode, should never hit this condition. 544 */ 545 return (BCM_E_INTERNAL); 546 } 547 548 return (BCM_E_NONE); 549 } 550 551 /* 552 * Function: 553 * _field_th_emstage_deinit 554 * Purpose: 555 * De-Initialize Exact Match Stage. 556 * Parameters: 557 * unit - (IN) BCM device number. 558 * stage_fc - (IN) Stage field control structure. 559 * Returns: 560 * BCM_E_XXX 561 * Notes: 562 */ 563 int 564 _field_th_emstage_deinit(int unit, _field_stage_t *stage_fc) 565 { 566 int rv = BCM_E_NONE; /* Operation Return Status */ 567 568 /* Input Parameter Check. */ 569 if (stage_fc == NULL) { 570 return (BCM_E_PARAM); 571 } 572 573 /* Do nothing for non EM stage. */ 574 if (stage_fc->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 575 return (BCM_E_NONE); 576 } 577 578 /* Since Exact Match Stage uses same extractor and input 579 * bus database as ingress stage. hence deinit will happen 580 * during ingress stage delete. Set to NULL here as we 581 * are simply using ingress stage database previously. 582 */ 583 584 return (rv); 585 } 586 587 /* 588 * Function: 589 * _field_th_em_entries_free_get 590 * Purpose: 591 * Retreive Free Entries available in UFT table. 592 * Parameters: 593 * unit - (IN) BCM device number. 594 * fg - (IN) Field group structure. 595 * free_count - (OUT) Free Entries Count. 596 * Returns: 597 * BCM_E_XXX 598 * Notes: 599 */ 600 int 601 _field_th_em_entries_free_get(int unit, _field_group_t *fg, 602 int *free_count) 603 { 604 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 605 _field_slice_t *fs = NULL; /* Slice info. */ 606 int slice = 0; /* Slice Count Iterator. */ 607 608 /* Input Paramter Check. */ 609 if ((fg == NULL) || 610 (free_count == NULL)) { 611 return (BCM_E_PARAM); 612 } 613 614 /* Initialize free entry count. */ 615 *free_count = 0; 616 617 /* Not applicable for non exact match stages. */ 618 if (fg->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 619 return (BCM_E_INTERNAL); 620 } 621 622 /* Retreive Stage Control. */ 623 BCM_IF_ERROR_RETURN( 624 _field_stage_control_get(unit, fg->stage_id, &stage_fc)); 625 626 /* Retreive Slice Instance. */ 627 fs = stage_fc->slices[fg->instance]; 628 629 /* Calculate free entry count. */ 630 for (slice = 0; slice < stage_fc->tcam_slices; slice++) { 631 *free_count += fs[slice].free_count; 632 } 633 634 return (BCM_E_NONE); 635 } 636 637 /* 638 * Function: 639 * _field_th_em_qualifier_set 640 * Purpose: 641 * Set Exact Match Qualifier Value. 642 * Parameters: 643 * unit - (IN) BCM device number. 644 * entry - (IN) Entry ID. 645 * qual - (IN) Qualifier Field. 646 * data - (IN) Matching Data. 647 * mask - (IN) Bit Mask For Data. 648 * Returns: 649 * BCM_E_XXX 650 * Notes: 651 */ 652 int 653 _field_th_em_qualifier_set(int unit, bcm_field_entry_t entry, 654 int qual, uint32 *data, uint32 *mask) 655 { 656 int rv = BCM_E_NONE; /* Operational Status. */ 657 _field_entry_t *f_ent; /* Field Entry Control. */ 658 _field_group_t *fg; /* Field Group Struc. */ 659 bcm_field_qualify_t qual_id; /* Qualfier ID. */ 660 int flag = 0; /* Flag. */ 661 662 if (NULL == data || NULL == mask) { 663 return BCM_E_PARAM; 664 } 665 666 /* Retrieve the field entry. */ 667 rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent); 668 BCM_IF_ERROR_RETURN(rv); 669 670 /* Retreive Field Group. */ 671 fg = f_ent->group; 672 673 if (qual == bcmFieldQualifyExactMatchHitStatus) { 674 if (BCM_FIELD_QSET_TEST(fg->qset, 675 _bcmFieldQualifyExactMatchHitStatusLookup0)) { 676 qual_id = _bcmFieldQualifyExactMatchHitStatusLookup0; 677 rv = _bcm_field_th_qualify_set(unit, entry, qual_id, 678 data, mask, 679 _FP_QUALIFIER_DEL); 680 BCM_IF_ERROR_RETURN(rv); 681 flag = 1; 682 } 683 if (BCM_FIELD_QSET_TEST(fg->qset, 684 _bcmFieldQualifyExactMatchHitStatusLookup1)) { 685 qual_id = _bcmFieldQualifyExactMatchHitStatusLookup1; 686 rv = _bcm_field_th_qualify_set(unit, entry, qual_id, 687 data, mask, 688 _FP_QUALIFIER_DEL); 689 BCM_IF_ERROR_RETURN(rv); 690 flag = 1; 691 } 692 } else if (qual == bcmFieldQualifyExactMatchActionClassId) { 693 if (BCM_FIELD_QSET_TEST(fg->qset, 694 _bcmFieldQualifyExactMatchActionClassIdLookup0)) { 695 qual_id = _bcmFieldQualifyExactMatchActionClassIdLookup0; 696 rv = _bcm_field_th_qualify_set(unit, entry, qual_id, 697 data, mask, 698 _FP_QUALIFIER_DEL); 699 BCM_IF_ERROR_RETURN(rv); 700 flag = 1; 701 } 702 if (BCM_FIELD_QSET_TEST(fg->qset, 703 _bcmFieldQualifyExactMatchActionClassIdLookup1)) { 704 qual_id = _bcmFieldQualifyExactMatchActionClassIdLookup1; 705 rv = _bcm_field_th_qualify_set(unit, entry, qual_id, 706 data, mask, 707 _FP_QUALIFIER_DEL); 708 BCM_IF_ERROR_RETURN(rv); 709 flag = 1; 710 } 711 } else if (qual == bcmFieldQualifyExactMatchGroupClassId) { 712 if (BCM_FIELD_QSET_TEST(fg->qset, 713 _bcmFieldQualifyExactMatchGroupClassIdLookup0)) { 714 qual_id = _bcmFieldQualifyExactMatchGroupClassIdLookup0; 715 rv = _bcm_field_th_qualify_set(unit, entry, qual_id, 716 data, mask, 717 _FP_QUALIFIER_DEL); 718 BCM_IF_ERROR_RETURN(rv); 719 flag = 1; 720 } 721 if (BCM_FIELD_QSET_TEST(fg->qset, 722 _bcmFieldQualifyExactMatchGroupClassIdLookup1)) { 723 qual_id = _bcmFieldQualifyExactMatchGroupClassIdLookup1; 724 rv = _bcm_field_th_qualify_set(unit, entry, qual_id, 725 data, mask, 726 _FP_QUALIFIER_DEL); 727 BCM_IF_ERROR_RETURN(rv); 728 flag = 1; 729 } 730 } else { 731 rv = BCM_E_PARAM; 732 } 733 734 /* Check if qual was present. */ 735 if (flag == 0) { 736 LOG_ERROR(BSL_LS_BCM_FP, 737 (BSL_META_U(unit, 738 "FP(unit %d) Error: qual=%s not in group=%d Qset\n"), 739 unit, _field_qual_name(qual), fg->gid)); 740 rv = BCM_E_PARAM; 741 } 742 743 return (rv); 744 } 745 746 /* 747 * Function: 748 * _field_th_em_group_lookup_get 749 * Purpose: 750 * Get Lookup information for exact match group 751 * with given priority. 752 * Parameters: 753 * unit - (IN) BCM device number. 754 * priority - (IN) Exact Match Group Priority. 755 * lookup - (OUT) Exact Match Lookup Information. 756 * Returns: 757 * BCM_E_XXX 758 * Notes: 759 * This function is applicable only for exact match 760 * group. 761 */ 762 int 763 _field_th_em_group_lookup_get(int unit, 764 int priority, 765 uint8 *lookup) 766 { 767 int rv = BCM_E_NONE; /* Operational Status. */ 768 _field_control_t *fc; /* Unit FP control structure. */ 769 _field_group_t *fg = NULL; /* Group information. */ 770 771 /* Input Parameter Check. */ 772 if (lookup == NULL) { 773 return (BCM_E_PARAM); 774 } 775 776 /* Get unit FP control structure. */ 777 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 778 779 /* Iterate over the groups linked-list looking for a matching 780 * group Id. */ 781 fg = fc->groups; 782 while (fg != NULL) { 783 if ((fg->priority == priority) && 784 (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH)) { 785 break; 786 } 787 fg = fg->next; 788 } 789 790 /* Exact Match Group Check. */ 791 if (fg == NULL) { 792 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 793 "FP(unit %d) Error: Exact Match Group with priority %d " 794 "does not exist.\n"), 795 unit,priority)); 796 return (BCM_E_NOT_FOUND); 797 } 798 799 /* Slice Check. */ 800 if (fg->slices == NULL) { 801 return (BCM_E_INTERNAL); 802 } 803 804 /* Return Lookup Information. */ 805 if (fg->slices->slice_number == 0) { 806 *lookup = BCM_FIELD_EXACT_MATCH_LOOKUP_0; 807 } else if (fg->slices->slice_number == 1) { 808 *lookup = BCM_FIELD_EXACT_MATCH_LOOKUP_1; 809 } else { 810 rv = BCM_E_INTERNAL; 811 } 812 813 return (rv); 814 } 815 816 /* 817 * Function: 818 * _field_th_em_ltid_based_groupid_get 819 * Purpose: 820 * Get group id information for exact match group 821 * with given logical table id. 822 * Parameters: 823 * unit - (IN) BCM device number. 824 * ltid - (IN) Exact Match Logical Table Id. 825 * group - (OUT) Exact Match Group Id. 826 * Returns: 827 * BCM_E_XXX 828 * Notes: 829 * This function is only applicable for exact match 830 * group. 831 */ 832 int 833 _field_th_em_ltid_based_groupid_get(int unit, int ltid, 834 bcm_field_group_t *group) 835 { 836 int rv = BCM_E_NONE; /* Operational Status. */ 837 _field_control_t *fc; /* Unit FP control structure. */ 838 _field_group_t *fg = NULL; /* Group information. */ 839 840 /* Input Parameter Check */ 841 if (group == NULL) { 842 return (BCM_E_PARAM); 843 } 844 845 /* Get unit FP control structure. */ 846 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 847 848 /* Iterate over the groups linked-list looking for a matching Group ID */ 849 fg = fc->groups; 850 while (fg != NULL) { 851 if ((fg->lt_id == ltid) && 852 (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH)) { 853 break; 854 } 855 fg = fg->next; 856 } 857 858 /* Exact Match Group Check. */ 859 if (fg == NULL) { 860 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 861 "FP(unit %d) Error: Exact Match Group with ltid %d " 862 "does not exist.\n"), 863 unit,ltid)); 864 return (BCM_E_NOT_FOUND); 865 } 866 867 /* Return Group Information. */ 868 *group = fg->gid; 869 870 return (rv); 871 } 872 873 /* 874 * Function: 875 * _field_th_em_group_priority_hintbased_qset_update 876 * Purpose: 877 * Update Field Group Qset based on Group Priority. 878 * Parameters: 879 * unit - (IN) BCM device number. 880 * hint_entry - (IN) - Field Hint Structure. 881 * fg - (OUT) field group structure. 882 * Returns: 883 * BCM_E_XXX 884 * Notes: 885 */ 886 int 887 _field_th_em_group_priority_hintbased_qset_update(int unit, 888 _field_group_t *fg, 889 bcm_field_hint_t *hint_entry) 890 { 891 int rv = BCM_E_NONE; /* Operational Status. */ 892 uint8 lkup = 0; /* Exact Match Lookup. */ 893 894 /* Input Parameter Check. */ 895 if ((fg == NULL) || (hint_entry == NULL)) { 896 return (BCM_E_PARAM); 897 } 898 899 /* Get Exact Match with provided priority. */ 900 rv = _field_th_em_group_lookup_get(unit, hint_entry->priority, &lkup); 901 if (BCM_FAILURE(rv)) { 902 return (rv); 903 } 904 905 /* Set Exact Match Hit Status. */ 906 if (hint_entry->qual == bcmFieldQualifyExactMatchHitStatus) { 907 if (BCM_FIELD_QSET_TEST(fg->qset, bcmFieldQualifyExactMatchHitStatus)) { 908 if (lkup == BCM_FIELD_EXACT_MATCH_LOOKUP_0) { 909 BCM_FIELD_QSET_ADD(fg->qset, 910 _bcmFieldQualifyExactMatchHitStatusLookup0); 911 } else if (lkup == BCM_FIELD_EXACT_MATCH_LOOKUP_1) { 912 BCM_FIELD_QSET_ADD(fg->qset, 913 _bcmFieldQualifyExactMatchHitStatusLookup1); 914 } else { 915 rv = BCM_E_INTERNAL; 916 } 917 } 918 } else if (hint_entry->qual == bcmFieldQualifyExactMatchGroupClassId) { 919 /* Set Exact Match Group Class Id. */ 920 if (BCM_FIELD_QSET_TEST(fg->qset, bcmFieldQualifyExactMatchGroupClassId)) { 921 if (lkup == BCM_FIELD_EXACT_MATCH_LOOKUP_0) { 922 BCM_FIELD_QSET_ADD(fg->qset, 923 _bcmFieldQualifyExactMatchGroupClassIdLookup0); 924 } else if (lkup == BCM_FIELD_EXACT_MATCH_LOOKUP_1) { 925 BCM_FIELD_QSET_ADD(fg->qset, 926 _bcmFieldQualifyExactMatchGroupClassIdLookup1); 927 } else { 928 rv = BCM_E_INTERNAL; 929 } 930 } 931 } else if (hint_entry->qual == bcmFieldQualifyExactMatchActionClassId) { 932 /* Set Exact Match Action Class Id. */ 933 if (BCM_FIELD_QSET_TEST(fg->qset, bcmFieldQualifyExactMatchActionClassId)) { 934 if (lkup == BCM_FIELD_EXACT_MATCH_LOOKUP_0) { 935 BCM_FIELD_QSET_ADD(fg->qset, 936 _bcmFieldQualifyExactMatchActionClassIdLookup0); 937 } else if (lkup == BCM_FIELD_EXACT_MATCH_LOOKUP_1) { 938 BCM_FIELD_QSET_ADD(fg->qset, 939 _bcmFieldQualifyExactMatchActionClassIdLookup1); 940 } else { 941 rv = BCM_E_INTERNAL; 942 } 943 } 944 } else { 945 rv = BCM_E_PARAM; 946 } 947 948 return (rv); 949 } 950 951 /* 952 * Function: 953 * _field_th_exactmatch_slice_validate 954 * Purpose: 955 * Validate Exact Match Slice Allocation. 956 * Parameters: 957 * unit - (IN) BCM device number. 958 * stage_fc - (IN) Stage Control structure. 959 * fg - (IN) field group structure. 960 * slice_id - (IN) Slice Identifier. 961 * Returns: 962 * BCM_E_XXX 963 * Notes: 964 */ 965 int 966 _field_th_exactmatch_slice_validate(int unit, 967 _field_stage_t *stage_fc, 968 _field_group_t *fg, int slice_id) 969 { 970 int rv = BCM_E_NONE; /* Operational Status */ 971 _field_group_t *fg_ptr = NULL; /* Field Group Pointer. */ 972 _field_lt_slice_t *lt_slice = NULL; /* Lt Slice Pointer. */ 973 _field_slice_t *fs_part = NULL; /* Field slice Pointer. */ 974 975 /* Input parameters check. */ 976 if (NULL == stage_fc || NULL == fg) { 977 return (BCM_E_PARAM); 978 } 979 980 /* Lookup One is not present in TH3 EM */ 981 #if defined(BCM_TOMAHAWK3_SUPPORT) 982 if (soc_feature(unit, soc_feature_th3_style_fp)) { 983 if (1 == (slice_id % 3)) { 984 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 985 "FP(unit %d) Verb: Lookup One" 986 " not supported.\n"), unit)); 987 return (BCM_E_CONFIG); 988 } 989 } 990 #endif 991 /* In Exact Match Single and Double Wide 992 * Groups can share slices. 993 */ 994 if ((fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE) && (1 == (slice_id % 3))) { 995 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 996 "FP(unit %d) Verb: slices not available for DoubleWide" 997 " exact match group.\n"), unit)); 998 return (BCM_E_CONFIG); 999 } 1000 1001 if ((fg->flags & _FP_GROUP_SPAN_SINGLE_SLICE) && (1 == (slice_id % 3))) { 1002 fs_part = stage_fc->slices[fg->instance] + (slice_id - 1); 1003 if (fs_part->group_flags & _FP_GROUP_SPAN_DOUBLE_SLICE) { 1004 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 1005 "FP(unit %d) Verb: slice=%d is secondary " 1006 "slice of DoubleWide" 1007 " group.\n"), unit, slice_id)); 1008 return (BCM_E_CONFIG); 1009 } 1010 } 1011 1012 if ((fg->flags & _FP_GROUP_SPAN_DOUBLE_SLICE)) { 1013 fs_part = stage_fc->slices[fg->instance] + (slice_id + 1); 1014 if (fs_part->group_flags & _FP_GROUP_SPAN_SINGLE_SLICE) { 1015 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 1016 "FP(unit %d) Verb: slice=%d is already occupied " 1017 "by SingleWide" 1018 " group.\n"), unit, (slice_id + 1))); 1019 return (BCM_E_CONFIG); 1020 } 1021 } 1022 1023 /* Retrieve the existing groups associated with the Slice */ 1024 rv = _bcm_field_slice_group_get_next(unit, fg->instance, 1025 fg->stage_id, slice_id, 1026 &fg_ptr, &fg_ptr); 1027 if (BCM_SUCCESS(rv)) { 1028 1029 /* TH3 needs to fetch group other than internal group if any */ 1030 if ((soc_feature(unit, soc_feature_sw_mmu_flush_rqe_operation)) && 1031 (fg_ptr->gid == _FP_INTERNAL_RESERVED_EM_ID)) { 1032 1033 lt_slice = fg_ptr->lt_slices; 1034 1035 /* Retrieve the existing groups associated with the Slice */ 1036 rv = _bcm_field_slice_group_get_next(unit, fg->instance, 1037 fg->stage_id, slice_id, 1038 &fg_ptr, &fg_ptr); 1039 1040 if (rv == BCM_E_NOT_FOUND) { 1041 /* Nothing to do. */ 1042 rv = BCM_E_NONE; 1043 goto next; 1044 } else if (BCM_FAILURE(rv)) { 1045 return rv; 1046 } 1047 1048 } 1049 1050 /* Group with priority ANY, can't share 1051 * slice with any other group's. */ 1052 if (BCM_FIELD_GROUP_PRIO_ANY == fg->priority) { 1053 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 1054 "Group with prio ANY" 1055 "can't share slice with any other groups.\n\r"))); 1056 return BCM_E_CONFIG; 1057 } 1058 1059 /* Compare the group priority with 1060 the existing group in the slice. */ 1061 if (fg->priority != fg_ptr->priority) { 1062 LOG_VERBOSE(BSL_LS_BCM_FP, (BSL_META_U(unit, 1063 "Slice[%d] contains other" 1064 " groups with different priority.\n\r"), 1065 slice_id)); 1066 return (BCM_E_CONFIG); 1067 } 1068 1069 if ((fg_ptr->flags & _FP_GROUP_PRESELECTOR_SUPPORT) == 0) { 1070 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 1071 "Group creation failed, Already default group exists" 1072 " with the same priority[%d].\n\r"), 1073 fg_ptr->priority)); 1074 return (BCM_E_PARAM); 1075 } 1076 1077 if ((fg->flags & _FP_GROUP_PRESELECTOR_SUPPORT) == 0) { 1078 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 1079 "Group creation failed, can't create a group with the" 1080 " priority" 1081 " same as existing preselector group priority[%d]\n\r"), 1082 fg_ptr->priority)); 1083 return (BCM_E_PARAM); 1084 } 1085 1086 lt_slice = fg_ptr->lt_slices; 1087 1088 } else if (rv == BCM_E_NOT_FOUND) { 1089 /* Nothing to do. */ 1090 rv = BCM_E_NONE; 1091 } else { 1092 return rv; 1093 } 1094 1095 next: 1096 1097 BCM_IF_ERROR_RETURN(_field_th_group_lt_slice_validate(unit, stage_fc, fg, 1098 slice_id, lt_slice)); 1099 1100 return (rv); 1101 } 1102 1103 /* 1104 * Function: 1105 * _field_th_keygen_em_profile_entry_pack 1106 * Purpose: 1107 * Build a LT keygen exact match program profile 1108 * table entry. 1109 * Parameters: 1110 * unit - (IN) BCM device number. 1111 * stage_fc - (IN) Stage field control structure. 1112 * fg - (IN) Field group structure. 1113 * part - (IN) Entry part number. 1114 * mem - (IN) Memory name identifier. 1115 * prof_entry - (IN/OUT) Entry buffer pointer. 1116 * Returns: 1117 * BCM_E_XXX 1118 */ 1119 int 1120 _field_th_keygen_em_profile_entry_pack(int unit, _field_stage_t *stage_fc, 1121 _field_group_t *fg, int part, soc_mem_t mem, 1122 exact_match_key_gen_program_profile_entry_t *prof_entry) 1123 { 1124 int idx; /* Iterator index. */ 1125 static const soc_field_t l1_32_sel[] = /* 32 bit extractors. */ 1126 { 1127 L1_E32_SEL_0f, 1128 L1_E32_SEL_1f, 1129 L1_E32_SEL_2f, 1130 L1_E32_SEL_3f 1131 }; 1132 static const soc_field_t l1_16_sel[] = /* 16 bit extractors. */ 1133 { 1134 L1_E16_SEL_0f, 1135 L1_E16_SEL_1f, 1136 L1_E16_SEL_2f, 1137 L1_E16_SEL_3f, 1138 L1_E16_SEL_4f, 1139 L1_E16_SEL_5f, 1140 L1_E16_SEL_6f 1141 }; 1142 static const soc_field_t l1_8_sel[] = /* 8 bit extractors. */ 1143 { 1144 L1_E8_SEL_0f, 1145 L1_E8_SEL_1f, 1146 L1_E8_SEL_2f, 1147 L1_E8_SEL_3f, 1148 L1_E8_SEL_4f, 1149 L1_E8_SEL_5f, 1150 L1_E8_SEL_6f 1151 }; 1152 static const soc_field_t l1_4_sel[] = /* 4 bit extractors. */ 1153 { 1154 L1_E4_SEL_0f, 1155 L1_E4_SEL_1f, 1156 L1_E4_SEL_2f, 1157 L1_E4_SEL_3f, 1158 L1_E4_SEL_4f, 1159 L1_E4_SEL_5f, 1160 L1_E4_SEL_6f, 1161 L1_E4_SEL_7f 1162 }; 1163 static const soc_field_t l1_2_sel[] = /* 2 bit extractors. */ 1164 { 1165 L1_E2_SEL_0f, 1166 L1_E2_SEL_1f, 1167 L1_E2_SEL_2f, 1168 L1_E2_SEL_3f, 1169 L1_E2_SEL_4f, 1170 L1_E2_SEL_5f, 1171 L1_E2_SEL_6f, 1172 L1_E2_SEL_7f 1173 }; 1174 static const soc_field_t l2_16_sel[] = /* 16 bit extractors. */ 1175 { 1176 L2_E16_SEL_0f, 1177 L2_E16_SEL_1f, 1178 L2_E16_SEL_2f, 1179 L2_E16_SEL_3f, 1180 L2_E16_SEL_4f, 1181 L2_E16_SEL_5f, 1182 L2_E16_SEL_6f, 1183 L2_E16_SEL_7f, 1184 L2_E16_SEL_8f, 1185 L2_E16_SEL_9f 1186 }; 1187 static const soc_field_t l3_4_sel[] = /* 4 bit extractors. */ 1188 { 1189 L3_E4_SEL_0f, 1190 L3_E4_SEL_1f, 1191 L3_E4_SEL_2f, 1192 L3_E4_SEL_3f, 1193 L3_E4_SEL_4f, 1194 L3_E4_SEL_5f, 1195 L3_E4_SEL_6f, 1196 L3_E4_SEL_7f, 1197 L3_E4_SEL_8f, 1198 L3_E4_SEL_9f, 1199 L3_E4_SEL_10f, 1200 L3_E4_SEL_11f, 1201 L3_E4_SEL_12f, 1202 L3_E4_SEL_13f, 1203 L3_E4_SEL_14f, 1204 L3_E4_SEL_15f, 1205 L3_E4_SEL_16f, 1206 L3_E4_SEL_17f, 1207 L3_E4_SEL_18f, 1208 L3_E4_SEL_19f, 1209 L3_E4_SEL_20f 1210 }; 1211 static const soc_field_t l3_2_sel[] = /* 2 bit extractors. */ 1212 { 1213 L3_E2_SEL_0f, 1214 L3_E2_SEL_1f, 1215 L3_E2_SEL_2f, 1216 L3_E2_SEL_3f, 1217 L3_E2_SEL_4f 1218 }; 1219 static const soc_field_t l3_1_sel[] = /* 1 bit extractors. */ 1220 { 1221 L3_E1_SEL_0f, 1222 L3_E1_SEL_1f 1223 }; 1224 1225 /* Input parameters check. */ 1226 if ((NULL == stage_fc) || (NULL == fg) || (NULL == prof_entry)) { 1227 return (BCM_E_PARAM); 1228 } 1229 1230 /* Set 32bit extractor selcode values. */ 1231 for (idx = 0; idx < 4; idx++) { 1232 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l1_e32_sel[idx]) { 1233 soc_mem_field32_set(unit, mem, prof_entry, l1_32_sel[idx], 1234 fg->ext_codes[part].l1_e32_sel[idx]); 1235 } 1236 } 1237 1238 /* Set 16bit extractor selcode values. */ 1239 for (idx = 0; idx < 7; idx++) { 1240 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l1_e16_sel[idx]) { 1241 soc_mem_field32_set(unit, mem, prof_entry, l1_16_sel[idx], 1242 fg->ext_codes[part].l1_e16_sel[idx]); 1243 } 1244 } 1245 1246 /* Set 8bit extractor selcode values. */ 1247 for (idx = 0; idx < 7; idx++) { 1248 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l1_e8_sel[idx]) { 1249 soc_mem_field32_set(unit, mem, prof_entry, l1_8_sel[idx], 1250 fg->ext_codes[part].l1_e8_sel[idx]); 1251 } 1252 } 1253 1254 /* Set 4bit extractor selcode values. */ 1255 for (idx = 0; idx < 8; idx++) { 1256 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l1_e4_sel[idx]) { 1257 soc_mem_field32_set(unit, mem, prof_entry, l1_4_sel[idx], 1258 fg->ext_codes[part].l1_e4_sel[idx]); 1259 } 1260 } 1261 1262 /* Set 2bit extractor selcode values. */ 1263 for (idx = 0; idx < 8; idx++) { 1264 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l1_e2_sel[idx]) { 1265 soc_mem_field32_set(unit, mem, prof_entry, l1_2_sel[idx], 1266 fg->ext_codes[part].l1_e2_sel[idx]); 1267 } 1268 } 1269 1270 /* Set 16bit extractor selcode values. */ 1271 for (idx = 0; idx < 10; idx++) { 1272 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l2_e16_sel[idx]) { 1273 soc_mem_field32_set(unit, mem, prof_entry, l2_16_sel[idx], 1274 fg->ext_codes[part].l2_e16_sel[idx]); 1275 } 1276 } 1277 1278 /* Set 4bit extractor selcode values. */ 1279 for (idx = 0; idx < 21; idx++) { 1280 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l3_e4_sel[idx]) { 1281 soc_mem_field32_set(unit, mem, prof_entry, l3_4_sel[idx], 1282 fg->ext_codes[part].l3_e4_sel[idx]); 1283 } 1284 } 1285 1286 /* Set 2bit extractor selcode values. */ 1287 for (idx = 0; idx < 5; idx++) { 1288 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l3_e2_sel[idx]) { 1289 soc_mem_field32_set(unit, mem, prof_entry, l3_2_sel[idx], 1290 fg->ext_codes[part].l3_e2_sel[idx]); 1291 } 1292 } 1293 1294 /* Set 1bit extractor selcode values. */ 1295 for (idx = 0; idx < 2; idx++) { 1296 if (_FP_EXT_SELCODE_DONT_CARE != fg->ext_codes[part].l3_e1_sel[idx]) { 1297 soc_mem_field32_set(unit, mem, prof_entry, l3_1_sel[idx], 1298 fg->ext_codes[part].l3_e1_sel[idx]); 1299 } 1300 } 1301 1302 return (BCM_E_NONE); 1303 } 1304 /* 1305 * Function: 1306 * _bcm_field_th_em_udf_keygen_mask_get 1307 * Purpose: 1308 * Get the mask to be applied for data qualifiers. 1309 * Parameters: 1310 * unit - (IN) BCM device number. 1311 * fg - (IN) Field group structure. 1312 * qid - (IN) Qualifier number. 1313 * mask - (OUT) Mask to be applied. 1314 * Returns: 1315 * BCM_E_XXX 1316 */ 1317 int _bcm_field_th_em_udf_keygen_mask_get(int unit, 1318 _field_group_t *fg, 1319 uint16 qid, uint32 *mask) 1320 { 1321 _field_hints_t *f_ht = NULL; /* Field hints Structure. */ 1322 _field_hint_t *hint_node = NULL; /* Field hint Structure. */ 1323 int rv = BCM_E_NONE; /* Operational status. */ 1324 uint32 mask_temp = 0; 1325 uint8 idx = 0; /* Index Variable. */ 1326 uint8 num_bytes = 0; /* number of bytes used in each UDF chunk. */ 1327 _field_stage_t *stage_fc = NULL; /* Stage operational Structure. */ 1328 1329 /* Parameters Check. */ 1330 if (NULL == fg) { 1331 return BCM_E_PARAM; 1332 } 1333 1334 /* Exact Match and IFP shares UDF's */ 1335 rv = _field_stage_control_get(unit, _BCM_FIELD_STAGE_INGRESS, &stage_fc); 1336 BCM_IF_ERROR_RETURN(rv); 1337 1338 if (stage_fc->data_ctrl == NULL) { 1339 return BCM_E_INTERNAL; 1340 } 1341 1342 /* Derive the offset of byte bit map in QSET's udf_map 1343 * for a data qualifier. */ 1344 *mask = 0; 1345 switch (qid) { 1346 case _bcmFieldQualifyData0: 1347 num_bytes = 2; 1348 idx = stage_fc->data_ctrl->num_elems * 2; 1349 break; 1350 case _bcmFieldQualifyData1: 1351 num_bytes = 2; 1352 idx = (stage_fc->data_ctrl->num_elems * 2) + 2; 1353 break; 1354 case _bcmFieldQualifyData2: 1355 num_bytes = 4; 1356 idx = (stage_fc->data_ctrl->num_elems * 2) + 4; 1357 break; 1358 case _bcmFieldQualifyData3: 1359 num_bytes = 4; 1360 idx = (stage_fc->data_ctrl->num_elems * 2) + 8; 1361 break; 1362 case _bcmFieldQualifyData4: 1363 num_bytes = 4; 1364 idx = (stage_fc->data_ctrl->num_elems * 2) + 12; 1365 break; 1366 case _bcmFieldQualifyData5: 1367 num_bytes = 2; 1368 idx = (stage_fc->data_ctrl->num_elems * 2) + 16; 1369 break; 1370 case _bcmFieldQualifyData6: 1371 num_bytes = 2; 1372 idx = (stage_fc->data_ctrl->num_elems * 2) + 18; 1373 break; 1374 case _bcmFieldQualifyData7: 1375 num_bytes = 4; 1376 idx = (stage_fc->data_ctrl->num_elems * 2) + 20; 1377 break; 1378 case _bcmFieldQualifyData8: 1379 num_bytes = 4; 1380 idx = (stage_fc->data_ctrl->num_elems * 2) + 24; 1381 break; 1382 case _bcmFieldQualifyData9: 1383 num_bytes = 4; 1384 idx = (stage_fc->data_ctrl->num_elems * 2) + 28; 1385 break; 1386 default: 1387 *mask = 0xFFFFFFFF; 1388 break; 1389 } 1390 1391 if (idx) { 1392 if (SHR_BITGET(fg->qset.udf_map, idx)) { 1393 *mask |= 0xFF; 1394 } 1395 1396 if (SHR_BITGET(fg->qset.udf_map, idx + 1)) { 1397 *mask |= 0xFF00; 1398 } 1399 1400 if (4 == num_bytes) { 1401 if (SHR_BITGET(fg->qset.udf_map, idx + 2)) { 1402 *mask |= 0xFF0000; 1403 } 1404 1405 if (SHR_BITGET(fg->qset.udf_map, idx + 3)) { 1406 *mask |= 0xFF000000; 1407 } 1408 } 1409 } 1410 1411 if (fg->hintid) { 1412 if (0 == *mask) { 1413 return BCM_E_NONE; 1414 } 1415 mask_temp = *mask; 1416 *mask = 0; 1417 BCM_IF_ERROR_RETURN(_field_hints_control_get (unit, fg->hintid, &f_ht)); 1418 /* Not a valid hint Id. */ 1419 if (NULL == f_ht) { 1420 return BCM_E_NONE; 1421 } 1422 /* No hints are attached to the hintid. */ 1423 if (NULL == f_ht->hints) { 1424 return BCM_E_NONE; 1425 } 1426 /* Go through all the hints in the hintid. */ 1427 hint_node = f_ht->hints; 1428 while (NULL != hint_node) { 1429 if (bcmFieldHintTypeExtraction == hint_node->hint->hint_type) { 1430 BCM_IF_ERROR_RETURN(_bcm_th_qual_hint_bmp_get(unit, qid, 1, hint_node, mask, 1431 0, NULL, NULL)); 1432 } 1433 hint_node = hint_node->next; 1434 } 1435 if (0 == *mask) { 1436 *mask = mask_temp; 1437 } 1438 } 1439 1440 return BCM_E_NONE; 1441 } 1442 1443 1444 /* 1445 * Function: 1446 * _field_th_keygen_em_profile_mask_entry_pack 1447 * Purpose: 1448 * Build a LT keygen exact match program profile 1449 * mask table entry. 1450 * Parameters: 1451 * unit - (IN) BCM device number. 1452 * stage_fc - (IN) Stage field control structure. 1453 * fg - (IN) Field group structure. 1454 * part - (IN) Entry part number. 1455 * mem - (IN) Memory name identifier. 1456 * prof_entry - (IN/OUT) Entry buffer pointer. 1457 * Returns: 1458 * BCM_E_XXX 1459 */ 1460 int 1461 _field_th_keygen_em_profile_mask_entry_pack(int unit, 1462 _field_stage_t *stage_fc, 1463 _field_group_t *fg, 1464 int part, soc_mem_t mem, 1465 exact_match_key_gen_mask_entry_t *prof_entry) 1466 { 1467 _bcm_field_group_qual_t *q_arr = NULL; /* Group Qualifier Array. */ 1468 _bcm_field_qual_offset_t *offset = NULL; /* Qualifier Offset Pointer. */ 1469 uint32 *fn_data = NULL; /* Data Buffer Pointer. */ 1470 uint32 value = 0; /* Value. */ 1471 uint32 mask = 0; /* Mask. */ 1472 int i = 0, j = 0; /* Iterators. */ 1473 int rv = BCM_E_NONE; /* Operational Status */ 1474 1475 /* Input Parameter Check. */ 1476 if ((NULL == stage_fc) || 1477 (NULL == fg) || 1478 (NULL == prof_entry)) { 1479 return (BCM_E_PARAM); 1480 } 1481 1482 /* Retreive Buffer data pointer and qualifier array. */ 1483 fn_data = (uint32 *)prof_entry; 1484 q_arr = &(fg->qual_arr[_FP_ENTRY_TYPE_DEFAULT][part]); 1485 1486 /* Set Mask entry. */ 1487 if (q_arr != NULL) { 1488 if (q_arr->size > 0) { 1489 for(i=0; i < q_arr->size; i++) { 1490 1491 offset = q_arr->offset_arr + i; 1492 1493 if ((_bcmFieldQualifyData0 == q_arr->qid_arr[i]) || 1494 (_bcmFieldQualifyData1 == q_arr->qid_arr[i]) || 1495 (_bcmFieldQualifyData2 == q_arr->qid_arr[i]) || 1496 (_bcmFieldQualifyData3 == q_arr->qid_arr[i]) || 1497 (_bcmFieldQualifyData4 == q_arr->qid_arr[i]) || 1498 (_bcmFieldQualifyData5 == q_arr->qid_arr[i]) || 1499 (_bcmFieldQualifyData6 == q_arr->qid_arr[i]) || 1500 (_bcmFieldQualifyData7 == q_arr->qid_arr[i]) || 1501 (_bcmFieldQualifyData8 == q_arr->qid_arr[i]) || 1502 (_bcmFieldQualifyData9 == q_arr->qid_arr[i]) || 1503 (_bcmFieldQualifyData10 == q_arr->qid_arr[i]) || 1504 (_bcmFieldQualifyData11 == q_arr->qid_arr[i]) || 1505 (_bcmFieldQualifyData12 == q_arr->qid_arr[i]) || 1506 (_bcmFieldQualifyData13 == q_arr->qid_arr[i]) || 1507 (_bcmFieldQualifyData14 == q_arr->qid_arr[i]) || 1508 (_bcmFieldQualifyData15 == q_arr->qid_arr[i])) { 1509 1510 if (soc_feature(unit, soc_feature_udf_support)) { 1511 #if defined (BCM_TOMAHAWK3_SUPPORT) 1512 if (soc_feature(unit, soc_feature_th3_style_fp)) { 1513 rv = _bcm_field_th3_em_udf_keygen_mask_get(unit, fg, 1514 q_arr->qid_arr[i], 1515 &mask); 1516 } else 1517 #endif 1518 { 1519 rv = _bcm_field_th_em_udf_keygen_mask_get(unit, fg, 1520 q_arr->qid_arr[i], 1521 &mask); 1522 } 1523 } 1524 #if defined (BCM_TRIDENT3_SUPPORT) 1525 else if (soc_feature(unit, soc_feature_udf_td3x_support)) { 1526 rv = _bcm_field_td3_em_udf_keygen_mask_get(unit, fg, 1527 q_arr->qid_arr[i], 1528 &mask); 1529 } 1530 #endif 1531 BCM_IF_ERROR_RETURN(rv); 1532 1533 for (j=0; j < offset->num_offsets; j++) { 1534 if (offset->width[j] > 0) { 1535 value = (1 << offset->width[j]) - 1; 1536 value = value & mask; 1537 mask = (mask >> offset->width[j]); 1538 if (!value) { 1539 continue; 1540 } 1541 rv = _bcm_field_th_val_set(fn_data, &value, 1542 offset->offset[j], 1543 offset->width[j]); 1544 BCM_IF_ERROR_RETURN(rv); 1545 } 1546 } 1547 } else { 1548 for (j=0; j < offset->num_offsets; j++) { 1549 if (offset->width[j] > 0) { 1550 value = (1 << offset->width[j]) - 1; 1551 rv = _bcm_field_th_val_set(fn_data, &value, 1552 offset->offset[j], 1553 offset->width[j]); 1554 BCM_IF_ERROR_RETURN(rv); 1555 1556 } 1557 } 1558 } 1559 } 1560 } 1561 } 1562 1563 return (BCM_E_NONE); 1564 } 1565 1566 /* 1567 * Function: 1568 * _field_th_em_flex_stat_action_set 1569 * Purpose: 1570 * Attach Flex Stat Action data for Exact Match Entry. 1571 * Parameters: 1572 * unit - (IN) BCM device number. 1573 * f_ent - (IN) Field Entry. 1574 * buf - (OUT) Exact Match Action Stat Data Buffer. 1575 * Returns: 1576 * BCM_E_XXX 1577 * Notes: 1578 */ 1579 STATIC int 1580 _field_th_em_flex_stat_action_set(int unit, _field_entry_t *f_ent, 1581 soc_mem_t policy_mem, 1582 uint32 *buf) 1583 { 1584 int rv = BCM_E_NONE; /* BCM Operational Status. */ 1585 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 1586 _field_group_t *fg = NULL; /* Field Group Control. */ 1587 _field_stat_t *f_st = NULL; /* Field statistics descriptor. */ 1588 int idx = 0; /* Stat array index. */ 1589 uint32 g_off = 0, y_off = 0, r_off = 0; 1590 /* Color Offsets. */ 1591 uint32 hw_real_mode = 0; /* Real Hw Mode. */ 1592 uint32 hw_pool_num = 0; /* Stat pool Number. */ 1593 uint32 hw_ctr_base_idx = 0; /* Stat Ctr base index. */ 1594 soc_mem_t mem; /* Memory Identifier. */ 1595 1596 /* Input Parameters Check. */ 1597 if ((NULL == f_ent) || 1598 (NULL == f_ent->group) || 1599 (NULL == f_ent->fs) || 1600 (NULL == buf)) { 1601 return (BCM_E_PARAM); 1602 } 1603 1604 /* Retreive Field Group */ 1605 fg = f_ent->group; 1606 1607 /* Retreive Stage Control. */ 1608 BCM_IF_ERROR_RETURN( 1609 _field_stage_control_get(unit, fg->stage_id, &stage_fc)); 1610 1611 if (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 1612 /* Get Hardware Buffer Pointer and memory identifier. */ 1613 if ((fg->em_mode == _FieldExactMatchMode128) || 1614 (fg->em_mode == _FieldExactMatchMode160)) { 1615 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 1616 mem = EXACT_MATCH_2m; 1617 } else { 1618 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 1619 EXACT_MATCH_2m, 1620 fg->instance, &mem)); 1621 } 1622 } else { 1623 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 1624 mem = EXACT_MATCH_4m; 1625 } else { 1626 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 1627 EXACT_MATCH_4m, 1628 fg->instance, &mem)); 1629 } 1630 } 1631 } else { 1632 mem = policy_mem; 1633 } 1634 1635 /* Increment statistics hw reference count. */ 1636 if (f_ent->statistic.flags & _FP_ENTRY_STAT_VALID) { 1637 1638 /* Get statistics entity description structure. */ 1639 BCM_IF_ERROR_RETURN 1640 (_bcm_field_stat_get(unit, f_ent->statistic.sid, &f_st)); 1641 if (_FP_INVALID_INDEX != f_st->hw_index) { 1642 /* 1643 * Not detaching the stats if there is no change in it during entry modification (re-install). 1644 * Currently, it is applicable to only IFP stage. 1645 */ 1646 if ((_BCM_FIELD_STAGE_INGRESS != stage_fc->stage_id) || 1647 ((f_ent->statistic.flags & _FP_ENTRY_STAT_DIRTY) && 1648 !(f_ent->statistic.flags & _FP_ENTRY_STAT_INSTALLED))) { 1649 /* 1650 * For STATs that are shared by entries, hardware counters 1651 * are not allocated again. But reference count is incremented 1652 * for these counters. 1653 */ 1654 f_st->hw_ref_count++; 1655 1656 BCM_IF_ERROR_RETURN 1657 (_bcm_esw_stat_flex_attach_ingress_table_counters1 1658 (unit, mem, 0, f_st->hw_mode, f_st->hw_index, 1659 f_st->pool_index, buf)); 1660 1661 /* Mark entry as installed. */ 1662 f_ent->statistic.flags |= _FP_ENTRY_STAT_INSTALLED; 1663 } 1664 1665 /* Set Stat Action Buffer. */ 1666 #if defined(BCM_TOMAHAWK3_SUPPORT) 1667 if(soc_feature(unit, soc_feature_th3_style_fp)) { 1668 1669 rv = _bcm_field_th_em_color_offset_get(unit, f_st, 1670 &g_off, &y_off, &r_off); 1671 BCM_IF_ERROR_RETURN(rv); 1672 1673 rv = _bcm_field_th_val_set(buf, &y_off, 23, 2); 1674 BCM_IF_ERROR_RETURN(rv); 1675 1676 rv = _bcm_field_th_val_set(buf, &r_off, 21, 2); 1677 BCM_IF_ERROR_RETURN(rv); 1678 1679 rv = _bcm_field_th_val_set(buf, &g_off, 19, 2); 1680 BCM_IF_ERROR_RETURN(rv); 1681 1682 hw_pool_num = f_st->pool_index; 1683 rv = _bcm_field_th_val_set(buf, &hw_pool_num, 14, 5); 1684 BCM_IF_ERROR_RETURN(rv); 1685 1686 rv = _bcm_esw_stat_flex_get_hw_mode(unit, 1687 f_st->hw_mode, &hw_real_mode); 1688 BCM_IF_ERROR_RETURN(rv); 1689 1690 rv = _bcm_field_th_val_set(buf, &hw_real_mode, 12, 2); 1691 BCM_IF_ERROR_RETURN(rv); 1692 1693 hw_ctr_base_idx = f_st->hw_index; 1694 rv = _bcm_field_th_val_set(buf, &hw_ctr_base_idx, 0, 12); 1695 1696 BCM_IF_ERROR_RETURN(rv); 1697 } else 1698 #endif 1699 { 1700 rv = _bcm_field_th_em_color_offset_get(unit, f_st, 1701 &g_off, &y_off, &r_off); 1702 BCM_IF_ERROR_RETURN(rv); 1703 1704 rv = _bcm_field_th_val_set(buf, &g_off, 0, 2); 1705 BCM_IF_ERROR_RETURN(rv); 1706 1707 rv = _bcm_field_th_val_set(buf, &y_off, 2, 2); 1708 BCM_IF_ERROR_RETURN(rv); 1709 1710 rv = _bcm_field_th_val_set(buf, &r_off, 4, 2); 1711 BCM_IF_ERROR_RETURN(rv); 1712 1713 hw_pool_num = f_st->pool_index; 1714 rv = _bcm_field_th_val_set(buf, &hw_pool_num, 6, 5); 1715 BCM_IF_ERROR_RETURN(rv); 1716 1717 rv = _bcm_esw_stat_flex_get_hw_mode(unit, 1718 f_st->hw_mode, &hw_real_mode); 1719 BCM_IF_ERROR_RETURN(rv); 1720 1721 rv = _bcm_field_th_val_set(buf, &hw_real_mode, 11, 2); 1722 BCM_IF_ERROR_RETURN(rv); 1723 1724 hw_ctr_base_idx = f_st->hw_index; 1725 rv = _bcm_field_th_val_set(buf, &hw_ctr_base_idx, 13, 1726 (soc_feature(unit, soc_feature_td3_style_fp) ? 13 : 12)); 1727 BCM_IF_ERROR_RETURN(rv); 1728 } 1729 /* 1730 * Not detaching the stats if there is no change in it during entry modification (re-install). 1731 * So do not copy the previous stat value as the copy should be done only for the first time. 1732 * Currently, it is applicable to only IFP stage. 1733 */ 1734 if (((_BCM_FIELD_STAGE_INGRESS != stage_fc->stage_id) || 1735 (f_ent->statistic.flags & _FP_ENTRY_STAT_DIRTY)) && 1736 (1 == f_st->hw_ref_count)) { 1737 /* 1738 * Write individual statistics previous value, first time 1739 * entry is installed in hardware. 1740 */ 1741 for (idx = 0; idx < f_st->nstat; idx++) { 1742 BCM_IF_ERROR_RETURN 1743 (_field_stat_value_set(unit, f_st, f_st->stat_arr[idx], 1744 f_st->stat_values[idx])); 1745 } 1746 } 1747 } 1748 } 1749 1750 return (rv); 1751 } 1752 1753 /* 1754 * Function: 1755 * _field_th_em_qos_profile_actions_alloc 1756 * Purpose: 1757 * Allocate Qos Actions Profile for Exact Match Entry. 1758 * Parameters: 1759 * unit - (IN) BCM device number. 1760 * f_ent - (IN) Field Entry. 1761 * qp_idx - (OUT) Qos Actions Profile Index. 1762 * Returns: 1763 * BCM_E_XXX 1764 * Notes: 1765 * This api will allocate actions in exact match 1766 * qos profile table. Also will return qos profile 1767 * index allocated. 1768 */ 1769 STATIC int 1770 _field_th_em_qos_profile_actions_alloc(int unit, 1771 _field_entry_t *f_ent, 1772 uint32 *qp_idx) 1773 { 1774 int rv = BCM_E_NONE; /* Operational Status. */ 1775 _field_group_t *fg = NULL; /* Field Group Control. */ 1776 _field_action_t *fa = NULL; /* Field Action Structure. */ 1777 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 1778 exact_match_qos_actions_profile_entry_t qos_prof_entry; 1779 /* Qos Actions Profile Entry Buffer. */ 1780 void *entries[1]; /* Profile Entry. */ 1781 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 1782 soc_mem_t mem; /* Memory Identifier. */ 1783 1784 /* Input Parameter Check */ 1785 if ((NULL == f_ent) || 1786 (NULL == f_ent->group) || 1787 (NULL == qp_idx)) { 1788 return (BCM_E_PARAM); 1789 } 1790 1791 /* Retreive Field Entry Group */ 1792 fg = f_ent->group; 1793 1794 /* Retreive Stage Control */ 1795 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 1796 fg->stage_id, 1797 &stage_fc)); 1798 1799 /* Assign Qos Actions Profile Memory */ 1800 mem = EXACT_MATCH_QOS_ACTIONS_PROFILEm; 1801 1802 /* Initialize Qos Profile Actions Entry */ 1803 bufp = (uint32 *)&qos_prof_entry; 1804 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 1805 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 1806 1807 /* Set QoS Profile Action Buffer. */ 1808 for (fa = f_ent->actions; fa != NULL; fa = fa->next) { 1809 if (_FP_ACTION_VALID & fa->flags) { 1810 switch (fa->action) { 1811 case bcmFieldActionCosQNew: 1812 case bcmFieldActionGpCosQNew: 1813 case bcmFieldActionYpCosQNew: 1814 case bcmFieldActionRpCosQNew: 1815 case bcmFieldActionCosMapNew: 1816 case bcmFieldActionGpCosMapNew: 1817 case bcmFieldActionYpCosMapNew: 1818 case bcmFieldActionRpCosMapNew: 1819 case bcmFieldActionUcastCosQNew: 1820 case bcmFieldActionGpUcastCosQNew: 1821 case bcmFieldActionYpUcastCosQNew: 1822 case bcmFieldActionRpUcastCosQNew: 1823 case bcmFieldActionMcastCosQNew: 1824 case bcmFieldActionGpMcastCosQNew: 1825 case bcmFieldActionYpMcastCosQNew: 1826 case bcmFieldActionRpMcastCosQNew: 1827 case bcmFieldActionPrioIntNew: 1828 case bcmFieldActionGpPrioIntNew: 1829 case bcmFieldActionYpPrioIntNew: 1830 case bcmFieldActionRpPrioIntNew: 1831 case bcmFieldActionDropPrecedence: 1832 case bcmFieldActionGpDropPrecedence: 1833 case bcmFieldActionYpDropPrecedence: 1834 case bcmFieldActionRpDropPrecedence: 1835 case bcmFieldActionPrioIntCopy: 1836 case bcmFieldActionPrioIntTos: 1837 case bcmFieldActionPrioIntCancel: 1838 case bcmFieldActionGpPrioIntCopy: 1839 case bcmFieldActionGpPrioIntTos: 1840 case bcmFieldActionGpPrioIntCancel: 1841 case bcmFieldActionYpPrioIntCopy: 1842 case bcmFieldActionYpPrioIntTos: 1843 case bcmFieldActionYpPrioIntCancel: 1844 case bcmFieldActionRpPrioIntCopy: 1845 case bcmFieldActionRpPrioIntTos: 1846 case bcmFieldActionRpPrioIntCancel: 1847 case bcmFieldActionGpIntCongestionNotificationNew: 1848 case bcmFieldActionYpIntCongestionNotificationNew: 1849 case bcmFieldActionRpIntCongestionNotificationNew: 1850 case bcmFieldActionPfcClassNew: 1851 case bcmFieldActionUntaggedPacketPriorityNew: 1852 rv = _bcm_field_th_profile1_action_set(unit, 1853 f_ent, fa, 1854 bufp); 1855 BCM_IF_ERROR_RETURN(rv); 1856 fa->flags &= ~_FP_ACTION_DIRTY; 1857 break; 1858 case bcmFieldActionEcnNew: 1859 case bcmFieldActionGpEcnNew: 1860 case bcmFieldActionYpEcnNew: 1861 case bcmFieldActionRpEcnNew: 1862 case bcmFieldActionPrioPktNew: 1863 case bcmFieldActionGpPrioPktNew: 1864 case bcmFieldActionYpPrioPktNew: 1865 case bcmFieldActionRpPrioPktNew: 1866 case bcmFieldActionGpTosPrecedenceNew: 1867 case bcmFieldActionDscpNew: 1868 case bcmFieldActionGpDscpNew: 1869 case bcmFieldActionYpDscpNew: 1870 case bcmFieldActionRpDscpNew: 1871 case bcmFieldActionPrioPktCopy: 1872 case bcmFieldActionGpPrioPktCopy: 1873 case bcmFieldActionYpPrioPktCopy: 1874 case bcmFieldActionRpPrioPktCopy: 1875 case bcmFieldActionPrioPktTos: 1876 case bcmFieldActionGpPrioPktTos: 1877 case bcmFieldActionYpPrioPktTos: 1878 case bcmFieldActionRpPrioPktTos: 1879 case bcmFieldActionPrioPktCancel: 1880 case bcmFieldActionGpPrioPktCancel: 1881 case bcmFieldActionYpPrioPktCancel: 1882 case bcmFieldActionRpPrioPktCancel: 1883 case bcmFieldActionDot1pPreserve: 1884 case bcmFieldActionGpDot1pPreserve: 1885 case bcmFieldActionYpDot1pPreserve: 1886 case bcmFieldActionRpDot1pPreserve: 1887 case bcmFieldActionDscpCancel: 1888 case bcmFieldActionGpDscpCancel: 1889 case bcmFieldActionYpDscpCancel: 1890 case bcmFieldActionRpDscpCancel: 1891 case bcmFieldActionGpTosPrecedenceCopy: 1892 case bcmFieldActionDscpPreserve: 1893 case bcmFieldActionGpDscpPreserve: 1894 case bcmFieldActionYpDscpPreserve: 1895 case bcmFieldActionRpDscpPreserve: 1896 rv = _bcm_field_th_profile2_action_set(unit, 1897 f_ent, fa, 1898 bufp); 1899 BCM_IF_ERROR_RETURN(rv); 1900 fa->flags &= ~_FP_ACTION_DIRTY; 1901 break; 1902 default : 1903 /* Do nothing */ 1904 break; 1905 } 1906 } 1907 } 1908 1909 /* Set Profile Entry. */ 1910 entries[0] = bufp; 1911 1912 /* Add entry to Qos Actions Profile Tables In Hardware */ 1913 rv = soc_profile_mem_add(unit, 1914 &stage_fc->qos_action_profile[fg->instance], 1915 entries, 1, qp_idx); 1916 return rv; 1917 } 1918 1919 1920 1921 /* 1922 * Function: 1923 * _field_th_entry_action_profile_data_set 1924 * Purpose: 1925 * generate the action profiel data buffer from 1926 * Actions Profile index 1927 * 1) for Exact Match Entry of TH and TD3. 1928 * 2) for Ingress Entry of TD3. 1929 * Parameters: 1930 * unit - (IN) BCM device number. 1931 * f_ent - (IN) Field Entry. 1932 * abuf - (OUT) Action Data Buffer. 1933 * ap_idx - (IN) Actions Profile Index. 1934 * Returns: 1935 * BCM_E_XXX 1936 * Notes: 1937 * This api will return the filled action data 1938 * buffer using action profile entry index 1939 */ 1940 int 1941 _field_th_entry_action_profile_data_set(int unit, 1942 _field_entry_t *f_ent, 1943 uint32 *ap_idx, 1944 soc_mem_t policy_mem, 1945 uint32 *abuf) 1946 { 1947 int rv = BCM_E_NONE; /* Operational Status. */ 1948 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 1949 _field_group_t *fg = NULL; /* Field Group Control. */ 1950 _field_action_t *fa = NULL; /* Field Action Structure. */ 1951 exact_match_action_profile_entry_t em_act_prof_entry; 1952 /* Action Profile Table Buffer. */ 1953 ifp_policy_action_profile_entry_t ifp_act_prof_entry; 1954 /* Action Profile Table Buffer. */ 1955 void *act_prof_entry; /* Profile table buffer pointer */ 1956 _field_em_action_set_t acts_buf[_FieldActionSetCount]; 1957 /* Action Set Buuffer. */ 1958 _field_em_action_set_t *acts = NULL; 1959 /* Action Set Data. */ 1960 int idx; /* Exact Match Action Set 1961 Iterator. */ 1962 uint32 act_offset = 0; /* Exact Match Action Set 1963 Offset. */ 1964 uint32 meterbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 1965 /* Action Meter Data Buffer. */ 1966 uint8 field_action_set; /* to hold Action set value */ 1967 _bcm_field_action_conf_t *action_conf_ptr; 1968 /* Action configuration pointer */ 1969 int counter_present = 0; /* Counter Present flag. */ 1970 soc_mem_t mem; /* Memory Identifier. */ 1971 uint32 *action_set_bitmap; /* Action bitmap as per hardware*/ 1972 uint32 act_valid =0; /* Action valid flag */ 1973 _bcm_field_action_set_t *action_set_ptr; 1974 /* action set pointer */ 1975 uint8 *hw_bitmap; /* hw bitmap */ 1976 uint8 hw_bitmap_entries = 0; 1977 soc_field_info_t * f_info; /* field info structure. */ 1978 int meter_base = 0; /* meter field base offset */ 1979 1980 /* Input Parameter Check */ 1981 if ((NULL == f_ent) || 1982 (NULL == f_ent->group) || 1983 (NULL == abuf) || 1984 (NULL == ap_idx)) { 1985 return (BCM_E_PARAM); 1986 } 1987 1988 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 1989 "\n\n_field_th_entry_action_profile_data_set: ap_idx %d\n\r"),*ap_idx)); 1990 1991 /* Retreive Field Group */ 1992 fg = f_ent->group; 1993 1994 /* Retreive Stage Control */ 1995 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 1996 fg->stage_id, 1997 &stage_fc)); 1998 1999 /* Check whether it is a valid stage */ 2000 if (!(((SOC_IS_TOMAHAWKX(unit)) 2001 && (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH)) 2002 || soc_feature(unit, soc_feature_ifp_action_profiling))) 2003 { 2004 return BCM_E_INTERNAL; 2005 } 2006 action_set_ptr = stage_fc->action_set_ptr; 2007 /* Assign correct Action Profile Memory 2008 * and Action set's depending on stage */ 2009 if (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 2010 /* Assign Exact Match Action Profile Memory */ 2011 mem = EXACT_MATCH_ACTION_PROFILEm; 2012 act_prof_entry = &em_act_prof_entry; 2013 if (SOC_IS_TOMAHAWK(unit)) { 2014 hw_bitmap = em_action_profile_bitmap; 2015 hw_bitmap_entries = 2016 sizeof(em_action_profile_bitmap)/sizeof(uint8); 2017 } else if (SOC_IS_TOMAHAWK2(unit)){ 2018 hw_bitmap = em_th2_action_profile_bitmap; 2019 hw_bitmap_entries = 2020 sizeof(em_th2_action_profile_bitmap)/sizeof(uint8); 2021 } else if (SOC_IS_TOMAHAWK3(unit)){ 2022 hw_bitmap = em_th3_action_profile_bitmap; 2023 hw_bitmap_entries = 2024 sizeof(em_th3_action_profile_bitmap)/sizeof(uint8); 2025 } else { 2026 hw_bitmap = em_td3_action_profile_bitmap; 2027 hw_bitmap_entries = 2028 sizeof(em_td3_action_profile_bitmap)/sizeof(uint8); 2029 } 2030 } else { 2031 /* Assign ifp Action Profile Memory */ 2032 mem = IFP_POLICY_ACTION_PROFILEm; 2033 act_prof_entry = &ifp_act_prof_entry; 2034 hw_bitmap = ifp_td3_action_profile_bitmap; 2035 hw_bitmap_entries = 2036 sizeof(ifp_td3_action_profile_bitmap)/sizeof(uint8); 2037 } 2038 2039 /* Initialise variables */ 2040 sal_memset(acts_buf, 0, sizeof(acts_buf)); 2041 sal_memcpy(act_prof_entry, soc_mem_entry_null(unit, mem), 2042 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 2043 2044 /* Set Action Set Buffer. */ 2045 for (fa = f_ent->actions; fa != NULL; fa = fa->next) { 2046 if (_FP_ACTION_VALID & fa->flags) { 2047 /* get the action conf ptr from stage structure */ 2048 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2049 "field action %s is valid\n"),_field_action_name(fa->action))); 2050 action_conf_ptr = stage_fc->f_action_arr[fa->action]; 2051 /* Test whether the current action is 2052 * supported in this stage */ 2053 if (NULL != action_conf_ptr) { 2054 /* get the aset enum from action_conf_pointer */ 2055 field_action_set = action_conf_ptr->offset->aset; 2056 } else if (fa->action == bcmFieldActionPolicerGroup || 2057 fa->action == bcmFieldActionStatGroup) { 2058 /* Policer and Stat are dealt later */ 2059 continue; 2060 } else { 2061 2062 /* action is not supported in this stage */ 2063 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 2064 "FP(unit %d) Error: Action is not supported \n"), 2065 unit )); 2066 return (BCM_E_UNAVAIL); 2067 } 2068 2069 /* if the aset for current action is 0, or 2070 * action_set size is 0 for this stage/chip 2071 * skip updating the action set data */ 2072 if ((0 == field_action_set) || 2073 (0 == action_set_ptr[field_action_set].size)) { 2074 #if defined(BCM_TRIDENT3_SUPPORT) 2075 if(soc_feature(unit, soc_feature_ifp_action_profiling)) { 2076 rv = _bcm_field_td3_internal_action_profile_data_set(unit, f_ent, fa, acts_buf); 2077 BCM_IF_ERROR_RETURN(rv); 2078 } 2079 #endif /* BCM_TRIDENT3_SUPPORT */ 2080 continue; 2081 } else { 2082 /* Set Action Set Buffer. */ 2083 acts = &acts_buf[field_action_set]; 2084 rv = _bcm_field_th_action_set(unit, 0, f_ent, 2085 0, fa, acts->data); 2086 if (BCM_FAILURE(rv)) { 2087 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META("TH Action set failed.\n"))); 2088 return rv; 2089 } 2090 acts->valid = 1; 2091 } 2092 } 2093 } 2094 2095 /* Set Counter Action Data if present. 2096 * Stat can be attached to entry only if it is 2097 * present in entry group qset.*/ 2098 if (f_ent->statistic.flags & _FP_ENTRY_STAT_VALID) { 2099 counter_present = 1; 2100 } 2101 2102 if (counter_present) { 2103 acts = &acts_buf[_FieldActionCounterSet]; 2104 rv = _field_th_em_flex_stat_action_set(unit, f_ent, policy_mem, 2105 acts->data); 2106 BCM_IF_ERROR_RETURN(rv); 2107 acts->valid = 1; 2108 } 2109 2110 /* Set Meter related information */ 2111 acts = &acts_buf[_FieldActionMeterSet]; 2112 rv = _field_th_ingress_policer_action_set(unit, f_ent, meterbuf); 2113 BCM_IF_ERROR_RETURN(rv); 2114 if(soc_feature(unit, soc_feature_ifp_action_profiling)) { 2115 meter_base = 0; 2116 } else { 2117 f_info = soc_mem_fieldinfo_get(unit, IFP_POLICY_TABLEm, METER_SETf); 2118 meter_base = f_info->bp; 2119 } 2120 2121 rv = _bcm_field_th_val_get(meterbuf, 2122 acts->data, meter_base, 2123 action_set_ptr[_FieldActionMeterSet].size); 2124 BCM_IF_ERROR_RETURN(rv); 2125 acts->valid = 1; 2126 2127 /* Handle Green to Pid Action. */ 2128 if ((acts_buf[_FieldActionL3SwChangeL2Set].valid) || 2129 (acts_buf[_FieldActionRedirectSet].valid)) { 2130 acts = &acts_buf[_FieldActionGreenToPidSet]; 2131 acts->valid = 1; 2132 if (f_ent->flags & _FP_ENTRY_COLOR_INDEPENDENT) { 2133 acts->data[0] = 1; 2134 } else { 2135 acts->data[0] = 0; 2136 } 2137 } 2138 2139 /* Now Populate Action Data Buffer. 2140 * Sequence here for action set is hardware dependant 2141 */ 2142 /* get the action profile pointer from fg structure */ 2143 BCM_IF_ERROR_RETURN(soc_profile_mem_get(unit, 2144 &stage_fc->action_profile[fg->instance], 2145 *ap_idx, 1, &act_prof_entry)); 2146 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2147 "All action data is set, read action profile entry and set data one by one\n"))); 2148 /* For TH and TH2 EM, policy_data needs to be filled from LSB to MSB */ 2149 act_offset = 0; 2150 /* For TD3, policy data is filled from MSB to LSB */ 2151 #if defined(BCM_TRIDENT3_SUPPORT) 2152 if(soc_feature(unit, soc_feature_td3_style_fp)) { 2153 if (policy_mem == IFP_POLICY_TABLEm 2154 || policy_mem == IFP_POLICY_TABLE_PIPE0m 2155 || policy_mem == IFP_POLICY_TABLE_PIPE1m) { 2156 act_offset = _FP_ASET_DATA_SIZE_FOR_POLICY_NARROW; 2157 } else if (policy_mem == IFP_POLICY_TABLE_WIDEm 2158 || policy_mem == IFP_POLICY_TABLE_WIDE_PIPE0m 2159 || policy_mem == IFP_POLICY_TABLE_WIDE_PIPE1m) { 2160 act_offset = _FP_ASET_DATA_SIZE_FOR_POLICY_WIDE; 2161 } else if ((EXACT_MATCH_DEFAULT_POLICYm == policy_mem) || 2162 (EXACT_MATCH_DEFAULT_POLICY_PIPE0m == policy_mem) || 2163 (EXACT_MATCH_DEFAULT_POLICY_PIPE1m == policy_mem)) { 2164 act_offset = EM_DEFAULT_POLICY_ACTION_DATA_SIZE; 2165 } else if (fg->stage_id == _BCM_FIELD_STAGE_EXACTMATCH) { 2166 if(fg->em_mode == _FieldExactMatchMode128) { 2167 act_offset = EM_MODE128_ACTION_DATA_SIZE; 2168 } else if (fg->em_mode == _FieldExactMatchMode160){ 2169 act_offset = EM_MODE160_ACTION_DATA_SIZE; 2170 } else { 2171 act_offset = EM_MODE320_ACTION_DATA_SIZE; 2172 } 2173 } 2174 } 2175 #endif 2176 2177 action_set_bitmap = act_prof_entry; 2178 2179 /* Iterate through all the valid actions 2180 * for the group and update action data buffer */ 2181 if(soc_feature(unit, soc_feature_td3_style_fp)) { 2182 for (idx = hw_bitmap_entries-1; idx >= 0; idx--) 2183 { 2184 rv = _bcm_field_th_val_get(action_set_bitmap, &act_valid, idx, 1); 2185 BCM_IF_ERROR_RETURN(rv); 2186 if (act_valid == 1) { 2187 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2188 "hw action profile set at loc %d is valid\n"),idx)); 2189 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2190 "action buffer has %s data\n"), 2191 ((acts_buf[hw_bitmap[idx]].valid != 0) ? "VALID":"INVALID"))); 2192 /*idx Bit is set in the action profile */ 2193 if (acts_buf[hw_bitmap[idx]].valid) 2194 { 2195 rv = _bcm_field_th_val_set(abuf, 2196 &acts_buf[hw_bitmap[idx]].data[0], 2197 act_offset - action_set_ptr[hw_bitmap[idx]].size, 2198 action_set_ptr[hw_bitmap[idx]].size); 2199 BCM_IF_ERROR_RETURN(rv); 2200 } 2201 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2202 "action_set data at offset %d\n"),act_offset - action_set_ptr[hw_bitmap[idx]].size)); 2203 act_offset -= action_set_ptr[hw_bitmap[idx]].size; 2204 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 2205 "data[0] = 0x%08x, size of action set %d\n"), 2206 acts_buf[hw_bitmap[idx]].data[0],action_set_ptr[hw_bitmap[idx]].size)); 2207 } 2208 } 2209 } else { 2210 for (idx = 0; idx < hw_bitmap_entries; idx++) 2211 { 2212 rv = _bcm_field_th_val_get(action_set_bitmap, &act_valid, idx, 1); 2213 BCM_IF_ERROR_RETURN(rv); 2214 if (act_valid == 1) { 2215 /*idx Bit is set in the action profile */ 2216 if (acts_buf[hw_bitmap[idx]].valid) 2217 { 2218 rv = _bcm_field_th_val_set(abuf, 2219 &acts_buf[hw_bitmap[idx]].data[0], 2220 act_offset, 2221 action_set_ptr[hw_bitmap[idx]].size); 2222 BCM_IF_ERROR_RETURN(rv); 2223 } 2224 act_offset += action_set_ptr[hw_bitmap[idx]].size; 2225 } 2226 } 2227 } 2228 2229 return (rv); 2230 } 2231 2232 /* 2233 * Function: 2234 * _field_th_em_entry_data_set 2235 * Purpose: 2236 * Set Exact Match Policy Data. 2237 * Parameters: 2238 * unit - (IN) BCM device number. 2239 * f_ent - (IN) Field Entry. 2240 * entbuf - (OUT) Entry Policy Data Buffer. 2241 * qp_idx - (OUT) Qos Actions Profile Index. 2242 * ap_idx - (OUT) Action Profile Index. 2243 * Returns: 2244 * BCM_E_XXX 2245 * Notes: 2246 */ 2247 STATIC int 2248 _field_th_em_entry_data_set(int unit, 2249 _field_entry_t *f_ent, 2250 uint32 *entbuf, 2251 uint32 *qp_idx, 2252 uint32 *ap_idx) 2253 { 2254 int rv = BCM_E_NONE; /* Operation Return Status. */ 2255 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 2256 _field_group_t *fg = NULL; /* Field Group Control. */ 2257 _field_action_t *fa = NULL; /* Field action descriptor. */ 2258 uint32 abuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 2259 /* Action Profile Data Buffer. */ 2260 uint32 class_id = 0; /* Action Param 0. */ 2261 soc_mem_t mem, mem_wide; 2262 soc_field_t policy_data_128, policy_data_160, policy_data_320; 2263 soc_field_t act_prof_id_128, act_prof_id_160, act_prof_id_320; 2264 2265 /* Input Parameters Check. */ 2266 if ((NULL == f_ent) || 2267 (NULL == f_ent->group) || 2268 (NULL == entbuf) || 2269 (NULL == qp_idx) || 2270 (NULL == ap_idx)) { 2271 return (BCM_E_PARAM); 2272 } 2273 2274 /* Retreive Field Group. */ 2275 fg = f_ent->group; 2276 2277 /* Return for non EM Stage. */ 2278 if (fg->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 2279 return (BCM_E_INTERNAL); 2280 } 2281 2282 /* Retreive Stage Control. */ 2283 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 2284 fg->stage_id, &stage_fc)); 2285 2286 /* Get Action Exact Match class id. */ 2287 for (fa = f_ent->actions; fa != NULL; fa = fa->next) { 2288 if (_FP_ACTION_VALID & fa->flags) { 2289 if (fa->action == bcmFieldActionExactMatchClassId) { 2290 break; 2291 } 2292 } 2293 } 2294 2295 /* If found set class id. */ 2296 if (fa != NULL) { 2297 class_id = fa->param[0]; 2298 fa->flags &= ~_FP_ACTION_DIRTY; 2299 } 2300 2301 /* Set Qos Profile Index. */ 2302 rv = _field_th_em_qos_profile_actions_alloc(unit, 2303 f_ent, 2304 qp_idx); 2305 BCM_IF_ERROR_RETURN(rv); 2306 /* Set Action Profile data. */ 2307 rv = _field_th_entry_action_profile_data_set(unit, 2308 f_ent, 2309 ap_idx, 2310 0, abuf); 2311 if (BCM_FAILURE(rv)) { 2312 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2313 &stage_fc->qos_action_profile[fg->instance], 2314 *qp_idx)); 2315 return (rv); 2316 } 2317 2318 mem = EXACT_MATCH_2m; 2319 mem_wide = EXACT_MATCH_4m; 2320 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 2321 if(soc_feature(unit, soc_feature_td3_style_fp) || 2322 soc_feature(unit, soc_feature_th3_style_fp)) { 2323 policy_data_128 = MODE128__POLICY_DATAf; 2324 policy_data_160 = MODE160__POLICY_DATAf; 2325 policy_data_320 = MODE320__POLICY_DATAf; 2326 act_prof_id_128 = MODE128__DATA_TYPEf; 2327 act_prof_id_160 = MODE160__DATA_TYPEf; 2328 act_prof_id_320 = MODE320__DATA_TYPEf; 2329 } else 2330 #endif 2331 { 2332 policy_data_128 = MODE128__ACTION_DATAf; 2333 policy_data_160 = MODE160__ACTION_DATAf; 2334 policy_data_320 = MODE320__ACTION_DATAf; 2335 act_prof_id_128 = MODE128__ACTION_PROFILE_IDf; 2336 act_prof_id_160 = MODE160__ACTION_PROFILE_IDf; 2337 act_prof_id_320 = MODE320__ACTION_PROFILE_IDf; 2338 } 2339 2340 /* Set Action Data in entry Buffer. */ 2341 if (fg->em_mode == _FieldExactMatchMode128) { 2342 soc_mem_field32_set(unit, mem, 2343 entbuf, 2344 MODE128__QOS_PROFILE_IDf, *qp_idx); 2345 soc_mem_field32_set(unit, mem, 2346 entbuf, 2347 act_prof_id_128, *ap_idx); 2348 soc_mem_field_set(unit, mem, 2349 entbuf, 2350 policy_data_128, abuf); 2351 soc_mem_field32_set(unit, mem, 2352 entbuf, 2353 MODE128__EXACT_MATCH_CLASS_IDf, 2354 class_id); 2355 } else if (fg->em_mode == _FieldExactMatchMode160) { 2356 soc_mem_field32_set(unit, mem, 2357 entbuf, 2358 MODE160__QOS_PROFILE_IDf, *qp_idx); 2359 soc_mem_field32_set(unit, mem, 2360 entbuf, 2361 act_prof_id_160, *ap_idx); 2362 soc_mem_field_set(unit, mem, 2363 entbuf, 2364 policy_data_160, abuf); 2365 soc_mem_field32_set(unit, mem, 2366 entbuf, 2367 MODE160__EXACT_MATCH_CLASS_IDf, 2368 class_id); 2369 } else if (fg->em_mode == _FieldExactMatchMode320) { 2370 soc_mem_field32_set(unit, mem_wide, 2371 entbuf, 2372 MODE320__QOS_PROFILE_IDf, *qp_idx); 2373 soc_mem_field32_set(unit, mem_wide, 2374 entbuf, 2375 act_prof_id_320, *ap_idx); 2376 soc_mem_field_set(unit, mem_wide, 2377 entbuf, 2378 policy_data_320, abuf); 2379 soc_mem_field32_set(unit, mem_wide, 2380 entbuf, 2381 MODE320__EXACT_MATCH_CLASS_IDf, class_id); 2382 } else { 2383 /* Invalid Exact Match Mode. */ 2384 return (BCM_E_PARAM); 2385 } 2386 2387 return rv; 2388 } 2389 2390 /* 2391 * Function: 2392 * _field_th_em_entry_action_size_get 2393 * Purpose: 2394 * Get exact match entry action size. 2395 * required to add an action 2396 * Parameters: 2397 * unit - (IN) BCM device number. 2398 * f_ent - (IN) Field Entry. 2399 * action_size - (OUT) Qos Actions Profile Index. 2400 * Returns: 2401 * BCM_E_XXX 2402 * Notes: 2403 * This api returns size of action data based on 2404 * actions added to entry, stat and policer 2405 * attached to it. 2406 */ 2407 int 2408 _field_th_em_entry_action_size_get(int unit, _field_entry_t *f_ent, 2409 int *action_size, uint32 *action_prof_idx) 2410 { 2411 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 2412 _field_group_t *fg; /* Field Group structure pointer. */ 2413 _field_action_t *fa = NULL; /* Field action descriptor. */ 2414 _field_entry_stat_t *f_ent_st; /* Field entry statistics structure.*/ 2415 _field_entry_policer_t *f_ent_pl; /* Field entry policer . */ 2416 uint16 aset_key_size = 0; /* Action Set Size. */ 2417 uint8 aset_cnt[_FieldActionSetCount] = {0}; 2418 /* Action Per Set Count. */ 2419 _bcm_field_action_conf_t *action_conf_ptr; 2420 /* action configuration pointer */ 2421 uint8 field_action_set; /* to hold Aset enum */ 2422 exact_match_action_profile_entry_t em_act_prof_entry; 2423 /* Action Profile Table Buffer. */ 2424 void *entries[1]; /* Profile Entry. */ 2425 void *act_prof_entry; /* Profile table buffer pointer */ 2426 soc_mem_t mem; /* Memory Identifier. */ 2427 _bcm_field_action_set_t *action_set_ptr; 2428 /* action set pointer */ 2429 uint32 action_profile_idx; /* Action profile index */ 2430 2431 /* Input Parameter Check. */ 2432 if ((f_ent == NULL) || 2433 (f_ent->group == NULL) || 2434 (action_size == NULL)) { 2435 return (BCM_E_PARAM); 2436 } 2437 fg = f_ent->group; 2438 /* Allowed only for exact match stage currently. */ 2439 if (f_ent->group->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 2440 return (BCM_E_PARAM); 2441 } 2442 /* Retreive Stage Control. */ 2443 BCM_IF_ERROR_RETURN( 2444 _field_stage_control_get(unit, f_ent->group->stage_id, &stage_fc)); 2445 2446 mem = EXACT_MATCH_ACTION_PROFILEm; 2447 act_prof_entry = &em_act_prof_entry; 2448 action_set_ptr = stage_fc->action_set_ptr; 2449 2450 /* Initialise variables */ 2451 sal_memcpy(act_prof_entry, soc_mem_entry_null(unit, mem), 2452 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 2453 2454 f_ent_st = &f_ent->statistic; 2455 if (f_ent_st->flags & _FP_ENTRY_STAT_VALID) { 2456 if (aset_cnt[_FieldActionCounterSet] == 0) { 2457 aset_key_size += 2458 action_set_ptr[_FieldActionCounterSet].size; 2459 aset_cnt[_FieldActionCounterSet]++; 2460 if (NULL != action_prof_idx) { 2461 soc_mem_field32_set(unit, mem, act_prof_entry, 2462 action_set_ptr[_FieldActionCounterSet].hw_field, 1); 2463 } 2464 } 2465 } 2466 2467 f_ent_pl = f_ent->policer; 2468 if (f_ent_pl->flags & _FP_POLICER_VALID) { 2469 if (aset_cnt[_FieldActionMeterSet] == 0) { 2470 aset_key_size += 2471 action_set_ptr[_FieldActionMeterSet].size; 2472 aset_cnt[_FieldActionMeterSet]++; 2473 if (NULL != action_prof_idx) { 2474 soc_mem_field32_set(unit, mem, act_prof_entry, 2475 action_set_ptr[_FieldActionMeterSet].hw_field, 1); 2476 } 2477 } 2478 } 2479 2480 for (fa = f_ent->actions; fa != NULL; fa = fa->next) { 2481 if (_FP_ACTION_VALID & fa->flags) { 2482 /* get the action conf ptr from stage structure */ 2483 action_conf_ptr = stage_fc->f_action_arr[fa->action]; 2484 /* Test whether the current action is 2485 * supported in this stage */ 2486 if (NULL != action_conf_ptr) { 2487 /* get the aset enum from action_conf_pointer */ 2488 field_action_set = action_conf_ptr->offset->aset; 2489 } else if (fa->action == bcmFieldActionPolicerGroup) { 2490 /* Flag in ASETs to indicate group 2491 * policer usage with the group */ 2492 field_action_set = _FieldActionMeterSet; 2493 } else if (fa->action == bcmFieldActionStatGroup) { 2494 /* Flag in ASETs to indicate stat group 2495 * usage with the group */ 2496 field_action_set = _FieldActionCounterSet; 2497 } else { 2498 /* action is not supported in this stage */ 2499 /* add log_error with stage, action, chip*/ 2500 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 2501 "FP(unit %d) Error: Action is not supported \n"), 2502 unit )); 2503 return BCM_E_INTERNAL; 2504 } 2505 /* if the aset for current action is 0, or 2506 action_set size is 0 for this stage/chip 2507 skip the hw field updation step */ 2508 if ((0 == field_action_set) || 2509 (0 == action_set_ptr[field_action_set].size)) { 2510 continue; 2511 } else { 2512 if (aset_cnt[field_action_set] ==0) { 2513 aset_key_size += 2514 action_set_ptr[field_action_set].size; 2515 aset_cnt[field_action_set]++; 2516 if (NULL != action_prof_idx) { 2517 soc_mem_field32_set(unit, mem, act_prof_entry, 2518 action_set_ptr[field_action_set].hw_field, 1); 2519 } 2520 } 2521 } 2522 } 2523 } 2524 /* Check if L3SW/Redirect action is set. 2525 * If yes then reserve 1 bit for Green To Pid. */ 2526 if (aset_cnt[_FieldActionL3SwChangeL2Set] || 2527 aset_cnt[_FieldActionRedirectSet]) { 2528 aset_key_size += 2529 action_set_ptr[_FieldActionGreenToPidSet].size; 2530 if (NULL != action_prof_idx) { 2531 soc_mem_field32_set(unit, mem, act_prof_entry, 2532 action_set_ptr[_FieldActionGreenToPidSet].hw_field , 1); 2533 } 2534 } 2535 2536 *action_size = aset_key_size; 2537 LOG_VERBOSE(BSL_LS_BCM_FP,(BSL_META_U(unit, 2538 "VERB: Default entry EM aset size %d \n\r"), 2539 aset_key_size)); 2540 2541 if (NULL != action_prof_idx) { 2542 entries[0] = act_prof_entry; 2543 /* Add Entries To Action Profile Table In Hardware. */ 2544 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 2545 &stage_fc->action_profile[fg->instance], 2546 entries, 1, &action_profile_idx)); 2547 *action_prof_idx = action_profile_idx; 2548 } 2549 return (BCM_E_NONE); 2550 } 2551 2552 /* 2553 * Function: 2554 * _field_th_em_default_entry_install 2555 * Purpose: 2556 * Install Default Exact Match Entry. 2557 * Parameters: 2558 * unit - (IN) BCM device number. 2559 * f_ent - (IN) Field Entry. 2560 * Returns: 2561 * BCM_E_XXX 2562 * Notes: 2563 */ 2564 STATIC int 2565 2566 _field_th_em_default_entry_install(int unit, _field_entry_t *f_ent) 2567 { 2568 int rv = BCM_E_NONE; /* Operational Status. */ 2569 _field_group_t *fg = NULL; /* Field Group Control. */ 2570 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 2571 exact_match_default_policy_entry_t ebuf; 2572 /* Default Entry Buffer. */ 2573 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 2574 uint32 abuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 2575 /* Action Data Buffer. */ 2576 uint32 lt_entry[SOC_MAX_MEM_FIELD_WORDS] = {0}; 2577 /* LT Entry buffer. */ 2578 _field_presel_entry_t *f_presel = NULL; 2579 /* Presel entry structure. */ 2580 _field_lt_entry_t *f_lt_ent = NULL; 2581 /* Logical entry strucutre. */ 2582 _field_entry_t *f_ent_part = NULL; /* Field Entry Part. */ 2583 _field_action_t *fa = NULL; /* Field action descriptor. */ 2584 int part_idx = 0; /* Entry Part Index. */ 2585 int parts_count = 0; /* Field Entry Parts Count. */ 2586 uint32 qp_idx = 0; /* Qos Actions Profile Index.*/ 2587 uint32 ap_idx = 0; /* Actions Profile Index. */ 2588 uint32 class_id = 0; /* Exact Match Classs Id. */ 2589 int aset_size = 0; /* Action Data Size. */ 2590 int idx = 0, tcam_idx = 0; /* Iter variables. */ 2591 soc_mem_t mem; /* Memory Identifier. */ 2592 soc_mem_t lt_tcam_mem; /* LT memory identifier. */ 2593 2594 /* Input Parameter Check. */ 2595 if ((NULL == f_ent) || 2596 (NULL == f_ent->group) || 2597 (NULL == f_ent->fs)) { 2598 return (BCM_E_PARAM); 2599 } 2600 2601 /* Retreive Field Group */ 2602 fg = f_ent->group; 2603 2604 /* Group must have a valid KeyGen index, else return error. */ 2605 if (_FP_EXT_SELCODE_DONT_CARE == fg->ext_codes[0].keygen_index) { 2606 return (BCM_E_INTERNAL); 2607 } 2608 2609 /* Should be default entry. */ 2610 if (!(f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT)) { 2611 return (BCM_E_CONFIG); 2612 } 2613 2614 /* Do nothing for non EM Stage. */ 2615 if (fg->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 2616 return (BCM_E_INTERNAL); 2617 } 2618 2619 /* Retreive Stage Control. */ 2620 BCM_IF_ERROR_RETURN( 2621 _field_stage_control_get(unit, fg->stage_id, &stage_fc)); 2622 2623 /* Get Hardware Buffer Pointer and memory identifier. */ 2624 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 2625 mem = EXACT_MATCH_DEFAULT_POLICYm; 2626 } else { 2627 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 2628 EXACT_MATCH_DEFAULT_POLICYm, 2629 fg->instance, &mem)); 2630 } 2631 2632 /* Initialize exact match default policy entry buffer. */ 2633 bufp = (uint32 *)&ebuf; 2634 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 2635 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 2636 2637 /* Get number of entry parts. */ 2638 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 2639 fg->flags, &parts_count); 2640 BCM_IF_ERROR_RETURN(rv); 2641 2642 /* Get Size of action attached to entry. */ 2643 rv = _field_th_em_entry_action_size_get(unit, f_ent, &aset_size, &ap_idx); 2644 BCM_IF_ERROR_RETURN(rv); 2645 2646 /* Validate action Data Size. */ 2647 if (aset_size > EM_DEFAULT_POLICY_ACTION_DATA_SIZE) { 2648 /* Delete Action Profile. */ 2649 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2650 &stage_fc->action_profile[fg->instance], 2651 ap_idx)); 2652 return (BCM_E_RESOURCE); 2653 } 2654 2655 /* Get Action Exact Match class id. */ 2656 for (fa = f_ent->actions; fa != NULL; fa = fa->next) { 2657 if (_FP_ACTION_VALID & fa->flags) { 2658 if (fa->action == bcmFieldActionExactMatchClassId) { 2659 break; 2660 } 2661 } 2662 } 2663 2664 /* If found set class id. */ 2665 if (fa != NULL) { 2666 class_id = fa->param[0]; 2667 fa->flags &= ~_FP_ACTION_DIRTY; 2668 } 2669 2670 /* Set Qos Profile Index. */ 2671 rv = _field_th_em_qos_profile_actions_alloc(unit, 2672 f_ent, 2673 &qp_idx); 2674 BCM_IF_ERROR_RETURN(rv); 2675 /* Set Action Profile data. */ 2676 rv = _field_th_entry_action_profile_data_set(unit, 2677 f_ent, 2678 &ap_idx, 2679 mem, abuf); 2680 if (BCM_FAILURE(rv)) { 2681 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2682 &stage_fc->qos_action_profile[fg->instance], 2683 qp_idx)); 2684 /* Delete Action Profile. */ 2685 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2686 &stage_fc->action_profile[fg->instance], 2687 ap_idx)); 2688 } 2689 2690 /* Set Default Policy Data Buffer. */ 2691 soc_mem_field32_set(unit, mem, 2692 bufp, 2693 QOS_PROFILE_IDf, qp_idx); 2694 soc_mem_field32_set(unit, mem, 2695 bufp, 2696 soc_feature(unit, soc_feature_td3_style_fp) ? DATA_TYPEf : ACTION_PROFILE_IDf, 2697 ap_idx); 2698 soc_mem_field_set(unit, mem, 2699 bufp, 2700 soc_feature(unit, soc_feature_td3_style_fp) ? POLICY_DATAf : ACTION_DATAf, 2701 abuf); 2702 soc_mem_field32_set(unit, mem, bufp, 2703 EXACT_MATCH_CLASS_IDf, class_id); 2704 2705 /* Install entry in hardware. */ 2706 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, 2707 fg->ext_codes[0].keygen_index, bufp); 2708 if (BCM_FAILURE(rv)) { 2709 goto bcm_error; 2710 } 2711 2712 /* Enable Default Policy in Logical table entries. */ 2713 if (fg->flags & _FP_GROUP_PRESELECTOR_SUPPORT) { 2714 for (idx = 0; idx < _FP_PRESEL_ENTRIES_MAX_PER_GROUP; idx++) { 2715 if (fg->presel_ent_arr[idx] != NULL) { 2716 f_presel = fg->presel_ent_arr[idx]; 2717 2718 tcam_idx = f_presel->hw_index + f_presel->lt_fs->start_tcam_idx; 2719 2720 rv = _bcm_field_th_lt_tcam_policy_mem_get(unit, 2721 stage_fc, fg->instance, 2722 _BCM_FIELD_MEM_TYPE_EM_LT, 2723 _BCM_FIELD_MEM_VIEW_TYPE_TCAM_DATA_COMB, 2724 <_tcam_mem, NULL); 2725 if (BCM_FAILURE(rv)) { 2726 goto bcm_error; 2727 } 2728 2729 /* Read entry into SW buffer. */ 2730 rv = soc_mem_read(unit, lt_tcam_mem, MEM_BLOCK_ANY, tcam_idx, 2731 lt_entry); 2732 if (BCM_FAILURE(rv)) { 2733 goto bcm_error; 2734 } 2735 2736 /* Set entry valid bit status. */ 2737 soc_mem_field32_set(unit, lt_tcam_mem, lt_entry, 2738 DEFAULT_POLICY_ENABLEf, 1); 2739 2740 /* Install entry in hardware. */ 2741 rv = soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL, 2742 tcam_idx, lt_entry); 2743 if (BCM_FAILURE(rv)) { 2744 goto bcm_error; 2745 } 2746 } 2747 } 2748 } else { 2749 for (idx = 0; idx < (fg->lt_grp_status.entry_count); idx++) { 2750 if (fg->lt_entry_arr[idx] == NULL) { 2751 continue; 2752 } 2753 f_lt_ent = fg->lt_entry_arr[idx]; 2754 2755 tcam_idx = f_lt_ent->index + f_lt_ent->lt_fs->start_tcam_idx; 2756 rv = _bcm_field_th_lt_tcam_policy_mem_get(unit, stage_fc, fg->instance, 2757 _BCM_FIELD_MEM_TYPE_EM_LT, 2758 _BCM_FIELD_MEM_VIEW_TYPE_TCAM_DATA_COMB, 2759 <_tcam_mem, NULL); 2760 if (BCM_FAILURE(rv)) { 2761 goto bcm_error; 2762 } 2763 2764 /* Read entry into SW buffer. */ 2765 rv = soc_mem_read(unit, lt_tcam_mem, MEM_BLOCK_ANY, tcam_idx, 2766 lt_entry); 2767 if (BCM_FAILURE(rv)) { 2768 goto bcm_error; 2769 } 2770 2771 /* Set entry valid bit status. */ 2772 soc_mem_field32_set(unit, lt_tcam_mem, lt_entry, DEFAULT_POLICY_ENABLEf, 1); 2773 2774 /* Install entry in hardware. */ 2775 rv = soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL, 2776 tcam_idx, lt_entry); 2777 if (BCM_FAILURE(rv)) { 2778 goto bcm_error; 2779 } 2780 } 2781 } 2782 2783 /* Set Flags. */ 2784 for (part_idx = 0; part_idx < parts_count; part_idx++) { 2785 f_ent_part = f_ent + part_idx; 2786 2787 /* Set Entry Flags. */ 2788 f_ent_part->flags &= ~_FP_ENTRY_DIRTY; 2789 f_ent_part->flags |= _FP_ENTRY_INSTALLED; 2790 f_ent_part->flags |= _FP_ENTRY_ENABLED; 2791 } 2792 2793 return (rv); 2794 2795 bcm_error: 2796 /* Delete QoS Action Profile. */ 2797 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2798 &stage_fc->qos_action_profile[fg->instance], 2799 qp_idx)); 2800 return (rv); 2801 } 2802 2803 /* 2804 * Function: 2805 * _field_th_em_default_entry_remove 2806 * Purpose: 2807 * Remove Default Exact Match Entry. 2808 * Parameters: 2809 * unit - (IN) BCM device number. 2810 * f_ent - (IN) Field Entry. 2811 * Returns: 2812 * BCM_E_XXX 2813 * Notes: 2814 */ 2815 STATIC int 2816 _field_th_em_default_entry_remove(int unit, _field_entry_t *f_ent) 2817 { 2818 int rv = BCM_E_NONE; /* Operational Status. */ 2819 _field_control_t *fc; /* Field control structure. */ 2820 _field_group_t *fg = NULL; /* Field Group Control. */ 2821 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 2822 exact_match_default_policy_entry_t ebuf; 2823 /* Default Entry Buffer. */ 2824 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 2825 uint32 lt_entry[SOC_MAX_MEM_FIELD_WORDS] = {0}; 2826 /* LT Entry buffer. */ 2827 _field_presel_entry_t *f_presel = NULL; 2828 /* Presel entry structure. */ 2829 _field_lt_entry_t *f_lt_ent = NULL; 2830 /* Logical entry strucutre. */ 2831 _field_entry_t *f_ent_part = NULL; /* Field Entry Part. */ 2832 int part_idx = 0; /* Entry Part Index. */ 2833 int parts_count = 0; /* Field Entry Parts Count. */ 2834 uint32 qp_idx = 0; /* Qos Actions Profile Index.*/ 2835 uint32 ap_idx = 0; /* Actions Profile Index. */ 2836 int idx = 0, tcam_idx = 0; /* Iter variables. */ 2837 soc_mem_t mem; /* Memory Identifier. */ 2838 soc_mem_t lt_tcam_mem; /* LT memory identifier. */ 2839 2840 /* Input Parameter Check. */ 2841 if ((NULL == f_ent) || 2842 (NULL == f_ent->group) || 2843 (NULL == f_ent->fs)) { 2844 return (BCM_E_PARAM); 2845 } 2846 2847 /* Retreive Field Group */ 2848 fg = f_ent->group; 2849 2850 /* Group must have a valid KeyGen index, else return error. */ 2851 if (_FP_EXT_SELCODE_DONT_CARE == fg->ext_codes[0].keygen_index) { 2852 return (BCM_E_INTERNAL); 2853 } 2854 2855 /* Should be default entry. */ 2856 if (!(f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT)) { 2857 return (BCM_E_CONFIG); 2858 } 2859 2860 /* Do nothing for non EM Stage. */ 2861 if (fg->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 2862 return (BCM_E_INTERNAL); 2863 } 2864 2865 /* Get Field Control structure. */ 2866 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 2867 2868 /* Retreive Stage Control. */ 2869 BCM_IF_ERROR_RETURN( 2870 _field_stage_control_get(unit, fg->stage_id, &stage_fc)); 2871 2872 /* Get Hardware Buffer Pointer and memory identifier. */ 2873 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 2874 mem = EXACT_MATCH_DEFAULT_POLICYm; 2875 } else { 2876 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 2877 EXACT_MATCH_DEFAULT_POLICYm, 2878 fg->instance, &mem)); 2879 } 2880 2881 /* Initialize exact match entries. */ 2882 bufp = (uint32 *)&ebuf; 2883 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 2884 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 2885 2886 /* Get number of entry parts. */ 2887 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 2888 fg->flags, &parts_count); 2889 BCM_IF_ERROR_RETURN(rv); 2890 2891 /* Read Exact Match Default Policy Entry. */ 2892 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 2893 fg->ext_codes[0].keygen_index, bufp); 2894 BCM_IF_ERROR_RETURN(rv); 2895 2896 /* Retreive Qos profile index from entry. */ 2897 qp_idx = soc_mem_field32_get(unit, mem, 2898 bufp, QOS_PROFILE_IDf); 2899 2900 /* Delete Entry QoS Profile Memories for actions. */ 2901 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2902 &stage_fc->qos_action_profile[fg->instance], 2903 qp_idx)); 2904 /* 2905 * For regular EM entries, action profile is group property 2906 * So _bcm_field_th_group_deinit will clear EM action profile 2907 * whereas for EM default entry, Action profile is specifically used by EM default entry alone 2908 * So need to remove Action profile for EM default entry. 2909 */ 2910 /* 2911 * For regular EM entries, action profile will be cleared in _bcm_field_th_group_deinit. 2912 * So in case of bcm_field_init, method _bcm_field_th_group_deinit will clear 2913 * all EM action profiles for regular EM entries and default entry. 2914 * Skip to clear the action profile for now. 2915 */ 2916 if (fc->init) { 2917 /* Retreive Action profile index from entry. */ 2918 ap_idx = soc_mem_field32_get(unit, mem, 2919 bufp, 2920 soc_feature(unit, soc_feature_td3_style_fp) ? DATA_TYPEf : 2921 ACTION_PROFILE_IDf); 2922 /* Delete Entry Action Profile Memories for actions. */ 2923 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 2924 &stage_fc->action_profile[fg->instance], 2925 ap_idx)); 2926 } 2927 2928 /* Clear entry buffer. */ 2929 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 2930 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 2931 2932 /* Install clear entry in hardware. */ 2933 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 2934 fg->ext_codes[0].keygen_index, bufp)); 2935 2936 /* Enable Default Policy in Logical table entries. */ 2937 if (fg->flags & _FP_GROUP_PRESELECTOR_SUPPORT) { 2938 for (idx = 0; idx < _FP_PRESEL_ENTRIES_MAX_PER_GROUP; idx++) { 2939 if (fg->presel_ent_arr[idx] != NULL) { 2940 f_presel = fg->presel_ent_arr[idx]; 2941 2942 tcam_idx = f_presel->hw_index + f_presel->lt_fs->start_tcam_idx; 2943 2944 BCM_IF_ERROR_RETURN 2945 (_bcm_field_th_lt_tcam_policy_mem_get(unit, stage_fc, fg->instance, 2946 _BCM_FIELD_MEM_TYPE_EM_LT, 2947 _BCM_FIELD_MEM_VIEW_TYPE_TCAM_DATA_COMB, 2948 <_tcam_mem, NULL)); 2949 /* Read entry into SW buffer. */ 2950 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 2951 lt_tcam_mem, MEM_BLOCK_ANY, 2952 tcam_idx, lt_entry)); 2953 2954 /* Set entry valid bit status. */ 2955 soc_mem_field32_set(unit, lt_tcam_mem, 2956 lt_entry, DEFAULT_POLICY_ENABLEf, 0); 2957 2958 /* Install entry in hardware. */ 2959 BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL, 2960 tcam_idx, lt_entry)); 2961 } 2962 } 2963 } else { 2964 for (idx = 0; idx < (fg->lt_grp_status.entry_count); idx++) { 2965 if (fg->lt_entry_arr[idx] == NULL) { 2966 continue; 2967 } 2968 f_lt_ent = fg->lt_entry_arr[idx]; 2969 2970 tcam_idx = f_lt_ent->index + f_lt_ent->lt_fs->start_tcam_idx; 2971 2972 BCM_IF_ERROR_RETURN 2973 (_bcm_field_th_lt_tcam_policy_mem_get(unit, stage_fc, fg->instance, 2974 _BCM_FIELD_MEM_TYPE_EM_LT, 2975 _BCM_FIELD_MEM_VIEW_TYPE_TCAM_DATA_COMB, 2976 <_tcam_mem, NULL)); 2977 2978 /* Read entry into SW buffer. */ 2979 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 2980 lt_tcam_mem, MEM_BLOCK_ANY, 2981 tcam_idx, lt_entry)); 2982 2983 /* Set entry valid bit status. */ 2984 soc_mem_field32_set(unit, lt_tcam_mem, 2985 lt_entry, DEFAULT_POLICY_ENABLEf, 0); 2986 2987 /* Install entry in hardware. */ 2988 BCM_IF_ERROR_RETURN(soc_mem_write(unit, lt_tcam_mem, MEM_BLOCK_ALL, 2989 tcam_idx, lt_entry)); 2990 } 2991 } 2992 2993 /* Clear Flags. */ 2994 for (part_idx = 0; part_idx < parts_count; part_idx++) { 2995 f_ent_part = f_ent + part_idx; 2996 /* CLear Entry Flags. */ 2997 f_ent_part->flags |= _FP_ENTRY_DIRTY; 2998 f_ent_part->flags &= ~_FP_ENTRY_INSTALLED; 2999 f_ent_part->flags &= ~_FP_ENTRY_ENABLED; 3000 } 3001 3002 return (rv); 3003 } 3004 3005 /* 3006 * Function: 3007 * _field_th_em_entry_install 3008 * Purpose: 3009 * Install Exact Match Entry in Hardware. 3010 * Parameters: 3011 * unit - (IN) BCM device number. 3012 * f_ent - (IN) Field Entry Pointer. 3013 * Returns: 3014 * BCM_E_XXX 3015 * Notes: 3016 * f_ent is primary entry part. 3017 */ 3018 int 3019 _field_th_em_entry_install(int unit, _field_entry_t *f_ent) 3020 { 3021 int rv = BCM_E_NONE; /* Operational Status. */ 3022 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 3023 _field_group_t *fg = NULL; /* Field Group Control. */ 3024 _field_entry_t *f_ent_part = NULL; /* Field Entry Part. */ 3025 uint32 qp_idx = 0; /* Qos Actions Profile Index.*/ 3026 uint32 ap_idx = 0; /* Actions Profile Index. */ 3027 int part_idx = 0; /* Entry Part Index. */ 3028 int parts_count = 0; /* Field Entry Parts Count. */ 3029 soc_mem_t mem; /* Memory Identifier. */ 3030 uint32 bufp[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* Hardware Buffer*/ 3031 3032 /* Input Parameters Check. */ 3033 if ((NULL == f_ent) || 3034 (NULL == f_ent->group) || 3035 (NULL == f_ent->fs)) { 3036 return (BCM_E_PARAM); 3037 } 3038 3039 /* Retreive Field Group */ 3040 fg = f_ent->group; 3041 3042 /* Retreive Stage Control. */ 3043 BCM_IF_ERROR_RETURN( 3044 _field_stage_control_get(unit, fg->stage_id, &stage_fc)); 3045 3046 /* Not applicable for non EM Stage. */ 3047 if (fg->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 3048 return (BCM_E_INTERNAL); 3049 } 3050 /* set Action profile index */ 3051 ap_idx = fg->action_profile_idx[0]; 3052 /* Default Entry Install. */ 3053 if (f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT) { 3054 return _field_th_em_default_entry_install(unit, f_ent); 3055 } 3056 rv = _bcm_field_th_tcam_policy_mem_get(unit, f_ent, 3057 &mem, &mem); 3058 BCM_IF_ERROR_RETURN(rv); 3059 /* Get number of entry parts. */ 3060 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 3061 fg->flags, &parts_count); 3062 BCM_IF_ERROR_RETURN(rv); 3063 3064 /* Get Key If Not Installed, for all entry parts. */ 3065 if (!(f_ent->flags & _FP_ENTRY_INSTALLED)) { 3066 for (part_idx = 0; part_idx < parts_count; part_idx++) { 3067 f_ent_part = f_ent + part_idx; 3068 BCM_IF_ERROR_RETURN( 3069 _bcm_field_qual_tcam_key_mask_get(unit, f_ent_part)); 3070 } 3071 } 3072 3073 /* Initialize exact match entries. */ 3074 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 3075 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 3076 3077 /* Validate Parts and EM View. */ 3078 if ((((fg->em_mode == _FieldExactMatchMode128) || 3079 (fg->em_mode == _FieldExactMatchMode160)) && 3080 (parts_count != 1)) || 3081 ((fg->em_mode == _FieldExactMatchMode320) && 3082 (parts_count != 2))) { 3083 return (BCM_E_INTERNAL); 3084 } 3085 3086 /* Set Action Buffer. */ 3087 rv = _field_th_em_entry_data_set(unit, f_ent, bufp, &qp_idx, &ap_idx); 3088 BCM_IF_ERROR_RETURN(rv); 3089 3090 if (soc_feature(unit, soc_feature_th3_style_fp)) { 3091 rv = _field_th3_em_entry_set(unit, f_ent, mem, bufp, 0); 3092 } else if (soc_feature(unit, soc_feature_td3_style_fp)) { 3093 rv = _field_td3_em_entry_set(unit, f_ent, mem, bufp, 0); 3094 } else { 3095 rv = _field_th_em_entry_set(unit, f_ent, mem, bufp, 0); 3096 } 3097 BCM_IF_ERROR_RETURN(rv); 3098 /* Write Entry In Hardware. */ 3099 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, bufp); 3100 3101 if (BCM_FAILURE(rv)) { 3102 goto bcm_error; 3103 } 3104 3105 /* Copy into Hw Key. */ 3106 for (part_idx = 0; part_idx < parts_count; part_idx++) { 3107 f_ent_part = f_ent + part_idx; 3108 if(f_ent_part->tcam.key_hw == NULL) { 3109 _FP_XGS3_ALLOC(f_ent_part->tcam.key_hw, 3110 f_ent_part->tcam.key_size, "EM_TCAM Key Alloc."); 3111 } 3112 3113 sal_memcpy(f_ent_part->tcam.key_hw, 3114 f_ent_part->tcam.key, f_ent_part->tcam.key_size); 3115 3116 /* Set Entry Flags. */ 3117 f_ent_part->flags &= ~_FP_ENTRY_DIRTY; 3118 f_ent_part->flags |= _FP_ENTRY_INSTALLED; 3119 f_ent_part->flags |= _FP_ENTRY_ENABLED; 3120 } 3121 3122 /* Increment Hardware Count to count of entry parts. */ 3123 for (part_idx = 0; part_idx < parts_count; part_idx++) { 3124 f_ent->fs->hw_ent_count++; 3125 } 3126 3127 return rv; 3128 3129 bcm_error: 3130 /* Delete QoS Action Profile. */ 3131 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 3132 &stage_fc->qos_action_profile[fg->instance], 3133 qp_idx)); 3134 return (rv); 3135 } 3136 3137 /* 3138 * Function: 3139 * _field_th_em_entry_remove 3140 * Purpose: 3141 * Remove Exact Match Entry from hardware. 3142 * Parameters: 3143 * unit - (IN) BCM device number. 3144 * f_ent - (IN) Field Entry. 3145 * Returns: 3146 * BCM_E_XXX 3147 * Notes: 3148 * Install and Enabled Flags will 3149 * be cleared by calling function. 3150 */ 3151 int 3152 _field_th_em_entry_remove(int unit, _field_entry_t *f_ent) 3153 { 3154 int rv = BCM_E_NONE; /* Operational Status. */ 3155 _field_control_t *fc = NULL; /* Field Control Structure. */ 3156 _field_stage_t *stage_fc = NULL; /* Field Stage Control. */ 3157 _field_group_t *fg = NULL; /* Field Group Control. */ 3158 _field_entry_t *f_ent_part = NULL; 3159 /* Field Entry Part. */ 3160 int eindex = 0; /* Entry Index inn UFT memory. */ 3161 uint32 qp_idx = 0; /* Qos Actions Profile Index. */ 3162 int parts_count = 0; /* Field entry parts count. */ 3163 int part_idx = 0; /* Entry Part Iterator. */ 3164 soc_mem_t mem; /* Memory Identifier. */ 3165 uint32 bufp[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* Hardware Buffer */ 3166 3167 /* Input Parameters Check. */ 3168 if ((NULL == f_ent) || 3169 (NULL == f_ent->group) || 3170 (NULL == f_ent->fs)) { 3171 return (BCM_E_PARAM); 3172 } 3173 3174 /* If secondary part return none as uninstall 3175 * has happened in primary part already. 3176 */ 3177 if (f_ent->flags & _FP_ENTRY_SECONDARY) { 3178 return (BCM_E_NONE); 3179 } 3180 3181 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 3182 3183 /* Retreive Field Group. */ 3184 fg = f_ent->group; 3185 3186 /* Retreive Stage Control. */ 3187 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 3188 fg->stage_id, &stage_fc)); 3189 3190 /* Do nothing for non EM Stage. */ 3191 if (fg->stage_id != _BCM_FIELD_STAGE_EXACTMATCH) { 3192 return (BCM_E_INTERNAL); 3193 } 3194 3195 /* Default Entry Remove. */ 3196 if (f_ent->flags & _FP_ENTRY_EXACT_MATCH_GROUP_DEFAULT) { 3197 return _field_th_em_default_entry_remove(unit, f_ent); 3198 } 3199 3200 /* Check if HW key is present to remove entry. */ 3201 if (NULL == f_ent->tcam.key_hw) { 3202 return (BCM_E_PARAM); 3203 } 3204 rv = _bcm_field_th_tcam_policy_mem_get(unit, f_ent, 3205 &mem, &mem); 3206 BCM_IF_ERROR_RETURN(rv); 3207 /* Initialize exact match entries. */ 3208 sal_memcpy(bufp, soc_mem_entry_null(unit, mem), 3209 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 3210 3211 /* Get number of entry parts. */ 3212 rv = _bcm_field_entry_tcam_parts_count(unit, fg->stage_id, 3213 fg->flags, &parts_count); 3214 BCM_IF_ERROR_RETURN(rv); 3215 3216 /* Validate Parts and EM View. */ 3217 if ((((fg->em_mode == _FieldExactMatchMode128) || 3218 (fg->em_mode == _FieldExactMatchMode160)) && 3219 (parts_count != 1)) || 3220 ((fg->em_mode == _FieldExactMatchMode320) && 3221 (parts_count != 2))) { 3222 return (BCM_E_INTERNAL); 3223 } 3224 if (soc_feature(unit, soc_feature_th3_style_fp)) { 3225 rv = _field_th3_em_entry_set(unit, f_ent, mem, bufp, 1); 3226 } else if (soc_feature(unit, soc_feature_td3_style_fp)) { 3227 rv = _field_td3_em_entry_set(unit, f_ent, mem, bufp, 1); 3228 } else { 3229 rv = _field_th_em_entry_set(unit, f_ent, mem, bufp, 1); 3230 } 3231 BCM_IF_ERROR_RETURN(rv); 3232 /* Search Entry First Before Delete. */ 3233 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &eindex, bufp, bufp, 0); 3234 if (BCM_FAILURE(rv)) { 3235 if (fc->init == TRUE) { 3236 return (rv); 3237 } else { 3238 /* If init is false it means field detach is happening. 3239 * which might be due to rc or fp init. 3240 * since soc init will clear all memories hence 3241 * exact match memory will be cleared and search will 3242 * not be a success. Since memory is cleared before itself 3243 * so delete call should return success in such case. 3244 */ 3245 rv = BCM_E_NONE; 3246 return rv; 3247 } 3248 } 3249 3250 /* Get Qos and Action Profile Index Allocated From Entry. */ 3251 if (fg->em_mode == _FieldExactMatchMode128) { 3252 qp_idx = soc_mem_field32_get(unit, mem, 3253 bufp, MODE128__QOS_PROFILE_IDf); 3254 } else if (fg->em_mode == _FieldExactMatchMode160) { 3255 qp_idx = soc_mem_field32_get(unit, mem, 3256 bufp, MODE160__QOS_PROFILE_IDf); 3257 } else if (fg->em_mode == _FieldExactMatchMode320) { 3258 qp_idx = soc_mem_field32_get(unit, mem, 3259 bufp, MODE320__QOS_PROFILE_IDf); 3260 } else { 3261 /* Invalid Exact Mode Mode. */ 3262 return (BCM_E_PARAM); 3263 } 3264 3265 /* Delete Entry From HW if found. */ 3266 BCM_IF_ERROR_RETURN( 3267 soc_mem_delete(unit, mem, MEM_BLOCK_ALL, bufp)); 3268 3269 /* Delete Entry Profile Memories for actions. */ 3270 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 3271 &stage_fc->qos_action_profile[fg->instance], 3272 qp_idx)); 3273 3274 /* Free Hw Entry Copy. */ 3275 for (part_idx = 0; part_idx < parts_count; part_idx++) { 3276 f_ent_part = f_ent + part_idx; 3277 sal_free(f_ent_part->tcam.key_hw); 3278 f_ent_part->tcam.key_hw = NULL; 3279 3280 /* Set Entry Flags. */ 3281 f_ent_part->flags |= _FP_ENTRY_DIRTY; 3282 f_ent_part->flags &= ~_FP_ENTRY_INSTALLED; 3283 f_ent_part->flags &= ~_FP_ENTRY_ENABLED; 3284 } 3285 3286 /* Decrement Hw Slice Entry Count to count of entry parts. */ 3287 for (part_idx = 0; part_idx < parts_count; part_idx++) { 3288 f_ent->fs->hw_ent_count--; 3289 } 3290 3291 return rv; 3292 } 3293 3294 int 3295 _bcm_field_th_em_entry_tcam_idx_get(int unit, _field_entry_t *f_ent, int *hw_index) 3296 { 3297 bcm_error_t rv = BCM_E_NONE; 3298 _field_stage_t *stage_fc = NULL; 3299 _field_group_t *fg = NULL; 3300 exact_match_2_entry_t ebuf_nar; /* Narrow Entry Buffer. */ 3301 exact_match_4_entry_t ebuf_wide; /* Wide Entry Buffer. */ 3302 soc_mem_t mem = INVALIDm; /* Memory Identifier. */ 3303 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3304 /* Temp Buffer One. */ 3305 uint32 *bufp = NULL; /* Hardware Buffer Ptr. */ 3306 3307 3308 fg = f_ent->group; 3309 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 3310 _BCM_FIELD_STAGE_EXACTMATCH, &stage_fc)); 3311 if ((fg->em_mode == _FieldExactMatchMode128) || 3312 (fg->em_mode == _FieldExactMatchMode160)) { 3313 bufp = (uint32 *)&ebuf_nar; 3314 sal_memset(bufp, 0, sizeof(exact_match_2_entry_t)); 3315 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 3316 mem = EXACT_MATCH_2m; 3317 } else { 3318 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 3319 EXACT_MATCH_2m, 3320 fg->instance, &mem)); 3321 } 3322 } else { 3323 bufp = (uint32 *)&ebuf_wide; 3324 sal_memset(bufp, 0, sizeof(exact_match_4_entry_t)); 3325 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 3326 mem = EXACT_MATCH_4m; 3327 } else { 3328 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 3329 EXACT_MATCH_4m, 3330 fg->instance, &mem)); 3331 } 3332 } 3333 3334 sal_memset(&ebuf_nar, 0x0, sizeof(exact_match_2_entry_t)); 3335 sal_memset(&ebuf_wide, 0x0, sizeof(exact_match_4_entry_t)); 3336 3337 if (soc_feature(unit, soc_feature_th3_style_fp)) { 3338 rv = _field_th3_em_entry_set(unit, f_ent, mem, bufp, 0); 3339 } else if (soc_feature(unit, soc_feature_td3_style_fp)) { 3340 rv = _field_td3_em_entry_set(unit, f_ent, mem, bufp, 0); 3341 } else { 3342 rv = _field_th_em_entry_set(unit, f_ent, mem, bufp, 0); 3343 } 3344 BCM_IF_ERROR_RETURN(rv); 3345 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, hw_index, 3346 bufp, tbuf, 0 ); 3347 BCM_IF_ERROR_RETURN(rv); 3348 3349 return rv; 3350 } 3351 3352 /* 3353 * Function: 3354 * _field_th_em_entry_set 3355 * Purpose: 3356 * Set Exact Match Policy Data. 3357 * Parameters: 3358 * unit - (IN) BCM device number. 3359 * f_ent - (IN) Field Entry. 3360 * entbuf - (OUT) Entry Policy Data Buffer. 3361 * qp_idx - (OUT) Qos Actions Profile Index. 3362 * ap_idx - (OUT) Action Profile Index. 3363 * Returns: 3364 * BCM_E_XXX 3365 * Notes: 3366 */ 3367 int 3368 _field_th_em_entry_set(int unit, 3369 _field_entry_t *f_ent, 3370 soc_mem_t mem, 3371 uint32 *bufp, int search_entry) 3372 { 3373 int rv = BCM_E_NONE; /* Operational Status. */ 3374 _field_group_t *fg = NULL; /* Field Group Control. */ 3375 _field_entry_t *f_ent_part = NULL; /* Field Entry Part. */ 3376 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3377 /* Temp Buffer One. */ 3378 uint32 tbuf_temp[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3379 /* Temp Buffer Two. */ 3380 uint32 *key; 3381 3382 /* Input Parameters Check. */ 3383 if ((NULL == f_ent) || 3384 (NULL == f_ent->group) || 3385 (NULL == f_ent->fs)) { 3386 return (BCM_E_PARAM); 3387 } 3388 3389 /* Retreive Field Group */ 3390 fg = f_ent->group; 3391 3392 /* Assign the correct key */ 3393 if (1 == search_entry) { 3394 key = f_ent->tcam.key_hw; 3395 } else { 3396 key = f_ent->tcam.key; 3397 } 3398 3399 /* Set Exact Match Entry */ 3400 if (fg->em_mode == _FieldExactMatchMode128) { 3401 3402 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_0f, fg->em_mode); 3403 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_1f, fg->em_mode); 3404 soc_mem_field32_set(unit, mem, bufp, VALID_0f, 1); 3405 soc_mem_field32_set(unit, mem, bufp, VALID_1f, 1); 3406 rv = _bcm_field_th_val_get(key, tbuf, 0, 3407 EM_MODE128_KEY_PART0_SIZE); 3408 BCM_IF_ERROR_RETURN(rv); 3409 soc_mem_field_set(unit, mem, bufp, MODE128__KEY_0_ONLYf, tbuf); 3410 rv = _bcm_field_th_val_get(key, tbuf, 3411 EM_MODE128_KEY_PART0_SIZE, 3412 EM_MODE128_KEY_PART1_SIZE); 3413 BCM_IF_ERROR_RETURN(rv); 3414 soc_mem_field_set(unit, mem, bufp, MODE128__KEY_1_ONLYf, tbuf); 3415 3416 } else if (fg->em_mode == _FieldExactMatchMode160) { 3417 3418 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_0f, fg->em_mode); 3419 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_1f, fg->em_mode); 3420 soc_mem_field32_set(unit, mem, bufp, VALID_0f, 1); 3421 soc_mem_field32_set(unit, mem, bufp, VALID_1f, 1); 3422 rv = _bcm_field_th_val_get(key, tbuf, 0, 3423 EM_MODE160_KEY_PART0_SIZE); 3424 BCM_IF_ERROR_RETURN(rv); 3425 soc_mem_field_set(unit, mem, bufp, MODE160__KEY_0_ONLYf, tbuf); 3426 rv = _bcm_field_th_val_get(key, tbuf, 3427 EM_MODE160_KEY_PART0_SIZE, 3428 EM_MODE160_KEY_PART1_SIZE); 3429 BCM_IF_ERROR_RETURN(rv); 3430 soc_mem_field_set(unit, mem, bufp, MODE160__KEY_1_ONLYf, tbuf); 3431 3432 } else if (fg->em_mode == _FieldExactMatchMode320) { 3433 3434 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_0f, fg->em_mode); 3435 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_1f, fg->em_mode); 3436 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_2f, fg->em_mode); 3437 soc_mem_field32_set(unit, mem, bufp, KEY_TYPE_3f, fg->em_mode); 3438 soc_mem_field32_set(unit, mem, bufp, VALID_0f, 1); 3439 soc_mem_field32_set(unit, mem, bufp, VALID_1f, 1); 3440 soc_mem_field32_set(unit, mem, bufp, VALID_2f, 1); 3441 soc_mem_field32_set(unit, mem, bufp, VALID_3f, 1); 3442 rv = _bcm_field_th_val_get(key, tbuf, 0, 3443 EM_MODE320_KEY_PART0_SIZE); 3444 BCM_IF_ERROR_RETURN(rv); 3445 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_0_ONLYf, tbuf); 3446 rv = _bcm_field_th_val_get(key, tbuf, 3447 EM_MODE320_KEY_PART0_SIZE, 3448 (EM_ENTRY_PART0_KEYSIZE - 3449 EM_MODE320_KEY_PART0_SIZE)); 3450 BCM_IF_ERROR_RETURN(rv); 3451 3452 /* Key From Second Entry Part. */ 3453 f_ent_part = f_ent + 1; 3454 3455 /* Assign the correct key */ 3456 if (1 == search_entry) { 3457 key = f_ent_part->tcam.key_hw; 3458 } else { 3459 key = f_ent_part->tcam.key; 3460 } 3461 if (key == NULL) { 3462 return BCM_E_PARAM; 3463 } 3464 rv = _bcm_field_th_val_get(key, tbuf_temp, 0, 3465 (EM_MODE320_KEY_PART1_SIZE - 3466 (EM_ENTRY_PART0_KEYSIZE - 3467 EM_MODE320_KEY_PART0_SIZE))); 3468 BCM_IF_ERROR_RETURN(rv); 3469 rv = _bcm_field_th_val_set(tbuf, tbuf_temp, 3470 (EM_ENTRY_PART0_KEYSIZE - 3471 EM_MODE320_KEY_PART0_SIZE), 3472 (EM_MODE320_KEY_PART1_SIZE - 3473 (EM_ENTRY_PART0_KEYSIZE - 3474 EM_MODE320_KEY_PART0_SIZE))); 3475 BCM_IF_ERROR_RETURN(rv); 3476 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_1_ONLYf, tbuf); 3477 rv = _bcm_field_th_val_get(key, tbuf, 3478 (EM_MODE320_KEY_PART1_SIZE - 3479 (EM_ENTRY_PART0_KEYSIZE - 3480 EM_MODE320_KEY_PART0_SIZE)), 3481 EM_MODE320_KEY_PART2_SIZE); 3482 BCM_IF_ERROR_RETURN(rv); 3483 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_2_ONLYf, tbuf); 3484 rv = _bcm_field_th_val_get(key, tbuf, 3485 ((EM_MODE320_KEY_PART1_SIZE - 3486 (EM_ENTRY_PART0_KEYSIZE - 3487 EM_MODE320_KEY_PART0_SIZE)) + 3488 EM_MODE320_KEY_PART2_SIZE), 3489 EM_MODE320_KEY_PART3_SIZE); 3490 BCM_IF_ERROR_RETURN(rv); 3491 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_3_ONLYf, tbuf); 3492 3493 } else { 3494 /* Invalid Exact Match Mode. */ 3495 return BCM_E_PARAM; 3496 } 3497 return rv; 3498 } 3499 /* 3500 * Function: 3501 * _field_td3_em_entry_set 3502 * Purpose: 3503 * Set Exact Match Policy Data. 3504 * Parameters: 3505 * unit - (IN) BCM device number. 3506 * f_ent - (IN) Field Entry. 3507 * entbuf - (OUT) Entry Policy Data Buffer. 3508 * qp_idx - (OUT) Qos Actions Profile Index. 3509 * ap_idx - (OUT) Action Profile Index. 3510 * Returns: 3511 * BCM_E_XXX 3512 * Notes: 3513 */ 3514 int 3515 _field_td3_em_entry_set(int unit, 3516 _field_entry_t *f_ent, 3517 soc_mem_t mem, 3518 uint32 *bufp, int search_entry) 3519 { 3520 int rv = BCM_E_NONE; /* Operational Status. */ 3521 _field_group_t *fg = NULL; /* Field Group Control. */ 3522 _field_entry_t *f_ent_part = NULL; /* Field Entry Part. */ 3523 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3524 /* Temp Buffer One. */ 3525 uint32 tbuf_temp[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3526 /* Temp Buffer Two. */ 3527 uint32 *key; 3528 3529 /* Input Parameters Check. */ 3530 if ((NULL == f_ent) || 3531 (NULL == f_ent->group) || 3532 (NULL == f_ent->fs)) { 3533 return (BCM_E_PARAM); 3534 } 3535 3536 /* Retreive Field Group */ 3537 fg = f_ent->group; 3538 3539 /* Assign the correct key */ 3540 if (1 == search_entry) { 3541 key = f_ent->tcam.key_hw; 3542 } else { 3543 key = f_ent->tcam.key; 3544 } 3545 3546 soc_mem_field32_set(unit, mem, bufp, KEY_TYPEf, fg->em_mode); 3547 /* Set Exact Match Entry */ 3548 if (fg->em_mode == _FieldExactMatchMode128) { 3549 3550 if (0 == search_entry) { 3551 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_0f, 3); 3552 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_1f, 4); 3553 } 3554 rv = _bcm_field_th_val_get(key, tbuf, 0, 3555 TD3_EM_MODE128_KEY_PART0_SIZE); 3556 BCM_IF_ERROR_RETURN(rv); 3557 soc_mem_field_set(unit, mem, bufp, MODE128__KEY_0_ONLYf, tbuf); 3558 rv = _bcm_field_th_val_get(key, tbuf, 3559 TD3_EM_MODE128_KEY_PART0_SIZE, 3560 TD3_EM_MODE128_KEY_PART1_SIZE); 3561 BCM_IF_ERROR_RETURN(rv); 3562 soc_mem_field_set(unit, mem, bufp, MODE128__KEY_1_ONLYf, tbuf); 3563 3564 } else if (fg->em_mode == _FieldExactMatchMode160) { 3565 3566 if (0 == search_entry) { 3567 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_0f, 3); 3568 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_1f, 4); 3569 } 3570 rv = _bcm_field_th_val_get(key, tbuf, 0, 3571 TD3_EM_MODE160_KEY_PART0_SIZE); 3572 BCM_IF_ERROR_RETURN(rv); 3573 soc_mem_field_set(unit, mem, bufp, MODE160__KEY_0_ONLYf, tbuf); 3574 rv = _bcm_field_th_val_get(key, tbuf, 3575 TD3_EM_MODE160_KEY_PART0_SIZE, 3576 TD3_EM_MODE160_KEY_PART1_SIZE); 3577 BCM_IF_ERROR_RETURN(rv); 3578 soc_mem_field_set(unit, mem, bufp, MODE160__KEY_1_ONLYf, tbuf); 3579 3580 } else if (fg->em_mode == _FieldExactMatchMode320) { 3581 3582 if (0 == search_entry) { 3583 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_0f, 5); 3584 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_1f, 6); 3585 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_2f, 6); 3586 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_3f, 6); 3587 } 3588 rv = _bcm_field_th_val_get(key, tbuf, 0, 3589 TD3_EM_MODE320_KEY_PART0_SIZE); 3590 BCM_IF_ERROR_RETURN(rv); 3591 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_0_ONLYf, tbuf); 3592 rv = _bcm_field_th_val_get(key, tbuf, 3593 TD3_EM_MODE320_KEY_PART0_SIZE, 3594 (EM_ENTRY_PART0_KEYSIZE - 3595 TD3_EM_MODE320_KEY_PART0_SIZE)); 3596 BCM_IF_ERROR_RETURN(rv); 3597 3598 /* Key From Second Entry Part. */ 3599 f_ent_part = f_ent + 1; 3600 3601 /* Assign the correct key */ 3602 if (1 == search_entry) { 3603 key = f_ent_part->tcam.key_hw; 3604 } else { 3605 key = f_ent_part->tcam.key; 3606 } 3607 3608 if (NULL == key) { 3609 return BCM_E_PARAM; 3610 } 3611 3612 rv = _bcm_field_th_val_get(key, tbuf_temp, 0, 3613 (TD3_EM_MODE320_KEY_PART1_SIZE - 3614 (EM_ENTRY_PART0_KEYSIZE - 3615 TD3_EM_MODE320_KEY_PART0_SIZE))); 3616 BCM_IF_ERROR_RETURN(rv); 3617 rv = _bcm_field_th_val_set(tbuf, tbuf_temp, 3618 (EM_ENTRY_PART0_KEYSIZE - 3619 TD3_EM_MODE320_KEY_PART0_SIZE), 3620 (TD3_EM_MODE320_KEY_PART1_SIZE - 3621 (EM_ENTRY_PART0_KEYSIZE - 3622 TD3_EM_MODE320_KEY_PART0_SIZE))); 3623 BCM_IF_ERROR_RETURN(rv); 3624 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_1_ONLYf, tbuf); 3625 rv = _bcm_field_th_val_get(key, tbuf, 3626 (TD3_EM_MODE320_KEY_PART1_SIZE - 3627 (EM_ENTRY_PART0_KEYSIZE - 3628 TD3_EM_MODE320_KEY_PART0_SIZE)), 3629 TD3_EM_MODE320_KEY_PART2_SIZE); 3630 BCM_IF_ERROR_RETURN(rv); 3631 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_2_ONLYf, tbuf); 3632 rv = _bcm_field_th_val_get(key, tbuf, 3633 ((TD3_EM_MODE320_KEY_PART1_SIZE - 3634 (EM_ENTRY_PART0_KEYSIZE - 3635 TD3_EM_MODE320_KEY_PART0_SIZE)) + 3636 TD3_EM_MODE320_KEY_PART2_SIZE), 3637 TD3_EM_MODE320_KEY_PART3_SIZE); 3638 BCM_IF_ERROR_RETURN(rv); 3639 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_3_ONLYf, tbuf); 3640 3641 } else { 3642 /* Invalid Exact Match Mode. */ 3643 rv = BCM_E_PARAM; 3644 } 3645 return rv; 3646 } 3647 3648 /* 3649 * Function: 3650 * _field_th3_em_entry_set 3651 * Purpose: 3652 * Set Exact Match Policy Data. 3653 * Parameters: 3654 * unit - (IN) BCM device number. 3655 * f_ent - (IN) Field Entry. 3656 * entbuf - (OUT) Entry Policy Data Buffer. 3657 * qp_idx - (OUT) Qos Actions Profile Index. 3658 * ap_idx - (OUT) Action Profile Index. 3659 * Returns: 3660 * BCM_E_XXX 3661 * Notes: 3662 */ 3663 int 3664 _field_th3_em_entry_set(int unit, 3665 _field_entry_t *f_ent, 3666 soc_mem_t mem, 3667 uint32 *bufp, int search_entry) 3668 { 3669 int rv = BCM_E_NONE; /* Operational Status. */ 3670 _field_group_t *fg = NULL; /* Field Group Control. */ 3671 _field_entry_t *f_ent_part = NULL; /* Field Entry Part. */ 3672 uint32 tbuf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3673 /* Temp Buffer One. */ 3674 uint32 tbuf_temp[SOC_MAX_MEM_FIELD_WORDS] = {0}; 3675 /* Temp Buffer Two. */ 3676 uint32 *key; 3677 3678 /* Input Parameters Check. */ 3679 if ((NULL == f_ent) || 3680 (NULL == f_ent->group) || 3681 (NULL == f_ent->fs)) { 3682 return (BCM_E_PARAM); 3683 } 3684 3685 /* Retreive Field Group */ 3686 fg = f_ent->group; 3687 3688 /* Assign the correct key */ 3689 if (1 == search_entry) { 3690 key = f_ent->tcam.key_hw; 3691 } else { 3692 key = f_ent->tcam.key; 3693 } 3694 3695 soc_mem_field32_set(unit, mem, bufp, KEY_TYPEf, fg->em_mode); 3696 /* Set Exact Match Entry */ 3697 if (fg->em_mode == _FieldExactMatchMode128) { 3698 if (0 == search_entry) { 3699 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_0f, 1); 3700 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_1f, 2); 3701 } 3702 rv = _bcm_field_th_val_get(key, tbuf, 0, 3703 TH3_EM_MODE128_KEY_PART0_SIZE); 3704 soc_mem_field_set(unit, mem, bufp, MODE128__KEY_0_ONLYf, tbuf); 3705 rv = _bcm_field_th_val_get(key, tbuf, 3706 TH3_EM_MODE128_KEY_PART0_SIZE, 3707 TH3_EM_MODE128_KEY_PART1_SIZE); 3708 soc_mem_field_set(unit, mem, bufp, MODE128__KEY_1_ONLYf, tbuf); 3709 } else if (fg->em_mode == _FieldExactMatchMode160) { 3710 if (0 == search_entry) { 3711 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_0f, 1); 3712 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_1f, 2); 3713 } 3714 rv = _bcm_field_th_val_get(key, tbuf, 0, 3715 TH3_EM_MODE160_KEY_PART0_SIZE); 3716 soc_mem_field_set(unit, mem, bufp, MODE160__KEY_0_ONLYf, tbuf); 3717 rv = _bcm_field_th_val_get(key, tbuf, 3718 TH3_EM_MODE160_KEY_PART0_SIZE, 3719 TH3_EM_MODE160_KEY_PART1_SIZE); 3720 soc_mem_field_set(unit, mem, bufp, MODE160__KEY_1_ONLYf, tbuf); 3721 } else if (fg->em_mode == _FieldExactMatchMode320) { 3722 if (0 == search_entry) { 3723 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_0f, 1); 3724 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_1f, 2); 3725 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_2f, 2); 3726 soc_mem_field32_set(unit, mem, bufp, BASE_VALID_3f, 7); 3727 } 3728 rv = _bcm_field_th_val_get(key, tbuf, 0, 3729 TH3_EM_MODE320_KEY_PART0_SIZE); 3730 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_0_ONLYf, tbuf); 3731 rv = _bcm_field_th_val_get(key, tbuf, 3732 TH3_EM_MODE320_KEY_PART0_SIZE, 3733 (EM_ENTRY_PART0_KEYSIZE - 3734 TH3_EM_MODE320_KEY_PART0_SIZE)); 3735 3736 /* Key From Second Entry Part. */ 3737 f_ent_part = f_ent + 1; 3738 3739 /* Assign the correct key */ 3740 if (1 == search_entry) { 3741 key = f_ent_part->tcam.key_hw; 3742 } else { 3743 key = f_ent_part->tcam.key; 3744 } 3745 3746 rv = _bcm_field_th_val_get(key, tbuf_temp, 0, 3747 (TH3_EM_MODE320_KEY_PART1_SIZE - 3748 (EM_ENTRY_PART0_KEYSIZE - 3749 TH3_EM_MODE320_KEY_PART0_SIZE))); 3750 rv = _bcm_field_th_val_set(tbuf, tbuf_temp, 3751 (EM_ENTRY_PART0_KEYSIZE - 3752 TH3_EM_MODE320_KEY_PART0_SIZE), 3753 (TH3_EM_MODE320_KEY_PART1_SIZE - 3754 (EM_ENTRY_PART0_KEYSIZE - 3755 TH3_EM_MODE320_KEY_PART0_SIZE))); 3756 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_1_ONLYf, tbuf); 3757 rv = _bcm_field_th_val_get(key, tbuf, 3758 (TH3_EM_MODE320_KEY_PART1_SIZE - 3759 (EM_ENTRY_PART0_KEYSIZE - 3760 TH3_EM_MODE320_KEY_PART0_SIZE)), 3761 TH3_EM_MODE320_KEY_PART2_SIZE); 3762 soc_mem_field_set(unit, mem, bufp, MODE320__KEY_2_ONLYf, tbuf); 3763 } else { 3764 /* Invalid Exact Match Mode. */ 3765 rv = BCM_E_PARAM; 3766 } 3767 return rv; 3768 } 3769 3770 #else /* BCM_TOMAHAWK_SUPPORT && BCM_FIELD_SUPPORT */ 3771 int _th_field_not_empty; 3772 #endif /* !BCM_TOMAHAWK_SUPPORT && !BCM_FIELD_SUPPORT */