fcmap_cmn.c (16145B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: fcmap_cmn.c 8 * Purpose: FCMAP software module intergation support 9 */ 10 11 #ifdef INCLUDE_FCMAP 12 13 #include <shared/bsl.h> 14 15 #include <soc/mem.h> 16 #include <soc/debug.h> 17 #include <soc/cm.h> 18 #include <soc/drv.h> 19 #include <soc/register.h> 20 #include <soc/memory.h> 21 #include <soc/phy.h> 22 #include <soc/ll.h> 23 #include <soc/ptable.h> 24 #include <soc/tucana.h> 25 #include <soc/firebolt.h> 26 #include <soc/xaui.h> 27 #include <soc/phyctrl.h> 28 #include <soc/phyreg.h> 29 #include <soc/fcmapphy.h> 30 #include <bfcmap.h> 31 #include <sal/core/libc.h> 32 #include <bcm/debug.h> 33 34 #include <bcm_int/common/fcmap_cmn.h> 35 36 #include <bcm_int/control.h> 37 #include <bcm_int/esw_dispatch.h> 38 39 #define UNIT_VALID(unit) \ 40 { \ 41 if (!BCM_UNIT_VALID(unit)) { return BCM_E_UNIT; } \ 42 } 43 44 static bfcmap_error_t error_tbl[] = { 45 BCM_E_NONE, 46 BCM_E_INTERNAL, 47 BCM_E_MEMORY, 48 BCM_E_PARAM, 49 BCM_E_EMPTY, 50 BCM_E_FULL, 51 BCM_E_NOT_FOUND, 52 BCM_E_EXISTS, 53 BCM_E_TIMEOUT, 54 BCM_E_FAIL, 55 BCM_E_DISABLED, 56 BCM_E_BADID, 57 BCM_E_RESOURCE, 58 BCM_E_CONFIG, 59 BCM_E_UNAVAIL, 60 BCM_E_INIT, 61 BCM_E_PORT, 62 }; 63 /* 64 * Convert FCMAP return codes to BCM return code. 65 */ 66 #define BCM_ERROR(e) error_tbl[-(e)] 67 68 typedef struct _bcm_fcmap_cb_args_s { 69 void *user_arg; 70 void *user_cb; 71 int unit; 72 int port; 73 } _bcm_fcmap_cb_args_t; 74 75 static int fcmap_cb_registered = 0; 76 77 /* 78 * Function: 79 * bcm_common_fcmap_init 80 * Purpose: 81 * Intiialize FCMAP for the specified unit. 82 */ 83 int _bcm_common_fcmap_init(int unit) 84 { 85 static int _bfcmap_init_done = 0; 86 87 /* 88 * Do FCMAP init and MDIO registration for the FCMAP module. 89 */ 90 if (!_bfcmap_init_done) { 91 /* Initilaize the FCMAP module */ 92 bfcmap_init(); 93 /* register MDIO routines */ 94 bfcmap_dev_mmi_mdio_register(soc_fcmapphy_miim_read, 95 soc_fcmapphy_miim_write); 96 /* Initialize the default print vectors. */ 97 98 bfcmap_config_print_set(BFCMAP_PRINT_PRINTF | BFCMAP_PRINT_DEBUG, bsl_printf); 99 _bfcmap_init_done = 1; 100 } 101 return BCM_E_NONE; 102 } 103 104 /* 105 * Local port traverse handler to filter out ports belonging to specified 106 * unit. 107 */ 108 STATIC int 109 _bcm_fcmap_port_traverse_cb(bfcmap_port_t p, 110 bfcmap_core_t dev_core, 111 bfcmap_dev_addr_t dev_addr, 112 int dev_port, 113 bfcmap_dev_io_f devio_f, 114 void *user_data) 115 { 116 int rv = BFCMAP_E_NONE ; 117 _bcm_fcmap_cb_args_t *ua; 118 bcm_fcmap_port_traverse_cb callback; 119 120 ua = (_bcm_fcmap_cb_args_t*) user_data; 121 122 if (SOC_FCMAP_PORTID2UNIT(p) == ua->unit) { 123 callback = (bcm_fcmap_port_traverse_cb) ua->user_cb; 124 rv = callback(SOC_FCMAP_PORTID2UNIT(p), 125 SOC_FCMAP_PORTID2PORT(p), 126 dev_core, dev_addr, 127 dev_port, devio_f, ua->user_arg); 128 } 129 return rv; 130 } 131 132 /* 133 * Function: 134 * bcm_fcmap_port_traverse 135 * Purpose: 136 * Destroy a FCMAP Port 137 */ 138 int 139 bcm_common_fcmap_port_traverse(int unit, 140 bcm_fcmap_port_traverse_cb callback, 141 void *user_data) 142 { 143 int rv; 144 _bcm_fcmap_cb_args_t ua; 145 146 UNIT_VALID(unit); 147 148 ua.user_arg = user_data; 149 ua.user_cb = (void*) callback; 150 ua.unit = unit; 151 152 rv = bfcmap_port_traverse(_bcm_fcmap_port_traverse_cb, (void*) &ua); 153 #ifdef BCM_CB_ABORT_ON_ERR 154 return BCM_ERROR(rv); 155 #else 156 return rv; 157 #endif 158 } 159 160 161 /* 162 * Function: 163 * bcm_fcmap_port_config_selective_set 164 * Purpose: 165 * Set the FCMAP Port configuration. 166 */ 167 int 168 bcm_common_fcmap_port_config_selective_set(int unit, bcm_port_t port, 169 bcm_fcmap_port_config_t *cfg) 170 { 171 int rv = BCM_E_UNAVAIL; 172 bfcmap_port_t p; 173 174 UNIT_VALID(unit); 175 176 p = SOC_FCMAP_PORTID(unit, port); 177 rv = bfcmap_port_config_selective_set(p, cfg); 178 return BCM_ERROR(rv); 179 } 180 181 /* 182 * Function: 183 * bcm_fcmap_port_config_selective_get 184 * Purpose: 185 * Get the current FCMAP Port configuration. 186 */ 187 int 188 bcm_common_fcmap_port_config_selective_get(int unit, bcm_port_t port, 189 bcm_fcmap_port_config_t *cfg) 190 { 191 int rv = BCM_E_UNAVAIL; 192 bfcmap_port_t p; 193 194 UNIT_VALID(unit); 195 196 p = SOC_FCMAP_PORTID(unit, port); 197 rv = bfcmap_port_config_selective_get(p, cfg); 198 return BCM_ERROR(rv); 199 } 200 201 /* 202 * Function: 203 * bcm_fcmap_port_config_set 204 * Purpose: 205 * Set the FCMAP Port configuration. 206 */ 207 int 208 bcm_common_fcmap_port_config_set(int unit, bcm_port_t port, 209 bcm_fcmap_port_config_t *cfg) 210 { 211 int rv = BCM_E_UNAVAIL; 212 bfcmap_port_t p; 213 214 UNIT_VALID(unit); 215 216 p = SOC_FCMAP_PORTID(unit, port); 217 rv = bfcmap_port_config_set(p, cfg); 218 return BCM_ERROR(rv); 219 } 220 221 /* 222 * Function: 223 * bcm_fcmap_port_config_get 224 * Purpose: 225 * Get the current FCMAP Port configuration. 226 */ 227 int 228 bcm_common_fcmap_port_config_get(int unit, bcm_port_t port, 229 bcm_fcmap_port_config_t *cfg) 230 { 231 int rv = BCM_E_UNAVAIL; 232 bfcmap_port_t p; 233 234 UNIT_VALID(unit); 235 236 p = SOC_FCMAP_PORTID(unit, port); 237 rv = bfcmap_port_config_get(p, cfg); 238 return BCM_ERROR(rv); 239 } 240 241 /* 242 * Function: 243 * bcm_fcmap_port_speed_set 244 * Purpose: 245 * Set speed attribute of the FC port. 246 */ 247 int 248 bcm_common_fcmap_port_speed_set(int unit, bcm_port_t port, 249 bcm_fcmap_port_speed_t speed) 250 { 251 int rv = BCM_E_UNAVAIL; 252 bfcmap_port_t p; 253 254 UNIT_VALID(unit); 255 256 p = SOC_FCMAP_PORTID(unit, port); 257 rv = bfcmap_port_speed_set(p, speed); 258 return BCM_ERROR(rv); 259 } 260 261 /* 262 * Function: 263 * bcm_fcmap_port_enable 264 * Purpose: 265 * Enable the FC port 266 */ 267 int 268 bcm_common_fcmap_port_enable(int unit, bcm_port_t port) 269 { 270 int rv = BCM_E_UNAVAIL; 271 bfcmap_port_t p; 272 273 UNIT_VALID(unit); 274 275 p = SOC_FCMAP_PORTID(unit, port); 276 rv = bfcmap_port_link_enable(p); 277 return BCM_ERROR(rv); 278 } 279 280 /* 281 * Function: 282 * bcm_fcmap_port_shutdown 283 * Purpose: 284 * Disable FC port 285 */ 286 int 287 bcm_common_fcmap_port_shutdown(int unit, bcm_port_t port) 288 { 289 int rv = BCM_E_UNAVAIL; 290 bfcmap_port_t p; 291 292 UNIT_VALID(unit); 293 294 p = SOC_FCMAP_PORTID(unit, port); 295 rv = bfcmap_port_shutdown(p); 296 return BCM_ERROR(rv); 297 } 298 299 /* 300 * Function: 301 * bcm_fcmap_port_link_reset 302 * Purpose: 303 * Issue a link reset on the FC port. 304 */ 305 int 306 bcm_common_fcmap_port_link_reset(int unit, bcm_port_t port) 307 { 308 int rv = BCM_E_UNAVAIL; 309 bfcmap_port_t p; 310 311 UNIT_VALID(unit); 312 313 p = SOC_FCMAP_PORTID(unit, port); 314 rv = bfcmap_port_reset(p); 315 return BCM_ERROR(rv); 316 } 317 /* 318 * Function: 319 * bcm_fcmap_vlan_map_add 320 * Purpose: 321 * Add entry to VLAN - VSAN MAP for FCMAP port 322 */ 323 int 324 bcm_common_fcmap_vlan_map_add(int unit, bcm_port_t port, 325 bcm_fcmap_vlan_vsan_map_t *vlan) 326 { 327 int rv = BCM_E_UNAVAIL; 328 bfcmap_port_t p; 329 330 UNIT_VALID(unit); 331 332 p = SOC_FCMAP_PORTID(unit, port); 333 rv = bfcmap_vlan_map_add(p, vlan); 334 return BCM_ERROR(rv); 335 } 336 337 /* 338 * Function: 339 * bcm_fcmap_vlan_map_get 340 * Purpose: 341 * Get entry from VLAN - VSAN MAP for FCMAP port 342 */ 343 int 344 bcm_common_fcmap_vlan_map_get(int unit, bcm_port_t port, 345 bcm_fcmap_vlan_vsan_map_t *vlan) 346 { 347 int rv = BCM_E_UNAVAIL; 348 bfcmap_port_t p; 349 350 UNIT_VALID(unit); 351 352 p = SOC_FCMAP_PORTID(unit, port); 353 rv = bfcmap_vlan_map_get(p, vlan); 354 return BCM_ERROR(rv); 355 } 356 357 /* 358 * Function: 359 * bcm_fcmap_vlan_map_delete 360 * Purpose: 361 * Delete entry from VLAN - VSAN MAP for FCMAP port 362 */ 363 int 364 bcm_common_fcmap_vlan_map_delete(int unit, bcm_port_t port, 365 bcm_fcmap_vlan_vsan_map_t *vlan) 366 { 367 int rv = BCM_E_UNAVAIL; 368 bfcmap_port_t p; 369 370 UNIT_VALID(unit); 371 372 p = SOC_FCMAP_PORTID(unit, port); 373 rv = bfcmap_vlan_map_delete(p, vlan); 374 return BCM_ERROR(rv); 375 } 376 377 #if 0 378 /* 379 * Function: 380 * bcm_fcmap_port_capability_get 381 * Purpose: 382 * Get the FCMAP Port capability 383 */ 384 int 385 bcm_common_fcmap_port_capability_get(int unit, bcm_port_t port, 386 bcm_fcmap_port_capability_t *cap) 387 { 388 int rv = BCM_E_UNAVAIL; 389 bfcmap_port_t p; 390 391 UNIT_VALID(unit); 392 393 p = SOC_FCMAP_PORTID(unit, port); 394 rv = bfcmap_port_capability_get(p, cap); 395 return BCM_ERROR(rv); 396 } 397 #endif 398 399 400 /* 401 * Function: 402 * bcm_fcmap_stat_clear 403 * Purpose: 404 * Clear stats for the specified port. 405 */ 406 int 407 bcm_common_fcmap_stat_clear(int unit, bcm_port_t port) 408 { 409 int rv = BCM_E_UNAVAIL; 410 bfcmap_port_t p; 411 412 UNIT_VALID(unit); 413 414 p = SOC_FCMAP_PORTID(unit, port); 415 rv = bfcmap_stat_clear(p); 416 return BCM_ERROR(rv); 417 } 418 419 int 420 bcm_common_fcmap_stat_get(int unit, bcm_port_t port, bcm_fcmap_stat_t stat, 421 uint64 *val) 422 { 423 int rv = BCM_E_UNAVAIL; 424 bfcmap_port_t p; 425 426 UNIT_VALID(unit); 427 428 p = SOC_FCMAP_PORTID(unit, port); 429 rv = bfcmap_stat_get(p, stat, (buint64_t *)val); 430 return BCM_ERROR(rv); 431 } 432 433 int 434 bcm_common_fcmap_stat_get32(int unit, bcm_port_t port, 435 bcm_fcmap_stat_t stat, uint32 *val) 436 { 437 int rv = BCM_E_UNAVAIL; 438 bfcmap_port_t p; 439 440 UNIT_VALID(unit); 441 442 p = SOC_FCMAP_PORTID(unit, port); 443 rv = bfcmap_stat_get32(p, stat, (buint32_t*)val); 444 return BCM_ERROR(rv); 445 } 446 447 448 typedef struct _bcm_fcmap_event_data_s { 449 bcm_fcmap_event_cb callback; 450 uint32 event_map; 451 } _bcm_fcmap_event_data_t; 452 453 STATIC _bcm_fcmap_event_data_t _fcmap_event_data[BCM_UNITS_MAX]; 454 455 STATIC int 456 _bcm_fcmap_event_cb(bfcmap_port_t p, /* Port ID */ 457 bfcmap_event_t event, /* Event */ 458 void *user_data) 459 { 460 int unit; 461 bcm_fcmap_event_cb callback; 462 _bcm_fcmap_event_data_t *event_data; 463 464 unit = SOC_FCMAP_PORTID2UNIT(p); 465 466 event_data = &_fcmap_event_data[unit]; 467 callback = (bcm_fcmap_event_cb) event_data->callback; 468 469 if (callback && (event_data->event_map & (1 << (uint32) event))) { 470 callback(SOC_FCMAP_PORTID2UNIT(p), 471 SOC_FCMAP_PORTID2PORT(p), 472 event, user_data); 473 } 474 return BFCMAP_E_NONE; 475 } 476 477 int 478 bcm_common_fcmap_event_register(int unit, bcm_fcmap_event_cb cb, void *user_data) 479 { 480 int rv = BCM_E_NONE; 481 _bcm_fcmap_event_data_t *event_data; 482 483 UNIT_VALID(unit); 484 485 event_data = &_fcmap_event_data[unit]; 486 event_data->callback = cb; 487 event_data->event_map = 0; 488 if (fcmap_cb_registered == 0) { 489 rv = bfcmap_event_register(_bcm_fcmap_event_cb, user_data); 490 if (rv == BFCMAP_E_NONE) { 491 fcmap_cb_registered = 1; 492 } 493 } 494 return BCM_ERROR(rv); 495 } 496 497 int 498 bcm_common_fcmap_event_unregister(int unit, bcm_fcmap_event_cb cb) 499 { 500 int rv = BCM_E_NONE, unregister = 1, ii; 501 _bcm_fcmap_event_data_t *event_data; 502 503 UNIT_VALID(unit); 504 505 event_data = &_fcmap_event_data[unit]; 506 if (event_data->callback) { 507 event_data->callback = NULL; 508 } 509 510 for (ii = 0; ii < BCM_UNITS_MAX; ii++) { 511 event_data = &_fcmap_event_data[ii]; 512 if (event_data->callback) { 513 unregister = 0; 514 break; 515 } 516 } 517 if (unregister) { 518 fcmap_cb_registered = 0; 519 rv = bfcmap_event_unregister(_bcm_fcmap_event_cb); 520 } 521 return BCM_ERROR(rv); 522 } 523 524 int 525 bcm_common_fcmap_event_enable_set(int unit, 526 bcm_fcmap_event_t event, int enable) 527 { 528 int rv = BCM_E_NONE, disable, ii; 529 _bcm_fcmap_event_data_t *event_data; 530 531 UNIT_VALID(unit); 532 533 event_data = &_fcmap_event_data[unit]; 534 if (enable) { 535 event_data->event_map |= (1 << (uint32) event); 536 rv = bfcmap_event_enable_set(event, enable); 537 } else { 538 event_data->event_map &= ~(1 << (uint32) event); 539 disable = 1; 540 for (ii = 0; ii < BCM_UNITS_MAX; ii++) { 541 event_data = &_fcmap_event_data[ii]; 542 if (event_data->event_map & (1 << (uint32) event)) { 543 disable = 0; 544 break; 545 } 546 } 547 if (disable) { 548 rv = bfcmap_event_enable_set(event, enable); 549 } 550 } 551 return BCM_ERROR(rv); 552 } 553 554 int 555 bcm_common_fcmap_event_enable_get(int unit, 556 bcm_fcmap_event_t event, int *enable) 557 { 558 int rv = BCM_E_NONE; 559 _bcm_fcmap_event_data_t *event_data; 560 561 UNIT_VALID(unit); 562 563 event_data = &_fcmap_event_data[unit]; 564 *enable = (event_data->event_map & (1 << (uint32) event)) ? 1 : 0; 565 return BCM_ERROR(rv); 566 } 567 568 569 /* 570 * Configure FCMAP print function for debug. 571 */ 572 int bcm_common_fcmap_config_print(uint32 level) 573 { 574 int rv = BCM_E_NONE; 575 uint32 flag = BFCMAP_PRINT_PRINTF; 576 577 #if defined(BROADCOM_DEBUG) 578 if (level & BSL_S_FCOE) { 579 flag |= BFCMAP_PRINT_DEBUG; 580 } 581 #endif /* BROADCOM_DEBUG */ 582 583 rv = bfcmap_config_print_set(flag, bsl_printf); 584 return BCM_ERROR(rv); 585 } 586 587 588 /* 589 * Function: 590 * bcm_common_fcmap_linkfault_trigger_rc_get 591 * Purpose: 592 * Get the current FCMAP Port linkfault trigger and reason code. 593 */ 594 int 595 bcm_common_fcmap_linkfault_trigger_rc_get(int unit, bcm_port_t port, 596 bcm_fcmap_lf_tr_t *lf_trigger, bcm_fcmap_lf_rc_t *lf_rc) 597 { 598 int rv = BCM_E_UNAVAIL; 599 bfcmap_port_t p; 600 601 UNIT_VALID(unit); 602 603 p = SOC_FCMAP_PORTID(unit, port); 604 rv = bfcmap_port_linkfault_trigger_rc_get(p, (bfcmap_lf_tr_t *)lf_trigger, (bfcmap_lf_rc_t *)lf_rc); 605 return BCM_ERROR(rv); 606 } 607 608 609 610 /* 611 * Function: 612 * bcm_common_fcmap_diag_get 613 * Purpose: 614 * Get the current FCMAP Port diagnostic code. 615 */ 616 int 617 bcm_common_fcmap_diag_get(int unit, bcm_port_t port, 618 bcm_fcmap_diag_code_t *diag) 619 { 620 int rv = BCM_E_UNAVAIL; 621 bfcmap_port_t p; 622 623 UNIT_VALID(unit); 624 625 p = SOC_FCMAP_PORTID(unit, port); 626 rv = bfcmap_port_diag_get(p, (bfcmap_diag_code_t *)diag); 627 return BCM_ERROR(rv); 628 } 629 630 /* 631 * Function: 632 * bcm_common_fcmap_port_ability_advert_set 633 * Purpose: 634 * Sets discrete port speeds for AN or single forced port speed 635 */ 636 int 637 bcm_common_fcmap_port_ability_advert_set(int unit, bcm_port_t port, 638 bcm_fcmap_port_ability_t *ability_mask) 639 { 640 int rv = BCM_E_UNAVAIL; 641 bfcmap_port_t p; 642 643 UNIT_VALID(unit); 644 645 p = SOC_FCMAP_PORTID(unit, port); 646 rv = bfcmap_port_ability_advert_set(p, (bfcmap_port_ability_t *)ability_mask); 647 return BCM_ERROR(rv); 648 } 649 650 /* 651 * Function: 652 * bcm_common_fcmap_port_ability_advert_get 653 * Purpose: 654 * Retrieves supported port speeds 655 */ 656 int 657 bcm_common_fcmap_port_ability_advert_get(int unit, bcm_port_t port, 658 bcm_fcmap_port_ability_t *ability_mask) 659 { 660 int rv = BCM_E_UNAVAIL; 661 bfcmap_port_t p; 662 663 UNIT_VALID(unit); 664 665 p = SOC_FCMAP_PORTID(unit, port); 666 rv = bfcmap_port_ability_advert_get(p, (bfcmap_port_ability_t *)ability_mask); 667 return BCM_ERROR(rv); 668 } 669 670 /* 671 * Function: 672 * bcm_common_fcmap_private_data_set 673 * Purpose: 674 * Pass private data to driver 675 */ 676 int 677 bcm_common_fcmap_private_data_set(int unit, bcm_port_t port, uint8 *data, int len) 678 { 679 int rv = BCM_E_UNAVAIL; 680 bfcmap_port_t p; 681 682 UNIT_VALID(unit); 683 684 p = SOC_FCMAP_PORTID(unit, port); 685 rv = bfcmap_port_private_data_set(p, data, len); 686 return BCM_ERROR(rv); 687 } 688 689 #else 690 int _fcmap_cmn_not_empty; 691 #endif /* INCLUDE_FCMAP */ 692