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