field_class.c (190545B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: field_class.c 8 * Purpose: BCM56960 Field Processor Group management functions. 9 */ 10 11 #include <soc/defs.h> 12 #if defined(BCM_TOMAHAWK_SUPPORT) && defined(BCM_FIELD_SUPPORT) 13 #include <shared/bsl.h> 14 #include <soc/mem.h> 15 #include <soc/drv.h> 16 #include <bcm_int/esw/tomahawk.h> 17 18 #if defined(BCM_TOMAHAWK3_SUPPORT) 19 #include <bcm_int/esw/tomahawk3.h> 20 #endif 21 22 #include <bcm/field.h> 23 #include <bcm_int/esw/field.h> 24 25 /* Local functions prototypes. */ 26 STATIC int 27 _field_th_class_group_validate(int unit, 28 _field_group_t *fg); 29 STATIC int 30 _field_th_class_group_sort(int unit, 31 _field_group_t *fg, 32 _field_class_type_t ctype); 33 STATIC void 34 _field_th_class_entry_key_show(int unit, 35 _field_entry_t *class_ent, 36 _field_class_type_t ctype, 37 uint32 *cdata); 38 STATIC int 39 _field_th_class_hwindex_get(int unit, 40 _field_entry_t *entry, 41 _field_class_type_t ctype, 42 int *hw_index); 43 STATIC int 44 _field_th_class_ethertype_install(int unit, 45 _field_entry_t *entry); 46 STATIC int 47 _field_th_class_ethertype_read(int unit, 48 _field_entry_t *entry, 49 uint32 *databuf); 50 STATIC int 51 _field_th_class_l4srcport_install(int unit, 52 _field_entry_t *entry); 53 STATIC int 54 _field_th_class_l4srcport_read(int unit, 55 _field_entry_t *entry, 56 uint32 *databuf); 57 STATIC int 58 _field_th_class_l4dstport_install(int unit, 59 _field_entry_t *entry); 60 STATIC int 61 _field_th_class_l4dstport_read(int unit, 62 _field_entry_t *entry, 63 uint32 *databuf); 64 STATIC int 65 _field_th_class_srccompression_install(int unit, 66 _field_entry_t *entry); 67 STATIC int 68 _field_th_class_srccompression_read(int unit, 69 _field_entry_t *entry, 70 uint32 *databuf); 71 STATIC int 72 _field_th_class_dstcompression_install(int unit, 73 _field_entry_t *entry); 74 STATIC int 75 _field_th_class_dstcompression_read(int unit, 76 _field_entry_t *entry, 77 uint32 *databuf); 78 STATIC int 79 _field_th_class_ttl_install(int unit, 80 _field_entry_t *entry); 81 STATIC int 82 _field_th_class_ttl_read(int unit, 83 _field_entry_t *entry, 84 uint32 *databuf); 85 STATIC int 86 _field_th_class_tos_install(int unit, 87 _field_entry_t *entry); 88 STATIC int 89 _field_th_class_tos_read(int unit, 90 _field_entry_t *entry, 91 uint32 *databuf); 92 STATIC int 93 _field_th_class_ipproto_install(int unit, 94 _field_entry_t *entry); 95 STATIC int 96 _field_th_class_ipproto_read(int unit, 97 _field_entry_t *entry, 98 uint32 *databuf); 99 STATIC int 100 _field_th_class_tcp_install(int unit, 101 _field_entry_t *entry); 102 STATIC int 103 _field_th_class_tcp_read(int unit, 104 _field_entry_t *entry, 105 uint32 *databuf); 106 107 STATIC int 108 _field_th_class_iptunnelttl_install(int unit, 109 _field_entry_t *entry); 110 STATIC int 111 _field_th_class_iptunnelttl_read(int unit, 112 _field_entry_t *entry, 113 uint32 *databuf); 114 115 /* 116 * Function: 117 * _bcm_field_th_class_type_qset_get 118 * Purpose: 119 * Get Field Class Type from qset. 120 * Parameters: 121 * unit - (IN) BCM device number. 122 * qset - (IN) Field Qualifier Set. 123 * ctype - (OUT) Field Class type. 124 * Returns: 125 * BCM_E_XXX 126 * Notes: 127 * This api assumes that only valid set of qset is passed 128 * for class type. 129 */ 130 int 131 _bcm_field_th_class_type_qset_get(int unit, bcm_field_qset_t *qset, 132 _field_class_type_t *ctype) 133 { 134 int rv = BCM_E_NONE; /* Operation Return Status */ 135 136 /* Input parameters check */ 137 if (qset == NULL || ctype == NULL) { 138 return (BCM_E_INTERNAL); 139 } 140 141 /* Retreive class type from provided qset */ 142 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyEtherType)) { 143 *ctype = _FieldClassEtherType; 144 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl)) { 145 *ctype = _FieldClassTtl; 146 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos)) { 147 *ctype = _FieldClassToS; 148 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpProtocol)) { 149 *ctype = _FieldClassIpProto; 150 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4SrcPort) || 151 (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeOxID))) { 152 *ctype = _FieldClassL4SrcPort; 153 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4DstPort) || 154 (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeRxID))) { 155 *ctype = _FieldClassL4DstPort; 156 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl)) { 157 *ctype = _FieldClassTcp; 158 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) || 159 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) || 160 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId)) { 161 *ctype = _FieldClassSrcCompression; 162 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) || 163 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) || 164 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId)) { 165 *ctype = _FieldClassDstCompression; 166 } else if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl)) { 167 *ctype = _FieldClassIpTunnelTtl; 168 } else { 169 rv = BCM_E_PARAM; 170 } 171 172 return (rv); 173 } 174 175 /* 176 * Function: 177 * _bcm_field_th_class_ctype_supported 178 * Purpose: 179 * Check if the class type is supported for the device. 180 * Parameters: 181 * unit - (IN) BCM Device number. 182 * ctype - (IN) Field Class Type. 183 * Returns: 184 * BCM_E_XXX 185 */ 186 int 187 _bcm_field_th_class_ctype_supported(int unit, 188 _field_class_type_t ctype) 189 { 190 int rv = BCM_E_NONE; 191 192 #if defined (BCM_TOMAHAWK3_SUPPORT) 193 if ((soc_feature(unit, soc_feature_th3_style_fp))) { 194 return _field_th3_class_ctype_supported (unit, ctype); 195 } 196 #endif 197 198 switch(ctype) { 199 case _FieldClassEtherType: 200 case _FieldClassTtl: 201 case _FieldClassToS: 202 case _FieldClassIpProto: 203 case _FieldClassL4SrcPort: 204 case _FieldClassL4DstPort: 205 case _FieldClassTcp: 206 case _FieldClassSrcCompression: 207 case _FieldClassDstCompression: 208 rv = BCM_E_NONE; 209 break; 210 default: 211 rv = BCM_E_UNAVAIL; 212 break; 213 } 214 215 return rv; 216 } 217 218 /* 219 * Function: 220 * _field_th_class_max_entries 221 * Purpose: 222 * Get Field Class max entries supported for 223 * provide class pipe and type. 224 * Parameters: 225 * unit - (IN) BCM Device number. 226 * cpipe - (IN) Field Class Pipe. 227 * ctype - (IN) Field Class Type. 228 * max_entries - (OUT) Max Entries Supported. 229 * Returns: 230 * BCM_E_XXX 231 */ 232 int 233 _field_th_class_max_entries(int unit, int cpipe, 234 _field_class_type_t ctype, 235 int *max_entries) 236 { 237 int rv = BCM_E_NONE; /* Operation Return Status */ 238 239 /* Validate class pipe */ 240 if (cpipe < 0 || cpipe >= _FP_MAX_NUM_PIPES) { 241 return (BCM_E_INTERNAL); 242 } 243 244 /* Validate and fill as per class type */ 245 switch(ctype) { 246 case _FieldClassEtherType: 247 *max_entries = _FP_MAX_NUM_CLASS_ETHERTYPE; 248 break; 249 case _FieldClassTtl: 250 *max_entries = _FP_MAX_NUM_CLASS_TTL; 251 break; 252 case _FieldClassToS: 253 *max_entries = _FP_MAX_NUM_CLASS_TOS; 254 break; 255 case _FieldClassIpProto: 256 *max_entries = _FP_MAX_NUM_CLASS_IP_PROTO; 257 break; 258 case _FieldClassL4SrcPort: 259 *max_entries = _FP_MAX_NUM_CLASS_L4_SRC_PORT; 260 break; 261 case _FieldClassL4DstPort: 262 *max_entries = _FP_MAX_NUM_CLASS_L4_DST_PORT; 263 break; 264 case _FieldClassTcp: 265 *max_entries = _FP_MAX_NUM_CLASS_TCP; 266 break; 267 case _FieldClassSrcCompression: 268 *max_entries = _FP_MAX_NUM_CLASS_SRC_COMPRESSION; 269 break; 270 case _FieldClassDstCompression: 271 *max_entries = _FP_MAX_NUM_CLASS_DST_COMPRESSION; 272 break; 273 case _FieldClassIpTunnelTtl: 274 *max_entries = _FP_MAX_NUM_CLASS_IPTUNNELTTL; 275 break; 276 default: 277 rv = BCM_E_PARAM; 278 } 279 280 return (rv); 281 } 282 283 /* 284 * Function: 285 * _field_th_class_group_validate 286 * Purpose: 287 * Validate a field processor group for stage class. 288 * Parameters: 289 * unit - (IN) BCM Device Number. 290 * class_fg - (IN/OUT) Field Class Group. 291 * Returns: 292 * BCM_E_XXX. 293 * Notes: 294 * This function is used to validate 295 * qset, aset , pbmp for field class group 296 * and update instance information. 297 */ 298 STATIC int 299 _field_th_class_group_validate(int unit, _field_group_t *class_fg) 300 { 301 int rv = BCM_E_NONE; /* Operation Return Status */ 302 int stage_cnt = 0, class_cnt = 0; 303 /* Stage and Class Count */ 304 _field_stage_t *stage_fc = NULL; 305 /* Field Stage Control */ 306 _field_control_t *fc = NULL; 307 /* Field Control Structure */ 308 _field_group_t *fg = NULL; 309 /* Field Group Control */ 310 int pipe; /* Device pipe iterator */ 311 bcm_pbmp_t t_pbmp; /* Pipe Port bitmap */ 312 bcm_field_qset_t *qset = NULL; 313 /* Field Qualifier Set */ 314 bcm_field_qset_t qset_supported; 315 /* Field Class Qualifier Set */ 316 _bcm_field_aset_t *aset = NULL; 317 /* Field Action Set */ 318 bcm_field_qset_t qset_fg; 319 /* Field Group Qualifier Set */ 320 bcm_pbmp_t all_pbmp; /* Group port bitmap. */ 321 322 /* Input parameters check. */ 323 if ((NULL == class_fg) || 324 (class_fg->stage_id != _BCM_FIELD_STAGE_CLASS)) { 325 return (BCM_E_INTERNAL); 326 } 327 328 /* Get Field Control */ 329 rv = _field_control_get(unit, &fc); 330 if (BCM_FAILURE(rv)) { 331 return (rv); 332 } 333 334 /* Get Field Class Stage Control */ 335 rv = _field_stage_control_get(unit, class_fg->stage_id, &stage_fc); 336 if (BCM_FAILURE(rv)) { 337 return (rv); 338 } 339 340 /* Assign qset and aset */ 341 qset = &class_fg->qset; 342 aset = &class_fg->aset; 343 344 /* Set Supported QSet for Stage Class */ 345 BCM_FIELD_QSET_INIT(qset_supported); 346 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyStageClass); 347 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyStageClassExactMatch); 348 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyEtherType); 349 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyTtl); 350 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyTos); 351 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyIpProtocol); 352 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyTcpControl); 353 354 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyVrf); 355 356 if (SOC_IS_TOMAHAWK3(unit)) { 357 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyIpTunnelTtl); 358 } else { 359 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyL4SrcPort); 360 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyL4DstPort); 361 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifySrcIp); 362 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifySrcIp6); 363 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyDstIp); 364 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyDstIp6); 365 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFcoeOxID); 366 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFcoeRxID); 367 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFibreChanSrcId); 368 BCM_FIELD_QSET_ADD(qset_supported, bcmFieldQualifyFibreChanDstId); 369 } 370 371 /* Validate Provided qset is supported */ 372 if(!(_field_qset_is_subset(&class_fg->qset, &qset_supported))) { 373 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 374 "FP(unit %d) Error: Un-Supported Qualifier in qset " 375 "for stage class.\n"), 376 unit)); 377 return (BCM_E_UNAVAIL); 378 } 379 380 /* 381 * First Check only one stage is passed either 382 * it is StageClass or StageClassExactMatch 383 */ 384 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClass)) 385 stage_cnt++; 386 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClassExactMatch)) 387 stage_cnt++; 388 389 if (stage_cnt != 1) { 390 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 391 "FP(unit %d) Error: StageClass Parameter not specified " 392 "or is not valid.\n"), 393 unit)); 394 return (BCM_E_PARAM); 395 } 396 397 /* Check only one class is specified */ 398 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyEtherType)) 399 class_cnt++; 400 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl)) 401 class_cnt++; 402 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos)) 403 class_cnt++; 404 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpProtocol)) 405 class_cnt++; 406 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4SrcPort) || 407 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeOxID)) 408 class_cnt++; 409 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4DstPort) || 410 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeRxID)) 411 class_cnt++; 412 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl)) 413 class_cnt++; 414 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) || 415 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) || 416 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId)) 417 class_cnt++; 418 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) || 419 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) || 420 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId)) 421 class_cnt++; 422 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl)) 423 class_cnt++; 424 425 if (class_cnt != 1) { 426 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 427 "FP(unit %d) Error: Un-Supported combination of class " 428 "qualifier.\n"), 429 unit)); 430 return (BCM_E_PARAM); 431 } 432 433 /* Check if Class action provided, if not return error */ 434 if (!(BCM_FIELD_ASET_TEST(*aset, bcmFieldActionClassZero) || 435 BCM_FIELD_ASET_TEST(*aset, bcmFieldActionClassOne))) { 436 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 437 "FP(unit %d) Error: Stage Action Paramter not " 438 "specified.\n"), 439 unit)); 440 return (BCM_E_PARAM); 441 } 442 443 /* ClassOne Action Validation */ 444 if (BCM_FIELD_ASET_TEST(*aset, bcmFieldActionClassOne)) { 445 if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl) || 446 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos) || 447 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl) || 448 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl))) { 449 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 450 "FP(unit %d) Error: ClassOne Action unsupported for " 451 "provided class qualfier.\n"), 452 unit)); 453 return (BCM_E_PARAM); 454 } 455 } 456 457 /* Stage Class Validation */ 458 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClass)) { 459 if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) || 460 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) || 461 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId) || 462 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) || 463 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) || 464 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId))) { 465 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 466 "FP(unit %d) Error: Qualifier unsupported for given " 467 "stage class.\n"), 468 unit)); 469 return (BCM_E_PARAM); 470 } 471 } 472 473 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyStageClassExactMatch)) { 474 if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyEtherType) || 475 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTtl) || 476 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTos) || 477 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpProtocol) || 478 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4SrcPort) || 479 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeOxID) || 480 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyL4DstPort) || 481 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFcoeRxID) || 482 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyTcpControl) || 483 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyIpTunnelTtl))) { 484 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 485 "FP(unit %d) Error: Qualifier unsupported for given " 486 "stage class exact match.\n"), 487 unit)); 488 return (BCM_E_PARAM); 489 } 490 } 491 492 /* VRF Check */ 493 if (BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyVrf)) { 494 if (!(BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp) || 495 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifySrcIp6) || 496 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanSrcId) || 497 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp) || 498 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyDstIp6) || 499 BCM_FIELD_QSET_TEST(*qset, bcmFieldQualifyFibreChanDstId))) { 500 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 501 "FP(unit %d) Error: Un-Supported Qualifier set " 502 "for VRF.\n"), 503 unit)); 504 return (BCM_E_PARAM); 505 } 506 } 507 508 /* Read device port configuration. */ 509 BCM_PBMP_CLEAR(all_pbmp); 510 BCM_IF_ERROR_RETURN(_bcm_field_valid_pbmp_get(unit, &all_pbmp)); 511 512 /* Verify pbmp based on stage operational mode */ 513 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 514 /* 515 * Validate user supplied IPBM value.For global mode, 516 * all ports must be part of IPBM value, if supplied. 517 */ 518 if (BCM_PBMP_NEQ(all_pbmp, class_fg->pbmp)) { 519 /* If port configuration get fails, go to end. */ 520 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 521 "FP(unit %d) Error: Global Mode - " 522 "Port Bitmap not valid.\n"), 523 unit)); 524 return (BCM_E_PARAM); 525 } 526 527 /* For group global operational mode, use the default instance. */ 528 class_fg->instance = _FP_DEF_INST; 529 } else { 530 /* 531 * For PipeLocal group oper mode, derive the 532 * instance information from group's PBM value. 533 */ 534 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++){ 535 BCM_PBMP_ASSIGN(t_pbmp, PBMP_PIPE(unit,pipe)); 536 BCM_PBMP_REMOVE(t_pbmp, PBMP_LB(unit)); 537 /* 538 * User must use bcm_port_config_get API to retrieve Pipe PBMP value 539 * and pass this value in Group's pbmp parameter when creating 540 * PipeLocal groups. 541 */ 542 if (BCM_PBMP_EQ(t_pbmp, class_fg->pbmp)) { 543 /* 544 * Pipe PBM matches user supplied PBM, update field group 545 * instance. 546 */ 547 class_fg->instance = pipe; 548 break; 549 } 550 } 551 552 /* 553 * Portbit map value supplied by the user not matching any of the pipe's 554 * port bitmap mask value, hence return input paramter error. 555 */ 556 if (NUM_PIPE(unit) == pipe) { 557 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 558 "FP(unit %d) Error: Per Pipe Mode - " 559 "Port Bitmap not valid.\n"), 560 unit)); 561 return (BCM_E_PARAM); 562 } 563 } 564 565 /* 566 * Only one class group is valid per compression 567 * table. Validate if it exist already in system. 568 */ 569 fg = fc->groups; 570 while (fg != NULL) { 571 /* Skip non class groups */ 572 if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 573 fg = fg->next; 574 continue; 575 } 576 /* 577 * Check overlapping qualifier additionally. 578 * SrcIp and DstIp compression groups are superset of 579 * IPv6 ,V6 and FCoE entries. Hence compare subset 580 * with superset qset than actual group qset. 581 */ 582 BCM_FIELD_QSET_INIT(qset_fg); 583 qset_fg = class_fg->qset; 584 if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyL4SrcPort) || 585 BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFcoeOxID)) { 586 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyL4SrcPort); 587 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFcoeOxID); 588 } 589 if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyL4DstPort) || 590 BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFcoeRxID)) { 591 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyL4DstPort); 592 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFcoeRxID); 593 } 594 if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifySrcIp) || 595 BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifySrcIp6) || 596 BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFibreChanSrcId)) { 597 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifySrcIp); 598 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifySrcIp6); 599 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFibreChanSrcId); 600 } 601 if (BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyDstIp) || 602 BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyDstIp6) || 603 BCM_FIELD_QSET_TEST(qset_fg, bcmFieldQualifyFibreChanDstId)) { 604 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyDstIp); 605 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyDstIp6); 606 BCM_FIELD_QSET_ADD(qset_fg, bcmFieldQualifyFibreChanDstId); 607 } 608 609 if (_field_qset_is_subset(&fg->qset, &qset_fg)) { 610 611 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 612 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 613 "FP(unit %d) Error: Global Mode - " 614 "Field Group Exist Already.\n"), 615 unit)); 616 return (BCM_E_PARAM); 617 } else { 618 if (BCM_PBMP_EQ(fg->pbmp, class_fg->pbmp)) { 619 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, 620 "FP(unit %d) Error: Per Pipe Mode - " 621 "Field Group Exist Already.\n"), 622 unit)); 623 return (BCM_E_PARAM); 624 } 625 } 626 } 627 fg = fg->next; 628 } 629 630 return (rv); 631 } 632 633 /* 634 * Function: 635 * _bcm_field_th_class_size_get 636 * Purpose: 637 * Get Field Class size supported for 638 * provide ctype. 639 * Parameters: 640 * unit - (IN) BCM Device number. 641 * ctype - (IN) Field Class Type. 642 * memsize - (OUT) Max Class Size. 643 * Returns: 644 * BCM_E_XXX 645 */ 646 int 647 _bcm_field_th_class_size_get(int unit, _field_class_type_t ctype, 648 int *memsize) 649 { 650 int rv = BCM_E_NONE; /* Operation Return Status */ 651 652 /* Validate and fill as per class type */ 653 switch(ctype) { 654 case _FieldClassEtherType: 655 *memsize = _FP_SIZE_CLASS_ETHERTYPE; 656 break; 657 case _FieldClassTtl: 658 *memsize = _FP_SIZE_CLASS_TTL; 659 break; 660 case _FieldClassToS: 661 *memsize = _FP_SIZE_CLASS_TOS; 662 break; 663 case _FieldClassIpProto: 664 *memsize = _FP_SIZE_CLASS_IP_PROTO; 665 break; 666 case _FieldClassL4SrcPort: 667 *memsize = _FP_SIZE_CLASS_L4_SRC_PORT; 668 break; 669 case _FieldClassL4DstPort: 670 *memsize = _FP_SIZE_CLASS_L4_DST_PORT; 671 break; 672 case _FieldClassTcp: 673 *memsize = _FP_SIZE_CLASS_TCP; 674 break; 675 case _FieldClassSrcCompression: 676 *memsize = _FP_SIZE_CLASS_SRC_COMPRESSION; 677 break; 678 case _FieldClassDstCompression: 679 *memsize = _FP_SIZE_CLASS_DST_COMPRESSION; 680 break; 681 case _FieldClassIpTunnelTtl: 682 *memsize = _FP_SIZE_CLASS_IPTUNNELTTL; 683 break; 684 default: 685 rv = BCM_E_PARAM; 686 } 687 688 return (rv); 689 } 690 691 /* 692 * Function: 693 * _bcm_field_th_class_stage_add 694 * Purpose: 695 * Add Pseudo Class Stage. 696 * Parameters: 697 * unit - (IN) BCM device number. 698 * fc - (IN) Field control structure. 699 * stage_fc - (IN) Stage field control structure. 700 * Returns: 701 * BCM_E_XXX 702 */ 703 int 704 _bcm_field_th_class_stage_add(int unit, _field_control_t *fc, 705 _field_stage_t *stage_fc) 706 { 707 int rv = BCM_E_NONE; /* Operation Return Status */ 708 709 /* Input parameters check. */ 710 if ((fc == NULL) || 711 (stage_fc == NULL)) { 712 return (BCM_E_INTERNAL); 713 } 714 715 /* Add stage to Field Control structure. */ 716 FP_LOCK(unit); 717 718 stage_fc->next = fc->stages; 719 fc->stages = stage_fc; 720 721 stage_fc->num_pipes = NUM_PIPE(unit); 722 723 if (bcmFieldGroupOperModePipeLocal == stage_fc->oper_mode) { 724 /* 725 * Initialize number of FP instances to number of pipes supported in 726 * hardware. 727 */ 728 stage_fc->num_instances = stage_fc->num_pipes; 729 } else { 730 /* Initialize to legacy TD2 mode - Global mode (single instance). */ 731 stage_fc->num_instances = 1; 732 } 733 734 /* Initialize Class Stage Tracking Structure. */ 735 rv = _bcm_field_th_class_stage_status_init(unit,stage_fc); 736 737 FP_UNLOCK(unit); 738 739 return (rv); 740 } 741 742 /* 743 * Function: 744 * _bcm_field_th_class_stage_status_init 745 * Purpose: 746 * Initialize Class Stage Tracking Structure. 747 * Parameters: 748 * unit - (IN) BCM device number. 749 * stage_fc - (IN) Stage field control structure. 750 * Returns: 751 * BCM_E_XXX 752 */ 753 int 754 _bcm_field_th_class_stage_status_init(int unit, _field_stage_t *stage_fc) 755 { 756 int rv = BCM_E_NONE; /* Operation Return Status */ 757 _field_class_type_t ctype; 758 /* Field Class Type */ 759 _field_class_info_t **class_status_arr; 760 /* Field Per Pipe Class Status Array */ 761 _field_class_info_t *class_status_info = NULL; 762 /* Field Per Compression table status */ 763 int alloc_sz; /* Memory allocation size. */ 764 int cpipe = 0, max_entries = 0,size = 0; 765 /* Misc Var */ 766 767 /* Input parameters check */ 768 if (stage_fc == NULL) { 769 return (BCM_E_INTERNAL); 770 } 771 772 /* Skip this routine for non-class stages. */ 773 if (_BCM_FIELD_STAGE_CLASS != stage_fc->stage_id) { 774 return (BCM_E_NONE); 775 } 776 777 /* Allocate Per-Pipe Class Stage Pointer Arrays */ 778 for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) { 779 if (stage_fc->class_info_arr[cpipe] == NULL) { 780 /* Allocate memory for stage class status. */ 781 _FP_XGS3_ALLOC(stage_fc->class_info_arr[cpipe], 782 (_FP_MAX_NUM_CLASS_TYPES * sizeof(_field_class_info_t *)), 783 "Field Class Status"); 784 if (NULL == stage_fc->class_info_arr[cpipe]) { 785 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 786 "FP(unit %d) Error: Allocation failure for field " 787 "class status arr info.\n"), 788 unit)); 789 return (BCM_E_MEMORY); 790 } 791 } else { 792 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 793 "FP(unit %d) Error: Allocation already present for " 794 "field class status arr info.\n"), 795 unit)); 796 return (BCM_E_INTERNAL); 797 } 798 } 799 800 /* Allocate Class Stage Tracking Strucutre for all classes per pipe */ 801 for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) { 802 class_status_arr = stage_fc->class_info_arr[cpipe]; 803 for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) { 804 /* Check the class types supported */ 805 rv = _bcm_field_th_class_ctype_supported(unit, ctype); 806 if (BCM_SUCCESS(rv)) { 807 class_status_info = class_status_arr[ctype]; 808 if (class_status_info == NULL) { 809 /* Allocate field class status info struct. */ 810 alloc_sz = sizeof(_field_class_info_t); 811 _FP_XGS3_ALLOC(class_status_info, alloc_sz, 812 "FP Class Status info"); 813 if (NULL == class_status_info) { 814 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 815 "FP(unit %d) Error: Allocation failure for " 816 "field class status info.\n"), 817 unit)); 818 return (BCM_E_MEMORY); 819 } 820 /* Update Class Status Info */ 821 class_status_info->classtype = ctype; 822 class_status_info->total_entries_used = 0; 823 824 /* Retreive Max Entries for class type */ 825 rv = _field_th_class_max_entries(unit,cpipe, 826 ctype,&max_entries); 827 828 if (BCM_SUCCESS(rv)) { 829 class_status_info->total_entries_available = max_entries; 830 size = SHR_BITALLOCSIZE(max_entries << 1); 831 class_status_info->class_bmp.w = 832 sal_alloc(size, "class_bmap"); 833 sal_memset(class_status_info->class_bmp.w, 0, size); 834 } else { 835 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 836 "FP(unit %d) Error: Retreiving max entries for " 837 "class type %d.\n"), 838 unit,ctype)); 839 sal_free(class_status_info); 840 return (BCM_E_INTERNAL); 841 } 842 class_status_arr[ctype] = class_status_info; 843 844 } else { 845 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 846 "FP(unit %d) Error: Allocation already present " 847 "for field class status info.\n"), 848 unit)); 849 return (BCM_E_MEMORY); 850 } 851 } 852 } 853 } 854 855 return (BCM_E_NONE); 856 } 857 858 /* 859 * Function: 860 * _bcm_field_th_class_stage_status_deinit 861 * Purpose: 862 * De-Initialize Class Stage Tracking Structure. 863 * Parameters: 864 * unit - (IN) BCM device number. 865 * stage_fc - (IN) Stage field control structure. 866 * Returns: 867 * BCM_E_XXX 868 */ 869 int 870 _bcm_field_th_class_stage_status_deinit(int unit, _field_stage_t *stage_fc) 871 { 872 int rv = BCM_E_NONE; /* Operation Return Status */ 873 _field_class_type_t ctype; /* Field Class Type */ 874 _field_class_info_t **class_status_arr; 875 /* Field Per Pipe Class Status Array */ 876 _field_class_info_t *class_status_info; 877 /* Field Per Compression table status */ 878 int cpipe = 0; /* Per Pipe Iterator */ 879 880 /* Input parameters check. */ 881 if (stage_fc == NULL) { 882 return (BCM_E_INTERNAL); 883 } 884 885 /* Skip this routine for non-class stages. */ 886 if (_BCM_FIELD_STAGE_CLASS != stage_fc->stage_id) { 887 return (BCM_E_NONE); 888 } 889 890 /* Free Memory Allocated for Class Status Structure */ 891 for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) { 892 class_status_arr = stage_fc->class_info_arr[cpipe]; 893 if (class_status_arr != NULL) { 894 for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) { 895 /* Check the class types supported */ 896 rv = _bcm_field_th_class_ctype_supported(unit, ctype); 897 if (BCM_SUCCESS(rv)) { 898 class_status_info = class_status_arr[ctype]; 899 if (class_status_info != NULL) { 900 if (class_status_info->class_bmp.w != NULL) { 901 sal_free(class_status_info->class_bmp.w); 902 class_status_info->class_bmp.w = NULL; 903 } 904 sal_free(class_status_info); 905 class_status_info = NULL; 906 class_status_arr[ctype] = class_status_info; 907 } 908 } 909 } 910 sal_free(class_status_arr); 911 class_status_arr = NULL; 912 stage_fc->class_info_arr[cpipe] = class_status_arr; 913 } 914 } 915 916 return (BCM_E_NONE); 917 } 918 919 /* 920 * Function: 921 * _bcm_field_th_class_group_add 922 * Purpose: 923 * Create a field processor group for stage class. 924 * Parameters: 925 * unit - (IN) BCM device number. 926 * fsm_ptr - (IN) State machine tracking structure. 927 * Returns: 928 * BCM_E_XXX 929 */ 930 int 931 _bcm_field_th_class_group_add(int unit, _field_group_add_fsm_t *fsm_ptr, 932 bcm_field_aset_t aset_class) 933 { 934 int rv = BCM_E_NONE; /* Operation Return Status */ 935 int mem_sz; /* Memory size to be allocated */ 936 _field_group_t *fg = NULL; /* New group information structure */ 937 _field_group_t *fg_temp; /* Pointer to an existing Field Group */ 938 _field_class_info_t **class_status_arr; 939 /* Field Per Pipe Class Status Array */ 940 _field_class_info_t *class_status_info; 941 /* Field Per Compression table status */ 942 _field_class_type_t ctype; 943 /* Field Class Type */ 944 int idx; 945 946 /* Input parameters check. */ 947 if (NULL == fsm_ptr) { 948 return (BCM_E_INTERNAL); 949 } 950 951 /* Validate Group ID Passed */ 952 if (BCM_SUCCESS(_field_group_get(unit, fsm_ptr->group_id, &fg_temp))) { 953 LOG_ERROR(BSL_LS_BCM_FP, 954 (BSL_META_U(unit, "FP(unit %d) Error: group=%d already " 955 "exists.\n"), 956 unit, fsm_ptr->group_id)); 957 return (BCM_E_EXISTS); 958 } 959 960 /* Get Field Control */ 961 rv = _field_control_get(unit, &fsm_ptr->fc); 962 if (BCM_FAILURE(rv)) { 963 return (rv); 964 } 965 966 /* Get Field Stage Class Control */ 967 rv = _field_stage_control_get(unit, _BCM_FIELD_STAGE_CLASS, 968 &fsm_ptr->stage_fc); 969 if (BCM_FAILURE(rv)) { 970 return (rv); 971 } 972 973 /* Determine field group structure buffer size. */ 974 mem_sz = sizeof(_field_group_t); 975 976 /* Allocate and initialize memory for Field Group. */ 977 _FP_XGS3_ALLOC(fg, mem_sz, "field group"); 978 979 if (NULL == fg) { 980 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 981 "FP(unit %d) Error:Allocation failure for " 982 "_field_group_t\n"), unit)); 983 return (BCM_E_MEMORY); 984 } 985 986 /* Initialize group structure. */ 987 fg->gid = fsm_ptr->group_id; 988 fg->stage_id = fsm_ptr->stage_fc->stage_id; 989 fg->qset = fsm_ptr->qset; 990 fg->pbmp = fsm_ptr->pbmp; 991 fg->priority = fsm_ptr->priority; 992 sal_memcpy(&fg->aset, &aset_class, sizeof(bcm_field_aset_t)); 993 994 /* Initialize the action profile index's to -1 */ 995 for (idx=0; idx < MAX_ACT_PROF_ENTRIES_PER_GROUP; idx++) { 996 fg->action_profile_idx[idx] = -1; 997 } 998 999 /* 1000 * Based on the Stage Group Operational mode, 1001 * set the Field Group's instance information. 1002 */ 1003 rv = _field_th_class_group_validate(unit, fg); 1004 if (BCM_FAILURE(rv)) { 1005 sal_free(fg); 1006 return rv; 1007 } 1008 1009 /* Initialize group status. */ 1010 bcm_field_group_status_t_init(&fg->group_status); 1011 1012 /* Retreive Class Type from entry qset */ 1013 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 1014 if (BCM_FAILURE(rv)) { 1015 sal_free(fg); 1016 return rv; 1017 } 1018 1019 /* Update Class Info Status Structure */ 1020 class_status_arr = fsm_ptr->stage_fc->class_info_arr[fg->instance]; 1021 if (class_status_arr == NULL) { 1022 sal_free(fg); 1023 return (BCM_E_INTERNAL); 1024 } 1025 class_status_info = class_status_arr[ctype]; 1026 if (class_status_info == NULL) { 1027 sal_free(fg); 1028 return (BCM_E_INTERNAL); 1029 } 1030 1031 fg->group_status.entry_count = 1032 class_status_info->total_entries_used; 1033 fg->group_status.entries_total = 1034 class_status_info->total_entries_available; 1035 fg->group_status.entries_free = fg->group_status.entries_total - 1036 fg->group_status.entry_count; 1037 1038 /* By default mark group as active. */ 1039 fg->flags |= _FP_GROUP_LOOKUP_ENABLED; 1040 1041 /* Set allocated pointer to FSM structure. */ 1042 fsm_ptr->fg = fg; 1043 1044 rv = _bcm_field_group_linked_list_insert(unit, fsm_ptr); 1045 if (BCM_FAILURE(rv)) { 1046 sal_free(fg); 1047 return (rv); 1048 } 1049 1050 return (rv); 1051 } 1052 1053 /* 1054 * Function: 1055 * _field_classtype_name 1056 * Purpose: 1057 * Translate classtype to a text string. 1058 * Parameters: 1059 * class_type stage field class type. 1060 * Returns: 1061 * Text name of indicated class type enum value. 1062 */ 1063 STATIC char * 1064 _field_classtype_name(_field_class_type_t class_type) 1065 { 1066 static char *stage_text[] = _BCM_FIELD_CLASS_TYPE_STRINGS; 1067 1068 if (class_type >= _FP_MAX_NUM_CLASS_TYPES) { 1069 return "??"; 1070 } 1071 return stage_text[class_type]; 1072 } 1073 1074 /* 1075 * Function: 1076 * _bcm_field_th_class_stage_dump 1077 * Purpose: 1078 * Dump field stage class info entries. 1079 * Parameters: 1080 * unit - (IN) BCM device number. 1081 * stage_fc - (IN) Field Class Stage Structure. 1082 * Returns: 1083 */ 1084 void 1085 _bcm_field_th_class_stage_dump(int unit, _field_stage_t *stage_fc) 1086 { 1087 _field_class_type_t ctype; 1088 /* Operation Return Status */ 1089 _field_class_info_t **class_status_arr; 1090 /* Field Per Pipe Class Status Array */ 1091 _field_class_info_t *class_status_info; 1092 /* Field Per Compression table status */ 1093 int cpipe = 0; /* Class Pipe Iterator */ 1094 int rv = BCM_E_NONE;/* Return Value */ 1095 1096 /* Input parameters check. */ 1097 if ((stage_fc != NULL) && 1098 (stage_fc->stage_id == _BCM_FIELD_STAGE_CLASS)) { 1099 1100 LOG_CLI((BSL_META_U(unit, 1101 "ClassPipe ClassType Flags " 1102 "Entries Used Entries Available\n"))); 1103 LOG_CLI((BSL_META_U(unit, 1104 "--------- --------------- ----- " 1105 "------------ -----------------\n"))); 1106 1107 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 1108 /* Global Mode - Display only default instance */ 1109 class_status_arr = stage_fc->class_info_arr[_FP_DEF_INST]; 1110 if (class_status_arr != NULL) { 1111 for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) { 1112 /* Check the class types supported */ 1113 rv = _bcm_field_th_class_ctype_supported(unit, ctype); 1114 if (BCM_SUCCESS(rv)) { 1115 class_status_info = class_status_arr[ctype]; 1116 if (class_status_info != NULL) { 1117 LOG_CLI((BSL_META_U(unit, 1118 "%9s %-14s %#5x %12d %17d\n"), 1119 "Default",_field_classtype_name(ctype), 1120 class_status_info->flags, 1121 class_status_info->total_entries_used, 1122 class_status_info->total_entries_available)); 1123 } 1124 } 1125 } 1126 } 1127 } else { 1128 /* Per Pipe Mode - Display all pipe instances */ 1129 for (cpipe = 0; cpipe < _FP_MAX_NUM_PIPES; cpipe++) { 1130 class_status_arr = stage_fc->class_info_arr[cpipe]; 1131 if (class_status_arr != NULL) { 1132 for (ctype = 0; ctype < _FP_MAX_NUM_CLASS_TYPES; ctype++) { 1133 /* Check the class types supported */ 1134 rv = _bcm_field_th_class_ctype_supported(unit, ctype); 1135 if (BCM_SUCCESS(rv)) { 1136 class_status_info = class_status_arr[ctype]; 1137 if (class_status_info != NULL) { 1138 LOG_CLI((BSL_META_U(unit, 1139 "%9d %-14s %#5x %12d %17d\n"), 1140 cpipe,_field_classtype_name(ctype), 1141 class_status_info->flags, 1142 class_status_info->total_entries_used, 1143 class_status_info->total_entries_available)); 1144 1145 } 1146 } 1147 } 1148 } 1149 } 1150 } 1151 } 1152 } 1153 1154 /* 1155 * Function: 1156 * _bcm_field_th_class_group_dump 1157 * Purpose: 1158 * Dump field stage class group. 1159 * Parameters: 1160 * unit - (IN) BCM device number. 1161 * class_fg - (IN) Field Class Stage Group Structure. 1162 * Returns: 1163 * BCM_E_XXX 1164 */ 1165 int 1166 _bcm_field_th_class_group_dump(int unit, _field_group_t *class_fg) 1167 { 1168 int rv = BCM_E_NONE; /* Operation Return Status */ 1169 _field_stage_t *stage_fc = NULL; 1170 /* Field Class Stage info */ 1171 int enable = 0; /* Group Enable */ 1172 int entry_count = 0; /* Field Entry Count */ 1173 int entry_index; /* Field Entry Index */ 1174 bcm_field_entry_t *entry_ids = NULL; 1175 /* Field Entry ID Array */ 1176 char buf[100]; /* Character Buffer */ 1177 1178 /* Input parameters check. */ 1179 if (class_fg == NULL) { 1180 return (BCM_E_INTERNAL); 1181 } 1182 1183 /* Skip if it is not stage class */ 1184 if (class_fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 1185 return (BCM_E_NONE); 1186 } 1187 1188 /* Retreive Field Stage Control */ 1189 rv = _field_stage_control_get(unit, class_fg->stage_id, &stage_fc); 1190 if (BCM_FAILURE(rv)) { 1191 return (rv); 1192 } 1193 1194 /* Dump Field Class Group Information */ 1195 LOG_CLI((BSL_META_U(unit, 1196 "GID %10d: gid=0x%x, instance=%d, flags %#x, stage=%d "), 1197 class_fg->gid, class_fg->gid, class_fg->instance, class_fg->flags, 1198 class_fg->stage_id)); 1199 bcm_esw_field_group_enable_get(unit, class_fg->gid, &enable); 1200 if (enable) { 1201 LOG_CLI((BSL_META_U(unit,"lookup=Enabled, "))); 1202 } else { 1203 LOG_CLI((BSL_META_U(unit,"lookup=Disabled, "))); 1204 } 1205 LOG_CLI((BSL_META_U(unit, 1206 "pbmp={%s},\n"), SOC_PBMP_FMT(class_fg->pbmp, buf))); 1207 _field_qset_dump(" qset=", class_fg->qset, ",\n"); 1208 _field_aset_dump(" aset=", class_fg->aset, ",\n"); 1209 LOG_CLI((BSL_META_U(unit," group_status="))); 1210 LOG_CLI((BSL_META("{entries_total=%d,"), 1211 class_fg->group_status.entries_total)); 1212 LOG_CLI((BSL_META(" entries_free=%d,"), 1213 class_fg->group_status.entries_free)); 1214 LOG_CLI((BSL_META(" entries_count=%d}"), 1215 class_fg->group_status.entry_count)); 1216 LOG_CLI((BSL_META_U(unit,"\n"))); 1217 1218 /* Print group's entries */ 1219 rv = bcm_esw_field_entry_multi_get(unit, class_fg->gid, 0, 1220 NULL, &entry_count); 1221 1222 if (BCM_SUCCESS(rv)) 1223 { 1224 entry_ids = sal_alloc(entry_count * sizeof (bcm_field_entry_t), 1225 "Entry ID array"); 1226 1227 if (entry_ids == NULL) 1228 { 1229 rv = BCM_E_MEMORY; 1230 } 1231 else 1232 { 1233 rv = bcm_esw_field_entry_multi_get(unit, class_fg->gid, 1234 entry_count, 1235 entry_ids, &entry_count); 1236 1237 if (BCM_SUCCESS(rv)) 1238 { 1239 for (entry_index = 0; entry_index < entry_count; 1240 ++entry_index) 1241 { 1242 _bcm_esw_field_entry_dump(unit, entry_ids[entry_index], -1); 1243 } 1244 } 1245 1246 sal_free(entry_ids); 1247 } 1248 } 1249 1250 return (BCM_E_NONE); 1251 } 1252 1253 /* 1254 * Function: 1255 * _bcm_field_th_class_group_brief_dump 1256 * Purpose: 1257 * Dump field stage class group brief. 1258 * Parameters: 1259 * unit - (IN) BCM device number. 1260 * class_fg - (IN) Field Class Stage Group Structure. 1261 * Returns: 1262 * BCM_E_XXX 1263 */ 1264 int 1265 _bcm_field_th_class_group_brief_dump(int unit, _field_group_t *class_fg) 1266 { 1267 int rv = BCM_E_NONE; /* Operation Return Status */ 1268 _field_stage_t *stage_fc = NULL; 1269 /* Field Class Stage info */ 1270 int enable = 0; /* Group Enable */ 1271 char buf[100]; /* Character Buffer */ 1272 1273 /* Input parameters check. */ 1274 if (class_fg == NULL) { 1275 return (BCM_E_INTERNAL); 1276 } 1277 1278 /* Skip if it is not stage class */ 1279 if (class_fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 1280 return (BCM_E_NONE); 1281 } 1282 1283 /* Retreive Field Stage Control */ 1284 rv = _field_stage_control_get(unit, class_fg->stage_id, &stage_fc); 1285 if (BCM_FAILURE(rv)) { 1286 return (rv); 1287 } 1288 1289 /* Dump Field Class Group Information */ 1290 LOG_CLI((BSL_META_U(unit, 1291 "GID %10d: gid=0x%x, instance=%d, flags %#x, stage=%d "), 1292 class_fg->gid, 1293 class_fg->gid, class_fg->instance, class_fg->flags, 1294 class_fg->stage_id)); 1295 bcm_esw_field_group_enable_get(unit, class_fg->gid, &enable); 1296 if (enable) { 1297 LOG_CLI((BSL_META_U(unit,"lookup=Enabled, "))); 1298 } else { 1299 LOG_CLI((BSL_META_U(unit,"lookup=Disabled, "))); 1300 } 1301 1302 LOG_CLI((BSL_META_U(unit, 1303 "pbmp={%s},\n"), SOC_PBMP_FMT(class_fg->pbmp, buf))); 1304 _field_qset_dump(" qset=", class_fg->qset, ",\n"); 1305 LOG_CLI((BSL_META_U(unit," group_status="))); 1306 LOG_CLI((BSL_META("{entries_total=%d,"), 1307 class_fg->group_status.entries_total)); 1308 LOG_CLI((BSL_META(" entries_free=%d,"), 1309 class_fg->group_status.entries_free)); 1310 LOG_CLI((BSL_META(" entries_count=%d}"), 1311 class_fg->group_status.entry_count)); 1312 LOG_CLI((BSL_META_U(unit,"\n"))); 1313 1314 return (BCM_E_NONE); 1315 } 1316 1317 /* 1318 * Function: 1319 * _bcm_field_th_class_entry_dump 1320 * Purpose: 1321 * Dump field stage class entry. 1322 * Parameters: 1323 * unit - (IN) BCM device number. 1324 * class_ent - (IN) Field Class Entry Structure. 1325 * Returns: 1326 * BCM_E_XXX 1327 */ 1328 int 1329 _bcm_field_th_class_entry_dump(int unit, _field_entry_t *class_ent) 1330 { 1331 int rv = BCM_E_NONE; /* Operation Return Status */ 1332 _field_group_t *fg = NULL; /* Field group info */ 1333 _field_class_type_t ctype; /* Field Class Type */ 1334 _field_action_t *fa = NULL; /* Field action info */ 1335 uint32 *databuf = 0; /* Data Buffer */ 1336 int tcam_sz = 0; 1337 1338 /* Input parameters check. */ 1339 if (class_ent == NULL || 1340 class_ent->group == NULL) { 1341 return (BCM_E_INTERNAL); 1342 } 1343 1344 /* Retreive Field Group Info */ 1345 fg = class_ent->group; 1346 1347 /* Skip if stage is not class */ 1348 if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 1349 return (BCM_E_NONE); 1350 } 1351 1352 /* Dump Field Class Group Info */ 1353 LOG_CLI((BSL_META_U(unit, 1354 "EID 0x%08x: gid=0x%x,\n"), 1355 class_ent->eid, fg->gid)); 1356 LOG_CLI((BSL_META_U(unit, 1357 " prio=%#x, flags=%#x, "), 1358 class_ent->prio, class_ent->flags)); 1359 if (class_ent->slice_idx != -1) { 1360 LOG_CLI((BSL_META_U(unit, 1361 "hw_index=%#x, "), 1362 class_ent->slice_idx)); 1363 } 1364 if (!(class_ent->flags & _FP_ENTRY_INSTALLED)) { 1365 LOG_CLI((BSL_META_U(unit, 1366 "Not installed\n"))); 1367 } else { 1368 LOG_CLI((BSL_META_U(unit, 1369 "Installed"))); 1370 if (class_ent->flags & _FP_ENTRY_DIRTY) { 1371 LOG_CLI((BSL_META_U(unit, 1372 ", Dirty\n"))); 1373 } 1374 else { 1375 LOG_CLI((BSL_META_U(unit, 1376 "\n"))); 1377 } 1378 } 1379 1380 /* Retreive Class Type from entry qset */ 1381 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 1382 if (BCM_FAILURE(rv)) { 1383 return (rv); 1384 } 1385 1386 /* Get key_size from class type */ 1387 rv = _bcm_field_th_class_size_get(unit, ctype, &tcam_sz); 1388 if (BCM_FAILURE(rv)) { 1389 return (rv); 1390 } 1391 class_ent->tcam.key_size = tcam_sz; 1392 1393 /* Allocate memory for class data */ 1394 _FP_XGS3_ALLOC(databuf, class_ent->tcam.key_size, "field class data buf"); 1395 if (databuf == NULL) {; 1396 LOG_ERROR(BSL_LS_BCM_FP, 1397 (BSL_META_U(unit, 1398 "FP(unit %d) Error: allocation failure for " 1399 "field class data buf\n"), 1400 unit)); 1401 return (BCM_E_MEMORY); 1402 } 1403 1404 LOG_CLI((BSL_META_U(unit, 1405 " Compression Type: %-14s\n"), 1406 _field_classtype_name(ctype))); 1407 1408 if (class_ent->tcam.key != NULL) { 1409 /* Entry is in tcam data buffer , read it from buffer */ 1410 sal_memcpy(databuf, class_ent->tcam.key, class_ent->tcam.key_size); 1411 } else { 1412 /* Entry is in hardware , read it from hardware */ 1413 rv = _bcm_field_th_class_entry_hwread(unit, class_ent, 1414 ctype, databuf); 1415 if (BCM_FAILURE(rv)) { 1416 sal_free(databuf); 1417 return (rv); 1418 } 1419 } 1420 1421 /* Dispaly Entry Key */ 1422 _field_th_class_entry_key_show(unit, class_ent, ctype, databuf); 1423 1424 /* Show Actions attached to entry */ 1425 LOG_CLI((BSL_META_U(unit," action="))); 1426 1427 fa = class_ent->actions; 1428 while (fa != NULL) { 1429 LOG_CLI((BSL_META("{act=%s, class=0x%x%08x}"), 1430 _field_action_name(fa->action), fa->param[1], fa->param[0])); 1431 fa = fa->next; 1432 } 1433 LOG_CLI((BSL_META_U(unit, 1434 "\n"))); 1435 1436 /* Free Entry Buffer */ 1437 sal_free(databuf); 1438 1439 return (BCM_E_NONE); 1440 } 1441 1442 /* 1443 * Function: 1444 * _field_th_class_entry_key_show. 1445 * Purpose: 1446 * Read Class Entry From Hardware. 1447 * Parameters: 1448 * unit - (IN) BCM device number. 1449 * entry - (IN) Field Entry Info. 1450 * ctype - (IN) Field Class Type. 1451 * cdata - (IN) Field Class Entry DataBuffer. 1452 * Returns: 1453 */ 1454 STATIC void 1455 _field_th_class_entry_key_show(int unit, _field_entry_t *class_ent, 1456 _field_class_type_t ctype, 1457 uint32 *cdata) 1458 { 1459 soc_reg_t reg; /* SOC Register */ 1460 soc_mem_t mem; /* SOC Memory */ 1461 uint32 keytype = 0; /* Class Entry Type */ 1462 uint32 validbit = 0; /* Entry Valid Bit */ 1463 uint32 cval = 0; /* Class Entry Value */ 1464 uint32 cmask = 0; /* Class Entry Mask */ 1465 uint32 cip6_field[4]; /* Class IP6 Field */ 1466 uint32 cip6_field_mask[4]; /* Class IP6 Field Mask */ 1467 bcm_ip6_t cip6_addr; /* Class IP6 Address */ 1468 bcm_ip6_t cip6_addr_mask; /* Class IP6 Address Mask */ 1469 int i = 0; /* Iterator */ 1470 1471 LOG_CLI((BSL_META_U(unit," {"))); 1472 1473 /* Show Key Based on Class Type */ 1474 switch(ctype) { 1475 case _FieldClassEtherType: 1476 reg = ETHERTYPE_MAPr; 1477 cval = soc_reg_field_get(unit, reg, *cdata, ETHERTYPEf); 1478 LOG_CLI((BSL_META_U(unit, 1479 "EtherType=0x%x"), 1480 cval)); 1481 break; 1482 case _FieldClassTtl: 1483 LOG_CLI((BSL_META_U(unit, 1484 "TTL=%d"), 1485 class_ent->tcam.ip_type)); 1486 break; 1487 case _FieldClassToS: 1488 LOG_CLI((BSL_META_U(unit, 1489 "TOS=%d"), 1490 class_ent->tcam.ip_type)); 1491 break; 1492 case _FieldClassIpProto: 1493 LOG_CLI((BSL_META_U(unit, 1494 "IP Protocol=0x%x"), 1495 class_ent->tcam.ip_type)); 1496 break; 1497 case _FieldClassL4SrcPort: 1498 reg = L4_SRC_PORT_MAPr; 1499 keytype = soc_reg_field_get(unit, reg, *cdata, MATCH_TYPEf); 1500 cval = soc_reg_field_get(unit, reg, *cdata, L4_SRC_PORTf); 1501 if (keytype == _FP_MATCH_L4_PORT_TYPE) { 1502 LOG_CLI((BSL_META_U(unit, 1503 "L4 SRC Port=%d"), 1504 cval)); 1505 } else if (keytype == _FP_MATCH_EXCHANGE_ID_TYPE) { 1506 LOG_CLI((BSL_META_U(unit, 1507 "FCoE OxID=0x%x"), 1508 cval)); 1509 } else { 1510 LOG_CLI((BSL_META_U(unit, 1511 "Unknown"))); 1512 } 1513 break; 1514 case _FieldClassL4DstPort: 1515 reg = L4_DST_PORT_MAPr; 1516 keytype = soc_reg_field_get(unit, reg, *cdata, MATCH_TYPEf); 1517 cval = soc_reg_field_get(unit, reg , *cdata, L4_DST_PORTf); 1518 if (keytype == _FP_MATCH_L4_PORT_TYPE) { 1519 LOG_CLI((BSL_META_U(unit, 1520 "L4 Dst Port=%d"), 1521 cval)); 1522 } else if (keytype == _FP_MATCH_EXCHANGE_ID_TYPE) { 1523 LOG_CLI((BSL_META_U(unit, 1524 "FCoE RxID=0x%x"), 1525 cval)); 1526 } else { 1527 LOG_CLI((BSL_META_U(unit, 1528 "Unknown"))); 1529 } 1530 break; 1531 case _FieldClassTcp: 1532 LOG_CLI((BSL_META_U(unit, 1533 "TCP=%d"), 1534 class_ent->tcam.ip_type)); 1535 break; 1536 case _FieldClassSrcCompression: 1537 mem = SRC_COMPRESSIONm; 1538 soc_mem_field_get(unit, mem, cdata, KEY_TYPEf, &keytype); 1539 soc_mem_field_get(unit, mem, cdata, VALIDf, &validbit); 1540 if (keytype == _FP_KEY_IPv4_TYPE) { 1541 soc_mem_field_get(unit, mem, cdata, 1542 IPV4__SIP_V4f, &cval); 1543 soc_mem_field_get(unit, mem, cdata, 1544 IPV4__SIP_V4_MASKf, &cmask); 1545 LOG_CLI((BSL_META_U(unit,"Source IPv4=0x%x, "),cval)); 1546 LOG_CLI((BSL_META_U(unit,"IPv4 Mask=0x%x, "),cmask)); 1547 } else if (keytype == _FP_KEY_FCoE_TYPE) { 1548 soc_mem_field_get(unit, mem, cdata, 1549 FCOE__S_IDf, &cval); 1550 soc_mem_field_get(unit, mem, cdata, 1551 FCOE__S_ID_MASKf, &cmask); 1552 LOG_CLI((BSL_META_U(unit,"FCoE S_ID=0x%x, "),cval)); 1553 LOG_CLI((BSL_META_U(unit,"S_ID Mask=0x%x, "),cmask)); 1554 } else if (keytype == _FP_KEY_IPv6_TYPE) { 1555 soc_mem_field_get(unit, mem, cdata, 1556 IPV6__SIP_V6f, cip6_field); 1557 soc_mem_field_get(unit, mem, cdata, 1558 IPV6__SIP_V6_MASKf, cip6_field_mask); 1559 SAL_IP6_ADDR_FROM_UINT32(cip6_addr, cip6_field); 1560 SAL_IP6_ADDR_FROM_UINT32(cip6_addr_mask, cip6_field_mask); 1561 LOG_CLI((BSL_META_U(unit,"Source Ipv6= "))); 1562 LOG_CLI((BSL_META("0x"))); 1563 for (i = 0; i < sizeof(bcm_ip6_t) - 1; i++) { 1564 LOG_CLI((BSL_META("%02x:"), cip6_addr[i])); 1565 } 1566 LOG_CLI((BSL_META("%02x"), cip6_addr[i])); 1567 LOG_CLI((BSL_META(", "))); 1568 LOG_CLI((BSL_META_U(unit,"Ipv6 Mask="))); 1569 LOG_CLI((BSL_META("0x"))); 1570 for (i = 0; i < sizeof(bcm_ip6_t); i++) { 1571 LOG_CLI((BSL_META("%02x:"), cip6_addr_mask[i])); 1572 } 1573 LOG_CLI((BSL_META(", "))); 1574 } else { 1575 LOG_CLI((BSL_META_U(unit,"Unknown, "))); 1576 } 1577 soc_mem_field_get(unit, mem, cdata, VRFf, &cval); 1578 soc_mem_field_get(unit, mem, cdata, VRF_MASKf, &cmask); 1579 1580 LOG_CLI((BSL_META_U(unit,"VRF=0x%x, "),cval)); 1581 LOG_CLI((BSL_META_U(unit,"VRF Mask=0x%x, "),cmask)); 1582 LOG_CLI((BSL_META_U(unit,"Valid=%d"),validbit)); 1583 break; 1584 case _FieldClassDstCompression: 1585 mem = DST_COMPRESSIONm; 1586 soc_mem_field_get(unit, mem, cdata, KEY_TYPEf, &keytype); 1587 soc_mem_field_get(unit, mem, cdata, VALIDf, &validbit); 1588 if (keytype == _FP_KEY_IPv4_TYPE) { 1589 soc_mem_field_get(unit, mem, cdata, 1590 IPV4__DIP_V4f, &cval); 1591 soc_mem_field_get(unit, mem, cdata, 1592 IPV4__DIP_V4_MASKf, &cmask); 1593 LOG_CLI((BSL_META_U(unit,"Destination IPv4=0x%x, "),cval)); 1594 LOG_CLI((BSL_META_U(unit,"IPv4 Mask=0x%x, "),cmask)); 1595 } else if (keytype == _FP_KEY_FCoE_TYPE) { 1596 soc_mem_field_get(unit, mem, cdata, 1597 FCOE__D_IDf, &cval); 1598 soc_mem_field_get(unit, mem, cdata, 1599 FCOE__D_ID_MASKf, &cmask); 1600 LOG_CLI((BSL_META_U(unit,"FCoE D_ID=0x%x, "),cval)); 1601 LOG_CLI((BSL_META_U(unit,"D_ID Mask=0x%x, "),cmask)); 1602 } else if (keytype == _FP_KEY_IPv6_TYPE) { 1603 soc_mem_field_get(unit, mem, cdata, 1604 IPV6__DIP_V6f, cip6_field); 1605 soc_mem_field_get(unit, mem, cdata, 1606 IPV6__DIP_V6_MASKf, cip6_field_mask); 1607 SAL_IP6_ADDR_FROM_UINT32(cip6_addr, cip6_field); 1608 SAL_IP6_ADDR_FROM_UINT32(cip6_addr_mask, cip6_field_mask); 1609 LOG_CLI((BSL_META_U(unit,"Destination Ipv6= "))); 1610 LOG_CLI((BSL_META("0x"))); 1611 for (i = 0; i < sizeof(bcm_ip6_t) - 1; i++) { 1612 LOG_CLI((BSL_META("%02x:"), cip6_addr[i])); 1613 } 1614 LOG_CLI((BSL_META("%02x"), cip6_addr[i])); 1615 LOG_CLI((BSL_META(", "))); 1616 LOG_CLI((BSL_META_U(unit,"Ipv6 Mask="))); 1617 LOG_CLI((BSL_META("0x"))); 1618 for (i = 0; i < sizeof(bcm_ip6_t); i++) { 1619 LOG_CLI((BSL_META("%02x:"), cip6_addr_mask[i])); 1620 } 1621 LOG_CLI((BSL_META(", "))); 1622 } else { 1623 LOG_CLI((BSL_META_U(unit,"Unknown, "))); 1624 } 1625 soc_mem_field_get(unit, mem, cdata, VRFf, &cval); 1626 soc_mem_field_get(unit, mem, cdata, VRF_MASKf, &cmask); 1627 1628 LOG_CLI((BSL_META_U(unit,"VRF=0x%x, "),cval)); 1629 LOG_CLI((BSL_META_U(unit,"VRF Mask=0x%x, "),cmask)); 1630 LOG_CLI((BSL_META_U(unit,"Valid=%d"),validbit)); 1631 break; 1632 #if defined(BCM_TOMAHAWK_SUPPORT) 1633 case _FieldClassIpTunnelTtl: 1634 LOG_CLI((BSL_META_U(unit, 1635 "TTL=%d"), 1636 class_ent->tcam.ip_type)); 1637 break; 1638 #endif 1639 default: 1640 LOG_CLI((BSL_META_U(unit,"Unknown"))); 1641 } 1642 LOG_CLI((BSL_META_U(unit,"}\n"))); 1643 } 1644 1645 1646 /* 1647 * Function: 1648 * _bcm_field_th_class_entry_create 1649 * Purpose: 1650 * Create Field Class Entry. 1651 * Parameters: 1652 * unit - (IN) BCM device number. 1653 * group - (IN) Field Group Id. 1654 * entry - (IN) Field Entry. 1655 * Returns: 1656 * BCM_E_XXX 1657 */ 1658 int 1659 _bcm_field_th_class_entry_create(int unit, bcm_field_group_t group, 1660 bcm_field_entry_t entry) 1661 { 1662 int rv = BCM_E_NONE; /* Operation Return Status */ 1663 _field_stage_t *stage_fc = NULL; 1664 /* Stage field control info */ 1665 _field_group_t *fg = NULL; 1666 /* Field group info */ 1667 _field_entry_t *f_ent = NULL; 1668 /* Field entry info */ 1669 int mem_sz = 0; /* Memory allocation size */ 1670 _field_class_info_t **class_status_arr; 1671 /* Field Per Pipe Class Status Array */ 1672 _field_class_info_t *class_status_info; 1673 /* Field Per Compression table status */ 1674 _field_class_type_t ctype; 1675 /* Field Class Type */ 1676 int tcam_sz = 0; /* TCAM data size */ 1677 1678 /* Confirm that 'entry' is not already used on unit */ 1679 if (BCM_SUCCESS(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) { 1680 LOG_ERROR(BSL_LS_BCM_FP, 1681 (BSL_META_U(unit, 1682 "FP(unit %d) Error: entry=(%d) already exists.\n"), 1683 unit, entry)); 1684 return (BCM_E_EXISTS); 1685 } 1686 1687 /* Get group control structure. */ 1688 rv = _field_group_get(unit, group, &fg); 1689 if (BCM_FAILURE(rv)) { 1690 LOG_ERROR(BSL_LS_BCM_FP, 1691 (BSL_META_U(unit, 1692 "FP(unit %d) Error: group=(%d) group get failure.\n"), 1693 unit, group)); 1694 return (rv); 1695 } 1696 1697 /* Get group stage control structure. */ 1698 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 1699 if (BCM_FAILURE(rv)) { 1700 LOG_ERROR(BSL_LS_BCM_FP, 1701 (BSL_META_U(unit, 1702 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 1703 unit, fg->stage_id)); 1704 return (rv); 1705 } 1706 1707 /* Allocate and zero memory for field entry. */ 1708 mem_sz = sizeof(_field_entry_t); 1709 1710 _FP_XGS3_ALLOC(f_ent, mem_sz, "field entry"); 1711 1712 if (f_ent == NULL) { 1713 LOG_ERROR(BSL_LS_BCM_FP, 1714 (BSL_META_U(unit, 1715 "FP(unit %d) Error: allocation failure for " 1716 "class field_entry.\n"), 1717 unit)); 1718 return (BCM_E_MEMORY); 1719 } 1720 1721 f_ent->eid = entry; 1722 f_ent->group = fg; 1723 1724 /* Retreive Class Type from entry qset */ 1725 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 1726 if (BCM_FAILURE(rv)) { 1727 sal_free(f_ent); 1728 return rv; 1729 } 1730 1731 /* Update Class Info Status Structure */ 1732 class_status_arr = stage_fc->class_info_arr[fg->instance]; 1733 if (class_status_arr == NULL) { 1734 sal_free(f_ent); 1735 return (BCM_E_INTERNAL); 1736 } 1737 class_status_info = class_status_arr[ctype]; 1738 if (class_status_info == NULL) { 1739 sal_free(f_ent); 1740 return (BCM_E_INTERNAL); 1741 } 1742 1743 /* Check if resources are present */ 1744 if ((class_status_info->total_entries_used + 1) > 1745 (class_status_info->total_entries_available)) { 1746 sal_free(f_ent); 1747 LOG_DEBUG(BSL_LS_BCM_FP, 1748 (BSL_META_U(unit, 1749 "FP(unit %d) Error: no resource available in " 1750 "hardware.\n"), 1751 unit)); 1752 return (BCM_E_RESOURCE); 1753 } 1754 1755 /* Allocate memory for tcam key and mask */ 1756 rv = _bcm_field_th_class_size_get(unit, ctype, &tcam_sz); 1757 if (BCM_FAILURE(rv)) { 1758 sal_free(f_ent); 1759 return (rv); 1760 } 1761 1762 /* Check Tcam Key and Size */ 1763 if ((f_ent->tcam.key != NULL) || 1764 (tcam_sz == 0)) { 1765 sal_free(f_ent); 1766 return (BCM_E_INTERNAL); 1767 } 1768 1769 /* Allocate memory for field class entry */ 1770 if (tcam_sz != 0) { 1771 _FP_XGS3_ALLOC(f_ent->tcam.key, tcam_sz, "field class entry key"); 1772 if (f_ent->tcam.key == NULL) { 1773 LOG_ERROR(BSL_LS_BCM_FP, 1774 (BSL_META_U(unit, 1775 "FP(unit %d) Error: allocation failure for " 1776 "class entry key\n"), 1777 unit)); 1778 sal_free(f_ent); 1779 return (BCM_E_MEMORY); 1780 } 1781 } 1782 1783 /* Add field entry in group structure */ 1784 rv = _field_group_entry_add(unit, fg, f_ent); 1785 if (BCM_FAILURE(rv)) { 1786 sal_free(f_ent); 1787 return (rv); 1788 } 1789 1790 /* Initialize slice idx */ 1791 f_ent->slice_idx = -1; 1792 1793 /* Set TCAM Key Size */ 1794 f_ent->tcam.key_size = tcam_sz; 1795 1796 /* Increment Field Entry Count */ 1797 fg->group_status.entries_free = 1798 fg->group_status.entries_total - 1799 fg->group_status.entry_count; 1800 class_status_info->total_entries_used++; 1801 1802 return (rv); 1803 } 1804 1805 /* 1806 * Function: 1807 * _bcm_field_th_class_entry_destroy 1808 * Purpose: 1809 * Delete Field Class Entry. 1810 * Parameters: 1811 * unit - (IN) BCM device number. 1812 * entryr - (IN) Field Class Entry. 1813 * Returns: 1814 * BCM_E_XXX 1815 * Notes: 1816 * This api should not delete entry if install flag 1817 * is set. This check happens in calling function. 1818 */ 1819 int 1820 _bcm_field_th_class_entry_destroy(int unit, _field_entry_t *entry) 1821 { 1822 int rv = BCM_E_NONE; /* Operation Return Status */ 1823 _field_stage_t *stage_fc; 1824 /* Stage field control info */ 1825 _field_group_t *fg; 1826 /* Field group info */ 1827 _field_entry_t *f_ent; 1828 /* Field Entry info */ 1829 _field_class_info_t **class_status_arr; 1830 /* Field Per Pipe Class Status Array */ 1831 _field_class_info_t *class_status_info; 1832 /* Field Per Compression table status */ 1833 _field_class_type_t ctype; 1834 /* Field Class Type */ 1835 1836 /* Input paramter check */ 1837 if ((entry == NULL) || 1838 (entry->group == NULL)) { 1839 return (BCM_E_INTERNAL); 1840 } 1841 1842 /* Assign Entry and Group Info */ 1843 f_ent = entry; 1844 fg = f_ent->group; 1845 1846 /* Get group stage control structure. */ 1847 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 1848 if (BCM_FAILURE(rv)) { 1849 LOG_ERROR(BSL_LS_BCM_FP, 1850 (BSL_META_U(unit, 1851 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 1852 unit, fg->stage_id)); 1853 return (rv); 1854 } 1855 1856 /* Retreive Class Type from entry qset */ 1857 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 1858 if (BCM_FAILURE(rv)) { 1859 return rv; 1860 } 1861 1862 /* Remove entry from hw before destroying sw image. */ 1863 if (f_ent->flags & _FP_ENTRY_INSTALLED) { 1864 BCM_IF_ERROR_RETURN( 1865 _bcm_field_th_class_entry_remove(unit, entry->eid)); 1866 } 1867 1868 /* Update Class status info structure */ 1869 class_status_arr = stage_fc->class_info_arr[fg->instance]; 1870 if (class_status_arr == NULL) { 1871 return (BCM_E_INTERNAL); 1872 } 1873 class_status_info = class_status_arr[ctype]; 1874 if (class_status_info == NULL) { 1875 return (BCM_E_INTERNAL); 1876 } 1877 1878 /* Free Entry Data */ 1879 if (f_ent->tcam.key != NULL) { 1880 sal_free(f_ent->tcam.key); 1881 } 1882 1883 /* Delete Entry From Linked List */ 1884 rv = _field_group_entry_delete(unit, fg, f_ent); 1885 if (BCM_FAILURE(rv)) { 1886 sal_free(f_ent); 1887 return (rv); 1888 } 1889 1890 /* Free Field Entry Resource */ 1891 sal_free(f_ent); 1892 1893 /* Decrement Field Entry Used Count */ 1894 fg->group_status.entries_free = fg->group_status.entries_total - 1895 fg->group_status.entry_count; 1896 class_status_info->total_entries_used--; 1897 1898 return (rv); 1899 } 1900 1901 /* 1902 * Function: 1903 * _bcm_field_th_class_entry_prio_set 1904 * Purpose: 1905 * Set Priority for Field Class Entry. 1906 * Parameters: 1907 * unit - (IN) BCM device number. 1908 * entry - (IN) Field Entry. 1909 * prio - (IN) New Field Entry Priority. 1910 * Returns: 1911 * BCM_E_XXX 1912 */ 1913 int 1914 _bcm_field_th_class_entry_prio_set(int unit, _field_entry_t *entry, int prio) 1915 { 1916 int rv = BCM_E_NONE; /* Operation Return Status */ 1917 _field_group_t *fg; /* Field Group Info */ 1918 _field_class_type_t ctype; /* Field Class Type */ 1919 int old_prio = 0; /* Field Entry Priority */ 1920 1921 /* Input paramter check */ 1922 if ((entry == NULL) || 1923 (entry->group == NULL)) { 1924 return (BCM_E_INTERNAL); 1925 } 1926 1927 /* Assign Group Info */ 1928 fg = entry->group; 1929 1930 /* Retreive Class Type from entry qset */ 1931 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 1932 if (BCM_FAILURE(rv)) { 1933 return rv; 1934 } 1935 1936 /* Modify entry priority. */ 1937 old_prio = entry->prio; 1938 entry->prio = prio; 1939 1940 /* Set and Sort entry priority. */ 1941 switch (ctype) { 1942 case _FieldClassEtherType: 1943 case _FieldClassTtl: 1944 case _FieldClassToS: 1945 case _FieldClassIpProto: 1946 case _FieldClassL4SrcPort: 1947 case _FieldClassL4DstPort: 1948 case _FieldClassTcp: 1949 rv = BCM_E_UNAVAIL; 1950 break; 1951 case _FieldClassIpTunnelTtl: 1952 if ((soc_feature(unit, soc_feature_th3_style_fp))) { 1953 rv = BCM_E_NONE; 1954 } else { 1955 rv = BCM_E_UNAVAIL; 1956 } 1957 break; 1958 case _FieldClassSrcCompression: 1959 case _FieldClassDstCompression: 1960 if (entry->slice_idx != -1) { 1961 rv = _field_th_class_group_sort(unit, fg, ctype); 1962 if (BCM_SUCCESS(rv)) { 1963 /* coverity[end_of_scope] */ 1964 return (rv); 1965 } 1966 } 1967 break; 1968 default: 1969 rv = BCM_E_PARAM; 1970 } 1971 1972 /* Restore old value. */ 1973 if (BCM_FAILURE(rv)) { 1974 entry->prio = old_prio; 1975 } 1976 1977 return (rv); 1978 } 1979 1980 /* 1981 * Function: 1982 * _field_th_class_ent_cmp 1983 * Purpose: 1984 * Compare class entries based on priority. 1985 * Parameters: 1986 * b - (IN) first compared field entry. 1987 * a - (IN) second compared field entry. 1988 * Returns: 1989 * a<=>b 1990 */ 1991 static INLINE int 1992 _field_th_class_ent_cmp(void *a, void *b) 1993 { 1994 _field_class_cmp_info_t *first; 1995 /* First Class Entry Configuration. */ 1996 _field_class_cmp_info_t *second; 1997 /* Second Class Entry Configuration. */ 1998 1999 first = (_field_class_cmp_info_t *)a; 2000 second = (_field_class_cmp_info_t *)b; 2001 2002 if (first->entry_prio < second->entry_prio) { 2003 return (1); 2004 } else if (first->entry_prio > second->entry_prio) { 2005 return (-1); 2006 } 2007 2008 return (0); 2009 } 2010 2011 /* 2012 * Function: 2013 * _field_th_class_valid_set 2014 * Purpose: 2015 * Set valid bit of given entry. 2016 * Parameters: 2017 * unit - (IN) Unit Number. 2018 * entry - (IN) Field Entry Info. 2019 * ctype - (IN) Field Class Type. 2020 * valid_bit - (IN) Valid Bit. 2021 * Returns: 2022 */ 2023 STATIC int 2024 _field_th_class_valid_set(int unit, 2025 _field_entry_t *entry, 2026 _field_class_type_t ctype, 2027 uint32 valid_bit) 2028 { 2029 int rv = BCM_E_NONE; /* Operation Return Status. */ 2030 _field_stage_t *stage_fc = NULL; 2031 /* Stage field control info. */ 2032 _field_group_t *fg = NULL; /* Field Group Info. */ 2033 soc_mem_t mem; /* SOC Memory. */ 2034 uint32 cdata[SOC_MAX_MEM_FIELD_WORDS] = {0}; 2035 /* Entry buffer. */ 2036 2037 /* Input paramter check */ 2038 if ((entry == NULL) || 2039 (entry->group == NULL)) { 2040 return (BCM_E_INTERNAL); 2041 } 2042 2043 /* Check Input Valid Bit. */ 2044 if (valid_bit > 1) { 2045 return (BCM_E_PARAM); 2046 } 2047 2048 #ifdef BCM_TOMAHAWK_SUPPORT 2049 /* VALIDf in SRC_COMPRESSIONm and DST_COMPRESSIONm 2050 * is two bit wide on TH2 and TD3.*/ 2051 if (valid_bit == 1 2052 && (SOC_IS_TOMAHAWK2(unit) 2053 || soc_feature(unit, soc_feature_td3_style_fp))) { 2054 valid_bit = 3; 2055 } 2056 #endif /*BCM_TOMAHAWK2_SUPPORT*/ 2057 2058 /* Assign Entry and Group Info */ 2059 fg = entry->group; 2060 2061 /* Get group stage control structure. */ 2062 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 2063 if (BCM_FAILURE(rv)) { 2064 LOG_ERROR(BSL_LS_BCM_FP, 2065 (BSL_META_U(unit, 2066 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 2067 unit, fg->stage_id)); 2068 return (rv); 2069 } 2070 2071 /* Get Memory based on compression and stage mode. */ 2072 switch(ctype) { 2073 case _FieldClassSrcCompression: 2074 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 2075 mem = SRC_COMPRESSIONm; 2076 } else { 2077 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 2078 SRC_COMPRESSIONm, 2079 fg->instance, 2080 &mem)); 2081 } 2082 break; 2083 case _FieldClassDstCompression: 2084 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 2085 mem = DST_COMPRESSIONm; 2086 } else { 2087 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 2088 DST_COMPRESSIONm, 2089 fg->instance, 2090 &mem)); 2091 } 2092 break; 2093 default: 2094 rv = BCM_E_PARAM; 2095 } 2096 2097 /* Check Compression Type. */ 2098 if (BCM_FAILURE(rv)) { 2099 return (rv); 2100 } 2101 2102 /* Read Memory */ 2103 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 2104 entry->slice_idx, cdata); 2105 if (BCM_FAILURE(rv)) { 2106 return (rv); 2107 } 2108 2109 /* Set valid bit. */ 2110 soc_mem_field_set(unit, mem, cdata, 2111 VALIDf, &valid_bit); 2112 2113 /* Write Memory. */ 2114 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, 2115 entry->slice_idx, cdata); 2116 2117 return (rv); 2118 } 2119 2120 /* 2121 * Function: 2122 * _field_th_class_entry_copy 2123 * Purpose: 2124 * Copy Entry from old index to new index. 2125 * Parameters: 2126 * unit - (IN) Unit Number. 2127 * mem - (IN) SoC Memory Identifier. 2128 * old_entry_idx - (IN) Old Entry Index. 2129 * new_entry_idx - (IN) New Entry Index. 2130 * Returns: 2131 */ 2132 STATIC int 2133 _field_th_class_entry_copy(int unit, 2134 soc_mem_t mem, 2135 uint32 old_entry_idx, 2136 uint32 new_entry_idx) 2137 { 2138 uint32 cdata[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* Entry buffer. */ 2139 int rv = BCM_E_NONE; 2140 2141 /* Read Memory */ 2142 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 2143 old_entry_idx, cdata); 2144 if (BCM_FAILURE(rv)) { 2145 return (rv); 2146 } 2147 /* Write Memory. */ 2148 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, 2149 new_entry_idx, cdata); 2150 return (rv); 2151 } 2152 2153 /* 2154 * Function: 2155 * _field_th_class_entry_del 2156 * Purpose: 2157 * Delete entry from provided index. 2158 * Parameters: 2159 * unit - (IN) Unit Number. 2160 * mem - (IN) SoC Memory Identifier. 2161 * entry_idx - (IN) Entry Index. 2162 * Returns: 2163 */ 2164 STATIC int 2165 _field_th_class_entry_del(int unit, 2166 soc_mem_t mem, 2167 uint32 entry_idx) 2168 { 2169 uint32 cdata[SOC_MAX_MEM_FIELD_WORDS] = {0}; /* Entry buffer. */ 2170 int rv = BCM_E_NONE; 2171 2172 /* Write Memory. */ 2173 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, 2174 entry_idx, cdata); 2175 return rv; 2176 } 2177 2178 /* 2179 * Function: 2180 * _field_th_class_entry_update 2181 * Purpose: 2182 * Update Class entry old entry idx. 2183 * Parameters: 2184 * unit - (IN) Unit Number. 2185 * class_cmp_info - (IN/OUT) - Class Entry Struct. 2186 * valid_entries - (IN) - Valid entries in array. 2187 * old_idx - (IN) - Old Entry Index. 2188 * new_idx - (IN) - New Entry Index. 2189 * Returns: 2190 */ 2191 STATIC void 2192 _field_th_class_entry_update(int unit, 2193 _field_class_cmp_info_t *class_cmp_info, 2194 int valid_entries, 2195 uint32 old_idx, uint32 new_idx) 2196 { 2197 int idx = 0; /* Index Iterator. */ 2198 _field_class_cmp_info_t *class_cmp_temp = NULL; 2199 /* Class Entry temp. */ 2200 int flag = 0; /* Flag var. */ 2201 2202 /* Find entry in array. */ 2203 for(idx = 0; idx < valid_entries; idx++) { 2204 class_cmp_temp = class_cmp_info + idx; 2205 if (class_cmp_temp->cur_entry_idx == old_idx) { 2206 flag = 1; 2207 break; 2208 } 2209 } 2210 2211 /* Update idx if entry is found. */ 2212 if(flag) { 2213 class_cmp_temp->cur_entry_idx = new_idx; 2214 } 2215 } 2216 2217 /* 2218 * Function: 2219 * _field_th_class_entry_shift 2220 * Purpose: 2221 * Shift Class entry old slice idx. 2222 * Parameters: 2223 * unit - (IN) Unit Number. 2224 * mem - (IN) SoC Memory Identifier. 2225 * class_cmp_info - (IN/OUT) - Class Entry Struct. 2226 * valid_entries - (IN) - Valid entries in array. 2227 * old_idx - (IN) - Old Entry Index. 2228 * new_idx - (IN) - New Entry Index. 2229 * Returns: 2230 * Notes: 2231 * This function shifts entry in hardware from new_idx 2232 * to free_idx and shift all entries down by 1. 2233 */ 2234 STATIC int 2235 _field_th_class_entry_shift(int unit, 2236 soc_mem_t mem, 2237 _field_class_cmp_info_t *class_cmp_info, 2238 _field_class_info_t *class_status_info, 2239 int valid_entries, 2240 uint32 new_idx, uint32 free_idx) 2241 { 2242 uint32 idx = 0; /* Index Iterator. */ 2243 uint32 ent_num = 0; /* No. of entries to shift. */ 2244 uint32 cur_shift_idx = 0; /* Current entry Shift Index. */ 2245 uint32 cur_free_idx = 0; /* Current free Index. */ 2246 int rv = BCM_E_NONE; /* Return Status */ 2247 2248 /* Initialise Variables. */ 2249 ent_num = free_idx - new_idx; 2250 cur_free_idx = free_idx; 2251 2252 /* Shift Entries. */ 2253 if ((class_cmp_info != NULL) && 2254 (class_status_info != NULL) && 2255 (ent_num > 0)) { 2256 2257 for(idx = 0; idx < ent_num; idx++) { 2258 2259 cur_shift_idx = free_idx - idx - 1; 2260 2261 if (_FP_CLASS_TABLE_BMP_TEST(class_status_info->class_bmp, 2262 cur_shift_idx)) { 2263 2264 /* Copy entry from new index to free index. */ 2265 rv = _field_th_class_entry_copy(unit, mem, 2266 cur_shift_idx, cur_free_idx); 2267 BCM_IF_ERROR_RETURN(rv); 2268 2269 _field_th_class_entry_update(unit, 2270 class_cmp_info, 2271 valid_entries, 2272 cur_shift_idx, cur_free_idx); 2273 _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, 2274 cur_free_idx); 2275 _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp, 2276 cur_shift_idx); 2277 } 2278 cur_free_idx--; 2279 } 2280 } 2281 return rv; 2282 } 2283 2284 /* 2285 * Function: 2286 * _field_th_class_group_sort 2287 * Purpose: 2288 * Sort Provided Class Field Group Entries based on priority. 2289 * Parameters: 2290 * unit - (IN) Unit. 2291 * fg - (IN/OUT) Field Group Structure. 2292 * ctype - (IN) Compression Type. 2293 * Returns: 2294 * BCM_E_XXX 2295 * Notes: 2296 * This api will sort Src/Dst Compression entries 2297 * based on priority. It can sort entries only 2298 * if there is one free index available in hardware 2299 * otherwide it will return error. Also it will do hitless 2300 * sort which means order of entry prio does not 2301 * change during sorting. 2302 */ 2303 STATIC int 2304 _field_th_class_group_sort(int unit, 2305 _field_group_t *fg, 2306 _field_class_type_t ctype) 2307 { 2308 int rv = BCM_E_NONE; /* Operation Return Status. */ 2309 _field_stage_t *stage_fc = NULL; 2310 /* Stage field control info. */ 2311 _field_class_info_t **class_status_arr; 2312 /* Field Per Pipe Class Status Array. */ 2313 _field_class_info_t *class_status_info; 2314 /* Field Per Compression table status.*/ 2315 _field_entry_t *f_ent = NULL; 2316 /* Field Entry Structure. */ 2317 _field_class_cmp_info_t *class_cmp_info = NULL; 2318 /* Class Entry Compare Info Struct. */ 2319 _field_class_cmp_info_t *class_cmp_temp = NULL; 2320 /* Class Entry Compare Info Temp. */ 2321 int idx, valid_entries = 0; /* Index and Valid Entries var. */ 2322 int entry_count = 0; /* Entry Count in Software. */ 2323 int e_idx = 0; /* Entry Iteration Index. */ 2324 bcm_field_entry_t *entry_ids = NULL; 2325 /* Entry Id. Array. */ 2326 /* SOC Per Pipe Memory. */ 2327 soc_mem_t mem; /* SOC Memory. */ 2328 int free_idx = 0; /* Free Index in Bitmap.. */ 2329 2330 /* Input paramter check */ 2331 if (fg == NULL) { 2332 return (BCM_E_INTERNAL); 2333 } 2334 2335 /* Get group stage control structure. */ 2336 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 2337 if (BCM_FAILURE(rv)) { 2338 LOG_ERROR(BSL_LS_BCM_FP, 2339 (BSL_META_U(unit, 2340 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 2341 unit, fg->stage_id)); 2342 return (rv); 2343 } 2344 2345 /* Update Class Info Status Structure */ 2346 class_status_arr = stage_fc->class_info_arr[fg->instance]; 2347 if (class_status_arr == NULL) { 2348 return (BCM_E_INTERNAL); 2349 } 2350 class_status_info = class_status_arr[ctype]; 2351 if (class_status_info == NULL) { 2352 return (BCM_E_INTERNAL); 2353 } 2354 2355 /* Check if free entry available in hardware. */ 2356 if(class_status_info->total_entries_used == 2357 class_status_info->total_entries_available) { 2358 return (BCM_E_PARAM); 2359 } 2360 2361 /* Get Memory based on compression and stage mode. */ 2362 switch(ctype) { 2363 case _FieldClassSrcCompression: 2364 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 2365 mem = SRC_COMPRESSIONm; 2366 } else { 2367 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 2368 SRC_COMPRESSIONm, 2369 fg->instance, 2370 &mem)); 2371 } 2372 break; 2373 case _FieldClassDstCompression: 2374 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 2375 mem = DST_COMPRESSIONm; 2376 } else { 2377 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 2378 DST_COMPRESSIONm, 2379 fg->instance, 2380 &mem)); 2381 } 2382 break; 2383 default: 2384 rv = BCM_E_PARAM; 2385 } 2386 2387 /* Check Compression Type. */ 2388 if (BCM_FAILURE(rv)) { 2389 return (rv); 2390 } 2391 2392 /* Count number of valid entries present in hardware. */ 2393 for (idx = 0; idx < class_status_info->total_entries_available; idx++) { 2394 if (_FP_CLASS_TABLE_BMP_TEST(class_status_info->class_bmp, idx)) { 2395 valid_entries++; 2396 } 2397 } 2398 2399 /* No valid entry found in Hardware. */ 2400 if (!valid_entries) { 2401 return (BCM_E_NONE); 2402 } 2403 2404 /* Allocate Memory. */ 2405 _FP_XGS3_ALLOC(class_cmp_info, 2406 (valid_entries * sizeof(_field_class_cmp_info_t)), 2407 "Field Class Status"); 2408 if (class_cmp_info == NULL) { 2409 return (BCM_E_MEMORY); 2410 } 2411 2412 /* Get group's entries */ 2413 entry_count = fg->group_status.entry_count; 2414 _FP_XGS3_ALLOC(entry_ids, 2415 (entry_count * sizeof(bcm_field_entry_t)), 2416 "Entry ID array"); 2417 if (entry_ids == NULL) { 2418 sal_free(class_cmp_info); 2419 return (BCM_E_MEMORY); 2420 } 2421 2422 rv = bcm_esw_field_entry_multi_get(unit, fg->gid, entry_count, 2423 entry_ids, &entry_count); 2424 2425 if (BCM_FAILURE(rv)) { 2426 goto cleanup; 2427 } 2428 2429 /* Copy entry info into class cmp struct. */ 2430 class_cmp_temp = class_cmp_info; 2431 for (e_idx = 0; e_idx < entry_count; ++e_idx) 2432 { 2433 rv = _bcm_field_entry_get_by_id(unit, entry_ids[e_idx], &f_ent); 2434 if (BCM_FAILURE(rv)) { 2435 goto cleanup; 2436 } 2437 /* Copy only if entry is installed. */ 2438 if (f_ent->slice_idx != -1) { 2439 class_cmp_temp->f_ent = f_ent; 2440 class_cmp_temp->cur_entry_idx = f_ent->slice_idx; 2441 class_cmp_temp->entry_prio = f_ent->prio; 2442 class_cmp_temp++; 2443 } 2444 } 2445 2446 /* Sort entries based on priority. */ 2447 _shr_sort(class_cmp_info, valid_entries, sizeof(_field_class_cmp_info_t), 2448 _field_th_class_ent_cmp); 2449 2450 /* Move entries in Hardware. */ 2451 for (e_idx = 0; e_idx< valid_entries; e_idx++) { 2452 2453 /* Update new slice idx. */ 2454 class_cmp_temp = class_cmp_info + e_idx; 2455 class_cmp_temp->new_entry_idx = e_idx; 2456 class_cmp_temp->f_ent->slice_idx = class_cmp_temp->new_entry_idx; 2457 2458 /* Check if new index is free. If yes then move entry from 2459 * old index to new and mark old as free. */ 2460 2461 if (!(_FP_CLASS_TABLE_BMP_TEST(class_status_info->class_bmp, e_idx))) { 2462 2463 /* Copy entry from old index to new index. */ 2464 rv = _field_th_class_entry_copy(unit, mem, 2465 class_cmp_temp->cur_entry_idx, e_idx); 2466 if (BCM_FAILURE(rv)) { 2467 goto cleanup; 2468 } 2469 2470 _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, e_idx); 2471 2472 /* Delete entry from old index. */ 2473 rv = _field_th_class_entry_del(unit, mem, 2474 class_cmp_temp->cur_entry_idx); 2475 if (BCM_FAILURE(rv)) { 2476 goto cleanup; 2477 } 2478 2479 _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp, 2480 class_cmp_temp->cur_entry_idx); 2481 class_cmp_temp->cur_entry_idx = e_idx; 2482 } else { 2483 2484 /* New index is not free, do something only if 2485 * new index is different from old index. */ 2486 if (class_cmp_temp->cur_entry_idx != e_idx) { 2487 2488 /* Find free index, it has to be greater than new index. */ 2489 for (idx = 0; idx < class_status_info->total_entries_available; 2490 idx++) { 2491 if (0 == _FP_CLASS_TABLE_BMP_TEST( 2492 class_status_info->class_bmp, idx)) { 2493 free_idx = idx; 2494 break; 2495 } 2496 } 2497 if (free_idx > e_idx) { 2498 2499 /* Shift entries down starting from e_idx to free_idx and 2500 * mark e_idx as free. */ 2501 rv = _field_th_class_entry_shift(unit, mem, 2502 class_cmp_info, 2503 class_status_info, 2504 valid_entries, 2505 e_idx, free_idx); 2506 if (BCM_FAILURE(rv)) { 2507 goto cleanup; 2508 } 2509 /* Now copy entry to new idx. */ 2510 rv = _field_th_class_entry_copy(unit, mem, 2511 class_cmp_temp->cur_entry_idx, 2512 e_idx); 2513 if (BCM_FAILURE(rv)) { 2514 goto cleanup; 2515 } 2516 2517 _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, e_idx); 2518 2519 /* Delete entry from old index. */ 2520 rv = _field_th_class_entry_del(unit, mem, 2521 class_cmp_temp->cur_entry_idx); 2522 if (BCM_FAILURE(rv)) { 2523 goto cleanup; 2524 } 2525 2526 _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp, 2527 class_cmp_temp->cur_entry_idx); 2528 class_cmp_temp->cur_entry_idx = e_idx; 2529 } 2530 } 2531 } 2532 } 2533 2534 cleanup: 2535 2536 /* Free Resources. */ 2537 sal_free(entry_ids); 2538 sal_free(class_cmp_info); 2539 2540 return (rv); 2541 } 2542 2543 /* 2544 * Function: 2545 * _bcm_field_th_class_entry_prio_get 2546 * Purpose: 2547 * Get Priority for Field Class Entry. 2548 * Parameters: 2549 * unit - (IN) BCM device number. 2550 * entry - (IN) Field Entry. 2551 * Returns: 2552 * BCM_E_XXX 2553 */ 2554 int 2555 _bcm_field_th_class_entry_prio_get(int unit, _field_entry_t *entry) 2556 { 2557 int rv = BCM_E_NONE; /* Operation Return Status */ 2558 _field_group_t *fg; /* Field Group Info */ 2559 _field_class_type_t ctype; /* Field Class Type */ 2560 2561 /* Input paramter check */ 2562 if ((entry == NULL) || 2563 (entry->group == NULL)) { 2564 return (BCM_E_INTERNAL); 2565 } 2566 2567 /* Assign Entry and Group Info */ 2568 fg = entry->group; 2569 2570 /* Retreive Class Type from entry qset */ 2571 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 2572 if (BCM_FAILURE(rv)) { 2573 return rv; 2574 } 2575 2576 /* Set and Sort entry priority. */ 2577 switch (ctype) { 2578 case _FieldClassEtherType: 2579 case _FieldClassTtl: 2580 case _FieldClassToS: 2581 case _FieldClassIpProto: 2582 case _FieldClassL4SrcPort: 2583 case _FieldClassL4DstPort: 2584 case _FieldClassTcp: 2585 rv = BCM_E_UNAVAIL; 2586 break; 2587 case _FieldClassIpTunnelTtl: 2588 if ((soc_feature(unit, soc_feature_th3_style_fp))) { 2589 rv = BCM_E_NONE; 2590 } else { 2591 rv = BCM_E_UNAVAIL; 2592 } 2593 break; 2594 case _FieldClassSrcCompression: 2595 case _FieldClassDstCompression: 2596 rv = BCM_E_NONE; 2597 break; 2598 default: 2599 rv = BCM_E_PARAM; 2600 } 2601 2602 return (rv); 2603 } 2604 2605 /* 2606 * Function: 2607 * _bcm_field_th_class_qualify_set 2608 * Purpose: 2609 * Qualify Field Class Entry. 2610 * Parameters: 2611 * unit - (IN) BCM device number. 2612 * entry - (IN) Field Class Entry Id. 2613 * qual - (IN) Field Qualifier. 2614 * data - (IN) Qualify Data Value. 2615 * mask - (IN) Qualify Data Mask. 2616 * Returns: 2617 * BCM_E_XXX 2618 */ 2619 int 2620 _bcm_field_th_class_qualify_set(int unit, bcm_field_entry_t entry, 2621 int qual, uint32 *data, uint32 *mask) 2622 { 2623 int rv = BCM_E_NONE; /* Operation Return Status */ 2624 uint32 *cdata = NULL; /* Field Class Data */ 2625 bcm_field_qset_t cqset; /* Class Qset */ 2626 _field_class_type_t ctype; /* Field Class Type */ 2627 soc_reg_t reg; /* SOC Register */ 2628 soc_mem_t mem; /* SOC Memory */ 2629 _field_entry_t *class_ent = NULL; 2630 /* Field Class Entry */ 2631 uint32 keytype = 0; /* Field Class Key Type */ 2632 uint32 keymask = 0; /* Field Class Key Type Mask */ 2633 uint32 validen = 0; /* Valid Enable */ 2634 2635 /* Retrieve the field entry. */ 2636 rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &class_ent); 2637 BCM_IF_ERROR_RETURN(rv); 2638 2639 /* Initialize Class Qset */ 2640 BCM_FIELD_QSET_INIT(cqset); 2641 2642 /* Input Parameter Check */ 2643 if (class_ent->group == NULL) { 2644 return (BCM_E_INTERNAL); 2645 } 2646 2647 /* Input Group Stage Check */ 2648 if (class_ent->group->stage_id != 2649 _BCM_FIELD_STAGE_CLASS) { 2650 return (BCM_E_INTERNAL); 2651 } 2652 2653 /* Add qual in class qset */ 2654 BCM_FIELD_QSET_ADD(cqset, qual); 2655 2656 /* 2657 * Check if qual is present in entry group qset 2658 */ 2659 if(!(_field_qset_is_subset(&cqset, &class_ent->group->qset))) { 2660 LOG_DEBUG(BSL_LS_BCM_FP, 2661 (BSL_META_U(unit, 2662 "FP(unit %d) Error: Qual=%s not in group=%d " 2663 "qset.\n"), 2664 unit, _field_qual_name(qual),class_ent->group->gid)); 2665 return (BCM_E_PARAM); 2666 } 2667 2668 /* Retreive Class Type from entry qset */ 2669 rv = _bcm_field_th_class_type_qset_get(unit, 2670 &class_ent->group->qset, 2671 &ctype); 2672 if (BCM_FAILURE(rv)) { 2673 return (rv); 2674 } 2675 2676 /* Assign class data buffer */ 2677 if (class_ent->tcam.key == NULL) { 2678 if ((class_ent->flags & _FP_ENTRY_INSTALLED) && 2679 (class_ent->slice_idx != -1)) { 2680 /* Allocate memory for class data */ 2681 _FP_XGS3_ALLOC(class_ent->tcam.key, 2682 class_ent->tcam.key_size, "field class data buf"); 2683 if (class_ent->tcam.key == NULL) { 2684 LOG_ERROR(BSL_LS_BCM_FP, 2685 (BSL_META_U(unit, 2686 "FP(unit %d) Error: allocation failure for " 2687 "field class data buf\n"), 2688 unit)); 2689 return (BCM_E_MEMORY); 2690 } 2691 /* Entry is in hardware , read it from hardware */ 2692 rv = _bcm_field_th_class_entry_hwread(unit, class_ent, 2693 ctype, class_ent->tcam.key); 2694 if (BCM_FAILURE(rv)) { 2695 sal_free(class_ent->tcam.key); 2696 return (rv); 2697 } 2698 } else { 2699 return (BCM_E_INTERNAL); 2700 } 2701 } 2702 2703 cdata = class_ent->tcam.key; 2704 2705 switch(ctype) { 2706 case _FieldClassEtherType: 2707 reg = ETHERTYPE_MAPr; 2708 soc_reg_field_set(unit, reg, cdata, 2709 ETHERTYPEf, *data); 2710 break; 2711 case _FieldClassTtl: 2712 class_ent->tcam.ip_type = *data; 2713 break; 2714 case _FieldClassToS: 2715 class_ent->tcam.ip_type = *data; 2716 break; 2717 case _FieldClassIpProto: 2718 class_ent->tcam.ip_type = *data; 2719 break; 2720 case _FieldClassL4SrcPort: 2721 /* 2722 * Validate L4 Src Port,should not be 2723 * more than 16 bits 2724 */ 2725 if (*data & ~(0xFFFF)) { 2726 return (BCM_E_PARAM); 2727 } 2728 reg = L4_SRC_PORT_MAPr; 2729 if (qual == bcmFieldQualifyL4SrcPort) { 2730 keytype = _FP_MATCH_L4_PORT_TYPE; 2731 soc_reg_field_set(unit, reg, cdata, 2732 MATCH_TYPEf, keytype); 2733 soc_reg_field_set(unit, reg, cdata, 2734 L4_SRC_PORTf, *data); 2735 } else if (qual == bcmFieldQualifyFcoeOxID) { 2736 keytype = _FP_MATCH_EXCHANGE_ID_TYPE; 2737 soc_reg_field_set(unit, reg, cdata, 2738 MATCH_TYPEf, keytype); 2739 soc_reg_field_set(unit, reg, cdata, 2740 L4_SRC_PORTf, *data); 2741 } else { 2742 rv = BCM_E_PARAM; 2743 } 2744 break; 2745 case _FieldClassL4DstPort: 2746 /* 2747 * Validate L4 Dst Port,should not be 2748 * more than 16 bits 2749 */ 2750 if (*data & ~(0xFFFF)) { 2751 return (BCM_E_PARAM); 2752 } 2753 reg = L4_DST_PORT_MAPr; 2754 if (qual == bcmFieldQualifyL4DstPort) { 2755 keytype = _FP_MATCH_L4_PORT_TYPE; 2756 soc_reg_field_set(unit, reg, cdata, 2757 MATCH_TYPEf, keytype); 2758 soc_reg_field_set(unit, reg, cdata, 2759 L4_DST_PORTf, *data); 2760 } else if (qual == bcmFieldQualifyFcoeRxID) { 2761 keytype = _FP_MATCH_EXCHANGE_ID_TYPE; 2762 soc_reg_field_set(unit, reg, cdata, 2763 MATCH_TYPEf, keytype); 2764 soc_reg_field_set(unit, reg, cdata, 2765 L4_DST_PORTf, *data); 2766 } else { 2767 rv = BCM_E_PARAM; 2768 } 2769 break; 2770 case _FieldClassTcp: 2771 class_ent->tcam.ip_type = *data; 2772 break; 2773 case _FieldClassSrcCompression: 2774 mem = SRC_COMPRESSIONm; 2775 validen = 0; 2776 if (qual == bcmFieldQualifySrcIp) { 2777 2778 keytype = _FP_KEY_IPv4_TYPE; 2779 keymask = _FP_KEY_TYPE_MASK; 2780 2781 soc_mem_field_set(unit, mem, cdata, 2782 KEY_TYPEf, &keytype); 2783 soc_mem_field_set(unit, mem, cdata, 2784 KEY_TYPE_MASKf, &keymask); 2785 soc_mem_field_set(unit, mem, cdata, 2786 VALIDf, &validen); 2787 soc_mem_field_set(unit, mem, cdata, 2788 IPV4__SIP_V4f, data); 2789 soc_mem_field_set(unit, mem, cdata, 2790 IPV4__SIP_V4_MASKf, mask); 2791 2792 } else if (qual == bcmFieldQualifyFibreChanSrcId) { 2793 /* 2794 * Validate Fibre Chan Src ID, 2795 * should not be more than 24 bits. 2796 */ 2797 if ((*data & ~(0xFFFFFF)) || 2798 (*mask & ~(0xFFFFFF))) { 2799 return (BCM_E_PARAM); 2800 } 2801 keytype = _FP_KEY_FCoE_TYPE; 2802 keymask = _FP_KEY_TYPE_MASK; 2803 2804 soc_mem_field_set(unit, mem, cdata, 2805 KEY_TYPEf, &keytype); 2806 soc_mem_field_set(unit, mem, cdata, 2807 KEY_TYPE_MASKf, &keymask); 2808 soc_mem_field_set(unit, mem, cdata, 2809 VALIDf, &validen); 2810 soc_mem_field_set(unit, mem, cdata, 2811 FCOE__S_IDf, data); 2812 soc_mem_field_set(unit, mem, cdata, 2813 FCOE__S_ID_MASKf, mask); 2814 2815 } else if (qual == bcmFieldQualifySrcIp6) { 2816 2817 keytype = _FP_KEY_IPv6_TYPE; 2818 keymask = _FP_KEY_TYPE_MASK; 2819 2820 soc_mem_field_set(unit, mem, cdata, 2821 KEY_TYPEf, &keytype); 2822 soc_mem_field_set(unit, mem, cdata, 2823 KEY_TYPE_MASKf, &keymask); 2824 soc_mem_field_set(unit, mem, cdata, 2825 VALIDf, &validen); 2826 soc_mem_field_set(unit, mem, cdata, 2827 IPV6__SIP_V6f, data); 2828 soc_mem_field_set(unit, mem, cdata, 2829 IPV6__SIP_V6_MASKf, mask); 2830 2831 } else if (qual == bcmFieldQualifyVrf) { 2832 /* 2833 * Validate VRF Id, 2834 * should not be more than 11 bits for TH/TH2. 2835 * should not be more than 12 bits for TD3. 2836 */ 2837 if (SOC_IS_TOMAHAWKX(unit) 2838 && ((*data & ~(0x7FF)) || (*mask & ~(0x7FF)))) { 2839 return (BCM_E_PARAM); 2840 } 2841 #if defined(BCM_TRIDENT3_SUPPORT) 2842 else { 2843 if (soc_feature(unit, soc_feature_td3_style_fp) 2844 && ((*data & ~(0xFFF)) || (*mask & ~(0xFFF)))) { 2845 return (BCM_E_PARAM); 2846 } 2847 } 2848 #endif 2849 soc_mem_field_set(unit, mem, cdata, 2850 VRFf, data); 2851 soc_mem_field_set(unit, mem, cdata, 2852 VRF_MASKf, mask); 2853 } else { 2854 rv = BCM_E_PARAM; 2855 } 2856 break; 2857 case _FieldClassDstCompression: 2858 mem = DST_COMPRESSIONm; 2859 validen = 0; 2860 2861 if (qual == bcmFieldQualifyDstIp) { 2862 2863 keytype = _FP_KEY_IPv4_TYPE; 2864 keymask = _FP_KEY_TYPE_MASK; 2865 2866 soc_mem_field_set(unit, mem, cdata, 2867 KEY_TYPEf, &keytype); 2868 soc_mem_field_set(unit, mem, cdata, 2869 KEY_TYPE_MASKf, &keymask); 2870 soc_mem_field_set(unit, mem, cdata, 2871 VALIDf, &validen); 2872 soc_mem_field_set(unit, mem, cdata, 2873 IPV4__DIP_V4f, data); 2874 soc_mem_field_set(unit, mem, cdata, 2875 IPV4__DIP_V4_MASKf, mask); 2876 2877 } else if (qual == bcmFieldQualifyFibreChanDstId) { 2878 /* 2879 * Validate Fibre Chan Dst ID, 2880 * should not be more than 24 bits. 2881 */ 2882 if ((*data & ~(0xFFFFFF)) || 2883 (*mask & ~(0xFFFFFF))) { 2884 return (BCM_E_PARAM); 2885 } 2886 2887 keytype = _FP_KEY_FCoE_TYPE; 2888 keymask = _FP_KEY_TYPE_MASK; 2889 2890 soc_mem_field_set(unit, mem, cdata, 2891 KEY_TYPEf, &keytype); 2892 soc_mem_field_set(unit, mem, cdata, 2893 KEY_TYPE_MASKf, &keymask); 2894 soc_mem_field_set(unit, mem, cdata, 2895 VALIDf, &validen); 2896 soc_mem_field_set(unit, mem, cdata, 2897 FCOE__D_IDf, data); 2898 soc_mem_field_set(unit, mem, cdata, 2899 FCOE__D_ID_MASKf, mask); 2900 2901 } else if (qual == bcmFieldQualifyDstIp6) { 2902 2903 keytype = _FP_KEY_IPv6_TYPE; 2904 keymask = _FP_KEY_TYPE_MASK; 2905 2906 soc_mem_field_set(unit, mem, cdata, 2907 KEY_TYPEf, &keytype); 2908 soc_mem_field_set(unit, mem, cdata, 2909 KEY_TYPE_MASKf, &keymask); 2910 soc_mem_field_set(unit, mem, cdata, 2911 VALIDf, &validen); 2912 soc_mem_field_set(unit, mem, cdata, 2913 IPV6__DIP_V6f, data); 2914 soc_mem_field_set(unit, mem, cdata, 2915 IPV6__DIP_V6_MASKf, mask); 2916 2917 } else if (qual == bcmFieldQualifyVrf) { 2918 /* 2919 * Validate VRF Id, 2920 * should not be more than 11 bits for TH/TH2. 2921 * should not be more than 12 bits for TD3. 2922 */ 2923 if (SOC_IS_TOMAHAWKX(unit) 2924 && ((*data & ~(0x7FF)) || (*mask & ~(0x7FF)))) { 2925 return (BCM_E_PARAM); 2926 } 2927 #if defined(BCM_TRIDENT3_SUPPORT) 2928 else { 2929 if (soc_feature(unit, soc_feature_td3_style_fp) 2930 && ((*data & ~(0xFFF)) || (*mask & ~(0xFFF)))) { 2931 return (BCM_E_PARAM); 2932 } 2933 } 2934 #endif 2935 soc_mem_field_set(unit, mem, cdata, 2936 VRFf, data); 2937 soc_mem_field_set(unit, mem, cdata, 2938 VRF_MASKf, mask); 2939 } else { 2940 rv = BCM_E_PARAM; 2941 } 2942 break; 2943 case _FieldClassIpTunnelTtl: 2944 class_ent->tcam.ip_type = *data; 2945 break; 2946 default: 2947 rv = BCM_E_PARAM; 2948 } 2949 2950 /* Mark entry as dirty. */ 2951 class_ent->flags |= _FP_ENTRY_DIRTY; 2952 2953 return (rv); 2954 } 2955 2956 /* 2957 * Function: 2958 * _bcm_field_th_class_entry_qualifier_key_get 2959 * Purpose: 2960 * Get Qualify Field Class Entry. 2961 * Parameters: 2962 * unit - (IN) BCM device number. 2963 * entry - (IN) Field Class Entry ID. 2964 * qual_id - (IN) Field Qualifier ID. 2965 * q_data - (OUT) Qualifier Data Array 2966 * q_mask - (OUT) Qualifier Mask Array. 2967 * Returns: 2968 * BCM_E_XXX 2969 */ 2970 int 2971 _bcm_field_th_class_entry_qualifier_key_get(int unit, 2972 bcm_field_entry_t entry, 2973 int qual_id, 2974 _bcm_field_qual_data_t q_data, 2975 _bcm_field_qual_data_t q_mask) 2976 { 2977 int rv = BCM_E_NONE; /* Operation Return Status */ 2978 _field_group_t *fg = NULL; /* Field group info */ 2979 _field_entry_t *class_ent = NULL; /* Field entry info */ 2980 _field_class_type_t ctype; /* Field Class Type */ 2981 uint32 *databuf = 0; /* Data Buffer */ 2982 soc_reg_t reg; /* SOC Register */ 2983 soc_mem_t mem; /* SOC Memory */ 2984 uint32 keytype = 0; /* Class Entry Type */ 2985 bcm_field_qset_t cqset; /* Class Qset */ 2986 2987 /* Confirm that 'entry' is present on unit */ 2988 if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, 2989 &class_ent))) { 2990 LOG_ERROR(BSL_LS_BCM_FP, 2991 (BSL_META_U(unit, 2992 "FP(unit %d) Error: entry=(%d) does not exists.\n"), 2993 unit, entry)); 2994 return (BCM_E_BADID); 2995 } 2996 2997 /* Retreive Field Group Info */ 2998 fg = class_ent->group; 2999 3000 /* Skip if stage is not class */ 3001 if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 3002 return (BCM_E_NONE); 3003 } 3004 3005 /* Initialize Class Qset */ 3006 BCM_FIELD_QSET_INIT(cqset); 3007 3008 /* Add qual in class qset */ 3009 BCM_FIELD_QSET_ADD(cqset, qual_id); 3010 3011 /* 3012 * Check if qual is present in entry group 3013 * qset. 3014 */ 3015 if(!(_field_qset_is_subset(&cqset, &class_ent->group->qset))) { 3016 LOG_DEBUG(BSL_LS_BCM_FP, 3017 (BSL_META_U(unit, 3018 "FP(unit %d) Error: Qual=%s not in group=%d " 3019 "qset.\n"), 3020 unit, _field_qual_name(qual_id),class_ent->group->gid)); 3021 return (BCM_E_NOT_FOUND); 3022 } 3023 3024 /* Retreive Class Type from entry qset */ 3025 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 3026 if (BCM_FAILURE(rv)) { 3027 return (rv); 3028 } 3029 3030 /* Allocate memory for class data */ 3031 _FP_XGS3_ALLOC(databuf, class_ent->tcam.key_size, "field class data buf"); 3032 if (databuf == NULL) {; 3033 LOG_ERROR(BSL_LS_BCM_FP, 3034 (BSL_META_U(unit, 3035 "FP(unit %d) Error: allocation failure for " 3036 "field class data buf\n"), 3037 unit)); 3038 return (BCM_E_MEMORY); 3039 } 3040 3041 if (class_ent->tcam.key != NULL) { 3042 /* Entry is in tcam data buffer , read it from buffer */ 3043 sal_memcpy(databuf, class_ent->tcam.key, class_ent->tcam.key_size); 3044 } else { 3045 /* Entry is in hardware , read it from hardware */ 3046 rv = _bcm_field_th_class_entry_hwread(unit, class_ent, 3047 ctype, databuf); 3048 if (BCM_FAILURE(rv)) { 3049 sal_free(databuf); 3050 return (rv); 3051 } 3052 } 3053 3054 switch(ctype) { 3055 case _FieldClassEtherType: 3056 reg = ETHERTYPE_MAPr; 3057 if (qual_id == bcmFieldQualifyEtherType) { 3058 q_data[0] = soc_reg_field_get(unit, reg, *databuf, 3059 ETHERTYPEf); 3060 } 3061 break; 3062 case _FieldClassTtl: 3063 if (qual_id == bcmFieldQualifyTtl) { 3064 q_data[0] = class_ent->tcam.ip_type; 3065 } 3066 break; 3067 case _FieldClassToS: 3068 if (qual_id == bcmFieldQualifyTos) { 3069 q_data[0] = class_ent->tcam.ip_type; 3070 } 3071 break; 3072 case _FieldClassIpProto: 3073 if (qual_id == bcmFieldQualifyIpProtocol) { 3074 q_data[0] = class_ent->tcam.ip_type; 3075 } 3076 break; 3077 case _FieldClassL4SrcPort: 3078 reg = L4_SRC_PORT_MAPr; 3079 keytype = soc_reg_field_get(unit, reg, *databuf, 3080 MATCH_TYPEf); 3081 if ((keytype == _FP_MATCH_L4_PORT_TYPE) && 3082 (qual_id == bcmFieldQualifyL4SrcPort)) { 3083 q_data[0] = soc_reg_field_get(unit, reg, *databuf, 3084 L4_SRC_PORTf); 3085 } 3086 if ((keytype == _FP_MATCH_EXCHANGE_ID_TYPE) && 3087 (qual_id == bcmFieldQualifyFcoeOxID)) { 3088 q_data[0] = soc_reg_field_get(unit, reg, *databuf, 3089 L4_SRC_PORTf); 3090 } 3091 break; 3092 case _FieldClassL4DstPort: 3093 reg = L4_DST_PORT_MAPr; 3094 keytype = soc_reg_field_get(unit, reg, *databuf, 3095 MATCH_TYPEf); 3096 if ((keytype == _FP_MATCH_L4_PORT_TYPE) && 3097 (qual_id == bcmFieldQualifyL4DstPort)) { 3098 q_data[0] = soc_reg_field_get(unit, reg, *databuf, 3099 L4_DST_PORTf); 3100 } 3101 if ((keytype == _FP_MATCH_EXCHANGE_ID_TYPE) && 3102 (qual_id == bcmFieldQualifyFcoeRxID)) { 3103 q_data[0] = soc_reg_field_get(unit, reg, *databuf, 3104 L4_DST_PORTf); 3105 } 3106 break; 3107 case _FieldClassTcp: 3108 if (qual_id == bcmFieldQualifyTcpControl) { 3109 q_data[0] = class_ent->tcam.ip_type; 3110 } 3111 break; 3112 case _FieldClassSrcCompression: 3113 mem = SRC_COMPRESSIONm; 3114 soc_mem_field_get(unit, mem, databuf, 3115 KEY_TYPEf, &keytype); 3116 if (keytype == _FP_KEY_IPv4_TYPE && 3117 (qual_id == bcmFieldQualifySrcIp)) { 3118 soc_mem_field_get(unit, mem, databuf, 3119 IPV4__SIP_V4f, q_data); 3120 soc_mem_field_get(unit, mem, databuf, 3121 IPV4__SIP_V4_MASKf, q_mask); 3122 } else if (keytype == _FP_KEY_FCoE_TYPE && 3123 (qual_id == bcmFieldQualifyFibreChanSrcId)) { 3124 soc_mem_field_get(unit, mem, databuf, 3125 FCOE__S_IDf, q_data); 3126 soc_mem_field_get(unit, mem, databuf, 3127 FCOE__S_ID_MASKf, q_mask); 3128 } else if (keytype == _FP_KEY_IPv6_TYPE && 3129 (qual_id == bcmFieldQualifySrcIp6)) { 3130 soc_mem_field_get(unit, mem, databuf, 3131 IPV6__SIP_V6f, q_data); 3132 soc_mem_field_get(unit, mem, databuf, 3133 IPV6__SIP_V6_MASKf, q_mask); 3134 } else { 3135 /* Do Nothing */ 3136 } 3137 if (qual_id == bcmFieldQualifyVrf) { 3138 soc_mem_field_get(unit, mem, databuf, 3139 VRFf, q_data); 3140 soc_mem_field_get(unit, mem, databuf, 3141 VRF_MASKf, q_mask); 3142 } 3143 break; 3144 case _FieldClassDstCompression: 3145 mem = DST_COMPRESSIONm; 3146 soc_mem_field_get(unit, mem, databuf, 3147 KEY_TYPEf, &keytype); 3148 if ((keytype == _FP_KEY_IPv4_TYPE) && 3149 (qual_id == bcmFieldQualifyDstIp)) { 3150 3151 soc_mem_field_get(unit, mem, databuf, 3152 IPV4__DIP_V4f, q_data); 3153 soc_mem_field_get(unit, mem, databuf, 3154 IPV4__DIP_V4_MASKf, q_mask); 3155 } else if ((keytype == _FP_KEY_FCoE_TYPE) && 3156 (qual_id == bcmFieldQualifyFibreChanDstId)) { 3157 3158 soc_mem_field_get(unit, mem, databuf, 3159 FCOE__D_IDf, q_data); 3160 soc_mem_field_get(unit, mem, databuf, 3161 FCOE__D_ID_MASKf, q_mask); 3162 } else if ((keytype == _FP_KEY_IPv6_TYPE) && 3163 (qual_id == bcmFieldQualifyDstIp6)) { 3164 soc_mem_field_get(unit, mem, databuf, 3165 IPV6__DIP_V6f, q_data); 3166 soc_mem_field_get(unit, mem, databuf, 3167 IPV6__DIP_V6_MASKf, q_mask); 3168 } else { 3169 /* Do Nothing */ 3170 } 3171 if (qual_id == bcmFieldQualifyVrf) { 3172 soc_mem_field_get(unit, mem, databuf, 3173 VRFf, q_data); 3174 soc_mem_field_get(unit, mem, databuf, 3175 VRF_MASKf, q_mask); 3176 } 3177 break; 3178 case _FieldClassIpTunnelTtl: 3179 if (qual_id == bcmFieldQualifyIpTunnelTtl) { 3180 q_data[0] = class_ent->tcam.ip_type; 3181 } 3182 break; 3183 default: 3184 rv = BCM_E_NONE; 3185 } 3186 3187 /* Free Entry Buffer */ 3188 sal_free(databuf); 3189 3190 return (BCM_E_NONE); 3191 } 3192 3193 /* 3194 * Function: 3195 * _bcm_field_th_class_qualify_clear 3196 * Purpose: 3197 * Clear Field Class Qualifiers. 3198 * Parameters: 3199 * unit - (IN) BCM device number. 3200 * entry - (IN) Field Entry Id. 3201 * Returns: 3202 * BCM_E_XXX 3203 */ 3204 int 3205 _bcm_field_th_class_qualify_clear(int unit, bcm_field_entry_t entry) 3206 { 3207 int rv = BCM_E_NONE; /* Operation Return Status */ 3208 _field_entry_t *class_ent = NULL; 3209 /* Field Class Entry */ 3210 _field_group_t *fg = NULL; 3211 /* Field group info */ 3212 int q = 0; /* Qset iterator */ 3213 _bcm_field_qual_data_t q_data; 3214 /* Qualifier match data */ 3215 _bcm_field_qual_data_t q_mask; 3216 /* Qualifier match mask */ 3217 3218 /* Retrieve the field entry. */ 3219 rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &class_ent); 3220 BCM_IF_ERROR_RETURN(rv); 3221 3222 /* Parameter Check */ 3223 if (class_ent->group == NULL) { 3224 return (BCM_E_INTERNAL); 3225 } 3226 3227 /* Input Group Stage Check */ 3228 if (class_ent->group->stage_id != _BCM_FIELD_STAGE_CLASS) { 3229 return (BCM_E_INTERNAL); 3230 } 3231 3232 /* Retreive Field Group from entry */ 3233 fg = class_ent->group; 3234 3235 /* Initialize qdata and qmask */ 3236 sal_memset(q_data, 0, sizeof(_bcm_field_qual_data_t)); 3237 sal_memset(q_mask, 0, sizeof(_bcm_field_qual_data_t)); 3238 3239 /* Clear all qualifier in entry group */ 3240 for (q = 0; q < (int)bcmFieldQualifyCount; q++) { 3241 if (BCM_FIELD_QSET_TEST(fg->qset, q)) { 3242 if ((q != bcmFieldQualifyStageClass) && 3243 (q != bcmFieldQualifyStageClassExactMatch)) { 3244 rv = _bcm_field_th_class_qualify_set(unit, entry, 3245 q, q_data, q_mask); 3246 if (BCM_FAILURE(rv)) { 3247 return (rv); 3248 } 3249 } 3250 } 3251 } 3252 3253 return (rv); 3254 } 3255 3256 /* 3257 * Function: 3258 * _bcm_field_th_class_action_set 3259 * Purpose: 3260 * Set Field Class Entry Action. 3261 * Parameters: 3262 * unit - (IN) BCM device number. 3263 * entry - (IN) Field Entry Id. 3264 * class_info - (IN) Field Class Info Structure. 3265 * Returns: 3266 * BCM_E_XXX 3267 */ 3268 int 3269 _bcm_field_th_class_action_set(int unit, bcm_field_entry_t entry, 3270 bcm_field_class_info_t *class_info) 3271 { 3272 int rv = BCM_E_NONE; /* Operation Return Status */ 3273 _field_group_t *fg = NULL; 3274 /* Field group info */ 3275 _field_entry_t *f_ent = NULL; 3276 /* Field entry info */ 3277 _field_action_t *fa = NULL; 3278 /* Field action info */ 3279 _field_action_t *faiter = NULL; 3280 /* Field action iterator */ 3281 uint32 *cdata; /* Class Data */ 3282 _field_class_type_t ctype; /* Field Class Type */ 3283 soc_reg_t reg; /* SOC Register */ 3284 soc_mem_t mem; /* SOC Memory */ 3285 3286 /* Confirm that 'entry' is present on unit */ 3287 if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) { 3288 LOG_ERROR(BSL_LS_BCM_FP, 3289 (BSL_META_U(unit, 3290 "FP(unit %d) Error: entry=(%d) does not exists.\n"), 3291 unit, entry)); 3292 return (BCM_E_NOT_FOUND); 3293 } 3294 3295 /* Retreive Field Group */ 3296 fg = f_ent->group; 3297 3298 /* Entry Group Check */ 3299 if (fg == NULL) { 3300 return (BCM_E_INTERNAL); 3301 } 3302 3303 /* Class Info Check */ 3304 if (class_info == NULL) { 3305 return (BCM_E_PARAM); 3306 } 3307 3308 /* Skip if stage is not class */ 3309 if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 3310 return (BCM_E_PARAM); 3311 } 3312 3313 /* Confirm that action is in aset. */ 3314 if (SHR_BITGET(fg->aset.w, class_info->action) == 0) { 3315 LOG_DEBUG(BSL_LS_BCM_FP, 3316 (BSL_META_U(unit, 3317 "FP(unit %d) Error: provided action not present in entry " 3318 "group aset.\n"), 3319 unit)); 3320 return (BCM_E_PARAM); 3321 } 3322 3323 /* Check action is not set already in entry */ 3324 faiter = f_ent->actions; 3325 while (faiter != NULL) { 3326 if (faiter->action == class_info->action) { 3327 LOG_DEBUG(BSL_LS_BCM_FP, 3328 (BSL_META_U(unit, 3329 "FP(unit %d) Error: provided action already present" 3330 " in field entry.\n"), 3331 unit)); 3332 return (BCM_E_EXISTS); 3333 } 3334 faiter = faiter->next; 3335 } 3336 3337 fa = sal_alloc(sizeof (_field_action_t), "field_action"); 3338 if (fa == NULL) { 3339 LOG_ERROR(BSL_LS_BCM_FP, 3340 (BSL_META_U(unit, 3341 "FP(unit %d) Error: allocation failure for field_action\n"), 3342 unit)); 3343 return (BCM_E_MEMORY); 3344 } 3345 3346 sal_memset(fa, 0, sizeof (_field_action_t)); 3347 3348 /* Assign and store class action values */ 3349 fa->action = class_info->action; 3350 COMPILER_64_TO_32_LO(fa->param[0], class_info->class_id); 3351 COMPILER_64_TO_32_HI(fa->param[1], class_info->class_id); 3352 3353 /* Retreive Class Type from entry qset */ 3354 rv = _bcm_field_th_class_type_qset_get(unit, 3355 &f_ent->group->qset, &ctype); 3356 if (BCM_FAILURE(rv)) { 3357 sal_free(fa); 3358 return (rv); 3359 } 3360 3361 /* Assign class data buffer */ 3362 if (f_ent->tcam.key == NULL) { 3363 if ((f_ent->flags & _FP_ENTRY_INSTALLED) && 3364 (f_ent->slice_idx != -1)) { 3365 /* Allocate memory for class data */ 3366 _FP_XGS3_ALLOC(f_ent->tcam.key, 3367 f_ent->tcam.key_size, "field class data buf"); 3368 if (f_ent->tcam.key == NULL) { 3369 LOG_ERROR(BSL_LS_BCM_FP, 3370 (BSL_META_U(unit, 3371 "FP(unit %d) Error: allocation failure for " 3372 "field class data buf\n"), 3373 unit)); 3374 sal_free(fa); 3375 return (BCM_E_MEMORY); 3376 } 3377 /* Entry is in hardware , read it from hardware */ 3378 rv = _bcm_field_th_class_entry_hwread(unit, f_ent, 3379 ctype, f_ent->tcam.key); 3380 if (BCM_FAILURE(rv)) { 3381 sal_free(f_ent->tcam.key); 3382 sal_free(fa); 3383 return (rv); 3384 } 3385 } else { 3386 sal_free(fa); 3387 return (BCM_E_INTERNAL); 3388 } 3389 } 3390 3391 /* Assign class data and mask buffer */ 3392 cdata = f_ent->tcam.key; 3393 3394 switch(ctype) { 3395 case _FieldClassEtherType: 3396 reg = ETHERTYPE_MAPr; 3397 if ((fa->param[0] & ~(0xF)) || 3398 (fa->param[1] & ~(0))) { 3399 rv = BCM_E_PARAM; 3400 } else { 3401 soc_reg_field_set(unit, reg, cdata, 3402 C_ETHERTYPEf, fa->param[0]); 3403 } 3404 break; 3405 case _FieldClassTtl: 3406 mem = TTL_FNm; 3407 if ((fa->param[0] & ~(0xFF)) || 3408 (fa->param[1] & ~(0))) { 3409 rv = BCM_E_PARAM; 3410 } else { 3411 if (class_info->action == bcmFieldActionClassZero) { 3412 soc_mem_field_set(unit, mem, cdata, 3413 FN0f, &fa->param[0]); 3414 } else { 3415 soc_mem_field_set(unit, mem, cdata, 3416 FN1f, &fa->param[0]); 3417 } 3418 } 3419 break; 3420 case _FieldClassToS: 3421 mem = TOS_FNm; 3422 if ((fa->param[0] & ~(0xFF)) || 3423 (fa->param[1] & ~(0))) { 3424 rv = BCM_E_PARAM; 3425 } else { 3426 if (class_info->action == bcmFieldActionClassZero) { 3427 soc_mem_field_set(unit, mem, cdata, 3428 FN0f, &fa->param[0]); 3429 } else { 3430 soc_mem_field_set(unit, mem, cdata, 3431 FN1f, &fa->param[0]); 3432 } 3433 } 3434 break; 3435 case _FieldClassIpProto: 3436 mem = IP_PROTO_MAPm; 3437 if ((fa->param[0] & ~(0xF)) || 3438 (fa->param[1] & ~(0))) { 3439 rv = BCM_E_PARAM; 3440 } else { 3441 soc_mem_field_set(unit, mem, cdata, 3442 C_IP_PROTOCOLf, &fa->param[0]); 3443 } 3444 break; 3445 case _FieldClassL4SrcPort: 3446 reg = L4_SRC_PORT_MAPr; 3447 if ((fa->param[0] & ~(0xF)) || 3448 (fa->param[1] & ~(0))) { 3449 rv = BCM_E_PARAM; 3450 } else { 3451 soc_reg_field_set(unit, reg, cdata, 3452 C_L4_SRC_PORTf, fa->param[0]); 3453 } 3454 break; 3455 case _FieldClassL4DstPort: 3456 reg = L4_DST_PORT_MAPr; 3457 if ((fa->param[0] & ~(0xF)) || 3458 (fa->param[1] & ~(0))) { 3459 rv = BCM_E_PARAM; 3460 } else { 3461 soc_reg_field_set(unit, reg, cdata, 3462 C_L4_DST_PORTf, fa->param[0]); 3463 } 3464 break; 3465 case _FieldClassTcp: 3466 mem = TCP_FNm; 3467 if ((fa->param[0] & ~(0xFF)) || 3468 (fa->param[1] & ~(0))) { 3469 rv = BCM_E_PARAM; 3470 } else { 3471 if (class_info->action == bcmFieldActionClassZero) { 3472 soc_mem_field_set(unit, mem, cdata, 3473 FN0f, &fa->param[0]); 3474 } else { 3475 soc_mem_field_set(unit, mem, cdata, 3476 FN1f, &fa->param[0]); 3477 } 3478 } 3479 break; 3480 case _FieldClassSrcCompression: 3481 mem = SRC_COMPRESSIONm; 3482 if (fa->param[1] & ~(0xF)) { 3483 rv = BCM_E_PARAM; 3484 } else { 3485 soc_mem_field_set(unit, mem, cdata, 3486 C_SRCf, &fa->param[0]); 3487 } 3488 break; 3489 case _FieldClassDstCompression: 3490 mem = DST_COMPRESSIONm; 3491 if (fa->param[1] & ~(0xF)) { 3492 rv = BCM_E_PARAM; 3493 } else { 3494 soc_mem_field_set(unit, mem, cdata, 3495 C_DSTf, &fa->param[0]); 3496 } 3497 break; 3498 case _FieldClassIpTunnelTtl: 3499 mem = ALT_TTL_FNm; 3500 if ((fa->param[0] & ~(0xFF)) || 3501 (fa->param[1] & ~(0))) { 3502 rv = BCM_E_PARAM; 3503 } else { 3504 if (class_info->action == bcmFieldActionClassZero) { 3505 soc_mem_field_set(unit, mem, cdata, 3506 FN0f, &fa->param[0]); 3507 } else { 3508 rv = BCM_E_PARAM; 3509 } 3510 } 3511 break; 3512 default: 3513 rv = BCM_E_PARAM; 3514 } 3515 3516 if (BCM_FAILURE(rv)) { 3517 sal_free(fa); 3518 return (rv); 3519 } 3520 3521 /* Add action to front of entry's linked-list. */ 3522 fa->next = f_ent->actions; 3523 f_ent->actions = fa; 3524 3525 /* Mark entry as dirty. */ 3526 f_ent->flags |= _FP_ENTRY_DIRTY; 3527 3528 return (rv); 3529 } 3530 3531 /* 3532 * Function: 3533 * _bcm_field_th_class_action_delete 3534 * Purpose: 3535 * Delete Field Class Entry Action. 3536 * Parameters: 3537 * unit - (IN) BCM device number. 3538 * entry - (IN) Field Entry Id. 3539 * action - (IN) Field Action info. 3540 * Returns: 3541 * BCM_E_XXX 3542 */ 3543 int 3544 _bcm_field_th_class_action_delete(int unit, bcm_field_entry_t entry, 3545 bcm_field_action_t action) 3546 { 3547 int rv = BCM_E_NONE; /* Operation Return Status */ 3548 _field_group_t *fg = NULL; /* Field group info */ 3549 _field_entry_t *f_ent = NULL; 3550 /* Field entry info */ 3551 _field_action_t *fa = NULL; 3552 /* Field action info */ 3553 _field_action_t *fa_prev = NULL; 3554 /* Field action info previous */ 3555 uint32 *cdata = NULL; /* Class Data */ 3556 _field_class_type_t ctype; /* Field Class Type */ 3557 soc_reg_t reg; /* SOC Register */ 3558 soc_mem_t mem; /* SOC Memory */ 3559 uint32 valid = 0; /* Valid */ 3560 uint32 action_clear[2] = {0, 0}; 3561 /* Class Src/Dst */ 3562 3563 /* Confirm that 'entry' is present on unit */ 3564 if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) { 3565 LOG_ERROR(BSL_LS_BCM_FP, 3566 (BSL_META_U(unit, 3567 "FP(unit %d) Error: entry=(%d) does not exists.\n"), 3568 unit, entry)); 3569 return (BCM_E_NOT_FOUND); 3570 } 3571 3572 /* Retreive Field Group */ 3573 fg = f_ent->group; 3574 3575 /* Entry Group Check */ 3576 if (fg == NULL) { 3577 return (BCM_E_INTERNAL); 3578 } 3579 3580 /* Find the action in the entry */ 3581 fa = f_ent->actions; /* start at head */ 3582 3583 while (fa != NULL) { 3584 if (fa->action != action) { 3585 fa_prev = fa; 3586 fa = fa->next; 3587 continue; 3588 } 3589 break; 3590 } 3591 3592 if (NULL == fa) { 3593 LOG_ERROR(BSL_LS_BCM_FP, 3594 (BSL_META_U(unit, 3595 "FP(unit %d) Error: action=(%d) is not present in entry.\n"), 3596 unit, action)); 3597 return (BCM_E_NOT_FOUND); 3598 } 3599 3600 /* Retreive Class Type from entry qset */ 3601 rv = _bcm_field_th_class_type_qset_get(unit, 3602 &f_ent->group->qset, 3603 &ctype); 3604 if (BCM_FAILURE(rv)) { 3605 return (rv); 3606 } 3607 3608 /* Assign class data buffer */ 3609 if (f_ent->tcam.key == NULL) { 3610 if ((f_ent->flags & _FP_ENTRY_INSTALLED) && 3611 (f_ent->slice_idx != -1)) { 3612 /* Allocate memory for class data */ 3613 _FP_XGS3_ALLOC(f_ent->tcam.key, 3614 f_ent->tcam.key_size, "field class data buf"); 3615 if (f_ent->tcam.key == NULL) { 3616 LOG_ERROR(BSL_LS_BCM_FP, 3617 (BSL_META_U(unit, 3618 "FP(unit %d) Error: allocation failure for " 3619 "field class data buf\n"), 3620 unit)); 3621 return (BCM_E_MEMORY); 3622 } 3623 /* Entry is in hardware , read it from hardware */ 3624 rv = _bcm_field_th_class_entry_hwread(unit, f_ent, 3625 ctype, f_ent->tcam.key); 3626 if (BCM_FAILURE(rv)) { 3627 sal_free(f_ent->tcam.key); 3628 return (rv); 3629 } 3630 } else { 3631 return (BCM_E_INTERNAL); 3632 } 3633 } 3634 3635 /* Assign class data and mask buffer */ 3636 cdata = f_ent->tcam.key; 3637 3638 switch(ctype) { 3639 case _FieldClassEtherType: 3640 reg = ETHERTYPE_MAPr; 3641 soc_reg_field_set(unit, reg, cdata, C_ETHERTYPEf, valid); 3642 break; 3643 case _FieldClassTtl: 3644 mem = TTL_FNm; 3645 if (fa->action == bcmFieldActionClassZero) { 3646 soc_mem_field_set(unit, mem, cdata, FN0f, &valid); 3647 } else { 3648 soc_mem_field_set(unit, mem, cdata, FN1f, &valid); 3649 } 3650 break; 3651 case _FieldClassToS: 3652 mem = TOS_FNm; 3653 if (fa->action == bcmFieldActionClassZero) { 3654 soc_mem_field_set(unit, mem, cdata, FN0f, &valid); 3655 } else { 3656 soc_mem_field_set(unit, mem, cdata, FN1f, &valid); 3657 } 3658 break; 3659 case _FieldClassIpProto: 3660 mem = IP_PROTO_MAPm; 3661 soc_mem_field_set(unit, mem, cdata, C_IP_PROTOCOLf, &valid); 3662 break; 3663 case _FieldClassL4SrcPort: 3664 reg = L4_SRC_PORT_MAPr; 3665 soc_reg_field_set(unit, reg , cdata, C_L4_SRC_PORTf, valid); 3666 break; 3667 case _FieldClassL4DstPort: 3668 reg = L4_DST_PORT_MAPr; 3669 soc_reg_field_set(unit, reg , cdata, C_L4_DST_PORTf, valid); 3670 break; 3671 case _FieldClassTcp: 3672 mem = TCP_FNm; 3673 if (fa->action == bcmFieldActionClassZero) { 3674 soc_mem_field_set(unit, mem, cdata, FN0f, &valid); 3675 } else { 3676 soc_mem_field_set(unit, mem, cdata, FN1f, &valid); 3677 } 3678 break; 3679 case _FieldClassSrcCompression: 3680 mem = SRC_COMPRESSIONm; 3681 soc_mem_field_set(unit, mem, cdata, C_SRCf, action_clear); 3682 break; 3683 case _FieldClassDstCompression: 3684 mem = DST_COMPRESSIONm; 3685 soc_mem_field_set(unit, mem, cdata, C_DSTf, action_clear); 3686 break; 3687 case _FieldClassIpTunnelTtl: 3688 mem = ALT_TTL_FNm; 3689 if (fa->action == bcmFieldActionClassZero) { 3690 soc_mem_field_set(unit, mem, cdata, FN0f, &valid); 3691 } else { 3692 rv = BCM_E_PARAM; 3693 } 3694 break; 3695 default: 3696 rv = BCM_E_PARAM; 3697 } 3698 3699 if (fa_prev != NULL) { 3700 fa_prev->next = fa->next; 3701 } else { /* matched head of list */ 3702 f_ent->actions = fa->next; 3703 } 3704 3705 /* okay to free action */ 3706 sal_free(fa); 3707 fa = NULL; 3708 3709 /* Mark Entry as Dirty */ 3710 f_ent->flags |= _FP_ENTRY_DIRTY; 3711 3712 return rv; 3713 } 3714 3715 /* 3716 * Function: 3717 * _bcm_field_th_class_action_get 3718 * Purpose: 3719 * Get Field Class Entry Action. 3720 * Parameters: 3721 * unit - (IN) BCM device number. 3722 * entry - (IN) Field Entry Id. 3723 * class_info - (INOUT) Field Class Info Structure. 3724 * Returns: 3725 * BCM_E_XXX 3726 */ 3727 int 3728 _bcm_field_th_class_action_get(int unit, bcm_field_entry_t entry, 3729 bcm_field_class_info_t *class_info) 3730 { 3731 int rv = BCM_E_NONE; /* Operation Return Status */ 3732 _field_group_t *fg = NULL; 3733 /* Field group info */ 3734 _field_entry_t *f_ent = NULL; 3735 /* Field entry info */ 3736 _field_action_t *fa = NULL; 3737 /* Field action info */ 3738 3739 /* Confirm that 'entry' is present on unit */ 3740 if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) { 3741 LOG_ERROR(BSL_LS_BCM_FP, 3742 (BSL_META_U(unit, 3743 "FP(unit %d) Error: entry=(%d) does not exists.\n"), 3744 unit, entry)); 3745 return (BCM_E_BADID); 3746 } 3747 3748 /* Retreive Field Group */ 3749 fg = f_ent->group; 3750 3751 /* Entry Group Check */ 3752 if (fg == NULL) { 3753 return (BCM_E_INTERNAL); 3754 } 3755 3756 /* Class Info Check */ 3757 if (class_info == NULL) { 3758 return (BCM_E_PARAM); 3759 } 3760 3761 /* Skip if stage is not class */ 3762 if (fg->stage_id != _BCM_FIELD_STAGE_CLASS) { 3763 return (BCM_E_PARAM); 3764 } 3765 3766 /* Check action is not set already in entry */ 3767 fa = f_ent->actions; 3768 while (fa != NULL) { 3769 if (fa->action == class_info->action) { 3770 break; 3771 } 3772 fa = fa->next; 3773 } 3774 3775 if (NULL == fa) { 3776 LOG_ERROR(BSL_LS_BCM_FP, 3777 (BSL_META_U(unit, 3778 "FP(unit %d) Error: action=(%d) is not present in entry.\n"), 3779 unit, class_info->action)); 3780 return (BCM_E_NOT_FOUND); 3781 } 3782 3783 COMPILER_64_SET(class_info->class_id, fa->param[1], fa->param[0]); 3784 3785 return (rv); 3786 } 3787 3788 /* 3789 * Function: 3790 * _bcm_field_th_qual_class_size_get 3791 * Purpose: 3792 * Get Field Qualifier Class Size 3793 * Parameters: 3794 * unit - (IN) BCM device number. 3795 * qual - (IN) Field Qualifier. 3796 * class_size - (OUT) Field Qualifier Class Size. 3797 * Returns: 3798 * BCM_E_XXX 3799 * Notes: 3800 * This api returns class size for provided qualifier 3801 * Size provided is in bits. 3802 */ 3803 int 3804 _bcm_field_th_qual_class_size_get(int unit, bcm_field_qualify_t qual, 3805 uint16 *class_size) 3806 { 3807 int rv = BCM_E_NONE; /* Operation Return Status */ 3808 3809 #if defined (BCM_TOMAHAWK3_SUPPORT) 3810 if (SOC_IS_TOMAHAWK3(unit)) { 3811 return _bcm_field_th3_qual_class_size_get(unit, qual, class_size); 3812 } 3813 #endif 3814 3815 switch (qual) { 3816 case bcmFieldQualifyEtherType: 3817 *class_size = _FP_QUAL_CLASS_SIZE_ETHERTYPE; 3818 break; 3819 case bcmFieldQualifyTtl: 3820 *class_size = _FP_QUAL_CLASS_SIZE_TTL; 3821 break; 3822 case bcmFieldQualifyTos: 3823 *class_size = _FP_QUAL_CLASS_SIZE_TOS; 3824 break; 3825 case bcmFieldQualifyIpProtocol: 3826 *class_size = _FP_QUAL_CLASS_SIZE_IP_PROTO; 3827 break; 3828 case bcmFieldQualifyL4SrcPort: 3829 *class_size = _FP_QUAL_CLASS_SIZE_L4_SRC_PORT; 3830 break; 3831 case bcmFieldQualifyFcoeOxID: 3832 *class_size = _FP_QUAL_CLASS_SIZE_L4_SRC_PORT; 3833 break; 3834 case bcmFieldQualifyL4DstPort: 3835 *class_size = _FP_QUAL_CLASS_SIZE_L4_DST_PORT; 3836 break; 3837 case bcmFieldQualifyFcoeRxID: 3838 *class_size = _FP_QUAL_CLASS_SIZE_L4_DST_PORT; 3839 break; 3840 case bcmFieldQualifyTcpControl: 3841 *class_size = _FP_QUAL_CLASS_SIZE_TCP; 3842 break; 3843 case bcmFieldQualifySrcIp: 3844 *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION; 3845 break; 3846 case bcmFieldQualifySrcIp6: 3847 *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION; 3848 break; 3849 case bcmFieldQualifyFibreChanSrcId: 3850 *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION; 3851 break; 3852 case bcmFieldQualifyDstIp: 3853 *class_size = _FP_QUAL_CLASS_SIZE_DST_COMPRESSION; 3854 break; 3855 case bcmFieldQualifyDstIp6: 3856 *class_size = _FP_QUAL_CLASS_SIZE_DST_COMPRESSION; 3857 break; 3858 case bcmFieldQualifyFibreChanDstId: 3859 *class_size = _FP_QUAL_CLASS_SIZE_DST_COMPRESSION; 3860 break; 3861 case bcmFieldQualifyVrf: 3862 *class_size = _FP_QUAL_CLASS_SIZE_SRC_COMPRESSION; 3863 break; 3864 default: 3865 rv = BCM_E_PARAM; 3866 } 3867 3868 return (rv); 3869 } 3870 3871 /* 3872 * Function: 3873 * _bcm_field_th_class_entry_install 3874 * Purpose: 3875 * Install Field Class Entry. 3876 * Parameters: 3877 * unit - (IN) BCM device number. 3878 * entry - (IN) Field Entry Id. 3879 * Returns: 3880 * BCM_E_XXX 3881 */ 3882 int 3883 _bcm_field_th_class_entry_install(int unit, bcm_field_entry_t entry) 3884 { 3885 int rv = BCM_E_NONE; /* Operation Return Status */ 3886 _field_group_t *fg = NULL; /* Field group info */ 3887 _field_entry_t *f_ent = NULL; /* Field entry info */ 3888 _field_class_type_t ctype; /* Field Class Type */ 3889 int hw_index = 0; /* Hardware Index */ 3890 _field_class_info_t **class_status_arr; 3891 /* Field Per Pipe Class Status Array */ 3892 _field_class_info_t *class_status_info; 3893 /* Field Per Compression table status */ 3894 _field_stage_t *stage_fc = NULL; 3895 /* Stage field control info */ 3896 3897 /* Confirm that 'entry' is present on unit */ 3898 if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) { 3899 LOG_ERROR(BSL_LS_BCM_FP, 3900 (BSL_META_U(unit, 3901 "FP(unit %d) Error: entry=(%d) does not exists.\n"), 3902 unit, entry)); 3903 return (BCM_E_BADID); 3904 } 3905 3906 /* Retreive Field Group */ 3907 fg = f_ent->group; 3908 3909 /* Check if group is associated */ 3910 if (fg == NULL) { 3911 return (BCM_E_INTERNAL); 3912 } 3913 3914 /* Get group stage control structure. */ 3915 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 3916 if (BCM_FAILURE(rv)) { 3917 LOG_ERROR(BSL_LS_BCM_FP, 3918 (BSL_META_U(unit, 3919 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 3920 unit, fg->stage_id)); 3921 return (rv); 3922 } 3923 3924 /* Check if entry is installed and not dirty */ 3925 if ((f_ent->flags & _FP_ENTRY_INSTALLED) && 3926 (!(f_ent->flags & _FP_ENTRY_DIRTY))) { 3927 /* Nothing to do - entry is installed and clean */ 3928 return (BCM_E_NONE); 3929 } 3930 3931 /* Check if data and action exist */ 3932 if ((f_ent->tcam.key == NULL) || 3933 (f_ent->actions == NULL)) { 3934 LOG_DEBUG(BSL_LS_BCM_FP, 3935 (BSL_META_U(unit, 3936 "FP(unit %d) Error: entry=(%d) data or action is not qualified.\n"), 3937 unit, entry)); 3938 return (BCM_E_PARAM); 3939 } 3940 3941 /* Retreive Class Type from entry qset */ 3942 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 3943 if (BCM_FAILURE(rv)) { 3944 return (rv); 3945 } 3946 3947 /* Update Class Status Info Structure */ 3948 class_status_arr = stage_fc->class_info_arr[fg->instance]; 3949 if (class_status_arr == NULL) { 3950 return (BCM_E_INTERNAL); 3951 } 3952 class_status_info = class_status_arr[ctype]; 3953 if (class_status_info == NULL) { 3954 return (BCM_E_INTERNAL); 3955 } 3956 3957 /* Allocate HwIndex Only if index is not allocate previously */ 3958 if (f_ent->slice_idx == -1) { 3959 rv = _field_th_class_hwindex_get(unit, f_ent, ctype, &hw_index); 3960 if (BCM_FAILURE(rv)) { 3961 return (BCM_E_RESOURCE); 3962 } 3963 f_ent->slice_idx = hw_index; 3964 } 3965 3966 /* Install Entry in Hardware */ 3967 rv = _bcm_field_th_class_entry_hwinstall(unit, f_ent, ctype); 3968 if (BCM_FAILURE(rv)) { 3969 f_ent->slice_idx = -1; 3970 return (rv); 3971 } 3972 3973 sal_free(f_ent->tcam.key); 3974 f_ent->tcam.key = NULL; 3975 f_ent->flags |= _FP_ENTRY_INSTALLED; 3976 f_ent->flags &= ~_FP_ENTRY_DIRTY; 3977 _FP_CLASS_TABLE_BMP_ADD(class_status_info->class_bmp, f_ent->slice_idx); 3978 3979 /* Sorted Insert for Src/Dst Compression. */ 3980 if ((ctype == _FieldClassSrcCompression) || 3981 (ctype == _FieldClassDstCompression)) { 3982 if (class_status_info->total_entries_used != 3983 class_status_info->total_entries_available) { 3984 rv = _bcm_field_th_class_entry_prio_set(unit, f_ent, f_ent->prio); 3985 if (BCM_FAILURE(rv)) { 3986 return (rv); 3987 } 3988 } 3989 rv = _field_th_class_valid_set(unit, f_ent, ctype, 1); 3990 } 3991 3992 return (rv); 3993 } 3994 3995 /* 3996 * Function: 3997 * _field_th_class_hwindex_get 3998 * Purpose: 3999 * Get Field Class Entry Hw Index. 4000 * Parameters: 4001 * unit - (IN) BCM device number. 4002 * entry - (IN) Field Entry Info. 4003 * ctype - (IN) Field Class Type. 4004 * hw_index - (OUT) Field Entry Hardware Index. 4005 * Returns: 4006 * BCM_E_XXX 4007 */ 4008 STATIC int 4009 _field_th_class_hwindex_get(int unit, _field_entry_t *entry, 4010 _field_class_type_t ctype, int *hw_index) 4011 { 4012 int rv = BCM_E_PARAM; /* Operation Return Status */ 4013 _field_group_t *fg = NULL; /* Field group info */ 4014 _field_class_info_t **class_status_arr; 4015 /* Field Per Pipe Class Status Array */ 4016 _field_class_info_t *class_status_info; 4017 /* Field Per Compression table status */ 4018 _field_stage_t *stage_fc = NULL; 4019 /* Stage field control info */ 4020 int idx = 0; /* Index Iterator */ 4021 4022 /* Input Parameters Check */ 4023 if (entry == NULL) { 4024 return (BCM_E_INTERNAL); 4025 } 4026 4027 /* Retreive Field Group */ 4028 fg = entry->group; 4029 4030 /* Get group stage control structure. */ 4031 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4032 if (BCM_FAILURE(rv)) { 4033 LOG_ERROR(BSL_LS_BCM_FP, 4034 (BSL_META_U(unit, 4035 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4036 unit, fg->stage_id)); 4037 return (rv); 4038 } 4039 4040 /* Update Class Info Status Structure */ 4041 class_status_arr = stage_fc->class_info_arr[fg->instance]; 4042 if (class_status_arr == NULL) { 4043 return (BCM_E_INTERNAL); 4044 } 4045 class_status_info = class_status_arr[ctype]; 4046 if (class_status_info == NULL) { 4047 return (BCM_E_INTERNAL); 4048 } 4049 4050 switch (ctype) { 4051 case _FieldClassEtherType: 4052 case _FieldClassL4SrcPort: 4053 case _FieldClassL4DstPort: 4054 case _FieldClassSrcCompression: 4055 case _FieldClassDstCompression: 4056 for (idx = 0; idx < class_status_info->total_entries_available; 4057 idx++) { 4058 if (0 == _FP_CLASS_TABLE_BMP_TEST( 4059 class_status_info->class_bmp, idx)) { 4060 *hw_index = idx; 4061 rv = BCM_E_NONE; 4062 break; 4063 } 4064 } 4065 break; 4066 case _FieldClassTtl: 4067 case _FieldClassToS: 4068 case _FieldClassIpProto: 4069 case _FieldClassTcp: 4070 case _FieldClassIpTunnelTtl: 4071 *hw_index = entry->tcam.ip_type; 4072 rv = BCM_E_NONE; 4073 break; 4074 default: 4075 rv = BCM_E_PARAM; 4076 } 4077 4078 return rv; 4079 } 4080 4081 /* 4082 * Function: 4083 * _bcm_field_th_class_entry_hwinstall 4084 * Purpose: 4085 * Install Class Entry In Hardware. 4086 * Parameters: 4087 * unit - (IN) BCM device number. 4088 * entry - (IN) Field Entry Info. 4089 * ctype - (IN) Field Class Type. 4090 * Returns: 4091 * BCM_E_XXX 4092 */ 4093 int 4094 _bcm_field_th_class_entry_hwinstall(int unit, _field_entry_t *entry, 4095 _field_class_type_t ctype) 4096 { 4097 int rv = BCM_E_NONE; /* Operation Return Status */ 4098 4099 /* Input Parameter Check */ 4100 if ((entry == NULL) || 4101 (entry->group == NULL) || 4102 (entry->tcam.key == NULL)) { 4103 return (BCM_E_INTERNAL); 4104 } 4105 4106 switch (ctype) { 4107 case _FieldClassEtherType: 4108 rv = _field_th_class_ethertype_install(unit,entry); 4109 break; 4110 case _FieldClassL4SrcPort: 4111 rv = _field_th_class_l4srcport_install(unit,entry); 4112 break; 4113 case _FieldClassL4DstPort: 4114 rv = _field_th_class_l4dstport_install(unit,entry); 4115 break; 4116 case _FieldClassSrcCompression: 4117 rv = _field_th_class_srccompression_install(unit,entry); 4118 break; 4119 case _FieldClassDstCompression: 4120 rv = _field_th_class_dstcompression_install(unit,entry); 4121 break; 4122 case _FieldClassTtl: 4123 rv = _field_th_class_ttl_install(unit,entry); 4124 break; 4125 case _FieldClassToS: 4126 rv = _field_th_class_tos_install(unit,entry); 4127 break; 4128 case _FieldClassIpProto: 4129 rv = _field_th_class_ipproto_install(unit,entry); 4130 break; 4131 case _FieldClassTcp: 4132 rv = _field_th_class_tcp_install(unit,entry); 4133 break; 4134 case _FieldClassIpTunnelTtl: 4135 rv = _field_th_class_iptunnelttl_install(unit,entry); 4136 break; 4137 default: 4138 rv = BCM_E_PARAM; 4139 } 4140 4141 return rv; 4142 } 4143 4144 /* 4145 * Function: 4146 * _bcm_field_th_class_entry_hwread. 4147 * Purpose: 4148 * Read Class Entry From Hardware. 4149 * Parameters: 4150 * unit - (IN) BCM device number. 4151 * entry - (IN) Field Entry Info. 4152 * ctype - (IN) Field Class Type. 4153 * cdata - (OUT) Field Class Entry DataBuffer. 4154 * Returns: 4155 * BCM_E_XXX 4156 */ 4157 int 4158 _bcm_field_th_class_entry_hwread(int unit, _field_entry_t *entry, 4159 _field_class_type_t ctype, 4160 uint32 *cdata) 4161 { 4162 int rv = BCM_E_NONE; /* Operation Return Status */ 4163 4164 /* Input Parameter Check */ 4165 if ((entry == NULL) || 4166 (entry->group == NULL) || 4167 (cdata == NULL)) { 4168 return (BCM_E_INTERNAL); 4169 } 4170 4171 /* Read based on class type */ 4172 switch (ctype) { 4173 case _FieldClassEtherType: 4174 rv = _field_th_class_ethertype_read(unit,entry,cdata); 4175 break; 4176 case _FieldClassL4SrcPort: 4177 rv = _field_th_class_l4srcport_read(unit,entry,cdata); 4178 break; 4179 case _FieldClassL4DstPort: 4180 rv = _field_th_class_l4dstport_read(unit,entry,cdata); 4181 break; 4182 case _FieldClassSrcCompression: 4183 rv = _field_th_class_srccompression_read(unit,entry,cdata); 4184 break; 4185 case _FieldClassDstCompression: 4186 rv = _field_th_class_dstcompression_read(unit,entry,cdata); 4187 break; 4188 case _FieldClassTtl: 4189 rv = _field_th_class_ttl_read(unit,entry,cdata); 4190 break; 4191 case _FieldClassToS: 4192 rv = _field_th_class_tos_read(unit,entry,cdata); 4193 break; 4194 case _FieldClassIpProto: 4195 rv = _field_th_class_ipproto_read(unit,entry,cdata); 4196 break; 4197 case _FieldClassTcp: 4198 rv = _field_th_class_tcp_read(unit,entry,cdata); 4199 break; 4200 case _FieldClassIpTunnelTtl: 4201 rv = _field_th_class_iptunnelttl_read(unit,entry,cdata); 4202 break; 4203 default: 4204 rv = BCM_E_PARAM; 4205 } 4206 4207 return rv; 4208 } 4209 4210 /* 4211 * Function: 4212 * _field_th_class_ethertype_install 4213 * Purpose: 4214 * Install EtherType Class Entry In Hardware. 4215 * Parameters: 4216 * unit - (IN) BCM device number. 4217 * entry - (IN) Field Entry Info. 4218 * Returns: 4219 * BCM_E_XXX: 4220 * Notes: 4221 * No Null Check for entry, group and key. 4222 * Done by calling function _bcm_field_th_class_entry_hwinstall 4223 * entry->slice_idx contains index to write 4224 * entry->tcam.key contains data to write 4225 */ 4226 STATIC int 4227 _field_th_class_ethertype_install(int unit, _field_entry_t *entry) 4228 { 4229 int rv = BCM_E_NONE; /* Operation Return Status */ 4230 _field_group_t *fg = NULL; 4231 /* Field group info */ 4232 _field_stage_t *stage_fc = NULL; 4233 /* Stage field control info */ 4234 uint32 rval = 0; /* Register Value */ 4235 soc_reg_t reg; /* SOC Register */ 4236 uint32 *cdata = NULL; /* Class Data */ 4237 4238 /* Get class data key and group info */ 4239 cdata = entry->tcam.key; 4240 fg = entry->group; 4241 4242 /* Get Class Data Value */ 4243 rval = *cdata; 4244 4245 /* Get group stage control structure. */ 4246 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4247 if (BCM_FAILURE(rv)) { 4248 LOG_ERROR(BSL_LS_BCM_FP, 4249 (BSL_META_U(unit, 4250 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4251 unit, fg->stage_id)); 4252 return (rv); 4253 } 4254 4255 /* Decide register based on operational mode */ 4256 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4257 reg = ETHERTYPE_MAPr; 4258 } else { 4259 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 4260 ETHERTYPE_MAPr, 4261 fg->instance, 4262 ®)); 4263 } 4264 4265 /* Write Register */ 4266 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, 4267 REG_PORT_ANY, entry->slice_idx, rval)); 4268 4269 return (rv); 4270 } 4271 4272 /* 4273 * Function: 4274 * _field_th_class_ethertype_read 4275 * Purpose: 4276 * Read EtherType Class Entry From Hardware. 4277 * Parameters: 4278 * unit - (IN) BCM device number. 4279 * entry - (IN) Field Entry Info. 4280 * cdata - (OUT) Field Class Entry DataBuffer. 4281 * Returns: 4282 * BCM_E_XXX 4283 * Notes: 4284 * No Null Check for entry, group and classdata buffer. 4285 * Done by calling function _bcm_field_th_class_entry_hwread 4286 * entry->slice_idx contains index to read 4287 * cdata contains data read from hardware. 4288 */ 4289 STATIC int 4290 _field_th_class_ethertype_read(int unit, _field_entry_t *entry, 4291 uint32 *cdata) 4292 { 4293 int rv = BCM_E_NONE; /* Operation Return Status */ 4294 _field_group_t *fg = NULL; 4295 /* Field group info */ 4296 _field_stage_t *stage_fc = NULL; 4297 /* Stage field control info */ 4298 soc_reg_t reg; /* SOC Register */ 4299 4300 /* Get class group info */ 4301 fg = entry->group; 4302 4303 /* Get group stage control structure. */ 4304 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4305 if (BCM_FAILURE(rv)) { 4306 LOG_ERROR(BSL_LS_BCM_FP, 4307 (BSL_META_U(unit, 4308 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4309 unit, fg->stage_id)); 4310 return (rv); 4311 } 4312 4313 /* Decide register based on operational mode */ 4314 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4315 reg = ETHERTYPE_MAPr; 4316 } else { 4317 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 4318 ETHERTYPE_MAPr, 4319 fg->instance, 4320 ®)); 4321 } 4322 4323 /* Read Register */ 4324 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, 4325 REG_PORT_ANY, entry->slice_idx, cdata)); 4326 4327 return (rv); 4328 } 4329 4330 /* 4331 * Function: 4332 * _field_th_class_l4srcport_install 4333 * Purpose: 4334 * Install L4 Src port Class Entry In Hardware. 4335 * Parameters: 4336 * unit - (IN) BCM device number. 4337 * entry - (IN) Field Entry Info. 4338 * Returns: 4339 * BCM_E_XXX 4340 * Notes: 4341 * No Null Check for entry, group and key. 4342 * Done by calling function _bcm_field_th_class_entry_hwinstall 4343 * entry->slice_idx contains index to write 4344 * entry->tcam.key contains data to write 4345 */ 4346 STATIC int 4347 _field_th_class_l4srcport_install(int unit, _field_entry_t *entry) 4348 { 4349 int rv = BCM_E_NONE; /* Operation Return Status */ 4350 _field_group_t *fg = NULL; 4351 /* Field group info */ 4352 _field_stage_t *stage_fc = NULL; 4353 /* Stage field control info */ 4354 uint32 rval = 0; /* Register Value */ 4355 soc_reg_t reg; /* SOC Register */ 4356 uint32 *cdata = NULL; /* Class Data */ 4357 4358 /* Get class data key and group info */ 4359 cdata = entry->tcam.key; 4360 fg = entry->group; 4361 4362 /* Get Class Data Value */ 4363 rval = *cdata; 4364 4365 /* Get group stage control structure. */ 4366 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4367 if (BCM_FAILURE(rv)) { 4368 LOG_ERROR(BSL_LS_BCM_FP, 4369 (BSL_META_U(unit, 4370 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4371 unit, fg->stage_id)); 4372 return (rv); 4373 } 4374 4375 /* Decide register based on operational mode */ 4376 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4377 reg = L4_SRC_PORT_MAPr; 4378 } else { 4379 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 4380 L4_SRC_PORT_MAPr, 4381 fg->instance, 4382 ®)); 4383 4384 } 4385 4386 /* Write Register */ 4387 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 4388 entry->slice_idx, rval)); 4389 4390 return (rv); 4391 } 4392 4393 /* 4394 * Function: 4395 * _field_th_class_l4srcport_read 4396 * Purpose: 4397 * Read L4 Src port Class Entry From Hardware. 4398 * Parameters: 4399 * unit - (IN) BCM device number. 4400 * entry - (IN) Field Entry Info. 4401 * cdata - (OUT) Field Class Entry DataBuffer. 4402 * Returns: 4403 * BCM_E_XXX 4404 * Notes: 4405 * No Null Check for entry, group and classdata buffer. 4406 * Done by calling function _bcm_field_th_class_entry_hwread 4407 * entry->slice_idx contains index to read 4408 * cdata contains data read from hardware. 4409 */ 4410 STATIC int 4411 _field_th_class_l4srcport_read(int unit, _field_entry_t *entry, 4412 uint32 *cdata) 4413 { 4414 int rv = BCM_E_NONE; /* Operation Return Status */ 4415 _field_group_t *fg = NULL; 4416 /* Field group info */ 4417 _field_stage_t *stage_fc = NULL; 4418 /* Stage field control info */ 4419 soc_reg_t reg; /* SOC Register */ 4420 4421 4422 /* Get class group info */ 4423 fg = entry->group; 4424 4425 /* Get group stage control structure. */ 4426 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4427 if (BCM_FAILURE(rv)) { 4428 LOG_ERROR(BSL_LS_BCM_FP, 4429 (BSL_META_U(unit, 4430 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4431 unit, fg->stage_id)); 4432 return (rv); 4433 } 4434 4435 /* Decide register based on operational mode */ 4436 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4437 reg = L4_SRC_PORT_MAPr; 4438 } else { 4439 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 4440 L4_SRC_PORT_MAPr, 4441 fg->instance, 4442 ®)); 4443 4444 } 4445 4446 /* Read Register */ 4447 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 4448 entry->slice_idx, cdata)); 4449 4450 return (rv); 4451 } 4452 4453 /* 4454 * Function: 4455 * _field_th_class_l4dstport_install 4456 * Purpose: 4457 * Install L4 Dst Port Class Entry In Hardware. 4458 * Parameters: 4459 * unit - (IN) BCM device number. 4460 * entry - (IN) Field Entry Info. 4461 * Returns: 4462 * BCM_E_XXX 4463 * Notes: 4464 * No Null Check for entry , group and key. 4465 * Done by calling function _bcm_field_th_class_entry_hwinstall 4466 * entry->slice_idx contains index to write 4467 * entry->tcam.key contains data to write 4468 */ 4469 STATIC int 4470 _field_th_class_l4dstport_install(int unit, _field_entry_t *entry) 4471 { 4472 int rv = BCM_E_NONE; /* Operation Return Status */ 4473 _field_group_t *fg = NULL; 4474 /* Field group info */ 4475 _field_stage_t *stage_fc = NULL; 4476 /* Stage field control info */ 4477 uint32 rval = 0; /* Register Value */ 4478 soc_reg_t reg; /* SOC Register */ 4479 uint32 *cdata = NULL; /* Class Data */ 4480 4481 /* Get class data key and group info */ 4482 cdata = entry->tcam.key; 4483 fg = entry->group; 4484 4485 /* Get Class Data Value */ 4486 rval = *cdata; 4487 4488 /* Get group stage control structure. */ 4489 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4490 if (BCM_FAILURE(rv)) { 4491 LOG_ERROR(BSL_LS_BCM_FP, 4492 (BSL_META_U(unit, 4493 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4494 unit, fg->stage_id)); 4495 return (rv); 4496 } 4497 4498 /* Decide register based on operational mode */ 4499 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4500 reg = L4_DST_PORT_MAPr; 4501 } else { 4502 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 4503 L4_DST_PORT_MAPr, 4504 fg->instance, 4505 ®)); 4506 } 4507 4508 /* Write Register */ 4509 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 4510 entry->slice_idx, rval)); 4511 4512 return (rv); 4513 } 4514 4515 /* 4516 * Function: 4517 * _field_th_class_l4dstport_read 4518 * Purpose: 4519 * Read L4 Dst Port Class Entry From Hardware. 4520 * Parameters: 4521 * unit - (IN) BCM device number. 4522 * entry - (IN) Field Entry Info. 4523 * cdata - (OUT) Field Class Entry DataBuffer. 4524 * Returns: 4525 * BCM_E_XXX 4526 * Notes: 4527 * No Null Check for entry, group and classdata buffer. 4528 * Done by calling function _bcm_field_th_class_entry_hwread 4529 * entry->slice_idx contains index to read 4530 * cdata contains data read from hardware. 4531 */ 4532 STATIC int 4533 _field_th_class_l4dstport_read(int unit, _field_entry_t *entry, 4534 uint32 *cdata) 4535 { 4536 int rv = BCM_E_NONE; /* Operation Return Status */ 4537 _field_group_t *fg = NULL; 4538 /* Field group info */ 4539 _field_stage_t *stage_fc = NULL; 4540 /* Stage field control info */ 4541 soc_reg_t reg; /* SOC Register */ 4542 4543 /* Get class group info */ 4544 fg = entry->group; 4545 4546 /* Get group stage control structure. */ 4547 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4548 if (BCM_FAILURE(rv)) { 4549 LOG_ERROR(BSL_LS_BCM_FP, 4550 (BSL_META_U(unit, 4551 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4552 unit, fg->stage_id)); 4553 return (rv); 4554 } 4555 4556 /* Decide register based on operational mode */ 4557 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4558 reg = L4_DST_PORT_MAPr; 4559 } else { 4560 BCM_IF_ERROR_RETURN(_bcm_field_reg_instance_get(unit, 4561 L4_DST_PORT_MAPr, 4562 fg->instance, 4563 ®)); 4564 } 4565 4566 /* Read Register */ 4567 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 4568 entry->slice_idx, cdata)); 4569 4570 return (rv); 4571 } 4572 4573 /* 4574 * Function: 4575 * _field_th_class_srccompression_install 4576 * Purpose: 4577 * Install Src Compression Class Entry In Hardware. 4578 * Parameters: 4579 * unit - (IN) BCM device number. 4580 * entry - (IN) Field Entry Info. 4581 * Returns: 4582 * BCM_E_XXX 4583 * Notes: 4584 * No Null Check for entry , group and key. 4585 * Done by calling function _bcm_field_th_class_entry_hwinstall 4586 * entry->slice_idx contains index to write 4587 * entry->tcam.key contains data to write 4588 */ 4589 STATIC int 4590 _field_th_class_srccompression_install(int unit, _field_entry_t *entry) 4591 { 4592 int rv = BCM_E_NONE; /* Operation Return Status */ 4593 _field_group_t *fg = NULL; 4594 /* Field group info */ 4595 _field_stage_t *stage_fc = NULL; 4596 /* Stage field control info */ 4597 soc_mem_t mem; /* SOC Memory */ 4598 4599 /* Get class group info */ 4600 fg = entry->group; 4601 4602 /* Get group stage control structure. */ 4603 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4604 if (BCM_FAILURE(rv)) { 4605 LOG_ERROR(BSL_LS_BCM_FP, 4606 (BSL_META_U(unit, 4607 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4608 unit, fg->stage_id)); 4609 return (rv); 4610 } 4611 4612 /* Decide register based on operational mode */ 4613 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4614 mem = SRC_COMPRESSIONm; 4615 } else { 4616 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4617 SRC_COMPRESSIONm, 4618 fg->instance, 4619 &mem)); 4620 } 4621 4622 /* Write Memory */ 4623 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 4624 entry->slice_idx, entry->tcam.key)); 4625 4626 return (rv); 4627 } 4628 4629 /* 4630 * Function: 4631 * _field_th_class_srccompression_read 4632 * Purpose: 4633 * Read Src Compression Class Entry From Hardware. 4634 * Parameters: 4635 * unit - (IN) BCM device number. 4636 * entry - (IN) Field Entry Info. 4637 * cdata - (OUT) Field Class Entry DataBuffer. 4638 * Returns: 4639 * BCM_E_XXX 4640 * Notes: 4641 * No Null Check for entry, group and classdata buffer. 4642 * Done by calling function _bcm_field_th_class_entry_hwread 4643 * entry->slice_idx contains index to read 4644 * cdata contains data read from hardware. 4645 */ 4646 STATIC int 4647 _field_th_class_srccompression_read(int unit, _field_entry_t *entry, 4648 uint32 *cdata) 4649 { 4650 int rv = BCM_E_NONE; /* Operation Return Status */ 4651 _field_group_t *fg = NULL; 4652 /* Field group info */ 4653 _field_stage_t *stage_fc = NULL; 4654 /* Stage field control info */ 4655 soc_mem_t mem; /* SOC Memory */ 4656 4657 /* Get class group info */ 4658 fg = entry->group; 4659 4660 /* Get group stage control structure. */ 4661 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4662 if (BCM_FAILURE(rv)) { 4663 LOG_ERROR(BSL_LS_BCM_FP, 4664 (BSL_META_U(unit, 4665 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4666 unit, fg->stage_id)); 4667 return (rv); 4668 } 4669 4670 /* Decide register based on operational mode */ 4671 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4672 mem = SRC_COMPRESSIONm; 4673 } else { 4674 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4675 SRC_COMPRESSIONm, 4676 fg->instance, 4677 &mem)); 4678 } 4679 4680 /* Read Memory */ 4681 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 4682 entry->slice_idx, cdata)); 4683 4684 return (rv); 4685 } 4686 4687 /* 4688 * Function: 4689 * _field_th_class_dstcompression_install 4690 * Purpose: 4691 * Install Dst Compression Class Entry In Hardware. 4692 * Parameters: 4693 * unit - (IN) BCM device number. 4694 * entry - (IN) Field Entry Info. 4695 * Returns: 4696 * BCM_E_XXX 4697 * Notes: 4698 * No Null Check for entry , group and key. 4699 * Done by calling function _bcm_field_th_class_entry_hwinstall 4700 * entry->slice_idx contains index to write 4701 * entry->tcam.key contains data to write 4702 */ 4703 STATIC int 4704 _field_th_class_dstcompression_install(int unit, _field_entry_t *entry) 4705 { 4706 int rv = BCM_E_NONE; /* Operation Return Status */ 4707 _field_group_t *fg = NULL; 4708 /* Field group info */ 4709 _field_stage_t *stage_fc = NULL; 4710 /* Stage field control info */ 4711 soc_mem_t mem; /* SOC Memory */ 4712 4713 /* Get class group info */ 4714 fg = entry->group; 4715 4716 /* Get group stage control structure. */ 4717 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4718 if (BCM_FAILURE(rv)) { 4719 LOG_ERROR(BSL_LS_BCM_FP, 4720 (BSL_META_U(unit, 4721 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4722 unit, fg->stage_id)); 4723 return (rv); 4724 } 4725 4726 /* Decide register based on operational mode */ 4727 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4728 mem = DST_COMPRESSIONm; 4729 } else { 4730 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4731 DST_COMPRESSIONm, 4732 fg->instance, 4733 &mem)); 4734 } 4735 4736 /* Write Memory */ 4737 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 4738 entry->slice_idx, entry->tcam.key)); 4739 4740 return (rv); 4741 } 4742 4743 /* 4744 * Function: 4745 * _field_th_class_dstcompression_read 4746 * Purpose: 4747 * Read Dst Compression Class Entry From Hardware. 4748 * Parameters: 4749 * unit - (IN) BCM device number. 4750 * entry - (IN) Field Entry Info. 4751 * cdata - (OUT) Field Class Entry DataBuffer. 4752 * Returns: 4753 * BCM_E_XXX 4754 * Notes: 4755 * No Null Check for entry, group and classdata buffer. 4756 * Done by calling function _bcm_field_th_class_entry_hwread 4757 * entry->slice_idx contains index to read 4758 * cdata contains data read from hardware. 4759 */ 4760 STATIC int 4761 _field_th_class_dstcompression_read(int unit, _field_entry_t *entry, 4762 uint32 *cdata) 4763 { 4764 int rv = BCM_E_NONE; /* Operation Return Status */ 4765 _field_group_t *fg = NULL; 4766 /* Field group info */ 4767 _field_stage_t *stage_fc = NULL; 4768 /* Stage field control info */ 4769 soc_mem_t mem; /* SOC Memory */ 4770 4771 /* Get class group info */ 4772 fg = entry->group; 4773 4774 /* Get group stage control structure. */ 4775 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4776 if (BCM_FAILURE(rv)) { 4777 LOG_ERROR(BSL_LS_BCM_FP, 4778 (BSL_META_U(unit, 4779 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4780 unit, fg->stage_id)); 4781 return (rv); 4782 } 4783 4784 /* Decide register based on operational mode */ 4785 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4786 mem = DST_COMPRESSIONm; 4787 } else { 4788 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4789 DST_COMPRESSIONm, 4790 fg->instance, 4791 &mem)); 4792 } 4793 4794 /* Read Memory */ 4795 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 4796 entry->slice_idx, cdata)); 4797 4798 return (rv); 4799 } 4800 4801 /* 4802 * Function: 4803 * _field_th_class_ttl_install 4804 * Purpose: 4805 * Install TTL Class Entry In Hardware. 4806 * Parameters: 4807 * unit - (IN) BCM device number. 4808 * entry - (IN) Field Entry Info. 4809 * Returns: 4810 * BCM_E_XXX 4811 * Notes: 4812 * No Null Check for entry, group and key. 4813 * Done by calling function _bcm_field_th_class_entry_hwinstall 4814 * entry->slice_idx contains index to write 4815 * entry->tcam.key contains data to write 4816 */ 4817 STATIC int 4818 _field_th_class_ttl_install(int unit, _field_entry_t *entry) 4819 { 4820 int rv = BCM_E_NONE; /* Operation Return Status */ 4821 _field_group_t *fg = NULL; 4822 /* Field group info */ 4823 _field_stage_t *stage_fc = NULL; 4824 /* Stage field control info */ 4825 soc_mem_t mem; /* SOC Memory */ 4826 4827 /* Get class group info */ 4828 fg = entry->group; 4829 4830 /* Get group stage control structure. */ 4831 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4832 if (BCM_FAILURE(rv)) { 4833 LOG_ERROR(BSL_LS_BCM_FP, 4834 (BSL_META_U(unit, 4835 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4836 unit, fg->stage_id)); 4837 return (rv); 4838 } 4839 4840 /* Decide register based on operational mode */ 4841 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4842 mem = TTL_FNm; 4843 } else { 4844 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4845 TTL_FNm, 4846 fg->instance, 4847 &mem)); 4848 } 4849 4850 /* Write Memory */ 4851 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 4852 entry->slice_idx, entry->tcam.key)); 4853 4854 return (rv); 4855 } 4856 4857 /* 4858 * Function: 4859 * _field_th_class_ttl_read 4860 * Purpose: 4861 * Read TTL Class Entry From Hardware. 4862 * Parameters: 4863 * unit - (IN) BCM device number. 4864 * entry - (IN) Field Entry Info. 4865 * cdata - (OUT) Field Class Entry DataBuffer. 4866 * Returns: 4867 * BCM_E_XXX 4868 * Notes: 4869 * No Null Check for entry, group and classdata buffer. 4870 * Done by calling function _bcm_field_th_class_entry_hwread 4871 * entry->slice_idx contains index to read 4872 * cdata contains data read from hardware. 4873 */ 4874 STATIC int 4875 _field_th_class_ttl_read(int unit, _field_entry_t *entry, 4876 uint32 *cdata) 4877 { 4878 int rv = BCM_E_NONE; /* Operation Return Status */ 4879 _field_group_t *fg = NULL; 4880 /* Field group info */ 4881 _field_stage_t *stage_fc = NULL; 4882 /* Stage field control info */ 4883 soc_mem_t mem; /* SOC Memory */ 4884 4885 /* Get class group info */ 4886 fg = entry->group; 4887 4888 /* Get group stage control structure. */ 4889 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4890 if (BCM_FAILURE(rv)) { 4891 LOG_ERROR(BSL_LS_BCM_FP, 4892 (BSL_META_U(unit, 4893 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4894 unit, fg->stage_id)); 4895 return (rv); 4896 } 4897 4898 /* Decide register based on operational mode */ 4899 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4900 mem = TTL_FNm; 4901 } else { 4902 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4903 TTL_FNm, 4904 fg->instance, 4905 &mem)); 4906 } 4907 4908 /* Read Memory */ 4909 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 4910 entry->slice_idx, cdata)); 4911 4912 return (rv); 4913 } 4914 4915 /* 4916 * Function: 4917 * _field_th_class_tos_install 4918 * Purpose: 4919 * Install TOS Class Entry In Hardware. 4920 * Parameters: 4921 * unit - (IN) BCM device number. 4922 * entry - (IN) Field Entry Info. 4923 * Returns: 4924 * BCM_E_XXX 4925 * Notes: 4926 * No Null Check for entry, group and key. 4927 * Done by calling function _bcm_field_th_class_entry_hwinstall 4928 * entry->slice_idx contains index to write 4929 * entry->tcam.key contains data to write 4930 */ 4931 STATIC int 4932 _field_th_class_tos_install(int unit, _field_entry_t *entry) 4933 { 4934 int rv = BCM_E_NONE; /* Operation Return Status */ 4935 _field_group_t *fg = NULL; 4936 /* Field group info */ 4937 _field_stage_t *stage_fc = NULL; 4938 /* Stage field control info */ 4939 soc_mem_t mem; /* SOC Memory */ 4940 4941 /* Get class group info */ 4942 fg = entry->group; 4943 4944 /* Get group stage control structure. */ 4945 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 4946 if (BCM_FAILURE(rv)) { 4947 LOG_ERROR(BSL_LS_BCM_FP, 4948 (BSL_META_U(unit, 4949 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 4950 unit, fg->stage_id)); 4951 return (rv); 4952 } 4953 4954 /* Decide register based on operational mode */ 4955 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 4956 mem = TOS_FNm; 4957 } else { 4958 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 4959 TOS_FNm, 4960 fg->instance, 4961 &mem)); 4962 } 4963 4964 /* Write Memory */ 4965 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 4966 entry->slice_idx, entry->tcam.key)); 4967 4968 return (rv); 4969 } 4970 4971 /* 4972 * Function: 4973 * _field_th_class_tos_read 4974 * Purpose: 4975 * Read TOS Class Entry From Hardware. 4976 * Parameters: 4977 * unit - (IN) BCM device number. 4978 * entry - (IN) Field Entry Info. 4979 * cdata - (OUT) Field Class Entry DataBuffer. 4980 * Returns: 4981 * BCM_E_XXX 4982 * Notes: 4983 * No Null Check for entry, group and classdata buffer. 4984 * Done by calling function _bcm_field_th_class_entry_hwread 4985 * entry->slice_idx contains index to read 4986 * cdata contains data read from hardware. 4987 */ 4988 STATIC int 4989 _field_th_class_tos_read(int unit, _field_entry_t *entry, 4990 uint32 *cdata) 4991 { 4992 int rv = BCM_E_NONE; /* Operation Return Status */ 4993 _field_group_t *fg = NULL; 4994 /* Field group info */ 4995 _field_stage_t *stage_fc = NULL; 4996 /* Stage field control info */ 4997 soc_mem_t mem; /* SOC Memory */ 4998 4999 /* Get class group info */ 5000 fg = entry->group; 5001 5002 /* Get group stage control structure. */ 5003 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5004 if (BCM_FAILURE(rv)) { 5005 LOG_ERROR(BSL_LS_BCM_FP, 5006 (BSL_META_U(unit, 5007 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5008 unit, fg->stage_id)); 5009 return (rv); 5010 } 5011 5012 /* Decide register based on operational mode */ 5013 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5014 mem = TOS_FNm; 5015 } else { 5016 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5017 TOS_FNm, 5018 fg->instance, 5019 &mem)); 5020 5021 } 5022 /* Read Memory */ 5023 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 5024 entry->slice_idx, cdata)); 5025 5026 return (rv); 5027 } 5028 5029 /* 5030 * Function: 5031 * _field_th_class_ipproto_install 5032 * Purpose: 5033 * Install IP Protocol Class Entry In Hardware. 5034 * Parameters: 5035 * unit - (IN) BCM device number. 5036 * entry - (IN) Field Entry Info. 5037 * Returns: 5038 * BCM_E_XXX 5039 * Notes: 5040 * No Null Check for entry , group and key. 5041 * Done by calling function _bcm_field_th_class_entry_hwinstall 5042 * entry->slice_idx contains index to write 5043 * entry->tcam.key contains data to write 5044 */ 5045 STATIC int 5046 _field_th_class_ipproto_install(int unit, _field_entry_t *entry) 5047 { 5048 int rv = BCM_E_NONE; /* Operation Return Status */ 5049 _field_group_t *fg = NULL; 5050 /* Field group info */ 5051 _field_stage_t *stage_fc = NULL; 5052 /* Stage field control info */ 5053 soc_mem_t mem; /* SOC Memory */ 5054 5055 /* Get class group info */ 5056 fg = entry->group; 5057 5058 /* Get group stage control structure. */ 5059 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5060 if (BCM_FAILURE(rv)) { 5061 LOG_ERROR(BSL_LS_BCM_FP, 5062 (BSL_META_U(unit, 5063 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5064 unit, fg->stage_id)); 5065 return (rv); 5066 } 5067 5068 /* Decide register based on operational mode */ 5069 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5070 mem = IP_PROTO_MAPm; 5071 } else { 5072 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5073 IP_PROTO_MAPm, 5074 fg->instance, 5075 &mem)); 5076 } 5077 5078 /* Write Memory */ 5079 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 5080 entry->slice_idx, entry->tcam.key)); 5081 5082 return (rv); 5083 } 5084 5085 /* 5086 * Function: 5087 * _field_th_class_ipproto_read 5088 * Purpose: 5089 * Read IP Protocol Class Entry From Hardware. 5090 * Parameters: 5091 * unit - (IN) BCM device number. 5092 * entry - (IN) Field Entry Info. 5093 * cdata - (OUT) Field Class Entry DataBuffer. 5094 * Returns: 5095 * BCM_E_XXX 5096 * Notes: 5097 * No Null Check for entry, group and classdata buffer. 5098 * Done by calling function _bcm_field_th_class_entry_hwread 5099 * entry->slice_idx contains index to read 5100 * cdata contains data read from hardware. 5101 */ 5102 STATIC int 5103 _field_th_class_ipproto_read(int unit, _field_entry_t *entry, 5104 uint32 *cdata) 5105 { 5106 int rv = BCM_E_NONE; /* Operation Return Status */ 5107 _field_group_t *fg = NULL; 5108 /* Field group info */ 5109 _field_stage_t *stage_fc = NULL; 5110 /* Stage field control info */ 5111 soc_mem_t mem; /* SOC Memory */ 5112 5113 /* Get class group info */ 5114 fg = entry->group; 5115 5116 /* Get group stage control structure. */ 5117 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5118 if (BCM_FAILURE(rv)) { 5119 LOG_ERROR(BSL_LS_BCM_FP, 5120 (BSL_META_U(unit, 5121 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5122 unit, fg->stage_id)); 5123 return (rv); 5124 } 5125 5126 /* Decide register based on operational mode */ 5127 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5128 mem = IP_PROTO_MAPm; 5129 } else { 5130 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5131 IP_PROTO_MAPm, 5132 fg->instance, 5133 &mem)); 5134 } 5135 5136 /* Read Memory */ 5137 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 5138 entry->slice_idx, cdata)); 5139 5140 return (rv); 5141 } 5142 5143 /* 5144 * Function: 5145 * _field_th_class_tcp_install 5146 * Purpose: 5147 * Install TCP Class Entry In Hardware. 5148 * Parameters: 5149 * unit - (IN) BCM device number. 5150 * entry - (IN) Field Entry Info. 5151 * Returns: 5152 * BCM_E_XXX 5153 * Notes: 5154 * No Null Check for entry , group and key. 5155 * Done by calling function _bcm_field_th_class_entry_hwinstall 5156 * entry->slice_idx contains index to write 5157 * entry->tcam.key contains data to write 5158 */ 5159 STATIC int 5160 _field_th_class_tcp_install(int unit, _field_entry_t *entry) 5161 { 5162 int rv = BCM_E_NONE; /* Operation Return Status */ 5163 _field_group_t *fg = NULL; 5164 /* Field group info */ 5165 _field_stage_t *stage_fc = NULL; 5166 /* Stage field control info */ 5167 soc_mem_t mem; /* SOC Memory */ 5168 5169 /* Get class group info */ 5170 fg = entry->group; 5171 5172 /* Get group stage control structure. */ 5173 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5174 if (BCM_FAILURE(rv)) { 5175 LOG_ERROR(BSL_LS_BCM_FP, 5176 (BSL_META_U(unit, 5177 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5178 unit, fg->stage_id)); 5179 return (rv); 5180 } 5181 5182 /* Decide register based on operational mode */ 5183 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5184 mem = TCP_FNm; 5185 } else { 5186 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5187 TCP_FNm, 5188 fg->instance, 5189 &mem)); 5190 } 5191 5192 /* Write Memory */ 5193 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 5194 entry->slice_idx, entry->tcam.key)); 5195 5196 return (rv); 5197 } 5198 5199 /* 5200 * Function: 5201 * _field_th_class_tcp_read 5202 * Purpose: 5203 * Read TCP Class Entry From Hardware. 5204 * Parameters: 5205 * unit - (IN) BCM device number. 5206 * entry - (IN) Field Entry Info. 5207 * cdata - (OUT) Field Class Entry DataBuffer. 5208 * Returns: 5209 * BCM_E_XXX 5210 * Notes: 5211 * No Null Check for entry, group and classdata buffer. 5212 * Done by calling function _bcm_field_th_class_entry_hwread 5213 * entry->slice_idx contains index to read 5214 * cdata contains data read from hardware. 5215 */ 5216 STATIC int 5217 _field_th_class_tcp_read(int unit, _field_entry_t *entry, 5218 uint32 *cdata) 5219 { 5220 int rv = BCM_E_NONE; /* Operation Return Status */ 5221 _field_group_t *fg = NULL; 5222 /* Field group info */ 5223 _field_stage_t *stage_fc = NULL; 5224 /* Stage field control info */ 5225 soc_mem_t mem; /* SOC Memory */ 5226 5227 /* Get class group info */ 5228 fg = entry->group; 5229 5230 /* Get group stage control structure. */ 5231 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5232 if (BCM_FAILURE(rv)) { 5233 LOG_ERROR(BSL_LS_BCM_FP, 5234 (BSL_META_U(unit, 5235 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5236 unit, fg->stage_id)); 5237 return (rv); 5238 } 5239 5240 /* Decide register based on operational mode */ 5241 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5242 mem = TCP_FNm; 5243 } else { 5244 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5245 TCP_FNm, 5246 fg->instance, 5247 &mem)); 5248 } 5249 5250 /* Read Memory */ 5251 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 5252 entry->slice_idx, cdata)); 5253 5254 return (rv); 5255 } 5256 /* 5257 * Function: 5258 * _field_th_class_iptunnelttl_install 5259 * Purpose: 5260 * Install IP Tunnel TTL Class Entry In Hardware. 5261 * Parameters: 5262 * unit - (IN) BCM device number. 5263 * entry - (IN) Field Entry Info. 5264 * Returns: 5265 * BCM_E_XXX 5266 * Notes: 5267 * No Null Check for entry, group and key. 5268 * Done by calling function _bcm_field_th_class_entry_hwinstall 5269 * entry->slice_idx contains index to write 5270 * entry->tcam.key contains data to write 5271 */ 5272 STATIC int 5273 _field_th_class_iptunnelttl_install(int unit, _field_entry_t *entry) 5274 { 5275 int rv = BCM_E_NONE; /* Operation Return Status */ 5276 _field_group_t *fg = NULL; 5277 /* Field group info */ 5278 _field_stage_t *stage_fc = NULL; 5279 /* Stage field control info */ 5280 soc_mem_t mem; /* SOC Memory */ 5281 5282 /* Get class group info */ 5283 fg = entry->group; 5284 5285 /* Get group stage control structure. */ 5286 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5287 if (BCM_FAILURE(rv)) { 5288 LOG_ERROR(BSL_LS_BCM_FP, 5289 (BSL_META_U(unit, 5290 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5291 unit, fg->stage_id)); 5292 return (rv); 5293 } 5294 5295 /* Decide register based on operational mode */ 5296 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5297 mem = ALT_TTL_FNm; 5298 } else { 5299 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5300 ALT_TTL_FNm, 5301 fg->instance, 5302 &mem)); 5303 } 5304 5305 /* Write Memory */ 5306 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 5307 entry->slice_idx, entry->tcam.key)); 5308 5309 return (rv); 5310 } 5311 5312 /* 5313 * Function: 5314 * _field_th_class_iptunnelttl_read 5315 * Purpose: 5316 * Read Ip Tunnel TTL Class Entry From Hardware. 5317 * Parameters: 5318 * unit - (IN) BCM device number. 5319 * entry - (IN) Field Entry Info. 5320 * cdata - (OUT) Field Class Entry DataBuffer. 5321 * Returns: 5322 * BCM_E_XXX 5323 * Notes: 5324 * No Null Check for entry, group and classdata buffer. 5325 * Done by calling function _bcm_field_th_class_entry_hwread 5326 * entry->slice_idx contains index to read 5327 * cdata contains data read from hardware. 5328 */ 5329 STATIC int 5330 _field_th_class_iptunnelttl_read(int unit, _field_entry_t *entry, 5331 uint32 *cdata) 5332 { 5333 int rv = BCM_E_NONE; /* Operation Return Status */ 5334 _field_group_t *fg = NULL; 5335 /* Field group info */ 5336 _field_stage_t *stage_fc = NULL; 5337 /* Stage field control info */ 5338 soc_mem_t mem; /* SOC Memory */ 5339 5340 /* Get class group info */ 5341 fg = entry->group; 5342 5343 /* Get group stage control structure. */ 5344 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5345 if (BCM_FAILURE(rv)) { 5346 LOG_ERROR(BSL_LS_BCM_FP, 5347 (BSL_META_U(unit, 5348 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5349 unit, fg->stage_id)); 5350 return (rv); 5351 } 5352 5353 /* Decide register based on operational mode */ 5354 if (stage_fc->oper_mode == bcmFieldGroupOperModeGlobal) { 5355 mem = ALT_TTL_FNm; 5356 } else { 5357 BCM_IF_ERROR_RETURN(_bcm_field_mem_instance_get(unit, 5358 ALT_TTL_FNm, 5359 fg->instance, 5360 &mem)); 5361 } 5362 5363 /* Read Memory */ 5364 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 5365 entry->slice_idx, cdata)); 5366 5367 return (rv); 5368 } 5369 5370 5371 /* 5372 * Function: 5373 * _bcm_field_th_class_entry_remove 5374 * Purpose: 5375 * Remove Field Class Entry In Hardware. 5376 * Parameters: 5377 * unit - (IN) BCM device number. 5378 * entry - (IN) Field Entry Id. 5379 * Returns: 5380 * BCM_E_XXX 5381 */ 5382 int 5383 _bcm_field_th_class_entry_remove(int unit, bcm_field_entry_t entry) 5384 { 5385 int rv = BCM_E_NONE; /* Operation Return Status */ 5386 _field_group_t *fg = NULL; /* Field group info */ 5387 _field_entry_t *f_ent = NULL; /* Field entry info */ 5388 _field_class_type_t ctype; /* Field Class Type */ 5389 _field_class_info_t **class_status_arr; 5390 /* Field Per Pipe Class Status Array */ 5391 _field_class_info_t *class_status_info; 5392 /* Field Per Compression table status */ 5393 _field_stage_t *stage_fc = NULL; 5394 /* Stage field control info */ 5395 5396 /* Confirm that 'entry' is present on unit */ 5397 if (BCM_FAILURE(_field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent))) { 5398 LOG_ERROR(BSL_LS_BCM_FP, 5399 (BSL_META_U(unit, 5400 "FP(unit %d) Error: entry=(%d) already exists.\n"), 5401 unit, entry)); 5402 return (BCM_E_EXISTS); 5403 } 5404 5405 /* Retreive Field Group and Action */ 5406 fg = f_ent->group; 5407 5408 /* Check if group is associated */ 5409 if (fg == NULL) { 5410 return (BCM_E_INTERNAL); 5411 } 5412 5413 /* Get group stage control structure. */ 5414 rv = _field_stage_control_get(unit, fg->stage_id, &stage_fc); 5415 if (BCM_FAILURE(rv)) { 5416 LOG_ERROR(BSL_LS_BCM_FP, 5417 (BSL_META_U(unit, 5418 "FP(unit %d) Error: Stage (%d) control get failure.\n"), 5419 unit, fg->stage_id)); 5420 return (rv); 5421 } 5422 5423 /* Entry not installed in hardware to perform remove operation. */ 5424 if (!(f_ent->flags & _FP_ENTRY_INSTALLED)) { 5425 return (BCM_E_NONE); 5426 } 5427 5428 /* Entry hardware index not present */ 5429 if (f_ent->slice_idx == -1) { 5430 return (BCM_E_INTERNAL); 5431 } 5432 5433 /* Retreive Class Type from entry qset */ 5434 rv = _bcm_field_th_class_type_qset_get(unit, &fg->qset, &ctype); 5435 if (BCM_FAILURE(rv)) { 5436 return (rv); 5437 } 5438 5439 if (f_ent->tcam.key != NULL) { 5440 sal_memset(f_ent->tcam.key, 0, f_ent->tcam.key_size); 5441 } else { 5442 _FP_XGS3_ALLOC(f_ent->tcam.key, 5443 f_ent->tcam.key_size, "field class entry key"); 5444 if (f_ent->tcam.key == NULL) { 5445 LOG_ERROR(BSL_LS_BCM_FP, 5446 (BSL_META_U(unit, 5447 "FP(unit %d) Error: allocation failure for " 5448 "class entry key.\n"), 5449 unit)); 5450 return (BCM_E_MEMORY); 5451 } 5452 } 5453 5454 /* Update Class Status Info Structure */ 5455 class_status_arr = stage_fc->class_info_arr[fg->instance]; 5456 if (class_status_arr == NULL) { 5457 return (BCM_E_INTERNAL); 5458 } 5459 class_status_info = class_status_arr[ctype]; 5460 if (class_status_info == NULL) { 5461 return (BCM_E_INTERNAL); 5462 } 5463 5464 rv = _bcm_field_th_class_entry_hwinstall(unit, f_ent, ctype); 5465 if (BCM_FAILURE(rv)) { 5466 return (rv); 5467 } 5468 5469 _FP_CLASS_TABLE_BMP_REMOVE(class_status_info->class_bmp, f_ent->slice_idx); 5470 f_ent->slice_idx = -1; 5471 f_ent->flags &= ~(_FP_ENTRY_INSTALLED); 5472 5473 return (rv); 5474 } 5475 5476 /* 5477 * Function: 5478 * _bcm_field_th_class_qual_support_check 5479 * Purpose: 5480 * Check if the qualifier is supported in the stage class 5481 * Parameters: 5482 * unit - (IN) BCM device number. 5483 * qual - (IN) Qualifier to check. 5484 * Returns: 5485 * TRUE - Qualifier is supported by the stage 5486 * FALSE - Qualifier is NOT supported by the stage 5487 */ 5488 int 5489 _bcm_field_th_class_qual_support_check(int unit, int qual) 5490 { 5491 switch(qual) 5492 { 5493 case bcmFieldQualifyStageClass: 5494 case bcmFieldQualifyIpProtocolClass: 5495 case bcmFieldQualifyEtherTypeClass: 5496 case bcmFieldQualifyL4SrcPortClass: 5497 case bcmFieldQualifyL4DstPortClass: 5498 case bcmFieldQualifySrcIpClass: 5499 case bcmFieldQualifySrcIpClassMsbNibble: 5500 case bcmFieldQualifySrcIpClassLower: 5501 case bcmFieldQualifySrcIpClassUpper: 5502 case bcmFieldQualifySrcIp6Class: 5503 case bcmFieldQualifySrcIp6ClassMsbNibble: 5504 case bcmFieldQualifySrcIp6ClassLower: 5505 case bcmFieldQualifySrcIp6ClassUpper: 5506 case bcmFieldQualifyFcoeOxIDClass: 5507 case bcmFieldQualifyDstIpClassMsbNibble: 5508 case bcmFieldQualifyDstIpClass: 5509 case bcmFieldQualifyDstIpClassLower: 5510 case bcmFieldQualifyDstIpClassUpper: 5511 case bcmFieldQualifyDstIp6Class: 5512 case bcmFieldQualifyDstIp6ClassMsbNibble: 5513 case bcmFieldQualifyDstIp6ClassLower: 5514 case bcmFieldQualifyDstIp6ClassUpper: 5515 case bcmFieldQualifyFcoeRxIDClass: 5516 case bcmFieldQualifyFibreChanSrcIdClass: 5517 case bcmFieldQualifyFibreChanSrcIdClassMsbNibble: 5518 case bcmFieldQualifyFibreChanSrcIdClassLower: 5519 case bcmFieldQualifyFibreChanSrcIdClassUpper: 5520 case bcmFieldQualifyFibreChanDstIdClass: 5521 case bcmFieldQualifyFibreChanDstIdClassMsbNibble: 5522 case bcmFieldQualifyFibreChanDstIdClassLower: 5523 case bcmFieldQualifyFibreChanDstIdClassUpper: 5524 case bcmFieldQualifyTcpClassZero: 5525 case bcmFieldQualifyTosClassZero: 5526 case bcmFieldQualifyTtlClassZero: 5527 case bcmFieldQualifyIpTunnelTtlClassZero: 5528 case bcmFieldQualifyTcpClassOne: 5529 case bcmFieldQualifyTosClassOne: 5530 case bcmFieldQualifyTtlClassOne: 5531 return TRUE; 5532 default: 5533 ; 5534 } 5535 return FALSE; 5536 } 5537 5538 #else /* BCM_TOMAHAWK_SUPPORT && BCM_FIELD_SUPPORT */ 5539 int _th_field_not_empty; 5540 #endif /* !BCM_TOMAHAWK_SUPPORT && !BCM_FIELD_SUPPORT */