oob.c (63178B)
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 * OOB Flow Control 7 * Purpose: API to set different OOB Flow Control and OOB Stats registers. 8 */ 9 #include <sal/core/libc.h> 10 11 #include <shared/bsl.h> 12 #include <soc/defs.h> 13 #include <soc/drv.h> 14 #include <soc/mem.h> 15 16 #if defined(BCM_KATANA2_SUPPORT) 17 #include <soc/profile_mem.h> 18 #include <soc/debug.h> 19 #include <soc/katana2.h> 20 21 #include <bcm/error.h> 22 #include <bcm/oob.h> 23 24 #include <bcm_int/esw/mbcm.h> 25 #include <bcm_int/esw/katana2.h> 26 27 #include <bcm_int/esw_dispatch.h> 28 #include <bcm_int/esw/stat.h> 29 30 #ifdef BCM_WARM_BOOT_SUPPORT 31 #include <bcm_int/esw/switch.h> 32 #endif /* BCM_WARM_BOOT_SUPPORT */ 33 34 #if defined(BCM_METROLITE_SUPPORT) 35 #include <soc/metrolite.h> 36 #endif 37 38 #define BCM_KT2_MMU_NUM_POOL 1 39 /* Number of Traffic Class */ 40 #define BCM_KT2_NUM_TC 8 41 /* Number of OOB FC Rx Interface */ 42 #define BCM_KT2_NUM_OOB_FC_RX_INTF 1 43 /* Maximum Value of Channel Base Value */ 44 #define BCM_KT2_MAX_CHANNEL_BASE 63 45 46 /* Total number of Indexes in OOBFC RX memory */ 47 #define BCM_KT2_MAX_RX_MEM_ENTRY 41 48 #define BCM_SB2_MAX_RX_MEM_ENTRY 29 49 #define BCM_ML_MAX_RX_MEM_ENTRY 13 50 51 typedef struct _bcm_kt2_oob_fc_rx_intf_info_s { 52 uint32 channel_base; /* HCFC channel base */ 53 int enable; /* Interface enable */ 54 uint8 num_ports; /* Number of ports monitored */ 55 uint8 lookup_base; /* Look up base in the OOB FC Rx Memory */ 56 } _bcm_kt2_oob_fc_rx_intf_info_t; 57 58 /* 59 * Function: 60 * _bcm_kt2_oob_fc_tx_config_flags_set 61 * Purpose: 62 * Set OOB FC Tx enable flags 63 * Parameters: 64 * unit - (IN) StrataSwitch unit number. 65 * flags - (IN) OOB FC Tx flags 66 * Returns: 67 * BCM_E_XXX 68 */ 69 STATIC int 70 _bcm_kt2_oob_fc_tx_config_flags_set(int unit, uint32 flags) 71 { 72 uint32 rval = 0; 73 uint64 rval64; 74 uint64 field64; 75 76 COMPILER_64_ZERO(rval64); 77 COMPILER_64_ZERO(field64); 78 79 if (flags & BCM_OOB_FC_TX_FCN_EN) { 80 BCM_IF_ERROR_RETURN 81 (soc_reg32_get(unit, INTFO_FCN_ENr, 0, 0, &rval)); 82 soc_reg_field_set(unit, INTFO_FCN_ENr, &rval, ENf, 0x1); 83 BCM_IF_ERROR_RETURN 84 (soc_reg32_set(unit, INTFO_FCN_ENr, 0, 0, rval)); 85 } else { 86 BCM_IF_ERROR_RETURN 87 (soc_reg32_get(unit, INTFO_FCN_ENr, 0, 0, &rval)); 88 soc_reg_field_set(unit, INTFO_FCN_ENr, &rval, ENf, 0x0); 89 BCM_IF_ERROR_RETURN 90 (soc_reg32_set(unit, INTFO_FCN_ENr, 0, 0, rval)); 91 } 92 93 BCM_IF_ERROR_RETURN 94 (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r, 95 0, 0, &rval64)); 96 if (flags & BCM_OOB_FC_TX_ING_EN) { 97 COMPILER_64_SET(field64, 0, 1); 98 } 99 soc_reg64_field_set(unit, OOBFC_CHANNEL_BASE_64r, &rval64, 100 ING_ENf, field64); 101 102 COMPILER_64_ZERO(field64); 103 if (flags & BCM_OOB_FC_TX_EGR_EN) { 104 COMPILER_64_SET(field64, 0, 1); 105 } 106 soc_reg64_field_set(unit, OOBFC_CHANNEL_BASE_64r, &rval64, 107 ENG_ENf, field64); 108 109 /* pool enable not present */ 110 if (flags & BCM_OOB_FC_TX_POOL_EN) { 111 return BCM_E_PARAM; 112 } 113 BCM_IF_ERROR_RETURN 114 (soc_reg64_set(unit, OOBFC_CHANNEL_BASE_64r, 0, 0, rval64)); 115 return BCM_E_NONE; 116 } 117 118 /* 119 * Function: 120 * _bcm_kt2_oob_fc_tx_config_ipg_set 121 * Purpose: 122 * Set OOB FC Tx inter packet gap 123 * Parameters: 124 * unit - (IN) StrataSwitch unit number. 125 * ipg - (IN) OOB FC Tx inter packet gap 126 * Returns: 127 * BCM_E_XXX 128 */ 129 STATIC int 130 _bcm_kt2_oob_fc_tx_config_ipg_set(int unit, uint8 ipg) 131 { 132 uint32 rval; 133 134 BCM_IF_ERROR_RETURN 135 (soc_reg32_get(unit, OOBFC_TX_IDLEr, 0, 0, &rval)); 136 soc_reg_field_set(unit, OOBFC_TX_IDLEr, &rval, 137 IDLE_GAPf, ipg); 138 BCM_IF_ERROR_RETURN 139 (soc_reg32_set(unit, OOBFC_TX_IDLEr, 0, 0, rval)); 140 return BCM_E_NONE; 141 } 142 143 /* 144 * Function: 145 * _bcm_kt2_oob_fc_tx_config_gcs_id_set 146 * Purpose: 147 * Set OOB FC Tx global congestion reporting 148 * service pool id 149 * Parameters: 150 * unit - (IN) StrataSwitch unit number. 151 * id - (IN) OOB FC Tx global congestion service pool id 152 * Returns: 153 * BCM_E_XXX 154 */ 155 STATIC int 156 _bcm_kt2_oob_fc_tx_config_gcs_id_set(int unit, 157 bcm_service_pool_id_t id) 158 { 159 uint32 rval; 160 161 BCM_IF_ERROR_RETURN 162 (soc_reg32_get(unit, OOBFC_GCSr, 0, 0, &rval)); 163 soc_reg_field_set(unit, OOBFC_GCSr, &rval, 164 GCS_IDf, id); 165 BCM_IF_ERROR_RETURN 166 (soc_reg32_set(unit, OOBFC_GCSr, 0, 0, rval)); 167 168 return BCM_E_NONE; 169 } 170 171 /* 172 * Function: 173 * _bcm_kt2_oob_fc_tx_config_egr_mode_set 174 * Purpose: 175 * Set OOB FC Tx egress congestion reporting mode 176 * Parameters: 177 * unit - (IN) StrataSwitch unit number. 178 * mode - (IN) OOB FC Tx egress congestion reporting mode 179 * Returns: 180 * BCM_E_XXX 181 */ 182 STATIC int 183 _bcm_kt2_oob_fc_tx_config_egr_mode_set(int unit, 184 bcm_oob_egress_mode_t mode) 185 { 186 uint64 rval64; 187 uint64 field64; 188 189 COMPILER_64_ZERO(field64); 190 COMPILER_64_ZERO(rval64); 191 BCM_IF_ERROR_RETURN 192 (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r, 193 0, 0, &rval64)); 194 COMPILER_64_SET(field64, 0, mode); 195 soc_reg64_field_set(unit, OOBFC_CHANNEL_BASE_64r, &rval64, 196 ENG_MODEf, field64); 197 BCM_IF_ERROR_RETURN 198 (soc_reg64_set(unit, OOBFC_CHANNEL_BASE_64r, 199 0, 0, rval64)); 200 201 return BCM_E_NONE; 202 } 203 204 /* 205 * Function: 206 * _bcm_kt2_oob_fc_tx_config_flags_get 207 * Purpose: 208 * Get OOB FC Tx enable status 209 * Parameters: 210 * unit - (IN) StrataSwitch unit number. 211 * config - (OUT) OOB FC Tx configuration 212 * Returns: 213 * BCM_E_XXX 214 */ 215 STATIC int 216 _bcm_kt2_oob_fc_tx_config_flags_get(int unit, 217 bcm_oob_fc_tx_config_t *config) 218 { 219 uint32 rval = 0; 220 uint64 rval64; 221 uint64 regval64; 222 223 COMPILER_64_ZERO(rval64); 224 COMPILER_64_ZERO(regval64); 225 226 config->flags = 0x0; 227 228 BCM_IF_ERROR_RETURN 229 (soc_reg32_get(unit, INTFO_FCN_ENr, 0, 0, &rval)); 230 231 if (soc_reg_field_get(unit, INTFO_FCN_ENr, rval, ENf)) { 232 config->flags |= BCM_OOB_FC_TX_FCN_EN; 233 } 234 235 BCM_IF_ERROR_RETURN 236 (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r, 237 0, 0, &rval64)); 238 239 regval64 = soc_reg64_field_get(unit, OOBFC_CHANNEL_BASE_64r, 240 rval64, ING_ENf); 241 if (!COMPILER_64_IS_ZERO(regval64)) { 242 config->flags |= BCM_OOB_FC_TX_ING_EN; 243 } 244 245 regval64 = soc_reg64_field_get(unit, OOBFC_CHANNEL_BASE_64r, 246 rval64, ENG_ENf); 247 if (!COMPILER_64_IS_ZERO(regval64)) { 248 config->flags |= BCM_OOB_FC_TX_EGR_EN; 249 } 250 return BCM_E_NONE; 251 } 252 253 /* 254 * Function: 255 * _bcm_kt2_oob_fc_tx_config_ipg_get 256 * Purpose: 257 * Get OOB FC Tx inter packet gap 258 * Parameters: 259 * unit - (IN) StrataSwitch unit number. 260 * config - (OUT) OOB FC Tx configuration 261 * Returns: 262 * BCM_E_XXX 263 */ 264 STATIC int 265 _bcm_kt2_oob_fc_tx_config_ipg_get(int unit, 266 bcm_oob_fc_tx_config_t *config) 267 { 268 uint32 rval; 269 270 BCM_IF_ERROR_RETURN 271 (soc_reg32_get(unit, OOBFC_TX_IDLEr, 0, 0, &rval)); 272 273 config->inter_pkt_gap = soc_reg_field_get(unit, OOBFC_TX_IDLEr, 274 rval, IDLE_GAPf); 275 276 return BCM_E_NONE; 277 } 278 279 /* 280 * Function: 281 * _bcm_kt2_oob_fc_tx_config_gcs_id_get 282 * Purpose: 283 * Get OOB FC Tx global congestion reporting 284 * service pool id 285 * Parameters: 286 * unit - (IN) StrataSwitch unit number. 287 * config - (OUT) OOB FC Tx configuration 288 * Returns: 289 * BCM_E_XXX 290 */ 291 STATIC int 292 _bcm_kt2_oob_fc_tx_config_gcs_id_get(int unit, 293 bcm_oob_fc_tx_config_t *config) 294 { 295 uint32 rval; 296 297 BCM_IF_ERROR_RETURN 298 (soc_reg32_get(unit, OOBFC_GCSr, 0, 0, &rval)); 299 300 config->gcs_id = soc_reg_field_get(unit, OOBFC_GCSr, rval, 301 GCS_IDf); 302 303 return BCM_E_NONE; 304 } 305 306 /* 307 * Function: 308 * _bcm_kt2_oob_fc_tx_config_egr_mode_get 309 * Purpose: 310 * Get OOB FC Tx egress congestion reporting mode 311 * Parameters: 312 * unit - (IN) StrataSwitch unit number. 313 * config - (OUT) OOB FC Tx configuration 314 * Returns: 315 * BCM_E_XXX 316 */ 317 STATIC int 318 _bcm_kt2_oob_fc_tx_config_egr_mode_get(int unit, 319 bcm_oob_fc_tx_config_t *config) 320 { 321 uint64 rval64; 322 323 BCM_IF_ERROR_RETURN 324 (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r, 325 0, 0, &rval64)); 326 327 config->egr_mode = soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r, 328 rval64, ENG_MODEf); 329 330 return BCM_E_NONE; 331 } 332 333 /* 334 * Function: 335 * _bcm_kt2_oob_localport_resolve 336 * Purpose: 337 * Get the logical port from modport gport 338 * Parameters: 339 * unit - (IN) StrataSwitch unit number. 340 * gport - (IN) Modport gport. 341 * local_port - (OUT) Logical port number. 342 * Returns: 343 * BCM_E_XXX 344 */ 345 STATIC int 346 _bcm_kt2_oob_localport_resolve(int unit, bcm_gport_t gport, 347 bcm_port_t *local_port) 348 { 349 bcm_module_t module; 350 bcm_port_t port; 351 bcm_trunk_t trunk; 352 int id, result; 353 354 if (!BCM_GPORT_IS_SET(gport)) { 355 if (!SOC_PORT_VALID(unit, gport)) { 356 return BCM_E_PORT; 357 } 358 *local_port = gport; 359 return BCM_E_NONE; 360 } 361 362 BCM_IF_ERROR_RETURN 363 (_bcm_esw_gport_resolve(unit, gport, &module, &port, &trunk, &id)); 364 365 BCM_IF_ERROR_RETURN(_bcm_esw_modid_is_local(unit, module, &result)); 366 if (result == FALSE) { 367 return BCM_E_PARAM; 368 } 369 370 *local_port = port; 371 372 return BCM_E_NONE; 373 } 374 375 /* 376 * Function: 377 * _bcm_kt2_oob_fc_rx_get_intf_info 378 * Purpose: 379 * Get the per OOBFC Rx interface info structure 380 * Parameters: 381 * unit - (IN) StrataSwitch unit number. 382 * info - (OUT) Per OOBFC RX interface info structure. 383 * intf_id - (IN) OOBFC Rx Interface ID. 384 * Returns: 385 * BCM_E_XXX 386 */ 387 STATIC int 388 _bcm_kt2_oob_fc_rx_get_intf_info(int unit, _bcm_kt2_oob_fc_rx_intf_info_t *info, 389 bcm_oob_fc_rx_intf_id_t intf_id) 390 { 391 uint32 rval = 0x0; 392 soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr}; 393 394 BCM_IF_ERROR_RETURN 395 (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval)); 396 397 info->enable = soc_reg_field_get(unit, cfg_reg[intf_id], rval, 398 OOBFC_CH_ENf); 399 if (info->enable == 1) { 400 info->num_ports = soc_reg_field_get(unit, cfg_reg[intf_id], rval, 401 CH_PORT_NUMf); 402 info->lookup_base = soc_reg_field_get(unit, cfg_reg[intf_id], rval, 403 LOOKUP_BASEf); 404 info->channel_base = soc_reg_field_get(unit, cfg_reg[intf_id], rval, 405 OOBFC_CH_BASEf); 406 } 407 return BCM_E_NONE; 408 } 409 410 /* 411 * Function: 412 * _bcm_kt2_oob_fc_rx_disable_intf 413 * Purpose: 414 * Disable OOBFC Rx interface. 415 * Parameters: 416 * unit - (IN) StrataSwitch unit number. 417 * intf_id - (IN) OOBFC Rx Interface ID. 418 * Returns: 419 * BCM_E_XXX 420 */ 421 STATIC int 422 _bcm_kt2_oob_fc_rx_disable_intf(int unit, 423 bcm_oob_fc_rx_intf_id_t intf_id) 424 { 425 uint32 rval = 0x0; 426 soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr}; 427 428 BCM_IF_ERROR_RETURN 429 (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval)); 430 soc_reg_field_set(unit, cfg_reg[intf_id], &rval, 431 OOBFC_CH_ENf, 0); 432 BCM_IF_ERROR_RETURN 433 (soc_reg32_set(unit, cfg_reg[intf_id], 0, 0, rval)); 434 435 return BCM_E_NONE; 436 } 437 438 /* 439 * Function: 440 * _bcm_kt2_oob_fc_rx_enable_intf 441 * Purpose: 442 * Enable OOBFC Rx interface. 443 * Parameters: 444 * unit - (IN) StrataSwitch unit number. 445 * intf_id - (IN) OOBFC Rx Interface ID. 446 * Returns: 447 * BCM_E_XXX 448 */ 449 STATIC int 450 _bcm_kt2_oob_fc_rx_enable_intf(int unit, 451 bcm_oob_fc_rx_intf_id_t intf_id) 452 { 453 uint32 rval = 0x0; 454 soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr}; 455 456 BCM_IF_ERROR_RETURN 457 (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval)); 458 459 soc_reg_field_set(unit, cfg_reg[intf_id], &rval, 460 OOBFC_CH_ENf, 1); 461 BCM_IF_ERROR_RETURN 462 (soc_reg32_set(unit, cfg_reg[intf_id], 0, 0, rval)); 463 464 return BCM_E_NONE; 465 } 466 467 /* 468 * Function: 469 * _bcm_kt2_oob_fc_rx_intf_get_lookup_base 470 * Purpose: 471 * Get the look base in OOBFC Rx Memory for 472 * given OOBFC Rx interface. 473 * Parameters: 474 * unit - (IN) StrataSwitch unit number. 475 * intf_id - (IN) OOBFC Rx Interface ID. 476 * look_base - (OUT) Lookup base in OOBFC Rx Memory 477 * Returns: 478 * BCM_E_XXX 479 */ 480 STATIC int 481 _bcm_kt2_oob_fc_rx_intf_get_lookup_base(int unit, 482 bcm_oob_fc_rx_intf_id_t intf_id, 483 uint32 *lookup_base) 484 { 485 uint32 rval = 0x0; 486 soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr}; 487 488 BCM_IF_ERROR_RETURN 489 (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval)); 490 491 *lookup_base = soc_reg_field_get(unit, cfg_reg[intf_id], rval, 492 LOOKUP_BASEf); 493 494 return BCM_E_NONE; 495 } 496 497 498 /* 499 * Function: 500 * bcm_kt2_oob_fc_tx_config_set 501 * Purpose: 502 * Set OOB FC Tx global configuration. 503 * Parameters: 504 * unit - (IN) StrataSwitch unit number. 505 * config - (IN) OOB FC Tx global configuration 506 * Returns: 507 * BCM_E_XXX 508 */ 509 int 510 bcm_kt2_oob_fc_tx_config_set(int unit, 511 bcm_oob_fc_tx_config_t *config) 512 { 513 if (config == NULL) { 514 return BCM_E_PARAM; 515 } 516 517 if ((config->gcs_id < 0) || (config->gcs_id >= BCM_KT2_MMU_NUM_POOL)) { 518 return BCM_E_PARAM; 519 } 520 521 if ((config->egr_mode < 0) || (config->egr_mode >= bcmOOBFCTxReportCount)) { 522 return BCM_E_PARAM; 523 } 524 525 /* Enabling/Disabling FCN, OOBFC Tx Ingress, Egress and Service Pool */ 526 BCM_IF_ERROR_RETURN 527 (_bcm_kt2_oob_fc_tx_config_flags_set(unit, config->flags)); 528 529 /* Setting Inter packet Gap between two HCFC message */ 530 BCM_IF_ERROR_RETURN 531 (_bcm_kt2_oob_fc_tx_config_ipg_set(unit, config->inter_pkt_gap)); 532 533 /* Setting service pool id whose congestion state will be 534 reported in every HCFC message */ 535 BCM_IF_ERROR_RETURN 536 (_bcm_kt2_oob_fc_tx_config_gcs_id_set(unit, config->gcs_id)); 537 538 /* Setting Egress mode for reporting OOBFC message. */ 539 BCM_IF_ERROR_RETURN 540 (_bcm_kt2_oob_fc_tx_config_egr_mode_set(unit, config->egr_mode)); 541 542 return BCM_E_NONE; 543 } 544 545 /* 546 * Function: 547 * bcm_kt2_oob_fc_tx_config_get 548 * Purpose: 549 * Get OOB FC Tx global configuration. 550 * Parameters: 551 * unit - (IN) StrataSwitch unit number. 552 * config - (OUT) OOB FC Tx global configuration 553 * Returns: 554 * BCM_E_XXX 555 */ 556 int 557 bcm_kt2_oob_fc_tx_config_get(int unit, 558 bcm_oob_fc_tx_config_t *config) 559 { 560 if (config == NULL) { 561 return BCM_E_PARAM; 562 } 563 564 /* Get the congestion state reporting status of FCN, 565 OOBFC Tx Ingress, Egress and Service Pool */ 566 BCM_IF_ERROR_RETURN 567 (_bcm_kt2_oob_fc_tx_config_flags_get(unit, config)); 568 569 /* Get the configured Inter Packet Gap between OOBFC Tx message.*/ 570 BCM_IF_ERROR_RETURN 571 (_bcm_kt2_oob_fc_tx_config_ipg_get(unit, config)); 572 573 /* Setting service pool id whose congestion state will be 574 reported in every HCFC message */ 575 BCM_IF_ERROR_RETURN 576 (_bcm_kt2_oob_fc_tx_config_gcs_id_get(unit, config)); 577 578 /* Get the configured Egress mode of OOBFC Tx side */ 579 BCM_IF_ERROR_RETURN 580 (_bcm_kt2_oob_fc_tx_config_egr_mode_get(unit, config)); 581 582 return BCM_E_NONE; 583 } 584 585 /* 586 * Function: 587 * _bcm_kt2_oob_fc_tx_port_control_set 588 * Purpose: 589 * Set OOB FC Tx Port configuration. 590 * Parameters: 591 * unit - (IN) StrataSwitch unit number. 592 * gport - (IN) Modport Gport 593 * status - (IN) Status of Congestion State reporting 594 * dir - (IN) Direction 0 = Ingreess, 1 = Egress 595 * Returns: 596 * BCM_E_XXX 597 */ 598 int 599 _bcm_kt2_oob_fc_tx_port_control_set(int unit, bcm_port_t localport, 600 int status, int dir) 601 { 602 uint64 rval64; 603 static const soc_field_t field[2] = {ING_PORT_ENf, ENG_PORT_ENf}; 604 static const soc_reg_t reg_kt2[2][1] = { 605 {OOBFC_ING_PORT_EN_41r}, 606 {OOBFC_ENG_PORT_EN_41r}}; 607 static const soc_reg_t reg_sb2[2][1] = { 608 {OOBFC_ING_PORT_EN_29r}, 609 {OOBFC_ENG_PORT_EN_29r}}; 610 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 611 612 if ((status != 1) && (status != 0)) { 613 return BCM_E_PARAM; 614 } 615 616 if (dir > 1) { 617 return BCM_E_PARAM; 618 } 619 620 COMPILER_64_ZERO(rval64); 621 622 if (SOC_IS_SABER2(unit)) { 623 #ifdef BCM_METROLITE_SUPPORT 624 if (SOC_IS_METROLITE(unit)) { 625 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 626 } else 627 #endif 628 { 629 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 630 } 631 if ((0 <= localport) && (localport < max_rx_mem_entry)) { 632 BCM_IF_ERROR_RETURN 633 (soc_reg64_get(unit, reg_sb2[dir][0], 0, 0, &rval64)); 634 if (((status == 1) && (!COMPILER_64_BITTEST(rval64, localport))) || 635 ((status == 0) && (COMPILER_64_BITTEST(rval64, localport)))) { 636 if (status == 1) { 637 COMPILER_64_BITSET(rval64, localport); 638 } else { 639 COMPILER_64_BITCLR(rval64, localport); 640 } 641 soc_reg64_field_set(unit, reg_sb2[dir][0], &rval64, 642 field[dir], rval64); 643 BCM_IF_ERROR_RETURN 644 (soc_reg64_set(unit, reg_sb2[dir][0], 0, 0, rval64)); 645 } 646 } else { 647 return BCM_E_PARAM; 648 } 649 } else if (SOC_IS_KATANA2(unit)) { 650 if ((0 <= localport) && (localport < max_rx_mem_entry)) { 651 BCM_IF_ERROR_RETURN 652 (soc_reg64_get(unit, reg_kt2[dir][0], 0, 0, &rval64)); 653 if (((status == 1) && (!COMPILER_64_BITTEST(rval64, localport))) || 654 ((status == 0) && (COMPILER_64_BITTEST(rval64, localport)))) { 655 if (status == 1) { 656 COMPILER_64_BITSET(rval64, localport); 657 } else { 658 COMPILER_64_BITCLR(rval64, localport); 659 } 660 soc_reg64_field_set(unit, reg_kt2[dir][0], &rval64, 661 field[dir], rval64); 662 BCM_IF_ERROR_RETURN 663 (soc_reg64_set(unit, reg_kt2[dir][0], 0, 0, rval64)); 664 } 665 } else { 666 return BCM_E_PARAM; 667 } 668 } 669 return BCM_E_NONE; 670 } 671 672 /* 673 * Function: 674 * _bcm_kt2_oob_fc_tx_port_control_get 675 * Purpose: 676 * Get OOB FC Tx side Port configuration. 677 * Parameters: 678 * unit - (IN) StrataSwitch unit number. 679 * gport - (IN) Modport Gport 680 * status - (OUT) Status of Congestion State reporting 681 * dir - (IN) Direction 0 = Ingreess, 1 = Egress 682 * Returns: 683 * BCM_E_XXX 684 */ 685 int 686 _bcm_kt2_oob_fc_tx_port_control_get(int unit, bcm_port_t localport, 687 int *status, int dir) 688 { 689 uint64 rval64; 690 static const soc_reg_t reg_kt2[2][1] = { 691 {OOBFC_ING_PORT_EN_41r}, 692 {OOBFC_ENG_PORT_EN_41r}}; 693 static const soc_reg_t reg_sb2[2][1] = { 694 {OOBFC_ING_PORT_EN_29r}, 695 {OOBFC_ENG_PORT_EN_29r}}; 696 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 697 if (dir > 1) { 698 return BCM_E_PARAM; 699 } 700 701 COMPILER_64_ZERO(rval64); 702 703 if (SOC_IS_SABER2(unit)) { 704 #ifdef BCM_METROLITE_SUPPORT 705 if (SOC_IS_METROLITE(unit)) { 706 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 707 } else 708 #endif 709 { 710 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 711 } 712 if ((0 <= localport) && (localport < max_rx_mem_entry)) { 713 BCM_IF_ERROR_RETURN 714 (soc_reg64_get(unit, reg_sb2[dir][0], 0, 0, &rval64)); 715 } else { 716 return BCM_E_PARAM; 717 } 718 } else if (SOC_IS_KATANA2(unit)) { 719 if ((0 <= localport) && (localport < max_rx_mem_entry)) { 720 BCM_IF_ERROR_RETURN 721 (soc_reg64_get(unit, reg_kt2[dir][0], 0, 0, &rval64)); 722 } else { 723 return BCM_E_PARAM; 724 } 725 } 726 727 if (COMPILER_64_BITTEST(rval64, localport)) { 728 *status = 0x1; 729 } else { 730 *status = 0x0; 731 } 732 return BCM_E_NONE; 733 } 734 735 /* 736 * Function: 737 * bcm_kt2_oob_fc_tx_info_get 738 * Purpose: 739 * Get OOB FC Tx global information. 740 * Parameters: 741 * unit - (IN) StrataSwitch unit number. 742 * info - (OUT) OOB FC Tx global information 743 * Returns: 744 * BCM_E_XXX 745 */ 746 int 747 bcm_kt2_oob_fc_tx_info_get(int unit, bcm_oob_fc_tx_info_t *info) 748 { 749 uint64 rval64; 750 751 if (info == NULL) { 752 return BCM_E_PARAM; 753 } 754 755 BCM_IF_ERROR_RETURN 756 (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r, 757 0, 0, &rval64)); 758 759 /* Get the Channel base value for HCFC messages containing 760 congestion state of different resources */ 761 /* Ingress Ports */ 762 info->ing_base = (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r, 763 rval64, ING_BASEf); 764 765 /* Egress Unicast Queue */ 766 info->ucast_base = (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r, 767 rval64, ENGU_BASEf); 768 769 /* Egress Multicast Queue */ 770 info->mcast_base = (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r, 771 rval64, ENGM_BASEf); 772 773 /* Egress Cos Queue */ 774 info->cos_base = (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r, 775 rval64, ENGG_BASEf); 776 777 return BCM_E_NONE; 778 } 779 780 /* 781 * Function: 782 * _bcm_kt2_oob_fc_rx_config_enable_set 783 * Purpose: 784 * Enable and configure the given OOB FC Rx Interface 785 * Parameters: 786 * unit - (IN) StrataSwitch unit number 787 * intf_id - (IN) OOB FC Rx Interface Number 788 * channel_base - (IN) HCFC channel base 789 * array_count - (IN) Number of gports in the gport array 790 * gport_array - (IN) Array of modport type gport 791 * Returns: 792 * BCM_E_XXX 793 */ 794 STATIC int 795 _bcm_kt2_oob_fc_rx_config_enable_set(int unit, 796 bcm_oob_fc_rx_intf_id_t intf_id, 797 uint8 channel_base, 798 int array_count, 799 bcm_gport_t *gport_array) 800 { 801 _bcm_kt2_oob_fc_rx_intf_info_t info[BCM_KT2_NUM_OOB_FC_RX_INTF]; 802 char *sysport_buf, *tc2pri_buf; 803 uint32 sysport_list[BCM_KT2_MAX_RX_MEM_ENTRY]; 804 int rv = BCM_E_INTERNAL; 805 void *pentry1, *pentry2; 806 uint32 rval = 0x0; 807 int mem_wsz = 0; 808 int i = 0, total_num_ports = 0; 809 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 810 bcm_port_t localport = 0; 811 uint64 tc_to_pri_mapping; 812 uint32 tc_to_pri_mapping_low = 0x0; 813 uint32 tc_to_pri_mapping_high = 0x0; 814 soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr}; 815 816 if (SOC_IS_SABER2(unit)) { 817 #ifdef BCM_METROLITE_SUPPORT 818 if (SOC_IS_METROLITE(unit)) { 819 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 820 } else 821 #endif 822 { 823 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 824 } 825 } 826 COMPILER_64_ZERO(tc_to_pri_mapping); 827 828 sal_memset(info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t) * 829 BCM_KT2_NUM_OOB_FC_RX_INTF); 830 sal_memset(sysport_list, 0, sizeof(uint32) * 831 BCM_KT2_MAX_RX_MEM_ENTRY); 832 833 /* Backup the per OOBFC Rx interface configuration */ 834 for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) { 835 BCM_IF_ERROR_RETURN 836 (_bcm_kt2_oob_fc_rx_get_intf_info(unit, &info[i], i)); 837 /* Compute the total number of ports which is 838 already configured */ 839 if (info[i].enable == 1) { 840 total_num_ports += info[i].num_ports; 841 } 842 } 843 844 /* Return error if trying to enable already enabled 845 OOBFC Rx Interface */ 846 if (info[intf_id].enable == 1) { 847 return BCM_E_PARAM; 848 } 849 850 /* Return error if there is no room in memory to accomodate 851 the list of ports which need to programmed in memory */ 852 if ((total_num_ports + array_count) > max_rx_mem_entry) { 853 return BCM_E_PARAM; 854 } 855 856 /* Read the MMU_CHFC_SYSPORT_MAPPING memory into sysport_buf */ 857 mem_wsz = sizeof(uint32) * 858 soc_mem_entry_words(unit, MMU_CHFC_SYSPORT_MAPPINGm); 859 sysport_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 860 "oob sysport_buf"); 861 if (sysport_buf == NULL) { 862 return BCM_E_MEMORY; 863 } 864 865 if (soc_mem_read_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL, 866 0, max_rx_mem_entry - 1, sysport_buf)) { 867 rv = BCM_E_INTERNAL; 868 soc_cm_sfree(unit, sysport_buf); 869 return rv; 870 } 871 872 /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_buf */ 873 mem_wsz = sizeof(uint32) * 874 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm); 875 tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 876 "oob tc2pri_buf"); 877 if (tc2pri_buf == NULL) { 878 rv = BCM_E_MEMORY; 879 soc_cm_sfree(unit, sysport_buf); 880 return rv; 881 } 882 883 if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 884 0, max_rx_mem_entry - 1, tc2pri_buf)) { 885 rv = BCM_E_INTERNAL; 886 soc_cm_sfree(unit, tc2pri_buf); 887 soc_cm_sfree(unit, sysport_buf); 888 return rv; 889 } 890 891 /* Creating a list of logical port number from a list of 892 modport gport */ 893 for (i = 0; i < array_count; i++) { 894 rv = _bcm_kt2_oob_localport_resolve(unit, gport_array[i], 895 &localport); 896 if (rv != BCM_E_NONE) { 897 soc_cm_sfree(unit, tc2pri_buf); 898 soc_cm_sfree(unit, sysport_buf); 899 return rv; 900 } 901 sysport_list[i] = localport; 902 } 903 904 /* Fill the info structure for the given interface */ 905 info[intf_id].enable = 1; 906 info[intf_id].channel_base = channel_base; 907 info[intf_id].lookup_base = total_num_ports; 908 info[intf_id].num_ports = array_count; 909 910 /* Program sysport_list in MMU_CHFC_SYSPORT_MAPPING */ 911 /* Program default value into MMU_INTFO_TC2PRI_MAPPING */ 912 for (i = 0; i < array_count; i++) { 913 pentry1 = soc_mem_table_idx_to_pointer(unit, 914 MMU_CHFC_SYSPORT_MAPPINGm, 915 void*, sysport_buf, 916 (total_num_ports + i)); 917 pentry2 = soc_mem_table_idx_to_pointer(unit, 918 MMU_INTFO_TC2PRI_MAPPINGm, 919 void*, tc2pri_buf, 920 (total_num_ports + i)); 921 soc_mem_field32_set(unit, MMU_CHFC_SYSPORT_MAPPINGm, pentry1, 922 SYS_PORTf, sysport_list[i]); 923 /* TC to PRI Mapping Default Value is unity mapped 924 TC=7 mapped PRI=7 0x80 (bits 63-56) 925 TC=6 mapped PRI=6 0x40 (bits 55-48) 926 TC=5 mapped PRI=5 0x20 (bits 47-40) 927 TC=4 mapped PRI=4 0x10 (bits 39-32) 928 TC=3 mapped PRI=3 0x08 (bits 31-24) 929 TC=2 mapped PRI=2 0x04 (bits 23-16) 930 TC=1 mapped PRI=1 0x02 (bits 15-8) 931 TC=0 mapped PRI=0 0x01 (bits 7-0) 932 */ 933 tc_to_pri_mapping_high |= 0x80 << 24; 934 tc_to_pri_mapping_high |= 0x40 << 16; 935 tc_to_pri_mapping_high |= 0x20 << 8; 936 tc_to_pri_mapping_high |= 0x10; 937 tc_to_pri_mapping_low |= 0x08 << 24; 938 tc_to_pri_mapping_low |= 0x04 << 16; 939 tc_to_pri_mapping_low |= 0x02 << 8; 940 tc_to_pri_mapping_low |= 0x01; 941 942 COMPILER_64_SET(tc_to_pri_mapping, tc_to_pri_mapping_high, 943 tc_to_pri_mapping_low); 944 945 soc_mem_field64_set(unit, MMU_INTFO_TC2PRI_MAPPINGm, 946 pentry2, PRI_BMPf, tc_to_pri_mapping); 947 } 948 949 if (soc_mem_write_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL, 950 0, max_rx_mem_entry - 1, sysport_buf)) { 951 rv = BCM_E_INTERNAL; 952 soc_cm_sfree(unit, tc2pri_buf); 953 soc_cm_sfree(unit, sysport_buf); 954 return rv; 955 } 956 957 if (soc_mem_write_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 958 0, max_rx_mem_entry - 1, tc2pri_buf)) { 959 rv = BCM_E_INTERNAL; 960 soc_cm_sfree(unit, tc2pri_buf); 961 soc_cm_sfree(unit, sysport_buf); 962 return rv; 963 } 964 965 /* Program the given interface configuration register.*/ 966 rv = soc_reg32_get(unit, cfg_reg[intf_id], 967 0, 0, &rval); 968 if (rv != BCM_E_NONE) { 969 soc_cm_sfree(unit, tc2pri_buf); 970 soc_cm_sfree(unit, sysport_buf); 971 return rv; 972 } 973 soc_reg_field_set(unit, cfg_reg[intf_id], &rval, 974 OOBFC_CH_ENf, info[intf_id].enable); 975 soc_reg_field_set(unit, cfg_reg[intf_id], &rval, 976 OOBFC_CH_BASEf, info[intf_id].channel_base); 977 soc_reg_field_set(unit, cfg_reg[intf_id], &rval, 978 LOOKUP_BASEf, info[intf_id].lookup_base); 979 soc_reg_field_set(unit, cfg_reg[intf_id], &rval, 980 CH_PORT_NUMf, info[intf_id].num_ports); 981 rv = soc_reg32_set(unit, cfg_reg[intf_id], 982 0, 0, rval); 983 if (rv != BCM_E_NONE) { 984 soc_cm_sfree(unit, tc2pri_buf); 985 soc_cm_sfree(unit, sysport_buf); 986 return rv; 987 } 988 989 rv = BCM_E_NONE; 990 soc_cm_sfree(unit, tc2pri_buf); 991 soc_cm_sfree(unit, sysport_buf); 992 return rv; 993 } 994 995 /* 996 * Function: 997 * _bcm_kt2_oob_fc_rx_port_offset_get 998 * Purpose: 999 * Get the channel offset value for a given port 1000 * in the HCFC message received on a given OOB FC 1001 * Rx Interface 1002 * Parameters: 1003 * unit - (IN) StrataSwitch unit number 1004 * intf_id - (IN) OOB FC Rx Interface Number 1005 * gport - (IN) Modport gport 1006 * offset - (OUT) Channel offset value 1007 * Returns: 1008 * BCM_E_XXX 1009 */ 1010 STATIC int 1011 _bcm_kt2_oob_fc_rx_port_offset_get(int unit, 1012 bcm_oob_fc_rx_intf_id_t intf_id, 1013 bcm_gport_t gport, 1014 uint32 *offset) 1015 { 1016 bcm_oob_fc_rx_config_t config; 1017 bcm_gport_t gport_array[BCM_KT2_MAX_RX_MEM_ENTRY] = {0x0}; 1018 int array_count = 0, i = 0; 1019 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 1020 1021 if (SOC_IS_SABER2(unit)) { 1022 #ifdef BCM_METROLITE_SUPPORT 1023 if (SOC_IS_METROLITE(unit)) { 1024 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 1025 } else 1026 #endif 1027 { 1028 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 1029 } 1030 } 1031 1032 /* Get the configured list of gport array 1033 and array count*/ 1034 BCM_IF_ERROR_RETURN 1035 (bcm_kt2_oob_fc_rx_config_get(unit, intf_id, &config, 1036 max_rx_mem_entry, gport_array, 1037 &array_count)); 1038 1039 if (config.enable == 0) { 1040 return BCM_E_PARAM; 1041 } 1042 1043 /* Get the Channel offset of the port in HCFC message */ 1044 for (i = 0; i < array_count; i++) { 1045 if (gport == gport_array[i]) { 1046 break; 1047 } 1048 } 1049 1050 /* Return error if gport is not there in the list */ 1051 if (i == array_count) { 1052 return BCM_E_NOT_FOUND; 1053 } 1054 1055 *offset = i; 1056 1057 return BCM_E_NONE; 1058 } 1059 1060 /* 1061 * Function: 1062 * _bcm_kt2_oob_fc_rx_tc_mapping_get 1063 * Purpose: 1064 * Get the traffic class to priority 1065 * mapping for given OOB FC Rx Interface at 1066 * given idx in the memory. 1067 * Parameters: 1068 * unit - (IN) StrataSwitch unit number 1069 * intf_id - (IN) OOB FC Rx Interface Number 1070 * tc - (IN) Traffic Class array[0-7] 1071 * pri_bmp - (OUT) Priority Bitmap[0-7] 1072 * idx - (IN) Index in TC to PRI mapping memory 1073 * Returns: 1074 * BCM_E_XXX 1075 */ 1076 STATIC int 1077 _bcm_kt2_oob_fc_rx_tc_mapping_get(int unit, 1078 bcm_oob_fc_rx_intf_id_t intf_id, 1079 uint32 tc, uint32 *pri_bmp, 1080 uint32 idx) 1081 { 1082 char *tc2pri_buf; 1083 uint64 tc2pri; 1084 void *pentry; 1085 int mem_wsz = 0; 1086 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 1087 1088 if (SOC_IS_SABER2(unit)) { 1089 #ifdef BCM_METROLITE_SUPPORT 1090 if (SOC_IS_METROLITE(unit)) { 1091 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 1092 } else 1093 #endif 1094 { 1095 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 1096 } 1097 } 1098 COMPILER_64_ZERO(tc2pri); 1099 1100 /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_buf */ 1101 mem_wsz = sizeof(uint32) * 1102 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm); 1103 tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 1104 "oob tc2pri_buf"); 1105 if (tc2pri_buf == NULL) { 1106 return BCM_E_MEMORY; 1107 } 1108 1109 if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 1110 0, max_rx_mem_entry - 1, tc2pri_buf)) { 1111 soc_cm_sfree(unit, tc2pri_buf); 1112 return BCM_E_INTERNAL; 1113 } 1114 1115 /* Get the pointer to the given index. */ 1116 pentry = soc_mem_table_idx_to_pointer(unit, 1117 MMU_INTFO_TC2PRI_MAPPINGm, 1118 void*, tc2pri_buf, idx); 1119 1120 soc_mem_field64_get(unit, MMU_INTFO_TC2PRI_MAPPINGm, 1121 pentry, PRI_BMPf, &tc2pri); 1122 1123 /* Get tc2pri value */ 1124 COMPILER_64_SHR(tc2pri, (8 * tc)); 1125 *pri_bmp = COMPILER_64_LO(tc2pri) & 0xFF; 1126 1127 soc_cm_sfree(unit, tc2pri_buf); 1128 return BCM_E_NONE; 1129 } 1130 1131 /* 1132 * Function: 1133 * _bcm_kt2_oob_fc_rx_tc_mapping_set 1134 * Purpose: 1135 * Set the traffic class to priority 1136 * mapping for given OOB FC Rx Interface at 1137 * given idx in the memory. 1138 * Parameters: 1139 * unit - (IN) StrataSwitch unit number 1140 * intf_id - (IN) OOB FC Rx Interface Number 1141 * tc - (IN) Traffic Class array[0-7] 1142 * pri_bmp - (IN) Priority Bitmap[0-7] 1143 * idx - (IN) Index in TC to PRI mapping memory 1144 * Returns: 1145 * BCM_E_XXX 1146 */ 1147 STATIC int 1148 _bcm_kt2_oob_fc_rx_tc_mapping_set(int unit, 1149 bcm_oob_fc_rx_intf_id_t intf_id, uint32 tc, 1150 uint32 pri_bmp, uint32 idx) 1151 { 1152 char *tc2pri_buf; 1153 uint64 tc2pri; 1154 uint64 mask64; 1155 uint64 pri_bmp64; 1156 int rv = BCM_E_INTERNAL; 1157 void *pentry; 1158 int mem_wsz = 0; 1159 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 1160 1161 if (SOC_IS_SABER2(unit)) { 1162 #ifdef BCM_METROLITE_SUPPORT 1163 if (SOC_IS_METROLITE(unit)) { 1164 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 1165 } else 1166 #endif 1167 { 1168 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 1169 } 1170 } 1171 COMPILER_64_ZERO(tc2pri); 1172 COMPILER_64_ZERO(mask64); 1173 COMPILER_64_ZERO(pri_bmp64); 1174 1175 /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_buf */ 1176 mem_wsz = sizeof(uint32) * 1177 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm); 1178 tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 1179 "oob tc2pri_buf"); 1180 if (tc2pri_buf == NULL) { 1181 return BCM_E_MEMORY; 1182 } 1183 1184 if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 1185 0, max_rx_mem_entry - 1, tc2pri_buf)) { 1186 rv = BCM_E_INTERNAL; 1187 soc_cm_sfree(unit, tc2pri_buf); 1188 return rv; 1189 } 1190 1191 /* Get the pointer to the given index. */ 1192 pentry = soc_mem_table_idx_to_pointer(unit, 1193 MMU_INTFO_TC2PRI_MAPPINGm, 1194 void*, tc2pri_buf, idx); 1195 1196 soc_mem_field64_get(unit, MMU_INTFO_TC2PRI_MAPPINGm, 1197 pentry, PRI_BMPf, &tc2pri); 1198 1199 1200 /* Disable the given OOBFC Rx interface */ 1201 rv = _bcm_kt2_oob_fc_rx_disable_intf(unit, intf_id); 1202 if (rv != BCM_E_NONE) { 1203 soc_cm_sfree(unit, tc2pri_buf); 1204 return rv; 1205 } 1206 1207 /* Update tc2pri value */ 1208 COMPILER_64_SET(pri_bmp64, 0, pri_bmp); 1209 COMPILER_64_SHL(pri_bmp64, (tc * 8)); 1210 COMPILER_64_MASK_CREATE(mask64, 8, (tc * 8)); 1211 COMPILER_64_NOT(mask64); 1212 COMPILER_64_AND(tc2pri, mask64); 1213 COMPILER_64_OR(tc2pri, pri_bmp64); 1214 1215 /* Program tc2pri MMU_INTFO_TC2PRI_MAPPING */ 1216 soc_mem_field64_set(unit, MMU_INTFO_TC2PRI_MAPPINGm, 1217 pentry, PRI_BMPf, tc2pri); 1218 1219 if (soc_mem_write_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 1220 0, max_rx_mem_entry - 1, tc2pri_buf)) { 1221 rv = BCM_E_INTERNAL; 1222 soc_cm_sfree(unit, tc2pri_buf); 1223 return rv; 1224 } 1225 1226 /* Enable the given OOBFC Rx interface back */ 1227 rv = _bcm_kt2_oob_fc_rx_enable_intf(unit, intf_id); 1228 if (rv != BCM_E_NONE) { 1229 soc_cm_sfree(unit, tc2pri_buf); 1230 return rv; 1231 } 1232 1233 rv = BCM_E_NONE; 1234 soc_cm_sfree(unit, tc2pri_buf); 1235 return rv; 1236 } 1237 1238 /* 1239 * Function: 1240 * _bcm_kt2_oob_fc_rx_config_disable_set 1241 * Purpose: 1242 * Disable and reset the configuration of the 1243 * given OOB FC Rx Interface 1244 * Parameters: 1245 * unit - (IN) StrataSwitch unit number 1246 * intf_id - (IN) OOB FC Rx Interface Number 1247 * Returns: 1248 * BCM_E_XXX 1249 */ 1250 STATIC int 1251 _bcm_kt2_oob_fc_rx_config_disable_set(int unit, 1252 bcm_oob_fc_rx_intf_id_t intf_id) 1253 { 1254 _bcm_kt2_oob_fc_rx_intf_info_t old_info[BCM_KT2_NUM_OOB_FC_RX_INTF]; 1255 _bcm_kt2_oob_fc_rx_intf_info_t new_info[BCM_KT2_NUM_OOB_FC_RX_INTF]; 1256 char *sysport_buf, *tc2pri_buf; 1257 uint32 *old_sysport_list = NULL; 1258 uint64 *old_tc2pri_list = NULL; 1259 uint32 *new_sysport_list = NULL; 1260 uint64 *new_tc2pri_list = NULL; 1261 int rv = BCM_E_INTERNAL; 1262 int mem_wsz = 0; 1263 int i = 0, j = 0, k = 0; 1264 void *pentry; 1265 uint32 rval = 0x0; 1266 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 1267 soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr}; 1268 1269 1270 old_sysport_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint32), 1271 "oob old_sysport_list"); 1272 if (old_sysport_list == NULL) { 1273 return BCM_E_MEMORY; 1274 } 1275 old_tc2pri_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint64), 1276 "oob old_tc2pri_list"); 1277 if (old_tc2pri_list == NULL) { 1278 soc_cm_sfree(unit, old_sysport_list); 1279 return BCM_E_MEMORY; 1280 } 1281 1282 new_sysport_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint32), 1283 "oob new_sysport_list"); 1284 if (new_sysport_list == NULL) { 1285 soc_cm_sfree(unit, old_sysport_list); 1286 soc_cm_sfree(unit, old_tc2pri_list); 1287 return BCM_E_MEMORY; 1288 } 1289 1290 new_tc2pri_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint64), 1291 "oob new_tc2pri_list"); 1292 if (new_tc2pri_list == NULL) { 1293 soc_cm_sfree(unit, old_sysport_list); 1294 soc_cm_sfree(unit, old_tc2pri_list); 1295 soc_cm_sfree(unit, new_sysport_list); 1296 return BCM_E_MEMORY; 1297 } 1298 if (SOC_IS_SABER2(unit)) { 1299 #ifdef BCM_METROLITE_SUPPORT 1300 if (SOC_IS_METROLITE(unit)) { 1301 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 1302 } else 1303 #endif 1304 { 1305 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 1306 } 1307 } 1308 1309 sal_memset(old_info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t) * 1310 BCM_KT2_NUM_OOB_FC_RX_INTF); 1311 sal_memset(new_info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t) * 1312 BCM_KT2_NUM_OOB_FC_RX_INTF); 1313 sal_memset(old_sysport_list, 0, sizeof(uint32) * 1314 BCM_KT2_MAX_RX_MEM_ENTRY); 1315 sal_memset(new_sysport_list, 0, sizeof(uint32) * 1316 BCM_KT2_MAX_RX_MEM_ENTRY); 1317 sal_memset(old_tc2pri_list, 0, sizeof(uint64) * 1318 BCM_KT2_MAX_RX_MEM_ENTRY); 1319 sal_memset(new_tc2pri_list, 0, sizeof(uint64) * 1320 BCM_KT2_MAX_RX_MEM_ENTRY); 1321 1322 /* Store all the OOBFC Rx interface configuration */ 1323 for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) { 1324 BCM_IF_ERROR_RETURN 1325 (_bcm_kt2_oob_fc_rx_get_intf_info(unit, &old_info[i], i)); 1326 } 1327 1328 /* Read the MMU_CHFC_SYSPORT_MAPPING memory into sysport_buf */ 1329 mem_wsz = sizeof(uint32) * 1330 soc_mem_entry_words(unit, MMU_CHFC_SYSPORT_MAPPINGm); 1331 sysport_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 1332 "oob sysport_buf"); 1333 if (sysport_buf == NULL) { 1334 soc_cm_sfree(unit, old_sysport_list); 1335 soc_cm_sfree(unit, old_tc2pri_list); 1336 soc_cm_sfree(unit, new_sysport_list); 1337 soc_cm_sfree(unit, new_tc2pri_list); 1338 return BCM_E_MEMORY; 1339 } 1340 1341 if (soc_mem_read_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL, 1342 0, max_rx_mem_entry - 1, sysport_buf)) { 1343 rv = BCM_E_INTERNAL; 1344 soc_cm_sfree(unit, old_sysport_list); 1345 soc_cm_sfree(unit, old_tc2pri_list); 1346 soc_cm_sfree(unit, new_sysport_list); 1347 soc_cm_sfree(unit, new_tc2pri_list); 1348 soc_cm_sfree(unit, sysport_buf); 1349 return rv; 1350 } 1351 1352 /* Store the sysport_buf in old_sysport_list */ 1353 for (i = 0; i < max_rx_mem_entry; i++) { 1354 pentry = soc_mem_table_idx_to_pointer(unit, 1355 MMU_CHFC_SYSPORT_MAPPINGm, 1356 void*, sysport_buf, i); 1357 old_sysport_list[i] = soc_mem_field32_get(unit, 1358 MMU_CHFC_SYSPORT_MAPPINGm, 1359 pentry, SYS_PORTf); 1360 } 1361 1362 /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_list */ 1363 mem_wsz = sizeof(uint32) * 1364 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm); 1365 tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 1366 "oob tc2pri_buf"); 1367 if (tc2pri_buf == NULL) { 1368 rv = BCM_E_MEMORY; 1369 soc_cm_sfree(unit, old_sysport_list); 1370 soc_cm_sfree(unit, old_tc2pri_list); 1371 soc_cm_sfree(unit, new_sysport_list); 1372 soc_cm_sfree(unit, new_tc2pri_list); 1373 soc_cm_sfree(unit, sysport_buf); 1374 return rv; 1375 } 1376 1377 if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 1378 0, max_rx_mem_entry - 1, tc2pri_buf)) { 1379 rv = BCM_E_INTERNAL; 1380 soc_cm_sfree(unit, old_sysport_list); 1381 soc_cm_sfree(unit, old_tc2pri_list); 1382 soc_cm_sfree(unit, new_sysport_list); 1383 soc_cm_sfree(unit, new_tc2pri_list); 1384 soc_cm_sfree(unit, tc2pri_buf); 1385 soc_cm_sfree(unit, sysport_buf); 1386 return rv; 1387 } 1388 1389 /* Store the tc2pri_buf in old_tc2pri_list */ 1390 for (i = 0; i < max_rx_mem_entry; i++) { 1391 pentry = soc_mem_table_idx_to_pointer(unit, 1392 MMU_INTFO_TC2PRI_MAPPINGm, 1393 void*, tc2pri_buf, i); 1394 soc_mem_field64_get(unit, MMU_INTFO_TC2PRI_MAPPINGm, 1395 pentry, PRI_BMPf, &old_tc2pri_list[i]); 1396 } 1397 1398 /* Disable all the OOBFC Rx interface */ 1399 for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) { 1400 if (old_info[i].enable == 1) { 1401 rv = _bcm_kt2_oob_fc_rx_disable_intf(unit, i); 1402 if (rv != BCM_E_NONE) { 1403 soc_cm_sfree(unit, tc2pri_buf); 1404 soc_cm_sfree(unit, sysport_buf); 1405 soc_cm_sfree(unit, old_sysport_list); 1406 soc_cm_sfree(unit, old_tc2pri_list); 1407 soc_cm_sfree(unit, new_sysport_list); 1408 soc_cm_sfree(unit, new_tc2pri_list); 1409 return rv; 1410 } 1411 } 1412 } 1413 1414 /* Generate new_info */ 1415 /* Genrate new_sysport_list */ 1416 /* Genrate new_tc2pri_list */ 1417 j = 0; 1418 k = 0; 1419 for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) { 1420 if (i != intf_id) { 1421 new_info[i].enable = old_info[i].enable; 1422 new_info[i].channel_base = old_info[i].channel_base; 1423 new_info[i].num_ports = old_info[i].num_ports; 1424 if (new_info[i].enable) { 1425 new_info[i].lookup_base = j; 1426 } else { 1427 new_info[i].lookup_base = 0x0; 1428 } 1429 for (k = 0; k < new_info[i].num_ports; k++) { 1430 new_sysport_list[j] = old_sysport_list[old_info[i].lookup_base + k]; 1431 new_tc2pri_list[j] = old_tc2pri_list[old_info[i].lookup_base + k]; 1432 j++; 1433 } 1434 } else { 1435 new_info[i].enable = 0; 1436 new_info[i].channel_base = 0; 1437 new_info[i].lookup_base = 0; 1438 new_info[i].num_ports = 0; 1439 } 1440 } 1441 1442 /* Program new_tc2pri_list in MMU_INTFO_TC2PRI_MAPPING */ 1443 for (i = 0; i < max_rx_mem_entry; i++) { 1444 pentry = soc_mem_table_idx_to_pointer(unit, 1445 MMU_INTFO_TC2PRI_MAPPINGm, 1446 void*, tc2pri_buf, i); 1447 soc_mem_field64_set(unit, MMU_INTFO_TC2PRI_MAPPINGm, 1448 pentry, PRI_BMPf, new_tc2pri_list[i]); 1449 } 1450 1451 if (soc_mem_write_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL, 1452 0, max_rx_mem_entry - 1, tc2pri_buf)) { 1453 rv = BCM_E_INTERNAL; 1454 soc_cm_sfree(unit, tc2pri_buf); 1455 soc_cm_sfree(unit, sysport_buf); 1456 soc_cm_sfree(unit, old_sysport_list); 1457 soc_cm_sfree(unit, old_tc2pri_list); 1458 soc_cm_sfree(unit, new_sysport_list); 1459 soc_cm_sfree(unit, new_tc2pri_list); 1460 return rv; 1461 } 1462 1463 /* Program new_sysport_list MMU_CHFC_SYSPORT_MAPPING */ 1464 for (i = 0; i < max_rx_mem_entry; i++) { 1465 pentry = soc_mem_table_idx_to_pointer(unit, 1466 MMU_CHFC_SYSPORT_MAPPINGm, 1467 void*, sysport_buf, i); 1468 soc_mem_field32_set(unit, MMU_CHFC_SYSPORT_MAPPINGm, pentry, 1469 SYS_PORTf, new_sysport_list[i]); 1470 } 1471 1472 if (soc_mem_write_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL, 1473 0, max_rx_mem_entry - 1, sysport_buf)) { 1474 rv = BCM_E_INTERNAL; 1475 soc_cm_sfree(unit, old_sysport_list); 1476 soc_cm_sfree(unit, old_tc2pri_list); 1477 soc_cm_sfree(unit, new_sysport_list); 1478 soc_cm_sfree(unit, new_tc2pri_list); 1479 soc_cm_sfree(unit, tc2pri_buf); 1480 soc_cm_sfree(unit, sysport_buf); 1481 return rv; 1482 } 1483 1484 /* Program all the OOBFC Rx interface configuration register */ 1485 for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) { 1486 rv = soc_reg32_get(unit, cfg_reg[i], 1487 0, 0, &rval); 1488 if (rv != BCM_E_NONE) { 1489 soc_cm_sfree(unit, old_sysport_list); 1490 soc_cm_sfree(unit, old_tc2pri_list); 1491 soc_cm_sfree(unit, new_sysport_list); 1492 soc_cm_sfree(unit, new_tc2pri_list); 1493 soc_cm_sfree(unit, tc2pri_buf); 1494 soc_cm_sfree(unit, sysport_buf); 1495 return rv; 1496 } 1497 soc_reg_field_set(unit, cfg_reg[i], &rval, 1498 OOBFC_CH_ENf, new_info[i].enable); 1499 soc_reg_field_set(unit, cfg_reg[i], &rval, 1500 OOBFC_CH_BASEf, new_info[i].channel_base); 1501 soc_reg_field_set(unit, cfg_reg[i], &rval, 1502 LOOKUP_BASEf, new_info[i].lookup_base); 1503 soc_reg_field_set(unit, cfg_reg[i], &rval, 1504 CH_PORT_NUMf, new_info[i].num_ports); 1505 rv = soc_reg32_set(unit, cfg_reg[i], 1506 0, 0, rval); 1507 if (rv != BCM_E_NONE) { 1508 soc_cm_sfree(unit, old_sysport_list); 1509 soc_cm_sfree(unit, old_tc2pri_list); 1510 soc_cm_sfree(unit, new_sysport_list); 1511 soc_cm_sfree(unit, new_tc2pri_list); 1512 soc_cm_sfree(unit, tc2pri_buf); 1513 soc_cm_sfree(unit, sysport_buf); 1514 return rv; 1515 } 1516 } 1517 1518 rv = BCM_E_NONE; 1519 soc_cm_sfree(unit, old_sysport_list); 1520 soc_cm_sfree(unit, old_tc2pri_list); 1521 soc_cm_sfree(unit, new_sysport_list); 1522 soc_cm_sfree(unit, new_tc2pri_list); 1523 soc_cm_sfree(unit, tc2pri_buf); 1524 soc_cm_sfree(unit, sysport_buf); 1525 return rv; 1526 } 1527 1528 /* 1529 * Function: 1530 * _bcm_kt2_oob_fc_rx_config_get 1531 * Purpose: 1532 * Get the configuration and status 1533 * each OOB FC Rx Interface. 1534 * Parameters: 1535 * unit - (IN) StrataSwitch unit number 1536 * intf_id - (IN) OOB FC Rx Interface Number 1537 * config - (OUT) OOB FC Rx Interface Config 1538 * array_max - (IN) Maximum Lenght of Gport array passed 1539 * gport_array - (OUT) Array of modport type gport 1540 * array_count - (OUT) Number of gports returned in the gport array 1541 * Returns: 1542 * BCM_E_XXX 1543 */ 1544 STATIC int 1545 _bcm_kt2_oob_fc_rx_config_get(int unit, 1546 bcm_oob_fc_rx_intf_id_t intf_id, 1547 bcm_oob_fc_rx_config_t *config, 1548 int array_max, 1549 bcm_gport_t *gport_array, 1550 int *array_count) 1551 { 1552 _bcm_kt2_oob_fc_rx_intf_info_t info; 1553 int rv = BCM_E_INTERNAL; 1554 char *sysport_buf; 1555 void *pentry; 1556 int mem_wsz = 0; 1557 int i = 0 , j = 0; 1558 bcm_gport_t gport; 1559 uint32 new_sysport_list[BCM_KT2_MAX_RX_MEM_ENTRY]; 1560 int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 1561 1562 if (SOC_IS_SABER2(unit)) { 1563 #ifdef BCM_METROLITE_SUPPORT 1564 if (SOC_IS_METROLITE(unit)) { 1565 max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY; 1566 } else 1567 #endif 1568 { 1569 max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY; 1570 } 1571 } 1572 1573 sal_memset(&info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t)); 1574 sal_memset(new_sysport_list, 0, sizeof(uint32) * 1575 BCM_KT2_MAX_RX_MEM_ENTRY); 1576 1577 /* Store all the OOBFC Rx interface configuration */ 1578 BCM_IF_ERROR_RETURN 1579 (_bcm_kt2_oob_fc_rx_get_intf_info(unit, &info, intf_id)); 1580 1581 /* If given OOBFC Rx Interface is not enabled then 1582 return empty gport array */ 1583 if (info.enable == 0) { 1584 sal_memset(config, 0, sizeof(bcm_oob_fc_rx_config_t)); 1585 sal_memset(gport_array, 0, sizeof(bcm_gport_t) * array_max); 1586 *array_count = 0; 1587 return BCM_E_NONE; 1588 } else { 1589 config->enable = info.enable; 1590 config->channel_base = info.channel_base; 1591 /* Read the MMU_CHFC_SYSPORT_MAPPING memory into sysport_buf */ 1592 mem_wsz = sizeof(uint32) * 1593 soc_mem_entry_words(unit, MMU_CHFC_SYSPORT_MAPPINGm); 1594 sysport_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz, 1595 "oob sysport_buf"); 1596 if (sysport_buf == NULL) { 1597 return BCM_E_MEMORY; 1598 } 1599 1600 if (soc_mem_read_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL, 1601 0, max_rx_mem_entry - 1, sysport_buf)) { 1602 rv = BCM_E_INTERNAL; 1603 soc_cm_sfree(unit, sysport_buf); 1604 return rv; 1605 } 1606 1607 if (array_max >= info.num_ports) { 1608 *array_count = info.num_ports; 1609 } else { 1610 *array_count = array_max; 1611 } 1612 1613 /* Store the required number of indexes into a sysport_list */ 1614 for (i = info.lookup_base, j = 0; 1615 i < (info.lookup_base + *array_count); i++, j++) { 1616 pentry = soc_mem_table_idx_to_pointer(unit, 1617 MMU_CHFC_SYSPORT_MAPPINGm, 1618 void*, sysport_buf, i); 1619 new_sysport_list[j] = soc_mem_field32_get(unit, 1620 MMU_CHFC_SYSPORT_MAPPINGm, 1621 pentry, SYS_PORTf); 1622 } 1623 1624 /* Convert the sysport list into a modport gport list */ 1625 for (i = 0; i < *array_count; i++) { 1626 rv = bcm_esw_port_gport_get(unit, new_sysport_list[i], 1627 &gport); 1628 if (rv != BCM_E_NONE) { 1629 soc_cm_sfree(unit, sysport_buf); 1630 return rv; 1631 } 1632 gport_array[i] = gport; 1633 } 1634 1635 } 1636 1637 rv = BCM_E_NONE; 1638 soc_cm_sfree(unit, sysport_buf); 1639 return rv; 1640 } 1641 1642 /* 1643 * Function: 1644 * bcm_kt2_oob_fc_rx_config_set 1645 * Purpose: 1646 * Set the configuration and enable 1647 * each OOB FC Rx Interface. 1648 * Parameters: 1649 * unit - (IN) StrataSwitch unit number 1650 * intf_id - (IN) OOB FC Rx Interface Number 1651 * config - (IN) OOB FC Rx Interface Config 1652 * array_count - (IN) Number of gports in the gport array 1653 * gport_array - (IN) Array of modport type gport 1654 * Returns: 1655 * BCM_E_XXX 1656 */ 1657 int 1658 bcm_kt2_oob_fc_rx_config_set(int unit, 1659 bcm_oob_fc_rx_intf_id_t intf_id, 1660 bcm_oob_fc_rx_config_t *config, 1661 int array_count, 1662 bcm_gport_t *gport_array) 1663 { 1664 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1665 return BCM_E_PARAM; 1666 } 1667 1668 if (config == NULL) { 1669 return BCM_E_PARAM; 1670 } 1671 1672 if ((config->enable != 0) && (config->enable != 1)) { 1673 return BCM_E_PARAM; 1674 } 1675 1676 if ((config->enable == 1) && 1677 ((array_count <= 0) || (gport_array == NULL) || 1678 (array_count > BCM_KT2_MAX_RX_MEM_ENTRY))) { 1679 return BCM_E_PARAM; 1680 } 1681 1682 if ((config->enable == 1) && 1683 ((config->channel_base >= BCM_KT2_MAX_CHANNEL_BASE))) { 1684 return BCM_E_PARAM; 1685 } 1686 1687 if (config->enable == 1) { 1688 /* Add entries into MMU_CHFC_SYSPORT_MAPPING memory */ 1689 BCM_IF_ERROR_RETURN 1690 (_bcm_kt2_oob_fc_rx_config_enable_set(unit, intf_id, 1691 config->channel_base, 1692 array_count, gport_array)); 1693 } else { 1694 /* Remove entries from MMU_CHFC_SYSPORT_MAPPING memory */ 1695 BCM_IF_ERROR_RETURN 1696 (_bcm_kt2_oob_fc_rx_config_disable_set(unit, intf_id)); 1697 } 1698 1699 return BCM_E_NONE; 1700 } 1701 1702 /* 1703 * Function: 1704 * bcm_kt2_oob_fc_rx_config_get 1705 * Purpose: 1706 * Get the configuration and status 1707 * each OOB FC Rx Interface. 1708 * Parameters: 1709 * unit - (IN) StrataSwitch unit number 1710 * intf_id - (IN) OOB FC Rx Interface Number 1711 * config - (OUT) OOB FC Rx Interface Config 1712 * array_max - (IN) Maximum Lenght of Gport array passed 1713 * gport_array - (OUT) Array of modport type gport 1714 * array_count - (OUT) Number of gports returned in the gport array 1715 * Returns: 1716 * BCM_E_XXX 1717 */ 1718 int 1719 bcm_kt2_oob_fc_rx_config_get(int unit, 1720 bcm_oob_fc_rx_intf_id_t intf_id, 1721 bcm_oob_fc_rx_config_t *config, 1722 int array_max, 1723 bcm_gport_t *gport_array, 1724 int *array_count) 1725 { 1726 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1727 return BCM_E_PARAM; 1728 } 1729 1730 if ((gport_array == NULL) || 1731 (config == NULL) || 1732 (array_count == NULL) || 1733 (array_max <= 0)) { 1734 return BCM_E_PARAM; 1735 } 1736 1737 BCM_IF_ERROR_RETURN 1738 (_bcm_kt2_oob_fc_rx_config_get(unit, intf_id, 1739 config, array_max, 1740 gport_array, 1741 array_count)); 1742 1743 return BCM_E_NONE; 1744 } 1745 1746 /* 1747 * Function: 1748 * bcm_kt2_oob_fc_rx_port_tc_mapping_multi_set 1749 * Purpose: 1750 * Set the per port traffic class to priority 1751 * mapping for each OOB FC Rx Interface. 1752 * Parameters: 1753 * unit - (IN) StrataSwitch unit number 1754 * intf_id - (IN) OOB FC Rx Interface Number 1755 * gport - (IN) Modport type gport 1756 * array_count - (IN) Number of elements in Traffic Class array 1757 * tc - (IN) Traffic Class array[0-7] 1758 * pri_bmp - (IN) Priority Bitmap Array[0-7] 1759 * Returns: 1760 * BCM_E_XXX 1761 */ 1762 int 1763 bcm_kt2_oob_fc_rx_port_tc_mapping_multi_set(int unit, 1764 bcm_oob_fc_rx_intf_id_t intf_id, 1765 bcm_gport_t gport, 1766 int array_count, 1767 uint32 *tc, 1768 uint32 *pri_bmp) 1769 { 1770 int i = 0; 1771 1772 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1773 return BCM_E_PARAM; 1774 } 1775 1776 if ((array_count < 1) || (array_count > BCM_KT2_NUM_TC)) { 1777 return BCM_E_PARAM; 1778 } 1779 1780 if ((tc == NULL) || (pri_bmp == NULL)) { 1781 return BCM_E_PARAM; 1782 } 1783 1784 for (i = 0; i < array_count; i++) { 1785 if ((tc[i] > (BCM_KT2_NUM_TC - 1)) || (pri_bmp[i] > 0xFF)) { 1786 return BCM_E_PARAM; 1787 } 1788 } 1789 1790 for (i = 0; i < array_count; i++) { 1791 BCM_IF_ERROR_RETURN 1792 (bcm_kt2_oob_fc_rx_port_tc_mapping_set(unit, intf_id, 1793 gport, tc[i], 1794 pri_bmp[i])); 1795 } 1796 1797 return BCM_E_NONE; 1798 } 1799 1800 /* 1801 * Function: 1802 * bcm_kt2_oob_fc_rx_port_tc_mapping_multi_get 1803 * Purpose: 1804 * Get the per port traffic class to priority 1805 * mapping for each OOB FC Rx Interface. 1806 * Parameters: 1807 * unit - (IN) StrataSwitch unit number 1808 * intf_id - (IN) OOB FC Rx Interface Number 1809 * gport - (IN) Modport type gport 1810 * array_max - (IN) Maximum Length tc and pri_bmp array 1811 * tc - (OUT) Traffic Class array[0-7] 1812 * pri_bmp - (OUT) Priority Bitmap Array[0-7] 1813 * array_count - (OUT) Number of elements in Traffic Class array 1814 * Returns: 1815 * BCM_E_XXX 1816 */ 1817 int 1818 bcm_kt2_oob_fc_rx_port_tc_mapping_multi_get(int unit, 1819 bcm_oob_fc_rx_intf_id_t intf_id, 1820 bcm_gport_t gport, 1821 int array_max, 1822 uint32 *tc, 1823 uint32 *pri_bmp, 1824 int *array_count) 1825 { 1826 int i = 0; 1827 1828 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1829 return BCM_E_PARAM; 1830 } 1831 1832 if (array_max < 1) { 1833 return BCM_E_PARAM; 1834 } 1835 1836 if ((array_count == NULL) || 1837 (tc == NULL) || 1838 (pri_bmp == NULL)) { 1839 return BCM_E_PARAM; 1840 } 1841 1842 if (array_max > BCM_KT2_NUM_TC) { 1843 *array_count = BCM_KT2_NUM_TC; 1844 } else { 1845 *array_count = array_max; 1846 } 1847 1848 for (i = 0; i < *array_count; i++) { 1849 if (tc[i] > (BCM_KT2_NUM_TC - 1)) { 1850 return BCM_E_PARAM; 1851 } 1852 } 1853 1854 for (i = 0; i < *array_count; i++) { 1855 BCM_IF_ERROR_RETURN 1856 (bcm_kt2_oob_fc_rx_port_tc_mapping_get(unit, intf_id, 1857 gport, tc[i], 1858 &pri_bmp[i])); 1859 } 1860 return BCM_E_NONE; 1861 } 1862 1863 1864 /* 1865 * Function: 1866 * bcm_kt2_oob_fc_rx_port_tc_mapping_set 1867 * Purpose: 1868 * Set the per port traffic class to priority 1869 * mapping for each OOB FC Rx Interface. 1870 * Parameters: 1871 * unit - (IN) StrataSwitch unit number 1872 * intf_id - (IN) OOB FC Rx Interface Number 1873 * gport - (IN) Modport type gport 1874 * tc - (IN) Traffic Class array[0-7] 1875 * pri_bmp - (IN) Priority Bitmap[0-7] 1876 * Returns: 1877 * BCM_E_XXX 1878 */ 1879 int 1880 bcm_kt2_oob_fc_rx_port_tc_mapping_set(int unit, 1881 bcm_oob_fc_rx_intf_id_t intf_id, 1882 bcm_gport_t gport, 1883 uint32 tc, 1884 uint32 pri_bmp) 1885 { 1886 uint32 idx = 0; 1887 uint32 offset = 0; 1888 uint32 lookup_base = 0; 1889 1890 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1891 return BCM_E_PARAM; 1892 } 1893 1894 if ((tc > (BCM_KT2_NUM_TC - 1)) || (pri_bmp > 0xFF)) { 1895 return BCM_E_PARAM; 1896 } 1897 1898 BCM_IF_ERROR_RETURN 1899 (_bcm_kt2_oob_fc_rx_port_offset_get(unit, intf_id, 1900 gport, &offset)); 1901 1902 /* Get lookup base */ 1903 BCM_IF_ERROR_RETURN 1904 (_bcm_kt2_oob_fc_rx_intf_get_lookup_base(unit, intf_id, 1905 &lookup_base)); 1906 1907 idx = offset + lookup_base; 1908 1909 BCM_IF_ERROR_RETURN 1910 (_bcm_kt2_oob_fc_rx_tc_mapping_set(unit, intf_id, tc, 1911 pri_bmp, idx)); 1912 1913 return BCM_E_NONE; 1914 } 1915 1916 /* 1917 * Function: 1918 * bcm_kt2_oob_fc_rx_port_tc_mapping_get 1919 * Purpose: 1920 * Set the per port traffic class to priority 1921 * mapping for each OOB FC Rx Interface. 1922 * Parameters: 1923 * unit - (IN) StrataSwitch unit number 1924 * intf_id - (IN) OOB FC Rx Interface Number 1925 * gport - (IN) Modport type gport 1926 * tc - (IN) Traffic Class array[0-7] 1927 * pri_bmp - (OUT) Priority Bitmap[0-7] 1928 * Returns: 1929 * BCM_E_XXX 1930 */ 1931 int 1932 bcm_kt2_oob_fc_rx_port_tc_mapping_get(int unit, 1933 bcm_oob_fc_rx_intf_id_t intf_id, 1934 bcm_gport_t gport, 1935 uint32 tc, 1936 uint32 *pri_bmp) 1937 { 1938 uint32 idx = 0; 1939 uint32 offset = 0; 1940 uint32 lookup_base = 0; 1941 1942 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1943 return BCM_E_PARAM; 1944 } 1945 1946 if (tc > (BCM_KT2_NUM_TC - 1)) { 1947 return BCM_E_PARAM; 1948 } 1949 1950 BCM_IF_ERROR_RETURN 1951 (_bcm_kt2_oob_fc_rx_port_offset_get(unit, intf_id, 1952 gport, &offset)); 1953 1954 /* Get lookup base */ 1955 BCM_IF_ERROR_RETURN 1956 (_bcm_kt2_oob_fc_rx_intf_get_lookup_base(unit, intf_id, 1957 &lookup_base)); 1958 1959 idx = offset + lookup_base; 1960 1961 BCM_IF_ERROR_RETURN 1962 (_bcm_kt2_oob_fc_rx_tc_mapping_get(unit, intf_id, tc, 1963 pri_bmp, idx)); 1964 1965 return BCM_E_NONE; 1966 } 1967 1968 /* 1969 * Function: 1970 * bcm_kt2_oob_fc_rx_port_offset_get 1971 * Purpose: 1972 * Get the Channel offset value for a given port 1973 * on given OOB FC Rx Interface. 1974 * Parameters: 1975 * unit - (IN) StrataSwitch unit number 1976 * intf_id - (IN) OOB FC Rx Interface Number 1977 * gport - (IN) Modport type gport 1978 * offset - (OUT) Channel offset value in HCFC message 1979 * Returns: 1980 * BCM_E_XXX 1981 */ 1982 int 1983 bcm_kt2_oob_fc_rx_port_offset_get(int unit, 1984 bcm_oob_fc_rx_intf_id_t intf_id, 1985 bcm_gport_t gport, 1986 uint32 *offset) 1987 { 1988 if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) { 1989 return BCM_E_PARAM; 1990 } 1991 1992 BCM_IF_ERROR_RETURN 1993 (_bcm_kt2_oob_fc_rx_port_offset_get(unit, intf_id, 1994 gport, offset)); 1995 1996 return BCM_E_NONE; 1997 } 1998 1999 #endif /* BCM_KATANA2_SUPPORT */