port.c (292474B)
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: port.c 8 * Purpose: XGS5 Port common driver. 9 * 10 * Notes: 11 * More than likely only new Port APIs are found in 12 * this function driver due to a huge amount of legacy code 13 * that were implemented before this model. 14 */ 15 16 #include <shared/bsl.h> 17 #include <soc/defs.h> 18 #include <soc/drv.h> 19 20 #include <bcm/error.h> 21 #include <bcm/switch.h> 22 23 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 24 #include <bcm_int/esw/xgs5.h> 25 #include <bcm_int/esw/port.h> 26 #include <bcm_int/esw/portctrl.h> 27 #include <bcm_int/esw_dispatch.h> 28 #include <bcm_int/common/multicast.h> 29 #include <bcm_int/esw/trunk.h> 30 #include <bcm_int/esw/stack.h> 31 #include <bcm_int/esw/mirror.h> 32 #include <bcm_int/esw/firebolt.h> 33 #include <bcm_int/esw/triumph.h> 34 #include <bcm_int/esw/triumph2.h> 35 #include <bcm_int/esw/trident.h> 36 #include <bcm_int/esw/trx.h> 37 #include <bcm_int/esw/xgs3.h> 38 #include <bcm_int/esw/stat.h> 39 #include <bcm_int/esw/link.h> 40 #include <bcm/port.h> 41 42 #include <soc/counter.h> 43 #include <soc/esw/portctrl.h> 44 #if defined(BCM_TRIDENT3_SUPPORT) 45 #include <soc/trident3.h> 46 #endif /* BCM_TRIDENT3_SUPPORT */ 47 #if defined(BCM_HELIX5_SUPPORT) 48 #include <soc/helix5.h> 49 #endif /* BCM_HELIX5_SUPPORT */ 50 #if defined(BCM_TOMAHAWK2_SUPPORT) 51 #include <soc/tomahawk2.h> 52 #endif /* BCM_TOMAHAWK2_SUPPORT */ 53 54 #if defined(BCM_TOMAHAWK3_SUPPORT) 55 #include <soc/tomahawk3.h> 56 #endif /* BCM_TOMAHAWK3_SUPPORT */ 57 58 59 #undef DSCP_CODE_POINT_CNT 60 #define DSCP_CODE_POINT_CNT 64 61 62 /* Checks for 'null' argument */ 63 #define PARAM_NULL_CHECK(_arg) \ 64 if ((_arg) == NULL) { \ 65 return BCM_E_PARAM; \ 66 } 67 68 typedef struct bcmi_xgs5_port_resource_bmp_s { 69 70 pbmp_t inact_pbm_log; /* Logical ports to be inactive via legacy API */ 71 pbmp_t act_pbm_log; /* Logical ports to be active via legacy API */ 72 73 pbmp_t del_pbm_log; /* Logical ports to be deleted in Flexport */ 74 pbmp_t add_pbm_log; /* Logical ports to be added in Flexport */ 75 76 /* Bitmap of local physical ports in each pipe that to be inactived/actived 77 * during Flexport. 78 * Global physical ports should be local_phy_port + pipe_offset 79 */ 80 pbmp_t del_pbm_phy[SOC_MAX_NUM_PIPES]; 81 pbmp_t add_pbm_phy[SOC_MAX_NUM_PIPES]; 82 83 /* Port Macros to be inactived in Flexport */ 84 SHR_BITDCL del_bmp_pm[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)]; 85 /* Port Macros to be actived in Flexport */ 86 SHR_BITDCL add_bmp_pm[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)]; 87 } bcmi_xgs5_port_resource_bmp_t; 88 89 /* 90 * BCMI Port Driver 91 */ 92 static bcmi_xgs5_port_drv_t *bcmi_xgs5_port_drv[BCM_MAX_NUM_UNITS] = {0}; 93 94 #define BCMI_PORT_DRV(u_) (bcmi_xgs5_port_drv[(u_)]) 95 #define BCMI_PORT_DRV_CALL(u_) (bcmi_xgs5_port_drv[(u_)]->port_calls) 96 #define BCMI_PORT_DRV_DEV_INFO(u_) (bcmi_xgs5_port_drv[(u_)]->dev_info[(u_)]) 97 #define BCMI_PORT_DRV_PHY_INFO(u_, _p) \ 98 (BCMI_PORT_DRV_DEV_INFO(u_)->phy_port_info[(_p)]) 99 100 #define BCMI_PORT_SCHEDULE_STATE_INIT_OP_ASF(_op) \ 101 (_op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD | \ 102 BCMI_XGS5_PORT_RESOURCE_OP_DEL | \ 103 BCMI_XGS5_PORT_RESOURCE_OP_REMAP | \ 104 BCMI_XGS5_PORT_RESOURCE_OP_LANES | \ 105 BCMI_XGS5_PORT_RESOURCE_OP_SPEED | \ 106 BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE | \ 107 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX | \ 108 BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR)) 109 110 #define BCMI_PORT_SCHEDULE_STATE_INIT_OP_TDM(_op) \ 111 (_op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD | \ 112 BCMI_XGS5_PORT_RESOURCE_OP_DEL | \ 113 BCMI_XGS5_PORT_RESOURCE_OP_REMAP | \ 114 BCMI_XGS5_PORT_RESOURCE_OP_LANES | \ 115 BCMI_XGS5_PORT_RESOURCE_OP_SPEED | \ 116 BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE | \ 117 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX | \ 118 BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR)) 119 120 /* Hardware definitions */ 121 static bcmi_xgs5_port_hw_defs_t *bcmi_xgs5_port_hw_defs[BCM_MAX_NUM_UNITS] = {0}; 122 123 #define PORT_HW(u_) (bcmi_xgs5_port_hw_defs[(u_)]) 124 125 #define PORT_REDIRECTION_HW_DEFS_EGR_PORT(u_) \ 126 (bcmi_xgs5_port_hw_defs[(u_)]->egr_port) 127 128 129 #define BCMI_MAX_STRENGTH_VALUE (0x3E) 130 131 static char *bcmi_xgs5_port_attach_str[] = BCMI_XGS5_PORT_ATTACH_PHASES_MSG; 132 static char *bcmi_xgs5_port_detach_str[] = BCMI_XGS5_PORT_DETACH_PHASES_MSG; 133 134 /* 135 * Function: 136 * bcmi_xgs5_port_addressable_local_get 137 * Description: 138 * Validate that given port/gport parameter is an addressable 139 * local logical port and return local logical port in 140 * BCM port format (non-Gport). 141 * Logical port does not need to be defined (does not 142 * need to be a VALID port, only addressable). 143 * Parameters: 144 * unit - (IN) BCM device number 145 * port - (IN) Port / Gport to validate 146 * local_port - (OUT) Port number if valid. 147 * Return Value: 148 * BCM_E_NONE - Port OK 149 * BCM_E_INIT - Not initialized 150 * BCM_E_PORT - Port Invalid 151 * 152 * NOTE: 153 * This function only accepts those GPORT types that 154 * deal with logical BCM ports (i.e. MODPORT, LOCAL, etc.). 155 * 156 * Also, unlike bcm_esw_port_local_get(), this routine only checks 157 * that the port number is within the valid port range. 158 * It does NOT check whether the port 159 * is a BCM valid port (i.e. a defined/configured port). 160 * This allows functions that requires port validation with 161 * a new logical port that has not been declared/configured 162 * in the system. 163 */ 164 int 165 bcmi_xgs5_port_addressable_local_get(int unit, 166 bcm_port_t port, bcm_port_t *local_port) 167 { 168 bcm_module_t mod; 169 bcm_trunk_t trunk_id; 170 int id; 171 int is_local; 172 173 /* 174 * A logical port can be: 175 * - Defined and active. 176 * - Defined and inactive (SOC property portmap with ':i' option). 177 * - Not defined. 178 * 179 * The following port definitions/words (i.e. functions, macro names) 180 * are used in the SDK as follows: 181 * - VALID : The logical port is defined, it may be active or 182 * inactive. 183 * There IS a logical-to-physical port mapping. 184 * 185 * - ADDRESSABLE : The logical port number is within the valid 186 * range. 187 * The port may or may have not been defined 188 * (i.e. there is NO logical-to-physical port mapping.) 189 */ 190 if (BCM_GPORT_IS_SET(port)) { 191 BCM_IF_ERROR_RETURN 192 (_bcm_esw_gport_resolve(unit, port, &mod, local_port, 193 &trunk_id, &id)); 194 if ((trunk_id != -1) || (id != -1)) { 195 return BCM_E_PORT; 196 } 197 198 /* Check that port is local */ 199 BCM_IF_ERROR_RETURN 200 (_bcm_esw_modid_is_local(unit, mod, &is_local)); 201 202 if (!is_local) { 203 return BCM_E_PORT; 204 } 205 } else { 206 *local_port = port; 207 } 208 209 /* Check that port is within valid logical port range */ 210 if (!SOC_PORT_ADDRESSABLE(unit, *local_port)) { 211 return BCM_E_PORT; 212 } 213 214 return BCM_E_NONE; 215 } 216 217 /* 218 * Function: 219 * _bcmi_xgs5_port_soc_info_ptype_update 220 * Purpose: 221 * Update the SOC_INFO port type bitmaps and block information. 222 * Parameters: 223 * unit - (IN) Unit number. 224 * port_schedule_state - (IN) port_schedule_state 225 * 226 * 227 * Returns: 228 * SOC_E_XXX 229 * Notes: 230 * Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK 231 * locks are taken. 232 */ 233 STATIC int 234 _bcmi_xgs5_port_soc_info_ptype_update(int unit) 235 { 236 soc_info_t *si = &SOC_INFO(unit); 237 int logic_port, phy_port, port_idx, max_port; 238 int blk, bindex; 239 240 /* 241 * Update ptype information 242 */ 243 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \ 244 si->ptype.num = 0; \ 245 si->ptype.min = si->ptype.max = -1; \ 246 PBMP_ITER(si->ptype.bitmap, logic_port) { \ 247 si->port_offset[logic_port] = si->ptype.num; \ 248 si->ptype.port[si->ptype.num++] = logic_port; \ 249 if (si->ptype.min < 0) { \ 250 si->ptype.min = logic_port; \ 251 } \ 252 if (logic_port > si->ptype.max) { \ 253 si->ptype.max = logic_port; \ 254 } \ 255 } 256 257 RECONFIGURE_PORT_TYPE_INFO(ge); 258 RECONFIGURE_PORT_TYPE_INFO(xe); 259 RECONFIGURE_PORT_TYPE_INFO(c); 260 RECONFIGURE_PORT_TYPE_INFO(ce); 261 RECONFIGURE_PORT_TYPE_INFO(cde); 262 RECONFIGURE_PORT_TYPE_INFO(xl); 263 RECONFIGURE_PORT_TYPE_INFO(cl); 264 RECONFIGURE_PORT_TYPE_INFO(gx); 265 RECONFIGURE_PORT_TYPE_INFO(ether); 266 RECONFIGURE_PORT_TYPE_INFO(hg); 267 RECONFIGURE_PORT_TYPE_INFO(st); 268 RECONFIGURE_PORT_TYPE_INFO(port); 269 RECONFIGURE_PORT_TYPE_INFO(all); 270 271 #undef RECONFIGURE_PORT_TYPE_INFO 272 273 274 /* 275 * Update block port 276 * Use first logical port on block (logic follows ESW driver 277 * soc_info_config(). 278 */ 279 for (phy_port = 0; ; phy_port++) { 280 281 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 282 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0); 283 if (blk < 0 && bindex < 0) { /* End of port list */ 284 break; 285 } 286 287 logic_port = si->port_p2l_mapping[phy_port]; 288 if (logic_port < 0) { 289 continue; 290 } 291 292 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 293 port_idx++) { 294 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 295 if (blk < 0) { /* End of block list of each port */ 296 break; 297 } 298 299 if (si->block_port[blk] < 0) { 300 si->block_port[blk] = logic_port; 301 } 302 } 303 } 304 305 /* Update MAX_PORT(unit) */ 306 max_port = -1; 307 for (phy_port = 0; phy_port < BCMI_PORT_DRV_DEV_INFO(unit)->phy_ports_max; 308 phy_port++) { 309 logic_port = si->port_p2l_mapping[phy_port]; 310 if (logic_port < 0) { 311 continue; 312 } 313 if (max_port < logic_port) { 314 max_port = logic_port; 315 } 316 } 317 si->port_num = max_port + 1; 318 319 /* Update user port mappings (includes port names update) */ 320 soc_esw_dport_init(unit); 321 322 return SOC_E_NONE; 323 } 324 325 /* 326 * Function: 327 * _bcmi_xgs5_management_port_soc_info_ptype_update 328 * Purpose: 329 * Update the SOC_INFO port type bitmaps for management port. 330 * Parameters: 331 * unit - (IN) Unit number. 332 * port - (IN) Logical port. 333 * speed - (IN) speed for given port. 334 * Returns: 335 * BCM_E_XXX 336 * Notes: 337 */ 338 STATIC int 339 _bcmi_xgs5_management_port_soc_info_ptype_update(int unit, 340 bcm_port_t port, int speed) 341 { 342 soc_info_t *si = &SOC_INFO(unit); 343 int rv = BCM_E_NONE; 344 345 if (!SOC_PBMP_MEMBER(si->st.bitmap, port) 346 && (!SOC_PBMP_MEMBER(si->hg.bitmap, port))) { 347 SOC_CONTROL_LOCK(unit); 348 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port); 349 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 350 351 /* Current devices only support XE/GE/HG type management port */ 352 if (speed < 10000) { /* GE */ 353 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 354 } else { /* XE */ 355 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 356 } 357 358 rv = _bcmi_xgs5_port_soc_info_ptype_update(unit); 359 SOC_CONTROL_UNLOCK(unit); 360 } 361 362 return rv; 363 364 } 365 366 367 /* 368 * Function: 369 * bcmi_xgs5_port_fn_drv_init 370 * Purpose: 371 * Initialize the Port function driver. 372 * Parameters: 373 * unit - (IN) Unit number. 374 * drv - (IN) Pointer to the Port function driver. 375 * bcmi_drv - (IN) Pointer to the BCMI Port function driver. 376 * hw_defs - (IN) Pointer to the h/w definition struct. 377 * Returns: 378 * BCM_E_xxx 379 * Notes: 380 * This routine only intializes the function driver. 381 * The main port routine is still in the esw/port.c file. 382 */ 383 int 384 bcmi_xgs5_port_fn_drv_init(int unit, bcm_esw_port_drv_t *drv, 385 bcmi_xgs5_port_drv_t *bcmi_drv, 386 bcmi_xgs5_port_hw_defs_t *hw_defs) 387 { 388 PARAM_NULL_CHECK(drv); 389 390 /* Assign the driver */ 391 BCM_ESW_PORT_DRV(unit) = drv; 392 393 /* Assign the bcmi port driver */ 394 if (bcmi_drv) { 395 BCMI_PORT_DRV(unit) = bcmi_drv; 396 } 397 398 /* Assign the hardware definitions */ 399 if(hw_defs) { 400 PORT_HW(unit) = hw_defs; 401 } 402 403 return BCM_E_NONE; 404 } 405 406 /* 407 * Function: 408 * bcmi_xgs5_port_resource_set 409 * Purpose: 410 * Modify the following port resources: 411 * - Logical to physical port mapping 412 * - Speed 413 * - Number of PHY lanes 414 * - Encapsulation mode 415 * Parameters: 416 * unit - (IN) Unit number. 417 * port - (IN) Logical port. 418 * resource - (IN) Port resource configuration. 419 * Returns: 420 * BCM_E_XXX 421 * Note: 422 * Assumes caller has lock. 423 */ 424 int 425 bcmi_xgs5_port_resource_set(int unit, 426 bcm_gport_t port, bcm_port_resource_t *resource) 427 { 428 bcm_port_t lport1, lport2; 429 430 PARAM_NULL_CHECK(resource); 431 432 /* Check that given port matches logical port field in structure */ 433 BCM_IF_ERROR_RETURN 434 (bcmi_xgs5_port_addressable_local_get(unit, 435 port, &lport1)); 436 BCM_IF_ERROR_RETURN 437 (bcmi_xgs5_port_addressable_local_get(unit, 438 resource->port, &lport2)); 439 if (lport1 != lport2) { 440 return BCM_E_PARAM; 441 } 442 443 return BCM_ESW_PORT_DRV(unit)->resource_multi_set(unit, 1, resource); 444 } 445 446 447 /* 448 * Function: 449 * bcmi_xgs5_port_resource_get 450 * Purpose: 451 * Get the port resource configuration for the specified logical port. 452 * Parameters: 453 * unit - (IN) Unit number. 454 * port - (IN) Logical port. 455 * resource - (OUT) Returns port resource information. 456 * Returns: 457 * BCM_E_XXX 458 * Note: 459 * Assumes caller has lock. 460 */ 461 int 462 bcmi_xgs5_port_resource_get(int unit, 463 bcm_gport_t port, bcm_port_resource_t *resource) 464 { 465 bcm_port_t lport; 466 soc_info_t *si = &SOC_INFO(unit); 467 int encap = 0; 468 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 469 portmod_speed_config_t speed_config; 470 int rv; 471 #endif 472 473 PARAM_NULL_CHECK(resource); 474 475 BCM_IF_ERROR_RETURN 476 (bcmi_xgs5_port_addressable_local_get(unit, 477 port, &lport)); 478 bcm_port_resource_t_init(resource); 479 resource->flags = 0x0; 480 resource->port = lport; 481 resource->physical_port = si->port_l2p_mapping[lport]; 482 resource->lanes = si->port_num_lanes[lport]; 483 BCM_IF_ERROR_RETURN 484 (bcm_esw_port_speed_get(unit, lport, &resource->speed)); 485 BCM_IF_ERROR_RETURN 486 (bcm_esw_port_encap_get(unit, lport, &encap)); 487 resource->encap = encap; 488 489 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 490 rv = bcmi_esw_portctrl_speed_config_get(unit, port, &speed_config); 491 492 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 493 /* PM8x50's autoneg can change the number of lanes used, 494 * so if the user is in autoneg and does a bcm_port_resource_get 495 * they need to get the # of lanes being used in hardware 496 */ 497 resource->lanes = speed_config.num_lane; 498 499 resource->fec_type = speed_config.fec; 500 resource->phy_lane_config = speed_config.lane_config; 501 resource->link_training = speed_config.link_training; 502 } else 503 #endif 504 { 505 /* Upon error fetching from hardware, or if running BCMSIM, 506 * return the database values */ 507 resource->fec_type = SOC_INFO(unit).port_fec_type[lport]; 508 resource->phy_lane_config = SOC_INFO(unit).port_phy_lane_config[lport]; 509 resource->link_training = SOC_INFO(unit).port_link_training[lport]; 510 } 511 512 /* Flag BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR indicates 25G port use 50G TDM. 513 */ 514 if (SOC_PBMP_MEMBER(si->pbm_25g_use_50g_tdm, lport)) { 515 resource->flags |= BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR; 516 } 517 518 return BCM_E_NONE; 519 } 520 521 /* 522 * Function: 523 * _bcmi_xgs5_port_resource_resolve 524 * Purpose: 525 * Convert logical port number GPORT to BCM local port format. 526 * Parameters: 527 * unit - (IN) Unit number. 528 * nport - (IN) Number of elements in array resource. 529 * resource - (IN/OUT) Port resource configuration array. 530 * Returns: 531 * BCM_E_XXX 532 * Note: 533 * - Assumes caller has lock. 534 * - Resource is not NULL. 535 */ 536 STATIC int 537 _bcmi_xgs5_port_resource_resolve(int unit, 538 int nport, 539 bcm_port_resource_t *resource) 540 { 541 int i; 542 bcm_port_resource_t *pr; 543 bcmi_xgs5_dev_info_t *dev_info = BCMI_PORT_DRV_DEV_INFO(unit); 544 545 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 546 547 /* Check that logical port number is addressable and convert */ 548 BCM_IF_ERROR_RETURN 549 (bcmi_xgs5_port_addressable_local_get(unit, 550 pr->port, 551 &pr->port)); 552 553 /* Check that physical port is within the valid range */ 554 if (pr->physical_port != -1 && 555 pr->physical_port >= dev_info->phy_ports_max) { 556 LOG_ERROR(BSL_LS_BCM_PORT, 557 (BSL_META_U(unit, 558 "Invalid physical port %d\n"), 559 pr->physical_port)); 560 return BCM_E_PORT; 561 } 562 } 563 564 return BCM_E_NONE; 565 } 566 567 /* 568 * Function: 569 * bcmi_xgs5_port_resource_speed_multi_set 570 * Purpose: 571 * Modify the following port resources: 572 * - Speed 573 * - fec_type 574 * - phy_lane_config 575 * - link_training 576 * Parameters: 577 * unit - (IN) Unit number. 578 * nport - (IN) Number of elements in array resource. 579 * resource - (IN) Port resource configuration array. 580 * Returns: 581 * BCM_E_XXX 582 * Note: 583 * Assumes caller has lock. 584 */ 585 int 586 bcmi_xgs5_port_resource_speed_multi_set(int unit, 587 int nport, bcm_port_resource_t *resource) 588 { 589 590 soc_info_t *si = &SOC_INFO(unit); 591 int encap, i, soc_num, rindex, rv; 592 bcm_port_resource_t *local_resource = NULL; 593 int man_count = 0; 594 595 /* double the number of passed entries because we need to delete the ports, 596 * then add them. */ 597 soc_num = nport * 2; 598 599 local_resource = sal_alloc(soc_num * sizeof(bcm_port_resource_t), 600 "resource array"); 601 if (NULL == local_resource) { 602 return BCM_E_MEMORY; 603 } 604 605 for (i = 0; i < soc_num; i++) { 606 bcm_port_resource_t_init(&local_resource[i]); 607 } 608 609 /* Build port resource for delete */ 610 for (i = 0, rindex = 0; rindex < nport; i++, rindex++) { 611 /* Don't include Management Ports in this */ 612 if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) && 613 IS_MANAGEMENT_PORT(unit,resource[rindex].port)) { 614 /* back off one for this management port */ 615 i--; 616 continue; 617 } 618 619 local_resource[i].flags = SOC_PORT_RESOURCE_I_MAP| SOC_PORT_RESOURCE_SPEED; 620 local_resource[i].port = resource[rindex].port; 621 local_resource[i].physical_port = -1; 622 } 623 624 625 /* Build resource for add */ 626 for(i = nport, rindex = 0; rindex < nport; i++, rindex++) { 627 628 /* Do nothing except update port type in case auxiliary ports don't 629 * support flexport */ 630 /* Don't flex Management Ports; just update ptype */ 631 if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) && 632 IS_MANAGEMENT_PORT(unit,resource[rindex].port)) { 633 BCM_IF_ERROR_RETURN 634 (_bcmi_xgs5_management_port_soc_info_ptype_update(unit, 635 resource[rindex].port, resource[rindex].speed)); 636 /* back off one for this management port */ 637 i--; 638 man_count++; 639 continue; 640 } 641 642 643 /* Keep encap, lanes, phy_port the same */ 644 local_resource[i].flags = SOC_PORT_RESOURCE_I_MAP | SOC_PORT_RESOURCE_SPEED; 645 local_resource[i].port = resource[rindex].port; 646 local_resource[i].physical_port = si->port_l2p_mapping[resource[rindex].port]; 647 local_resource[i].speed = resource[rindex].speed; 648 local_resource[i].lanes = si->port_num_lanes[resource[rindex].port]; 649 650 /* Get current port encap */ 651 rv = bcm_esw_port_encap_get(unit, resource[rindex].port, 652 &encap); 653 if (!BCM_SUCCESS(rv)) { 654 goto cleanup; 655 } 656 local_resource[i].encap = encap; 657 658 /* Required Fields for new speed set */ 659 local_resource[i].fec_type = resource[rindex].fec_type; 660 local_resource[i].phy_lane_config = resource[rindex].phy_lane_config; 661 local_resource[i].link_training = resource[rindex].link_training; 662 663 } 664 665 rv = bcmi_xgs5_port_resource_multi_set(unit, soc_num - (man_count * 2), local_resource); 666 667 cleanup: 668 if (NULL != local_resource) { 669 sal_free(local_resource); 670 } 671 672 return rv; 673 } 674 675 /* 676 * Function: 677 * _bcmi_xgs5_port_flexible_validate 678 * Purpose: 679 * Check that FlexPort operation is valid on given physical port. 680 * Parameters: 681 * unit - (IN) Unit number. 682 * phy_port - (IN) Physical port number 683 * Returns: 684 * TRUE or FALSE. 685 */ 686 STATIC int 687 _bcmi_xgs5_port_flexible_validate(int unit, int phy_port) 688 { 689 if (phy_port != -1 && !BCMI_PORT_DRV_PHY_INFO(unit, phy_port).flex) { 690 LOG_ERROR(BSL_LS_BCM_PORT, 691 (BSL_META_U(unit, 692 "FlexPort operation is not enabled on " 693 "physical port %d\n"), 694 phy_port)); 695 return BCM_E_PARAM; 696 } 697 698 return BCM_E_NONE; 699 } 700 701 /* 702 * Function: 703 * _soc_td2p_phy_port_lanes_valid 704 * Purpose: 705 * Check that given lane setting is valid for physical port. 706 * Parameters: 707 * unit - (IN) Unit number. 708 * port - (IN) Base physical port. 709 * lanes - (IN) Number of PHY lanes. 710 * Returns: 711 * SOC_E_XXX 712 */ 713 STATIC int 714 _bcmi_xgs5_port_lanes_validate(int unit, int phy_port, int lanes) 715 { 716 uint32 lane_mask; 717 718 switch (lanes) { 719 case 1: 720 lane_mask = BCMI_XGS5_PORT_LANES_1; 721 break; 722 case 2: 723 lane_mask = BCMI_XGS5_PORT_LANES_2; 724 break; 725 case 4: 726 lane_mask = BCMI_XGS5_PORT_LANES_4; 727 break; 728 case 8: 729 lane_mask = BCMI_XGS5_PORT_LANES_8; 730 break; 731 case 10: 732 lane_mask = BCMI_XGS5_PORT_LANES_10; 733 break; 734 case 12: 735 lane_mask = BCMI_XGS5_PORT_LANES_12; 736 break; 737 default: 738 LOG_ERROR(BSL_LS_BCM_PORT, 739 (BSL_META_U(unit, 740 "Invalid number of lanes for " 741 "physical_port=%d, lanes=%d\n"), 742 phy_port, lanes)); 743 return BCM_E_PARAM; 744 } 745 746 if (!(BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & lane_mask)) { 747 LOG_ERROR(BSL_LS_BCM_PORT, 748 (BSL_META_U(unit, 749 "Invalid lane configuration for " 750 "physical_port=%d, lane=%d, " 751 "valid_lanes=%s %s %s %s %s %s\n"), 752 phy_port, lanes, 753 (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & 754 BCMI_XGS5_PORT_LANES_1) ? "1" : "", 755 (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & 756 BCMI_XGS5_PORT_LANES_2) ? "2" : "", 757 (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & 758 BCMI_XGS5_PORT_LANES_4) ? "4" : "", 759 (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & 760 BCMI_XGS5_PORT_LANES_8) ? "8" : "", 761 (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & 762 BCMI_XGS5_PORT_LANES_10) ? "10" : "", 763 (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & 764 BCMI_XGS5_PORT_LANES_12) ? "12" : "")); 765 766 return BCM_E_PARAM; 767 } 768 769 return BCM_E_NONE; 770 } 771 772 /* 773 * Function: 774 * _bcmi_xgs5_port_speed_validate 775 * Purpose: 776 * Check that given speed is valid for the number of serdes lanes. 777 * Parameters: 778 * unit - (IN) Unit number. 779 * port - (IN) Logical port number. 780 * phy_port - (IN) Physical port number. 781 * lanes - (IN) Number of PHY lanes. 782 * encap - (IN) Encap mode. 783 * speed - (IN) Port rate to check. 784 * Returns: 785 * SOC_E_XXX 786 */ 787 STATIC int 788 _bcmi_xgs5_port_speed_validate(int unit, int port, int phy_port, int lanes, 789 int encap, int speed) 790 { 791 uint32 speed_mask; 792 char speed_valid[256], *pos; 793 int i, string_len, len, is_hg_speed; 794 char *port_ability_speed_string[] = SOC_PA_SPEED_STRING; 795 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 796 portmod_dispatch_type_t pm_type; 797 int rv, existing_physical_port, autoneg = 0; 798 #endif 799 800 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 801 IS_MANAGEMENT_PORT(unit, port)) { 802 return BCM_E_NONE; 803 } 804 805 if (speed == 1000 && encap != BCM_PORT_ENCAP_IEEE) { 806 LOG_ERROR(BSL_LS_BCM_PORT, 807 (BSL_META_U(unit, 808 "Speed and encapsulation configuration unmatch " 809 "for port=%d: 1G ports don't support HG mode.\n"), 810 port)); 811 return BCM_E_PARAM; 812 } 813 814 if (speed > lanes * BCMI_PORT_DRV_PHY_INFO(unit, phy_port).max_lane_speed) { 815 LOG_ERROR(BSL_LS_BCM_PORT, 816 (BSL_META_U(unit, 817 "Invalid speed port=%d: Max lane speed is %d.\n"), 818 port, 819 BCMI_PORT_DRV_PHY_INFO(unit, phy_port).max_lane_speed)); 820 return BCM_E_PARAM; 821 } 822 823 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 824 /* PM8x50 don't support bcm_port_ability. Speeds will be verified 825 * in portmod, but check to make sure the device supports the speed too */ 826 BCM_IF_ERROR_RETURN(portmod_phy_pm_type_get(unit, phy_port, &pm_type)); 827 if (pm_type == portmodDispatchTypePm8x50) { 828 829 /* Autoneg in the PM8x50 allows scenarios like 50G with 4 lanes: 830 * Starting with a 200G port (4 lanes), autoneg can scale down to 1 lane 831 * with 50G. So we don't want to do device speed/lane validations 832 * if the port is in autoneg 833 */ 834 existing_physical_port = SOC_INFO(unit).port_l2p_mapping[port]; 835 if (existing_physical_port != -1) { 836 BCM_IF_ERROR_RETURN(bcm_esw_port_autoneg_get(unit, 837 port, &autoneg)); 838 rv = BCM_E_NONE; 839 } 840 841 if (autoneg == 0) { 842 rv = BCM_E_CONFIG; 843 844 if (BCM_ESW_PORT_DRV(unit) != NULL) { 845 if (BCM_ESW_PORT_DRV(unit)->device_speed_check != NULL) { 846 rv = (BCM_ESW_PORT_DRV(unit)->device_speed_check(unit, 847 speed, lanes)); 848 } 849 } 850 /* speed and lane configuration wasn't found */ 851 if (BCM_FAILURE(rv)) { 852 LOG_ERROR(BSL_LS_BCM_PORT, 853 (BSL_META_U(unit, 854 "Invalid speed configuration for " 855 "port=%d, speed=%d, lanes=%d\n"), 856 port, speed, lanes)); 857 return rv; 858 } 859 } 860 861 return rv; 862 } 863 #endif 864 865 speed_mask = SOC_PA_SPEED(speed); 866 is_hg_speed = SOC_PA_IS_HG_SPEED(speed_mask); 867 868 /* Expect non-higig speed for IEEE encapsulation mode. */ 869 if (is_hg_speed && encap == BCM_PORT_ENCAP_IEEE) { 870 LOG_ERROR(BSL_LS_BCM_PORT, 871 (BSL_META_U(unit, 872 "Speed and encapsulation configuration unmatch " 873 "for port=%d, speed=%d, encap=%d\n"), 874 port, speed, encap)); 875 return BCM_E_PARAM; 876 } 877 878 if (!(BCMI_PORT_DRV_DEV_INFO(unit)->speed_valid[lanes] & speed_mask)) { 879 LOG_ERROR(BSL_LS_BCM_PORT, 880 (BSL_META_U(unit, 881 "Invalid speed configuration for " 882 "port=%d, speed=%d\n"), 883 port, speed)); 884 885 sal_memset(speed_valid, 0, sizeof(speed_valid)); 886 string_len = sizeof(port_ability_speed_string)/sizeof(char *); 887 pos = speed_valid; 888 for (i = 0;i < string_len;i++){ 889 if (BCMI_PORT_DRV_DEV_INFO(unit)->speed_valid[lanes] & (1<<i)){ 890 len = sal_sprintf(pos, "%s ", port_ability_speed_string[i]); 891 if (len < 0) { 892 LOG_ERROR(BSL_LS_BCM_COMMON, 893 (BSL_META_U(unit, 894 "len = %d\n"), 895 len)); 896 return BCM_E_RESOURCE; 897 } 898 pos += len; 899 } 900 } 901 902 LOG_ERROR(BSL_LS_BCM_PORT, 903 (BSL_META_U(unit, "valid speeds: %s\n"), speed_valid)); 904 return BCM_E_PARAM; 905 } 906 907 return BCM_E_NONE; 908 } 909 910 /* 911 * Function: 912 * _bcmi_xgs5_port_encap_validate 913 * Purpose: 914 * Check that given encap is valid for unit. 915 * Parameters: 916 * unit - (IN) Unit number. 917 * port - (IN) Logical port number. 918 * phy_port - (IN) Physical port number. 919 * encap - (IN) Encap mode. 920 * Returns: 921 * SOC_E_XXX 922 */ 923 STATIC int 924 _bcmi_xgs5_port_encap_validate(int unit, int port, int phy_port, 925 int encap) 926 { 927 uint32 encap_mask; 928 929 switch (encap) { 930 case BCM_PORT_ENCAP_IEEE: 931 encap_mask = BCM_PA_ENCAP_IEEE; 932 break; 933 case BCM_PORT_ENCAP_HIGIG: 934 encap_mask = BCM_PA_ENCAP_HIGIG; 935 break; 936 case BCM_PORT_ENCAP_B5632: 937 encap_mask = BCM_PA_ENCAP_B5632; 938 break; 939 case BCM_PORT_ENCAP_HIGIG2: 940 encap_mask = BCM_PA_ENCAP_HIGIG2; 941 break; 942 case BCM_PORT_ENCAP_HIGIG2_LITE: 943 encap_mask = BCM_PA_ENCAP_HIGIG2_LITE; 944 break; 945 case BCM_PORT_ENCAP_HIGIG2_L2: 946 encap_mask = BCM_PA_ENCAP_HIGIG2_L2; 947 break; 948 case BCM_PORT_ENCAP_HIGIG2_IP_GRE: 949 encap_mask = BCM_PA_ENCAP_HIGIG2_IP_GRE; 950 break; 951 case BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET: 952 encap_mask = BCM_PA_ENCAP_HIGIG_OVER_ETHERNET; 953 break; 954 default: 955 LOG_ERROR(BSL_LS_BCM_PORT, 956 (BSL_META_U(unit, 957 "Invalid encapsulation for " 958 "unit=%d, encap=%d\n"), 959 unit, encap)); 960 return BCM_E_PARAM; 961 } 962 963 if (!(BCMI_PORT_DRV_DEV_INFO(unit)->encap_mask & encap_mask)) { 964 LOG_ERROR(BSL_LS_BCM_PORT, 965 (BSL_META_U(unit, 966 "Invalid encapsulation configuration for " 967 "unit=%d, encap=%d\n"), 968 unit, encap)); 969 return BCM_E_PARAM; 970 } 971 972 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 973 IS_MANAGEMENT_PORT(unit, port)) { 974 return BCM_E_NONE; 975 } 976 977 if (BCMI_PORT_DRV_DEV_INFO(unit)->phy_port_info[phy_port].force_hg && 978 !(BCMI_PORT_DRV_DEV_INFO(unit)->hg_encap_mask & encap_mask)) { 979 LOG_ERROR(BSL_LS_BCM_PORT, 980 (BSL_META_U(unit, 981 "Encapsulation configuration %d is invalid on " 982 "hg-only port %d of unit %d\n"), 983 encap, port, unit)); 984 return BCM_E_PARAM; 985 } 986 987 return BCM_E_NONE; 988 } 989 990 /* 991 * Function: 992 * _bcmi_xgs5_port_flex_max_validate 993 * Purpose: 994 * Check that the port num in a port macro shall not exceed the max num 995 * that it could flex to. 996 * Parameters: 997 * unit - (IN) Unit number. 998 * nport - (IN) Number of elements in array resource. 999 * resource - (IN/OUT) Port resource configuration array. 1000 * Returns: 1001 * BCM_E_XXX 1002 * Note: 1003 * - Assumes caller has lock. 1004 * - Resource is not NULL. 1005 */ 1006 STATIC int 1007 _bcmi_xgs5_port_flex_max_validate(int unit, 1008 int nport, 1009 bcm_port_resource_t *resource) 1010 { 1011 soc_info_t *si = &SOC_INFO(unit); 1012 bcm_port_resource_t *pr; 1013 int logic_port, phy_port, port_idx, blk; 1014 pbmp_t *blk_bitmap; 1015 int port_count; 1016 int i; 1017 1018 blk_bitmap = sal_alloc(SOC_MAX_NUM_BLKS * sizeof(pbmp_t), "blk_bitmap"); 1019 sal_memcpy(blk_bitmap, si->block_bitmap, SOC_MAX_NUM_BLKS * sizeof(pbmp_t)); 1020 1021 /* Entries to delete ports */ 1022 for (i = 0, pr = &resource[0]; (i < nport) && pr->physical_port == -1; 1023 i++, pr++) { 1024 logic_port = pr->port; 1025 phy_port = si->port_l2p_mapping[logic_port]; 1026 if (phy_port == -1) { 1027 continue; 1028 } 1029 1030 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 1031 port_idx++) { 1032 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 1033 if (blk < 0) { /* End of block list of each port */ 1034 break; 1035 } 1036 SOC_PBMP_COUNT(blk_bitmap[blk], port_count); 1037 if (port_count == 0) { 1038 LOG_ERROR(BSL_LS_BCM_PORT, 1039 (BSL_META_U(unit, 1040 "Port Macro %d doesn't have valid port " 1041 "to delete.\n"), 1042 SOC_BLOCK_NUMBER(unit,blk))); 1043 sal_free(blk_bitmap); 1044 return BCM_E_INTERNAL; 1045 } 1046 if (SOC_PBMP_MEMBER(blk_bitmap[blk], logic_port)) { 1047 SOC_PBMP_PORT_REMOVE(blk_bitmap[blk], logic_port); 1048 } 1049 } /* For each block in the given port */ 1050 } 1051 1052 /* Entries to add ports */ 1053 for (;i < nport; i++) { 1054 pr = &resource[i]; 1055 logic_port = pr->port; 1056 phy_port = pr->physical_port; 1057 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 1058 port_idx++) { 1059 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 1060 if (blk < 0) { /* End of block list of each port */ 1061 break; 1062 } 1063 if (!SOC_PBMP_MEMBER(blk_bitmap[blk], logic_port)) { 1064 SOC_PBMP_PORT_ADD(blk_bitmap[blk], logic_port); 1065 SOC_PBMP_COUNT(blk_bitmap[blk], port_count); 1066 if (port_count > si->pm_max_ports[blk]) { 1067 LOG_ERROR(BSL_LS_BCM_PORT, 1068 (BSL_META_U(unit, 1069 "Port num on Port Macro %d would " 1070 "exceed the Max num %d that it could " 1071 "flex to.\n"), 1072 SOC_BLOCK_NUMBER(unit,blk), 1073 si->pm_max_ports[blk])); 1074 sal_free(blk_bitmap); 1075 return BCM_E_PARAM; 1076 } 1077 } 1078 } /* For each block in the given port */ 1079 } 1080 1081 sal_free(blk_bitmap); 1082 return BCM_E_NONE; 1083 } 1084 1085 /* 1086 * Function: 1087 * _bcmi_xgs5_port_resource_input_validate 1088 * Purpose: 1089 * Validate function input requirements. 1090 * 1091 * This routine checks for function semantics and guidelines 1092 * from the API perspective: 1093 * - Check that logical port number is valid and convert GPORT port 1094 * format to BCM local port format. 1095 * - Logical and physical port number must be within valid range. 1096 * - Check the order of elements in array, 'delete' operations must 1097 * be placed first in array. 1098 * - Check that physical port is flexible. 1099 * - Check that lanes, speed and encap are valid. 1100 * Parameters: 1101 * unit - (IN) Unit number. 1102 * nport - (IN) Number of elements in array resource. 1103 * resource - (IN/OUT) Port resource configuration array. 1104 * Returns: 1105 * BCM_E_XXX 1106 * Note: 1107 * - Assumes caller has lock. 1108 * - Resource is not NULL. 1109 */ 1110 STATIC int 1111 _bcmi_xgs5_port_resource_input_validate(int unit, 1112 int nport, 1113 bcm_port_resource_t *resource) 1114 { 1115 int i; 1116 bcm_port_resource_t *pr; 1117 int enable; 1118 int delete = 1; 1119 soc_info_t *si = &SOC_INFO(unit); 1120 int old_phy_port; 1121 pbmp_t del_pbmp; 1122 1123 1124 LOG_VERBOSE(BSL_LS_BCM_PORT, 1125 (BSL_META_U(unit, 1126 "==== PORT RESOURCE INPUT VALIDATE ====\n"))); 1127 1128 /* Convert port format and validate logical and physical port numbers */ 1129 BCM_IF_ERROR_RETURN 1130 (_bcmi_xgs5_port_resource_resolve(unit, 1131 nport, resource)); 1132 1133 SOC_PBMP_CLEAR(del_pbmp); 1134 1135 /* Check array order and port state disable */ 1136 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 1137 1138 /* Check that delete operations are first */ 1139 if (pr->physical_port != -1) { /* First non-delete found */ 1140 delete = 0; 1141 } else if (pr->physical_port == -1) { 1142 if (!delete) { 1143 LOG_ERROR(BSL_LS_BCM_PORT, 1144 (BSL_META_U(unit, 1145 "Delete operations must be " 1146 "first in array\n"))); 1147 return BCM_E_PARAM; 1148 } 1149 SOC_PBMP_PORT_ADD(del_pbmp, pr->port); 1150 } 1151 1152 old_phy_port = si->port_l2p_mapping[pr->port]; 1153 1154 /* Check if flex is enabled on port */ 1155 if (!(pr->flags & SOC_PORT_RESOURCE_I_MAP)) { 1156 BCM_IF_ERROR_RETURN 1157 (_bcmi_xgs5_port_flexible_validate(unit, pr->physical_port)); 1158 1159 BCM_IF_ERROR_RETURN 1160 (_bcmi_xgs5_port_flexible_validate(unit, old_phy_port)); 1161 } 1162 1163 if (si->port_l2p_mapping[pr->port] != -1 && 1164 !(pr->flags & SOC_PORT_RESOURCE_SPEED)) { 1165 /* Check that ports are disabled */ 1166 BCM_IF_ERROR_RETURN 1167 (bcm_esw_port_enable_get(unit, pr->port, &enable)); 1168 if (enable) { 1169 LOG_ERROR(BSL_LS_BCM_PORT, 1170 (BSL_META_U(unit, 1171 "Port %d needs to be disabled\n"), 1172 pr->port)); 1173 return BCM_E_BUSY; 1174 } 1175 } 1176 1177 if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) && 1178 SOC_PBMP_MEMBER(BCMI_PORT_DRV_DEV_INFO(unit)->aux_pbm, pr->port)) { 1179 LOG_ERROR(BSL_LS_BCM_PORT, 1180 (BSL_META_U(unit, 1181 "FlexPort is not supported for auxiliary " 1182 "port %d.\n"), 1183 pr->port)); 1184 return BCM_E_PARAM; 1185 } 1186 1187 if (pr->physical_port != -1) { 1188 1189 /* Delete existing ports which are part of the FlexPort operation */ 1190 if (old_phy_port != -1 && !SOC_PBMP_MEMBER(del_pbmp, pr->port)) { 1191 LOG_ERROR(BSL_LS_BCM_PORT, 1192 (BSL_META_U(unit, 1193 "Delete entry is required for Port %d\n"), 1194 pr->port)); 1195 return BCM_E_PARAM; 1196 } 1197 1198 /* Check Lanes assignment */ 1199 BCM_IF_ERROR_RETURN 1200 (_bcmi_xgs5_port_lanes_validate(unit, pr->physical_port, 1201 pr->lanes)); 1202 1203 /* Check speeds */ 1204 BCM_IF_ERROR_RETURN 1205 (_bcmi_xgs5_port_speed_validate(unit, pr->port, 1206 pr->physical_port, 1207 pr->lanes, pr->encap, 1208 pr->speed)); 1209 1210 /* Check Encapsulation */ 1211 BCM_IF_ERROR_RETURN 1212 (_bcmi_xgs5_port_encap_validate(unit, pr->port, 1213 pr->physical_port, 1214 pr->encap)); 1215 } 1216 } 1217 1218 /* Check that the port num in a port macro shall not exceed the max num 1219 * that it could flex to. */ 1220 BCM_IF_ERROR_RETURN 1221 (_bcmi_xgs5_port_flex_max_validate(unit, nport, resource)); 1222 1223 return BCM_E_NONE; 1224 } 1225 1226 /* 1227 * Function: 1228 * _bcmi_xgs5_port_resource_op_set 1229 * Purpose: 1230 * Get the type of FlexPort operations/changes: 1231 * none, add, delete remap, lanes, speed, encap. 1232 * 1233 * Parameters: 1234 * unit - (IN) Unit number. 1235 * nport - (IN) Number of elements in array resource. 1236 * resource - (IN) BCM port resource configuration array. 1237 * soc_resource - (IN) SOC Port resource configuration array. 1238 * - (OUT) resource[i].op is set with FlexPort operation 1239 * op - (OUT) FlexPort operation BCMI_XGS5_PORT_RESOURCE_OP_... 1240 * Returns: 1241 * BCM_E_XXX 1242 * Note: 1243 * Assumes caller has lock. 1244 * Resource is not NULL. 1245 * Logical port in 'resource' is in BCM port format (non GPORT). 1246 * Example: 1247 * L1 --> -1 (current mapped to P1 with 1 lane), op is LANES 1248 * L2 --> -1 (current mapped to P2 with 1 lane), op is REMAP 1249 * L3 --> -1 (current mapped to P3 with 1 lane), op is DELETE 1250 * L1 --> P1 (with 4 lane) , op is SAME 1251 * L2 --> P5 (with 1 lane) , op is REMAP 1252 * L9 --> P9 (with 4 lane) , op is NEW 1253 * L6 --> P6 (speed/encap update) , op is SPEED/ENCAP 1254 */ 1255 STATIC int 1256 _bcmi_xgs5_port_resource_op_set(int unit, int nport, 1257 bcm_port_resource_t *resource, 1258 soc_port_resource_t *soc_resource, 1259 int *op) 1260 { 1261 int i; 1262 bcm_port_resource_t *r, cr; 1263 soc_port_resource_t *pr; 1264 soc_info_t *si = &SOC_INFO(unit); 1265 int lport, pport, pre_pport, iport, pre_iport; 1266 pbmp_t att_pbm, remap_pbm, lane_pbm, speed_pbm, encap_pbm; 1267 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 1268 portmod_dispatch_type_t pm_type; 1269 int autoneg = 0; 1270 #endif 1271 1272 *op = BCMI_XGS5_PORT_RESOURCE_OP_NONE; 1273 SOC_PBMP_CLEAR(att_pbm); 1274 SOC_PBMP_CLEAR(remap_pbm); 1275 SOC_PBMP_CLEAR(lane_pbm); 1276 SOC_PBMP_CLEAR(speed_pbm); 1277 SOC_PBMP_CLEAR(encap_pbm); 1278 1279 for (i = nport-1, pr = &soc_resource[nport-1], r = &resource[nport-1]; 1280 i >= 0; i--, pr--, r--) { 1281 lport = pr->logical_port; 1282 pport = pr->physical_port; 1283 pre_pport = si->port_l2p_mapping[lport]; 1284 iport = pr->idb_port; 1285 pre_iport = si->port_l2i_mapping[lport]; 1286 1287 if (pport != -1) { 1288 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 1289 /* If it's PM8x50, need to check if fec_type, link training 1290 * or phy lane config changed */ 1291 BCM_IF_ERROR_RETURN(portmod_phy_pm_type_get(unit, pport, &pm_type)); 1292 #endif 1293 1294 /* Entries for port-attach */ 1295 SOC_PBMP_PORT_ADD(att_pbm, lport); 1296 1297 /* Set op to ADD if port is non-existing */ 1298 if (pre_pport == -1) { 1299 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_ADD; 1300 } else { 1301 if ((pport != pre_pport) || (iport != pre_iport)) { 1302 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_REMAP; 1303 SOC_PBMP_PORT_ADD(remap_pbm, lport); 1304 } else { 1305 bcm_port_resource_t_init(&cr); 1306 BCM_IF_ERROR_RETURN 1307 (bcm_esw_port_resource_get(unit, lport, &cr)); 1308 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 1309 if (pm_type == portmodDispatchTypePm8x50) { 1310 /* On PM8x50, number of lanes can be changed during AN. 1311 * However, BCMI_XGS5_PORT_RESOURCE_OP_LANES should not 1312 * be set for AN ports. 1313 */ 1314 BCM_IF_ERROR_RETURN 1315 (bcm_esw_port_autoneg_get(unit, lport, &autoneg)); 1316 } 1317 if (!autoneg) 1318 #endif 1319 { 1320 if (r->lanes != cr.lanes) { 1321 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_LANES; 1322 SOC_PBMP_PORT_ADD(lane_pbm, lport); 1323 } 1324 } 1325 if (r->speed != si->port_init_speed[lport] || 1326 r->speed != cr.speed) { 1327 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_SPEED; 1328 SOC_PBMP_PORT_ADD(speed_pbm, lport); 1329 } 1330 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 1331 if (pm_type == portmodDispatchTypePm8x50) { 1332 /* Always set the Speed Op for PM8x50 if there's a port 1333 * passed in. There may have been a portmod VCO change 1334 * operation that requires the port to be reconfigured 1335 */ 1336 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_SPEED; 1337 SOC_PBMP_PORT_ADD(speed_pbm, lport); 1338 } 1339 #endif 1340 if (r->encap != cr.encap) { 1341 if (BCMI_PORT_DRV_DEV_INFO(unit)->encap_change_flex) { 1342 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX; 1343 SOC_PBMP_PORT_ADD(encap_pbm, lport); 1344 } else { 1345 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_ENCAP; 1346 } 1347 } 1348 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, lport)) { 1349 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE; 1350 } 1351 1352 /* Only TDM calendar change. Currently only between 25G port use 25G 1353 * TDM calendar and 25G port use 50G TDM. 1354 */ 1355 if ((SOC_PBMP_MEMBER(si->pbm_25g_use_50g_tdm, lport) && 1356 !(pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR) 1357 && (r->speed == 25000)) 1358 || 1359 (!SOC_PBMP_MEMBER(si->pbm_25g_use_50g_tdm, lport) && 1360 (cr.speed == 25000) && 1361 (pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR))) 1362 { 1363 pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR; 1364 } 1365 } 1366 } 1367 } else { 1368 /* Entries for port-detach */ 1369 /* Lane_num/speed/encap update don't require delete-port */ 1370 if (!SOC_PBMP_MEMBER(att_pbm, lport)) { 1371 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_DEL; 1372 } else if (SOC_PBMP_MEMBER(remap_pbm, lport)) { 1373 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_REMAP; 1374 } else if (SOC_PBMP_MEMBER(lane_pbm, lport)) { 1375 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_LANES; 1376 } else if (SOC_PBMP_MEMBER(speed_pbm, lport)) { 1377 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_SPEED; 1378 } else if (SOC_PBMP_MEMBER(encap_pbm, lport)) { 1379 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX; 1380 } else { 1381 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_NONE; 1382 } 1383 } 1384 *op |= pr->op; 1385 } 1386 1387 return BCM_E_NONE; 1388 } 1389 1390 /* 1391 * Function: 1392 * _bcmi_xgs5_port_soc_schedule_state_init 1393 * Purpose: 1394 * Construct soc_port_schedule_state_t structure which will pass to 1395 * FlexPort Tier1 API as input. 1396 * 1397 * Parameters: 1398 * unit - (IN) Unit number. 1399 * nport - (IN) Number of elements in array resource. 1400 * soc_resource - (IN) SOC Port resource configuration array. 1401 * op - (IN) Operation code 1402 * port_schedule_state - (OUT) soc_port_schedule_state_t. 1403 * Returns: 1404 * BCM_E_XXX 1405 * Note: 1406 * Assumes caller has lock. 1407 * Resource is not NULL. 1408 * Logical port in 'resource' is in BCM port format (non GPORT). 1409 */ 1410 STATIC int 1411 _bcmi_xgs5_port_soc_schedule_state_init(int unit, int nport, int op, 1412 soc_port_resource_t *soc_resource, 1413 soc_port_schedule_state_t *port_schedule_state) 1414 { 1415 soc_info_t *si = &SOC_INFO(unit); 1416 soc_port_map_type_t *in_port_map; 1417 soc_asf_prop_t *asf; 1418 int lossless, port, asf_mode, asf_prof; 1419 int speed, lanes, encap; 1420 int rv; 1421 #ifdef BCM_TOMAHAWK3_SUPPORT 1422 int dpr_freq; 1423 #endif 1424 1425 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 1426 BCMI_PORT_DRV_DEV_INFO(unit)->mmu_lossless); 1427 1428 /* port_schedule_state structure initialization */ 1429 sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t)); 1430 1431 /* Check the size, because port_schedule_state->resource is statically 1432 * allocated and we don't want to overflow the buffer */ 1433 if (nport > MAX_NUM_FLEXPORTS) { 1434 LOG_VERBOSE(BSL_LS_BCM_PORT, 1435 (BSL_META_U(unit, 1436 "Number of flexports (%d) exceeds maximum for " 1437 "structure soc_port_schedule_state_t (%d)\n"), 1438 nport, MAX_NUM_FLEXPORTS)); 1439 return BCM_E_INTERNAL; 1440 } 1441 1442 port_schedule_state->nport = nport; 1443 sal_memcpy(port_schedule_state->resource, soc_resource, 1444 nport * sizeof(soc_port_resource_t)); 1445 1446 port_schedule_state->frequency = si->frequency; 1447 port_schedule_state->bandwidth = si->bandwidth; 1448 port_schedule_state->io_bandwidth = si->io_bandwidth; 1449 port_schedule_state->lossless = lossless; 1450 port_schedule_state->is_flexport = TRUE; 1451 1452 /* ASF Setting */ 1453 if (soc_feature(unit, soc_feature_asf_multimode)) { 1454 1455 if (BCMI_PORT_SCHEDULE_STATE_INIT_OP_ASF(op)) { 1456 asf = &port_schedule_state->cutthru_prop; 1457 1458 asf->switch_bypass_mode = SOC_SWITCH_BYPASS_MODE(unit); 1459 1460 PBMP_PORT_ITER(unit, port) { 1461 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 1462 IS_MANAGEMENT_PORT(unit, port)) { 1463 continue; 1464 } 1465 BCM_IF_ERROR_RETURN 1466 (bcm_esw_switch_control_port_get(unit, port, 1467 bcmSwitchAlternateStoreForward, 1468 &asf_mode)); 1469 asf->asf_modes[port] = asf_mode; 1470 } 1471 1472 asf_prof = BCMI_PORT_DRV_DEV_INFO(unit)->asf_prof_default; 1473 asf_prof = soc_property_get(unit, spn_ASF_MEM_PROFILE, asf_prof); 1474 1475 if (!((asf_prof >= _SOC_ASF_MEM_PROFILE_NONE) && 1476 (asf_prof < _SOC_ASF_MEM_PROFILE_END))) { 1477 asf_prof = BCMI_PORT_DRV_DEV_INFO(unit)->asf_prof_default; 1478 } 1479 asf->asf_mem_prof = asf_prof; 1480 } 1481 } 1482 1483 /* Input port mapping */ 1484 in_port_map = &port_schedule_state->in_port_map; 1485 PBMP_PORT_ITER(unit, port) { 1486 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 1487 continue; 1488 } 1489 1490 speed = si->port_init_speed[port]; 1491 lanes = si->port_num_lanes[port]; 1492 if (LOG_CHECK(BSL_LS_BCM_PORT|BSL_VERBOSE)) { 1493 if (IS_HG_PORT(unit, port)) { 1494 if (soc_feature(unit, soc_feature_no_higig_plus)) { 1495 encap = SOC_ENCAP_HIGIG2; 1496 } else { 1497 encap = soc_property_port_get(unit, port, 1498 spn_HIGIG2_HDR_MODE, 0) ? 1499 SOC_ENCAP_HIGIG2 : SOC_ENCAP_HIGIG; 1500 } 1501 } else { 1502 encap = SOC_ENCAP_IEEE; 1503 } 1504 1505 rv = _bcmi_xgs5_port_speed_validate(unit, port, 1506 si->port_l2p_mapping[port], 1507 lanes, encap, speed); 1508 if (BCM_FAILURE(rv)) { 1509 LOG_VERBOSE(BSL_LS_BCM_PORT, 1510 (BSL_META_U(unit, 1511 "Invalid configuration for existing " 1512 "port %d: physical_port=%d, speed=%d, " 1513 "lanes=%d, encap=%d\n"), 1514 port, si->port_l2p_mapping[port], speed, 1515 lanes, encap)); 1516 } 1517 } 1518 if (speed < BCMI_PORT_DRV_DEV_INFO(unit)->tdm_speed_min) { 1519 speed = BCMI_PORT_DRV_DEV_INFO(unit)->tdm_speed_min; 1520 } 1521 in_port_map->log_port_speed[port] = speed; 1522 in_port_map->port_num_lanes[port] = lanes; 1523 #ifdef BCM_MAVERICK2_SUPPORT 1524 if (SOC_IS_MAVERICK2(unit) && IS_MANAGEMENT_PORT(unit, port)) { 1525 in_port_map->port_num_lanes[port] = 1; 1526 } 1527 #endif 1528 } 1529 1530 #ifdef BCM_TOMAHAWK3_SUPPORT 1531 /* DPR Frequency is stored in this unused field so that MMU can have 1532 PFC Optimized settings */ 1533 if (SOC_IS_TOMAHAWK3(unit)) { 1534 dpr_freq = soc_property_get(unit, spn_DPR_CLOCK_FREQUENCY, -1); 1535 in_port_map->port_p2PBLK_inst_mapping[0] = dpr_freq; 1536 } 1537 #endif 1538 1539 sal_memcpy(in_port_map->port_p2l_mapping, si->port_p2l_mapping, 1540 sizeof(int)*SOC_MAX_NUM_PORTS); 1541 sal_memcpy(in_port_map->port_l2p_mapping, si->port_l2p_mapping, 1542 sizeof(int)*SOC_MAX_NUM_PORTS); 1543 sal_memcpy(in_port_map->port_p2m_mapping, si->port_p2m_mapping, 1544 sizeof(int)*SOC_MAX_NUM_PORTS); 1545 sal_memcpy(in_port_map->port_m2p_mapping, si->port_m2p_mapping, 1546 sizeof(int)*SOC_MAX_NUM_MMU_PORTS); 1547 sal_memcpy(in_port_map->port_l2i_mapping, si->port_l2i_mapping, 1548 sizeof(int)*SOC_MAX_NUM_PORTS); 1549 sal_memcpy(&in_port_map->physical_pbm, &si->physical_pbm, sizeof(pbmp_t)); 1550 sal_memcpy(&in_port_map->hg2_pbm, &si->hg2_pbm, sizeof(pbmp_t)); 1551 sal_memcpy(&in_port_map->management_pbm, &si->management_pbm, 1552 sizeof(pbmp_t)); 1553 sal_memcpy(&in_port_map->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t)); 1554 1555 /* TDM info */ 1556 if (BCMI_PORT_SCHEDULE_STATE_INIT_OP_TDM(op)) { 1557 if (BCMI_PORT_DRV_CALL(unit)->pre_flexport_tdm) { 1558 BCM_IF_ERROR_RETURN 1559 (BCMI_PORT_DRV_CALL(unit)->pre_flexport_tdm(unit, 1560 port_schedule_state)); 1561 } 1562 } 1563 1564 return BCM_E_NONE; 1565 } 1566 1567 /* 1568 * Function: 1569 * _bcmi_xgs5_port_info_post_flex 1570 * Purpose: 1571 * Populate Post Flexport soc info. 1572 * 1573 * Certain validations need the post FlexPort information for all 1574 * the ports at the same time (mostly contained in SOC_INFO). 1575 * The global SOC_INFO is updated after the validation phase so 1576 * the information is not available yet. 1577 * Parameters: 1578 * unit - (IN) Unit number. 1579 * port_schedule_state - (IN/OUT) soc_port_schedule_state_t. 1580 * Returns: 1581 * SOC_E_XXX 1582 * Note: 1583 * This function does NOT modify the global SOC_INFO SW database, 1584 * the post information is returned in the local argument. 1585 * 1586 * Assumes values in resource are valid (logical port, etc.) 1587 */ 1588 STATIC int 1589 _bcmi_xgs5_port_info_post_flex(int unit, 1590 soc_port_schedule_state_t *port_schedule_state) 1591 { 1592 soc_info_t *si = &SOC_INFO(unit); 1593 soc_port_resource_t *pr; 1594 int nport = port_schedule_state->nport; 1595 soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map; 1596 int i; 1597 int logic_port, phy_port, mmu_port; 1598 1599 /* Get current information */ 1600 sal_memcpy(post_pi, &port_schedule_state->in_port_map, 1601 sizeof(soc_port_map_type_t)); 1602 1603 /* First process 'delete' mappings */ 1604 for (i = 0, pr = port_schedule_state->resource; 1605 (i < nport) && (pr->physical_port == -1); 1606 i++, pr++) { 1607 logic_port = pr->logical_port; 1608 1609 post_pi->log_port_speed[logic_port] = 0; 1610 post_pi->port_num_lanes[logic_port] = 0; 1611 SOC_PBMP_PORT_REMOVE(post_pi->oversub_pbm, logic_port); 1612 SOC_PBMP_PORT_REMOVE(post_pi->hg2_pbm, logic_port); 1613 SOC_PBMP_PORT_REMOVE(post_pi->physical_pbm, logic_port); 1614 1615 phy_port = si->port_l2p_mapping[logic_port]; 1616 if (phy_port == -1) { 1617 continue; 1618 } 1619 1620 mmu_port = si->port_p2m_mapping[phy_port]; 1621 1622 post_pi->port_l2p_mapping[logic_port] = -1; 1623 post_pi->port_p2l_mapping[phy_port] = -1; 1624 post_pi->port_p2m_mapping[phy_port] = -1; 1625 post_pi->port_m2p_mapping[mmu_port] = -1; 1626 post_pi->port_l2i_mapping[logic_port] = -1; 1627 } 1628 1629 /* Continue with 'add' mappings in rest of array */ 1630 for (; i < nport; i++, pr++) { 1631 logic_port = pr->logical_port; 1632 phy_port = pr->physical_port; 1633 mmu_port = pr->mmu_port; 1634 1635 post_pi->log_port_speed[logic_port] = pr->speed; 1636 post_pi->port_num_lanes[logic_port] = pr->num_lanes; 1637 post_pi->port_l2p_mapping[logic_port] = phy_port; 1638 post_pi->port_p2l_mapping[phy_port] = logic_port; 1639 post_pi->port_p2m_mapping[phy_port] = mmu_port; 1640 post_pi->port_m2p_mapping[mmu_port] = phy_port; 1641 post_pi->port_l2i_mapping[logic_port] = pr->idb_port; 1642 1643 if (pr->oversub) { 1644 SOC_PBMP_PORT_ADD(post_pi->oversub_pbm, logic_port); 1645 } else { 1646 SOC_PBMP_PORT_REMOVE(post_pi->oversub_pbm, logic_port); 1647 } 1648 if (pr->encap == _SHR_PORT_ENCAP_HIGIG2) { 1649 SOC_PBMP_PORT_ADD(post_pi->hg2_pbm, logic_port); 1650 } else { 1651 SOC_PBMP_PORT_REMOVE(post_pi->hg2_pbm, logic_port); 1652 } 1653 1654 /* physical_pbm used to store the port bitmap of 25G ports using 50G 1655 * TDM calendar. 1656 */ 1657 if (pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR) { 1658 SOC_PBMP_PORT_ADD(post_pi->physical_pbm, logic_port); 1659 } 1660 } 1661 1662 LOG_VERBOSE(BSL_LS_BCM_PORT, 1663 (BSL_META_U(unit, 1664 "\n--- SOC INFO Post FlexPort Data ---\n"))); 1665 LOG_VERBOSE(BSL_LS_BCM_PORT, 1666 (BSL_META_U(unit, 1667 "Index L2P Speed Encap Ovs\n"))); 1668 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) { 1669 if (post_pi->port_l2p_mapping[i] == -1) { 1670 continue; 1671 } 1672 /* coverity[overrun-local] */ 1673 LOG_VERBOSE(BSL_LS_BCM_PORT, 1674 (BSL_META_U(unit, 1675 " %3d %3d %6d %3s %1d\n"), 1676 i, 1677 post_pi->port_l2p_mapping[i], 1678 post_pi->log_port_speed[i], 1679 SOC_PBMP_MEMBER(post_pi->hg2_pbm, i) ? "HG" : "!HG", 1680 SOC_PBMP_MEMBER(post_pi->oversub_pbm, i) ? 1 : 0)); 1681 } 1682 LOG_VERBOSE(BSL_LS_BCM_PORT, 1683 (BSL_META_U(unit, 1684 "\n"))); 1685 1686 return SOC_E_NONE; 1687 } 1688 1689 /* 1690 * Function: 1691 * _bcmi_xgs5_port_info_post_flex_clear 1692 * Purpose: 1693 * Clear Post Flexport soc info in port_schedule_state. 1694 * Parameters: 1695 * unit - (IN) Unit number. 1696 * port_schedule_state - (IN/OUT) soc_port_schedule_state_t. 1697 * Returns: 1698 * 1699 * Note: 1700 */ 1701 STATIC void 1702 _bcmi_xgs5_port_info_post_flex_clear(int unit, 1703 soc_port_schedule_state_t *port_schedule_state) 1704 { 1705 sal_memset(&port_schedule_state->out_port_map, 0, 1706 sizeof(soc_port_map_type_t)); 1707 } 1708 /* 1709 * Function: 1710 * _bcmi_xgs5_port_linkscan_mode_validate 1711 * Purpose: 1712 * Check logical ports to be 'detached' do not have linkscan mode set. 1713 * Parameters: 1714 * unit - (IN) Unit number. 1715 * port_schedule_state - (IN) soc_port_schedule_state_t. 1716 * Returns: 1717 * SOC_E_XXX 1718 * Note: 1719 */ 1720 STATIC int 1721 _bcmi_xgs5_port_linkscan_mode_validate(int unit, 1722 soc_port_schedule_state_t *port_schedule_state) 1723 { 1724 soc_port_resource_t *pr; 1725 int nport = port_schedule_state->nport; 1726 int i, rv; 1727 1728 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 1729 if (pr->physical_port != -1) { 1730 continue; 1731 } 1732 1733 if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL | 1734 BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 1735 rv = bcm_esw_linkscan_enable_port_get(unit, pr->logical_port); 1736 if (rv == BCM_E_PORT) { 1737 return rv; 1738 } 1739 if (rv != BCM_E_DISABLED) { 1740 LOG_ERROR(BSL_LS_BCM_PORT, 1741 (BSL_META_U(unit, 1742 "Linkscan mode needs to be " 1743 "disabled on ports to be detached, " 1744 "port=%d\n"), 1745 pr->logical_port)); 1746 return BCM_E_BUSY; 1747 } 1748 } 1749 } 1750 return BCM_E_NONE; 1751 } 1752 1753 /* 1754 * Function: 1755 * _bcmi_xgs5_port_range_validate 1756 * Purpose: 1757 * Check logical port and physical port are in same pipe 1758 * Parameters: 1759 * unit - (IN) Unit number. 1760 * port_schedule_state - (IN) soc_port_schedule_state_t. 1761 * Returns: 1762 * SOC_E_XXX 1763 * Note: 1764 */ 1765 STATIC int 1766 _bcmi_xgs5_port_range_validate(int unit, 1767 soc_port_schedule_state_t *port_schedule_state) 1768 { 1769 soc_port_resource_t *pr; 1770 int nport = port_schedule_state->nport; 1771 bcmi_xgs5_dev_info_t *dev_info = BCMI_PORT_DRV_DEV_INFO(unit); 1772 bcmi_xgs5_phy_port_t *phy_info; 1773 int i; 1774 1775 if (!dev_info->pipe_bound) { 1776 return BCM_E_NONE; 1777 } 1778 1779 /* Check logical port and physical port are in same pipe */ 1780 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 1781 if (pr->physical_port == -1) { 1782 continue; 1783 } 1784 1785 phy_info = &BCMI_PORT_DRV_PHY_INFO(unit, pr->physical_port); 1786 if (pr->pipe != phy_info->pipe) { 1787 LOG_ERROR(BSL_LS_BCM_PORT, 1788 (BSL_META_U(unit, 1789 "Physical port %d and Logical port %d " 1790 "are not in same pipe\n"), 1791 pr->physical_port, pr->logical_port)); 1792 return BCM_E_PORT; 1793 } 1794 } 1795 1796 return BCM_E_NONE; 1797 } 1798 1799 /* 1800 * Function: 1801 * _bcmi_xgs5_logic_ports_max_validate 1802 * Purpose: 1803 * Check that number of logical ports do not exceed maximum allowed 1804 * Parameters: 1805 * unit - (IN) Unit number. 1806 * port_schedule_state - (IN) soc_port_schedule_state_t. 1807 * Returns: 1808 * SOC_E_XXX 1809 * Note: 1810 */ 1811 STATIC int 1812 _bcmi_xgs5_logic_ports_max_validate(int unit, 1813 soc_port_schedule_state_t *port_schedule_state) 1814 { 1815 soc_info_t *si = &SOC_INFO(unit); 1816 soc_port_resource_t *pr; 1817 int nport = port_schedule_state->nport; 1818 int num_ports[SOC_MAX_NUM_PIPES]; 1819 int i; 1820 1821 /* Get current num of logical ports per each pipe */ 1822 for (i = 0; i < SOC_MAX_NUM_PIPES; i++) { 1823 SOC_PBMP_COUNT(si->pipe_pbm[i], num_ports[i]); 1824 } 1825 1826 /* Calculate num of logical ports after flexport */ 1827 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 1828 if (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) { 1829 num_ports[pr->pipe]--; 1830 } else if (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) { 1831 num_ports[pr->pipe]--; 1832 } 1833 } 1834 1835 for (i = 0; i < SOC_MAX_NUM_PIPES; i++) { 1836 if (num_ports[i] > BCMI_PORT_DRV_DEV_INFO(unit)->ports_pipe_max[i]) { 1837 LOG_ERROR(BSL_LS_BCM_PORT, 1838 (BSL_META_U(unit, 1839 "Number of logical ports exceeds max " 1840 "allowed: pipe=%d count=%d max_count=%d\n"), 1841 i, num_ports[i], 1842 BCMI_PORT_DRV_DEV_INFO(unit)->ports_pipe_max[i])); 1843 return BCM_E_PARAM; 1844 } 1845 } 1846 1847 return BCM_E_NONE; 1848 } 1849 1850 /* 1851 * Function: 1852 * _bcmi_xgs5_port_mapping_validate 1853 * Purpose: 1854 * Validate: 1855 * - Port numbers are available and mappings are not replicated. 1856 * Parameters: 1857 * unit - (IN) Unit number. 1858 * port_schedule_state - (IN) soc_port_schedule_state_t. 1859 * Returns: 1860 * SOC_E_XXX 1861 * Note: 1862 * - Resource is not NULL. 1863 * - Assumes array order is correct 1864 * ('delete' operations are first in array). 1865 */ 1866 STATIC int 1867 _bcmi_xgs5_port_mapping_validate(int unit, 1868 soc_port_schedule_state_t *port_schedule_state) 1869 { 1870 soc_info_t *si = &SOC_INFO(unit); 1871 soc_port_resource_t *pr; 1872 int nport = port_schedule_state->nport; 1873 pbmp_t logic_pbmp; 1874 uint8 lane_taken[SOC_MAX_NUM_PORTS]; 1875 int phy_port, logic_port, lane, i; 1876 1877 SOC_PBMP_CLEAR(logic_pbmp); 1878 sal_memset(lane_taken, 0, sizeof(lane_taken)); 1879 1880 /* Get current port assignment */ 1881 for (phy_port = 0; phy_port < SOC_MAX_NUM_PORTS; phy_port++) { 1882 if (si->port_p2l_mapping[phy_port] == -1) { 1883 continue; 1884 } 1885 1886 #ifdef BCM_TRIDENT3_SUPPORT 1887 if (SOC_IS_TRIDENT3(unit)) { 1888 if ((phy_port == 128) && SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), 130)) { 1889 continue; 1890 } 1891 } 1892 #endif 1893 1894 lane_taken[phy_port] = 1; 1895 logic_port = si->port_p2l_mapping[phy_port]; 1896 SOC_PBMP_PORT_ADD(logic_pbmp, logic_port); 1897 1898 for (lane = 1; lane < si->port_num_lanes[logic_port]; lane++) { 1899 phy_port++; 1900 if (phy_port >= SOC_MAX_NUM_PORTS) { 1901 break; 1902 } 1903 lane_taken[phy_port] = 1; 1904 } 1905 } 1906 1907 /* First 'delete' mappings */ 1908 for (i = 0, pr = port_schedule_state->resource; 1909 (i < nport) && (pr->physical_port == -1); 1910 i++, pr++) { 1911 phy_port = si->port_l2p_mapping[pr->logical_port]; 1912 if (phy_port == -1) { 1913 LOG_ERROR(BSL_LS_BCM_PORT, 1914 (BSL_META_U(unit, 1915 "Logical port %d is not currently mapped\n"), 1916 pr->logical_port)); 1917 return SOC_E_PARAM; 1918 } 1919 1920 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 1921 continue; 1922 } 1923 1924 lane_taken[phy_port] = 0; 1925 SOC_PBMP_PORT_REMOVE(logic_pbmp, pr->logical_port); 1926 1927 for (lane = 1; lane < si->port_num_lanes[pr->logical_port]; 1928 lane++) { 1929 phy_port++; 1930 lane_taken[phy_port] = 0; 1931 } 1932 } 1933 1934 /* Continue with 'add' mappings in rest of array */ 1935 for (; i < nport; i++, pr++) { 1936 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 1937 continue; 1938 } 1939 if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD | 1940 BCMI_XGS5_PORT_RESOURCE_OP_LANES | 1941 BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 1942 /* Check that port number is 'available' */ 1943 if (SOC_PBMP_MEMBER(logic_pbmp, pr->logical_port)) { 1944 LOG_ERROR(BSL_LS_BCM_PORT, 1945 (BSL_META_U(unit, 1946 "Logical port %d is already mapped\n"), 1947 pr->logical_port)); 1948 return BCM_E_BUSY; 1949 } 1950 1951 for (lane = 0; lane < pr->num_lanes; lane++) { 1952 phy_port = pr->physical_port + lane; 1953 if (lane_taken[phy_port]) { 1954 LOG_ERROR(BSL_LS_BCM_PORT, 1955 (BSL_META_U(unit, 1956 "Physical port %d is already " 1957 "taken by other port\n"), 1958 phy_port)); 1959 return BCM_E_BUSY; 1960 } 1961 } 1962 1963 SOC_PBMP_PORT_ADD(logic_pbmp, pr->logical_port); 1964 for (lane = 0; lane < pr->num_lanes; lane++) { 1965 phy_port = pr->physical_port + lane; 1966 lane_taken[phy_port] = 1; 1967 } 1968 } 1969 } 1970 1971 return BCM_E_NONE; 1972 } 1973 1974 /* 1975 * Function: 1976 * _bcmi_xgs5_port_flex_restriction_mix_lr_ovs_dev 1977 * Purpose: 1978 * Port configurations with a mixture of line-rate and oversub regular 1979 * ports are not supported. 1980 * 1981 * Parameters: 1982 * unit - (IN) Unit number. 1983 * port_schedule_state - (IN) soc_port_schedule_state_t. 1984 * Returns: 1985 * BCM_E_XXX 1986 */ 1987 STATIC int 1988 _bcmi_xgs5_port_flex_restriction_mix_lr_ovs_dev(int unit, 1989 soc_port_schedule_state_t *port_schedule_state) 1990 { 1991 soc_info_t *si = &SOC_INFO(unit); 1992 soc_port_resource_t *pr; 1993 int nport = port_schedule_state->nport; 1994 int oversub_mode; 1995 int i; 1996 1997 oversub_mode = si->oversub_mode; 1998 1999 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 2000 if (pr->physical_port == -1) { 2001 continue; 2002 } 2003 if (oversub_mode ^ pr->oversub) { 2004 LOG_ERROR(BSL_LS_BCM_PORT, 2005 (BSL_META_U(unit, 2006 "-- Restriction: Port configurations " 2007 "with a mixture of line-rate and oversub " 2008 "ports are not supported\n"))); 2009 return BCM_E_PARAM; 2010 } 2011 } 2012 2013 LOG_VERBOSE(BSL_LS_BCM_PORT, 2014 (BSL_META_U(unit, 2015 "-- Flexport Restriction mix_lr_ovs_dev: PASS\n"))); 2016 return BCM_E_NONE; 2017 } 2018 2019 #if defined(BCM_TRIDENT3_SUPPORT) 2020 /* 2021 * Function: 2022 * _bcmi_xgs5_port_flex_restriction_pipe_lr_slot 2023 * Purpose: 2024 * FlexPort cannot change the total calender length available per pipeline to 2025 * linerate ports. 2026 * 2027 * Parameters: 2028 * unit - (IN) Unit number. 2029 * port_schedule_state - (IN) soc_port_schedule_state_t. 2030 * Returns: 2031 * BCM_E_XXX 2032 */ 2033 STATIC int 2034 _bcmi_xgs5_port_flex_restriction_pipe_lr_slot(int unit, 2035 soc_port_schedule_state_t *port_schedule_state) 2036 { 2037 soc_info_t *si = &SOC_INFO(unit); 2038 soc_port_resource_t *pr; 2039 int nport = port_schedule_state->nport; 2040 int callen[SOC_MAX_NUM_PIPES] = {0}; 2041 int i, pipe, logic_port, speed, tdm_speed_min; 2042 int eth = 1; 2043 soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map; 2044 uint32 cal = 0; 2045 2046 tdm_speed_min = BCMI_PORT_DRV_DEV_INFO(unit)->tdm_pipe_lr_bw_limit_checker_speed_min; 2047 2048 if (SOC_PBMP_NOT_NULL(post_pi->hg2_pbm)) { 2049 eth = 0; 2050 } 2051 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2052 callen[pipe] = 0; 2053 2054 SOC_PBMP_ITER(si->pipe_pbm[pipe], logic_port) { 2055 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, logic_port) || 2056 SOC_PBMP_MEMBER(si->oversub_pbm, logic_port)) { 2057 continue; 2058 } 2059 if (IS_CPU_PORT(unit, logic_port) || 2060 IS_MANAGEMENT_PORT(unit, logic_port) || 2061 IS_LB_PORT(unit, logic_port)) { 2062 continue; 2063 } 2064 2065 speed = si->port_init_speed[logic_port]; 2066 if (speed < tdm_speed_min) { 2067 speed = tdm_speed_min; 2068 } 2069 callen[pipe] += tdm_td3_cmn_get_speed_slots(speed); 2070 } 2071 } 2072 2073 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 2074 if (pr->oversub == 1) { 2075 continue; 2076 } 2077 if (pr->physical_port == -1 && 2078 pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL | 2079 BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 2080 pipe = si->port_pipe[pr->logical_port]; 2081 speed = si->port_init_speed[pr->logical_port]; 2082 if (speed < tdm_speed_min) { 2083 speed = tdm_speed_min; 2084 } 2085 callen[pipe] -= tdm_td3_cmn_get_speed_slots(speed); 2086 } else if (pr->physical_port != -1 && 2087 pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD| 2088 BCMI_XGS5_PORT_RESOURCE_OP_REMAP | 2089 BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE)) { 2090 speed = pr->speed; 2091 if (speed < tdm_speed_min) { 2092 speed = tdm_speed_min; 2093 } 2094 callen[pr->pipe] += tdm_td3_cmn_get_speed_slots(speed); 2095 } else if (pr->physical_port != -1 && 2096 pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_LANES| 2097 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX| 2098 BCMI_XGS5_PORT_RESOURCE_OP_SPEED)) { 2099 pipe = si->port_pipe[pr->logical_port]; 2100 speed = si->port_init_speed[pr->logical_port]; 2101 if (speed < tdm_speed_min) { 2102 speed = tdm_speed_min; 2103 } 2104 callen[pipe] -= tdm_td3_cmn_get_speed_slots(speed); 2105 speed = pr->speed; 2106 if (speed < tdm_speed_min) { 2107 speed = tdm_speed_min; 2108 } 2109 callen[pr->pipe] += tdm_td3_cmn_get_speed_slots(speed); 2110 } 2111 } 2112 if (SOC_IS_TRIDENT3(unit)) { 2113 soc_td3_max_lr_cal_len(unit, &cal, eth); 2114 } 2115 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2116 if (callen[pipe] > cal) { 2117 LOG_ERROR(BSL_LS_BCM_PORT, 2118 (BSL_META_U(unit, 2119 "-- Restriction: FlexPort requesting more calender slots" 2120 "per pipeline than the available slots per pipe." 2121 "pipe=%d slots req=%d max_slots=%d\n"), 2122 pipe, callen[pipe],cal)); 2123 return BCM_E_PARAM; 2124 } 2125 } 2126 2127 LOG_VERBOSE(BSL_LS_BCM_PORT, 2128 (BSL_META_U(unit, 2129 "-- Flexport restriction pipe_lr max calender length: PASS\n"))); 2130 2131 return BCM_E_NONE; 2132 2133 } 2134 #endif 2135 2136 /* 2137 * Function: 2138 * _bcmi_xgs5_port_flex_restriction_pipe_lr_bandwidth 2139 * Purpose: 2140 * FlexPort cannot change the total throughput available per pipeline to 2141 * linerate ports. 2142 * 2143 * Parameters: 2144 * unit - (IN) Unit number. 2145 * port_schedule_state - (IN) soc_port_schedule_state_t. 2146 * Returns: 2147 * BCM_E_XXX 2148 */ 2149 STATIC int 2150 _bcmi_xgs5_port_flex_restriction_pipe_lr_bandwidth(int unit, 2151 soc_port_schedule_state_t *port_schedule_state) 2152 { 2153 soc_info_t *si = &SOC_INFO(unit); 2154 soc_port_resource_t *pr; 2155 int nport = port_schedule_state->nport; 2156 int bandwidth[SOC_MAX_NUM_PIPES] = {0}; 2157 int i, pipe, logic_port, speed, tdm_speed_min; 2158 2159 tdm_speed_min = BCMI_PORT_DRV_DEV_INFO(unit)->tdm_pipe_lr_bw_limit_checker_speed_min; 2160 2161 /* Get current bandwidth of line rate ports per pipe */ 2162 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2163 bandwidth[pipe] = 0; 2164 2165 SOC_PBMP_ITER(si->pipe_pbm[pipe], logic_port) { 2166 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, logic_port) || 2167 SOC_PBMP_MEMBER(si->oversub_pbm, logic_port)) { 2168 continue; 2169 } 2170 if (IS_CPU_PORT(unit, logic_port) || 2171 IS_MANAGEMENT_PORT(unit, logic_port) || 2172 IS_LB_PORT(unit, logic_port)) { 2173 continue; 2174 } 2175 2176 speed = si->port_init_speed[logic_port]; 2177 if (speed < tdm_speed_min) { 2178 speed = tdm_speed_min; 2179 } 2180 bandwidth[pipe] += speed; 2181 } 2182 } 2183 2184 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 2185 if (pr->oversub == 1) { 2186 continue; 2187 } 2188 if (pr->physical_port == -1 && 2189 pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL | 2190 BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 2191 pipe = si->port_pipe[pr->logical_port]; 2192 speed = si->port_init_speed[pr->logical_port]; 2193 if (speed < tdm_speed_min) { 2194 speed = tdm_speed_min; 2195 } 2196 bandwidth[pipe] -= speed; 2197 } else if (pr->physical_port != -1 && 2198 pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD| 2199 BCMI_XGS5_PORT_RESOURCE_OP_REMAP | 2200 BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE)) { 2201 2202 speed = pr->speed; 2203 if (speed < tdm_speed_min) { 2204 speed = tdm_speed_min; 2205 } 2206 bandwidth[pr->pipe] += speed; 2207 } else if (pr->physical_port != -1 && 2208 pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_LANES| 2209 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX| 2210 BCMI_XGS5_PORT_RESOURCE_OP_SPEED)) { 2211 pipe = si->port_pipe[pr->logical_port]; 2212 speed = si->port_init_speed[pr->logical_port]; 2213 if (speed < tdm_speed_min) { 2214 speed = tdm_speed_min; 2215 } 2216 bandwidth[pipe] -= speed; 2217 speed = pr->speed; 2218 if (speed < tdm_speed_min) { 2219 speed = tdm_speed_min; 2220 } 2221 bandwidth[pr->pipe] += speed; 2222 } 2223 } 2224 2225 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2226 if (bandwidth[pipe] > BCMI_PORT_DRV_DEV_INFO(unit)->pipe_lr_bw) { 2227 LOG_ERROR(BSL_LS_BCM_PORT, 2228 (BSL_META_U(unit, 2229 "-- Restriction: FlexPort cannot change " 2230 "the total throughput available per " 2231 "pipeline to linerate ports. " 2232 "pipe=%d bandwidth=%d max_bandwidth=%d\n"), 2233 pipe, bandwidth[pipe], 2234 BCMI_PORT_DRV_DEV_INFO(unit)->pipe_lr_bw)); 2235 return BCM_E_PARAM; 2236 } 2237 } 2238 2239 LOG_VERBOSE(BSL_LS_BCM_PORT, 2240 (BSL_META_U(unit, 2241 "-- Flexport Restriction pipe_lr_bandwidth: PASS\n"))); 2242 2243 #if defined(BCM_TRIDENT3_SUPPORT) 2244 if (SOC_IS_TRIDENT3(unit)) { 2245 BCM_IF_ERROR_RETURN 2246 (_bcmi_xgs5_port_flex_restriction_pipe_lr_slot(unit, 2247 port_schedule_state)); 2248 } 2249 #endif 2250 return BCM_E_NONE; 2251 } 2252 2253 /* 2254 * Function: 2255 * _bcmi_xgs5_port_flex_restriction_speed_class 2256 * Purpose: 2257 * No port configuration with more than Maximum port speed classes are 2258 * supported. 2259 * 2260 * Parameters: 2261 * unit - (IN) Unit number. 2262 * port_schedule_state - (IN) soc_port_schedule_state_t. 2263 * Returns: 2264 * BCM_E_XXX 2265 */ 2266 STATIC int 2267 _bcmi_xgs5_port_flex_restriction_speed_class(int unit, 2268 soc_port_schedule_state_t *port_schedule_state) 2269 { 2270 uint32 speed_mask, mask, speed_class_num; 2271 int i, speed; 2272 soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map; 2273 bcmi_xgs5_speed_class_t *speed_class; 2274 #ifdef PORTMOD_PM8X50_SUPPORT 2275 int speed_200 = 0, speed_400 = 0; 2276 #endif 2277 2278 mask = 0; 2279 speed_mask = 0; 2280 speed_class_num = 0; 2281 2282 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) { 2283 /* coverity[overrun-local] */ 2284 if (post_pi->log_port_speed[i] <= 0 || IS_MANAGEMENT_PORT(unit,i)) { 2285 continue; 2286 } 2287 speed = soc_port_speed_higig2eth(post_pi->log_port_speed[i]); 2288 /* <=10G speeds in one speed class */ 2289 speed = speed < 10000 ? 10000 : speed; 2290 #ifdef PORTMOD_PM8X50_SUPPORT 2291 if (speed == 400000) { 2292 speed_400 = 1; 2293 } else if (speed == 200000) { 2294 speed_200 = 1; 2295 } else 2296 #endif 2297 { 2298 mask = SOC_PA_SPEED(speed); 2299 2300 if (!(speed_mask & mask)) { 2301 speed_mask |= mask; 2302 speed_class_num++; 2303 } 2304 } 2305 } 2306 2307 #ifdef PORTMOD_PM8X50_SUPPORT 2308 speed_class_num += speed_200; 2309 speed_class_num += speed_400; 2310 #endif 2311 2312 speed_class = &BCMI_PORT_DRV_DEV_INFO(unit)->speed_class; 2313 2314 if (speed_class_num > speed_class->speed_class_num) { 2315 LOG_ERROR(BSL_LS_BCM_PORT, 2316 (BSL_META_U(unit, 2317 "-- Restriction: No port configuration with more " 2318 "than %d port speed classes are supported. " 2319 "Speed class after flexport is %d\n"), 2320 speed_class->speed_class_num, 2321 speed_class_num)); 2322 return BCM_E_PARAM; 2323 } 2324 2325 if (speed_class->no_mix_speed_mask && 2326 ((speed_mask & speed_class->no_mix_speed_mask) == 2327 speed_class->no_mix_speed_mask)){ 2328 LOG_ERROR(BSL_LS_BCM_PORT, 2329 (BSL_META_U(unit, 2330 "-- Restriction: Not supported combination of " 2331 "speed classes. \n"))); 2332 return BCM_E_PARAM; 2333 } 2334 2335 if (BCMI_PORT_DRV_CALL(unit)->speed_mix_validate) { 2336 BCM_IF_ERROR_RETURN 2337 (BCMI_PORT_DRV_CALL(unit)->speed_mix_validate(unit, speed_mask)); 2338 } 2339 2340 LOG_VERBOSE(BSL_LS_BCM_PORT, 2341 (BSL_META_U(unit, 2342 "-- Flexport Restriction speed class: PASS\n"))); 2343 return BCM_E_NONE; 2344 } 2345 /* 2346 * Function: 2347 * _bcmi_xgs5_port_flex_restriction_vco_validation 2348 * Purpose: 2349 * Validate the following: 2350 * 1. FEC, Link Training, Phy Lane Config in flex situations 2351 * 2. VCO configuration is valid for Port macros 2352 * 2353 * Parameters: 2354 * unit - (IN) Unit number. 2355 * port_schedule_state - (IN) soc_port_schedule_state_t. 2356 * Returns: 2357 * BCM_E_XXX 2358 */ 2359 STATIC int 2360 _bcmi_xgs5_port_flex_restriction_vco_validation(int unit, 2361 soc_port_schedule_state_t *port_schedule_state) 2362 { 2363 int i; 2364 int autoneg; 2365 int logical_port; 2366 int existing_physical_port; 2367 int all_autoneg = 1; 2368 soc_port_resource_t *resource; 2369 2370 for (i = 0; i < port_schedule_state->nport; i++) { 2371 resource = &port_schedule_state->resource[i]; 2372 2373 /* Skip ports being deleted */ 2374 if (resource->physical_port == -1) { 2375 continue; 2376 } 2377 2378 logical_port = resource->logical_port; 2379 existing_physical_port = SOC_INFO(unit).port_l2p_mapping[logical_port]; 2380 2381 /* If the passed port already exists, and the lanes aren't changing, 2382 * check it for autoneg. We don't need to validate VCO if autoneg. 2383 * resource_speed_set disables autoneg, so this code should only 2384 * execute and skip VCO validation on a port update 2385 */ 2386 if (existing_physical_port != -1 && 2387 resource->op == BCMI_XGS5_PORT_RESOURCE_OP_SPEED) { 2388 2389 BCM_IF_ERROR_RETURN(bcm_esw_port_autoneg_get(unit, 2390 resource->logical_port, 2391 &autoneg)); 2392 2393 /* We don't need to do validation if the port is in autoneg */ 2394 if (autoneg == 1) { 2395 continue; 2396 } 2397 } 2398 2399 /* Not all of the ports in port_schedule_state are autoneg, so 2400 * port_schedule_state will need to be validated 2401 */ 2402 all_autoneg = 0; 2403 2404 /* Validate FEC */ 2405 if ((resource->fec_type >= socPortPhyFecCount) || 2406 (resource->fec_type < socPortPhyFecNone)) { 2407 LOG_ERROR(BSL_LS_BCM_PORT, 2408 (BSL_META_U(unit, 2409 "-- Restriction: All ports must have a valid " 2410 "FEC.\n"))); 2411 2412 return BCM_E_PARAM; 2413 } 2414 2415 /* Validate Link Training */ 2416 if ((resource->link_training > 1) || 2417 (resource->link_training < 0)) { 2418 LOG_ERROR(BSL_LS_BCM_PORT, 2419 (BSL_META_U(unit, 2420 "-- Restriction: All ports must have " 2421 "Link Training enabled or disabled.\n"))); 2422 2423 return BCM_E_PARAM; 2424 } 2425 2426 /* Phy Lane Config is validated inside Portmod since it's a bitmap 2427 * and there isn't a clear range to check at this layer*/ 2428 } 2429 2430 /* This info is filled in later, since it needs to be calculated. We'll use 2431 * it later in PM VCO calculation 2432 */ 2433 soc_esw_portctrl_pm_vco_store_clear(unit); 2434 2435 /* all the ports in port_schedule_state are autoneg, so we don't want to 2436 * do any validation 2437 */ 2438 if (all_autoneg == 1) { 2439 return BCM_E_NONE; 2440 } else { 2441 return soc_esw_portctrl_flex_vco_validation(unit, port_schedule_state); 2442 } 2443 } 2444 2445 /* 2446 * Function: 2447 * _bcmi_xgs5_port_flex_restriction_pm_sister_ports 2448 * Purpose: 2449 * Validate sister ports: 2450 * 1. All active ports in an oversub Port Macro must be the same speed 2451 * 2. All ports in a port macro must be derived from a common VCO freq 2452 * 3. Oversub and Line rate ports cannot coexist in one port macro 2453 * 4. Ethernet and HiGig ports cannot coexist in one port macro 2454 * 2455 * Parameters: 2456 * unit - (IN) Unit number. 2457 * port_schedule_state - (IN) soc_port_schedule_state_t. 2458 * mask - (IN) Restriction mask 2459 * Returns: 2460 * BCM_E_XXX 2461 */ 2462 STATIC int 2463 _bcmi_xgs5_port_flex_restriction_pm_sister_ports(int unit, 2464 soc_port_schedule_state_t *port_schedule_state, 2465 uint32 mask) 2466 { 2467 soc_port_resource_t *pr; 2468 soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map; 2469 int nport, check_ovs_lr, check_ovs_mix_speed, check_pll, check_mix_encap, check_hg_mix; 2470 int *sister_ports, len; 2471 int logic_port, phy_port, blk, bindex, btype_idx, first_p, blktype; 2472 int speed, first_speed, num_lanes, encap, first_encap, ovs, first_ovs, check_lr_mix_speed; 2473 int mixed_sister_25_50_en, mixed_sister_25_10_en; 2474 SHR_BITDCL blk_bmp[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)]; 2475 uint32 pll_div, first_pll_div; 2476 int i, offset, rv; 2477 uint32 speed_mask, mix_speed_mask, pm_mixed_pbm, pm_used_pbm; 2478 uint32 mix_10G_1000MB_speed_mask, mix_25G_10G_1000MB_speed_mask; 2479 soc_info_t *si = &SOC_INFO(unit); 2480 2481 check_ovs_lr = 2482 mask & BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_PM ? 1: 0; 2483 2484 check_ovs_mix_speed = 2485 mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_OVS_MIX_SISTER ? 1 : 0; 2486 2487 check_pll = 2488 mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_SINGLE_PLL ? 1 : 0; 2489 2490 check_mix_encap = 2491 mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_MIX_ETH_HIGIG ? 1 : 0; 2492 2493 check_hg_mix = 2494 mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_HG_MIX_SPEED ? 1 : 0; 2495 2496 check_lr_mix_speed = 2497 mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_LR_MIX_SISTER ? 1 : 0; 2498 2499 mix_speed_mask = SOC_PA_SPEED_50GB | SOC_PA_SPEED_25GB | SOC_PA_SPEED_1000MB; 2500 mix_10G_1000MB_speed_mask = SOC_PA_SPEED_10GB| SOC_PA_SPEED_1000MB | SOC_PA_SPEED_2500MB | SOC_PA_SPEED_5000MB; 2501 mix_25G_10G_1000MB_speed_mask = SOC_PA_SPEED_25GB | SOC_PA_SPEED_10GB| SOC_PA_SPEED_1000MB; 2502 2503 if (!check_ovs_lr && !check_ovs_mix_speed && !check_pll && 2504 !check_hg_mix && !check_lr_mix_speed && 2505 !check_mix_encap) { 2506 return BCM_E_NONE; 2507 } 2508 2509 /* Alloc sister_ports[SOC_MAX_NUM_BLKS][BCMI_XGS5_PORTS_PER_PBLK] */ 2510 len = SOC_MAX_NUM_BLKS * BCMI_XGS5_PORTS_PER_PBLK * sizeof(int); 2511 sister_ports = sal_alloc(len, "sister_ports"); 2512 if (sister_ports == NULL) { 2513 return BCM_E_MEMORY; 2514 } 2515 sal_memset(sister_ports, -1, len); 2516 2517 /* Get bitmap for block_id that have port flexing */ 2518 nport = port_schedule_state->nport; 2519 SHR_BITCLR_RANGE(blk_bmp, 0, SOC_MAX_NUM_BLKS); 2520 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 2521 if (pr->physical_port == -1) { 2522 continue; 2523 } 2524 phy_port = pr->physical_port; 2525 for (btype_idx = 0; btype_idx < SOC_DRIVER(unit)->port_num_blktype; 2526 btype_idx++) { 2527 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, btype_idx); 2528 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, btype_idx); 2529 if ((blk < 0) || (bindex < 0)) { 2530 continue; 2531 } 2532 SHR_BITSET(blk_bmp, blk); 2533 } 2534 } 2535 2536 /* Get sister ports for each block */ 2537 for (phy_port = 0; 2538 phy_port < BCMI_PORT_DRV_DEV_INFO(unit)->phy_ports_max; 2539 phy_port++) { 2540 2541 if (SOC_PORT_BLOCK(unit, phy_port) < 0 && 2542 SOC_PORT_BINDEX(unit, phy_port) < 0) { 2543 break; 2544 } 2545 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; 2546 i++) { 2547 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 2548 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i); 2549 if ((blk < 0) || (bindex < 0)) { 2550 continue; 2551 } 2552 blktype = SOC_BLOCK_INFO(unit, blk).type; 2553 if ((blktype == SOC_BLK_XLPORT) || (blktype == SOC_BLK_CLPORT)) { 2554 if (bindex > BCMI_XGS5_PORTS_PER_PBLK) { 2555 LOG_WARN(BSL_LS_BCM_PORT, 2556 (BSL_META_U(unit, 2557 "Index of port within block(bindex) " 2558 "exceeds the maximum.\n"))); 2559 continue; 2560 } 2561 offset = blk * BCMI_XGS5_PORTS_PER_PBLK + bindex; 2562 sister_ports[offset] = phy_port; 2563 } 2564 } 2565 } 2566 2567 mixed_sister_25_50_en = si->os_mixed_sister_25_50_enable; 2568 2569 /* For HX5 25g/10g mixed support is limited to LR ports only */ 2570 mixed_sister_25_10_en = SOC_IS_MAVERICK2(unit) ? 1 : 0; 2571 2572 /* Check that sister ports (ports within a Port Macro) have the same VCO */ 2573 SHR_BIT_ITER(blk_bmp, SOC_MAX_NUM_BLKS, blk) { 2574 first_p = 1; 2575 speed = 0; 2576 first_speed = 0; 2577 pll_div = 0; 2578 first_pll_div = 0; 2579 encap = -1; 2580 first_encap = -1; 2581 ovs = -1; 2582 first_ovs = -1; 2583 speed_mask = 0; 2584 pm_mixed_pbm = 0; 2585 pm_used_pbm = 0; 2586 2587 blktype = SOC_BLOCK_INFO(unit, blk).type; 2588 if (!((blktype == SOC_BLK_XLPORT) || (blktype == SOC_BLK_CLPORT))) { 2589 continue; 2590 } 2591 2592 for (i = 0; i < BCMI_XGS5_PORTS_PER_PBLK; i++) { 2593 offset = blk * BCMI_XGS5_PORTS_PER_PBLK + i; 2594 #ifdef BCM_TRIDENT3_SUPPORT 2595 if (SOC_IS_TRIDENT3(unit)) { 2596 if ((offset == 135) && SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), 130)) { 2597 continue; 2598 } 2599 } 2600 #endif 2601 phy_port = sister_ports[offset]; 2602 if (phy_port == -1) { 2603 LOG_ERROR(BSL_LS_BCM_PORT, 2604 (BSL_META_U(unit, "No sister ports.\n"))); 2605 sal_free(sister_ports); 2606 return BCM_E_INTERNAL; 2607 } 2608 logic_port = post_pi->port_p2l_mapping[phy_port]; 2609 if (logic_port == -1) { 2610 continue; 2611 } 2612 /* Skip inactive ports */ 2613 if (post_pi->log_port_speed[logic_port] <= 0) { 2614 continue; 2615 } 2616 2617 speed = post_pi->log_port_speed[logic_port]; 2618 num_lanes = post_pi->port_num_lanes[logic_port]; 2619 encap = SOC_PBMP_MEMBER(post_pi->hg2_pbm, logic_port) ? 2620 SOC_ENCAP_HIGIG2 : SOC_ENCAP_IEEE; 2621 ovs = SOC_PBMP_MEMBER(post_pi->oversub_pbm, logic_port) ? 1 : 0; 2622 rv = soc_esw_portctrl_pll_div_get(unit, logic_port, phy_port, speed, num_lanes, 2623 encap, &pll_div); 2624 speed_mask |= SOC_PA_SPEED(soc_port_speed_higig2eth(speed)); 2625 if (BCM_FAILURE(rv)) { 2626 LOG_VERBOSE(BSL_LS_BCM_PORT, 2627 (BSL_META_U(unit, "Failed to get PLL\n"))); 2628 sal_free(sister_ports); 2629 return rv; 2630 } 2631 if (first_p) { 2632 first_pll_div = pll_div; 2633 first_encap = encap; 2634 first_speed = speed; 2635 first_ovs = ovs; 2636 first_p = 0; 2637 } 2638 if (ovs && mixed_sister_25_50_en) { 2639 speed_mask |= SOC_PA_SPEED(soc_port_speed_higig2eth(speed)); 2640 pm_used_pbm |= 1 << ((phy_port - 1) % BCMI_XGS5_PORTS_PER_PBLK); 2641 if (SOC_PBMP_MEMBER(post_pi->physical_pbm, logic_port)) { 2642 if (SOC_PA_SPEED(soc_port_speed_higig2eth(speed)) 2643 & SOC_PA_SPEED_25GB){ 2644 pm_mixed_pbm |= 2645 1 << ((phy_port - 1) % BCMI_XGS5_PORTS_PER_PBLK); 2646 } else { 2647 LOG_ERROR(BSL_LS_SOC_PORT, 2648 (BSL_META_U(unit, 2649 "Only 25G port can with flag " 2650 "BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR, " 2651 "port %d with speed %d can't " 2652 "have flag " 2653 "BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR!\n"), 2654 logic_port, speed)); 2655 sal_free(sister_ports); 2656 return SOC_E_CONFIG; 2657 } 2658 } 2659 } 2660 if (check_pll && (first_pll_div != pll_div)) { 2661 LOG_ERROR(BSL_LS_BCM_PORT, 2662 (BSL_META_U(unit, 2663 "-- Restriction: All ports in a port " 2664 "macro must be derived from a common VCO " 2665 "frequency\n"))); 2666 sal_free(sister_ports); 2667 return BCM_E_PARAM; 2668 } 2669 if (check_mix_encap && (first_encap != encap)) { 2670 LOG_ERROR(BSL_LS_BCM_PORT, 2671 (BSL_META_U(unit, 2672 "-- Restriction: Ethernet and HiGig " 2673 "ports cannot coexist in one port macro" 2674 "\n"))); 2675 sal_free(sister_ports); 2676 return BCM_E_PARAM; 2677 } 2678 if (check_ovs_lr && (first_ovs != ovs)) { 2679 LOG_ERROR(BSL_LS_BCM_PORT, 2680 (BSL_META_U(unit, 2681 "-- Restriction: Oversub and Line-rate " 2682 "ports cannot coexist in one port macro" 2683 "\n"))); 2684 sal_free(sister_ports); 2685 return BCM_E_PARAM; 2686 } 2687 if (ovs && check_ovs_mix_speed && (soc_port_speed_higig2eth(first_speed) != 2688 soc_port_speed_higig2eth(speed))) { 2689 /* Support 25G/50G mix sister speeds in a PM. 2690 * Only include 25G and 50G speeds. 2691 */ 2692 if (mixed_sister_25_50_en && 2693 (!(speed_mask & (~mix_speed_mask)))) { 2694 continue; 2695 } else if (!(speed_mask & (~mix_10G_1000MB_speed_mask))) { 2696 /* 10G and <10G is considered same speed from TDM perspective although 2697 * speed mask is for mixed speed 2698 */ 2699 continue; 2700 } else if (mixed_sister_25_10_en && 2701 (!(speed_mask & (~mix_25G_10G_1000MB_speed_mask)))) { 2702 /* 25G/10G/1G mix supported */ 2703 continue; 2704 } else { 2705 LOG_ERROR(BSL_LS_BCM_PORT, 2706 (BSL_META_U(unit, 2707 "-- Restriction: Mixed-sister oversub " 2708 "ports are not supported.\n"))); 2709 sal_free(sister_ports); 2710 return BCM_E_PARAM; 2711 } 2712 } 2713 if ((encap == SOC_ENCAP_HIGIG2) && (check_hg_mix) && (soc_port_speed_higig2eth(first_speed) != 2714 soc_port_speed_higig2eth(speed))) { 2715 LOG_ERROR(BSL_LS_BCM_PORT, 2716 (BSL_META_U(unit, 2717 "-- Restriction: different speed sub ports in HG2 " 2718 "are not supported.\n"))); 2719 sal_free(sister_ports); 2720 return BCM_E_PARAM; 2721 } 2722 } 2723 if ((!ovs) && check_lr_mix_speed) { 2724 if (((speed_mask & SOC_PA_SPEED_25GB) && (speed_mask & SOC_PA_SPEED_10GB)) || 2725 ((speed_mask & SOC_PA_SPEED_25GB) && (speed_mask & SOC_PA_SPEED_1000MB))) { 2726 LOG_ERROR(BSL_LS_BCMAPI_PORT, 2727 (BSL_META_U(unit, 2728 "-- Restriction: Mixed-sister Linerate " 2729 "10G/1G and 25G ports are not supported.\n"))); 2730 sal_free(sister_ports); 2731 return BCM_E_PARAM; 2732 } 2733 } 2734 if (ovs && mixed_sister_25_50_en) { 2735 if (pm_mixed_pbm && (pm_used_pbm & 0xa)){ 2736 LOG_ERROR(BSL_LS_BCMAPI_PORT, 2737 (BSL_META_U(unit, 2738 "Mixed port speed configuration is wrong " 2739 "on port macro %d!\n Either more than 2 " 2740 "ports in this port macro or single lane " 2741 "ports on 2/4th lane!\n"), 2742 SOC_BLOCK_NUMBER(unit, blk))); 2743 sal_free(sister_ports); 2744 return BCM_E_PARAM; 2745 } else if (!pm_mixed_pbm && (speed_mask == mix_speed_mask)){ 2746 LOG_ERROR(BSL_LS_BCMAPI_PORT, 2747 (BSL_META_U(unit, 2748 "Mixed port speed bitmap not set on " 2749 "25G ports of port macro %d!\n"), 2750 SOC_BLOCK_NUMBER(unit, blk))); 2751 sal_free(sister_ports); 2752 return BCM_E_PARAM; 2753 } 2754 } 2755 } 2756 2757 LOG_VERBOSE(BSL_LS_BCM_PORT, 2758 (BSL_META_U(unit, 2759 "-- Flexport Restriction for sister ports: " 2760 "PASS\n"))); 2761 sal_free(sister_ports); 2762 return BCM_E_NONE; 2763 } 2764 2765 /* 2766 * Function: 2767 * _bcmi_xgs5_port_flex_restriction 2768 * Purpose: 2769 * Validate that the given FlexPort operation is valid. 2770 * 2771 * Parameters: 2772 * unit - (IN) Unit number. 2773 * port_schedule_state - (IN) soc_port_schedule_state_t. 2774 * Returns: 2775 * BCM_E_XXX 2776 */ 2777 STATIC int 2778 _bcmi_xgs5_port_flex_restriction(int unit, 2779 soc_port_schedule_state_t *port_schedule_state) 2780 { 2781 uint32 restrict_mask; 2782 2783 restrict_mask = BCMI_PORT_DRV_DEV_INFO(unit)->restriction_mask; 2784 2785 LOG_VERBOSE(BSL_LS_BCM_PORT, 2786 (BSL_META_U(unit, 2787 "---- FLEXPORT RESTRICTION VALIDATE ----\n"))); 2788 2789 /* 2790 * Restriction: 2791 * Port configurations with a mixture of line-rate and oversub regular 2792 * ports are not supported. 2793 */ 2794 if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_DEV) { 2795 BCM_IF_ERROR_RETURN 2796 (_bcmi_xgs5_port_flex_restriction_mix_lr_ovs_dev(unit, 2797 port_schedule_state)); 2798 } 2799 2800 /* 2801 * Restriction: 2802 * FlexPort cannot change the total throughput available per pipeline to 2803 * linerate ports. 2804 */ 2805 if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PIPE_BANDWIDTH) { 2806 BCM_IF_ERROR_RETURN 2807 (_bcmi_xgs5_port_flex_restriction_pipe_lr_bandwidth(unit, 2808 port_schedule_state)); 2809 } 2810 2811 /* 2812 * Restriction: 2813 * No port configuration with more than Maximum port speed classes are 2814 * supported. 2815 */ 2816 if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_SPEED_CLASS) { 2817 BCM_IF_ERROR_RETURN 2818 (_bcmi_xgs5_port_flex_restriction_speed_class(unit, 2819 port_schedule_state)); 2820 } 2821 2822 if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_DOUBLE_PLL) { 2823 BCM_IF_ERROR_RETURN 2824 (_bcmi_xgs5_port_flex_restriction_vco_validation(unit, 2825 port_schedule_state)); 2826 } else { 2827 /* 2828 * Restriction: 2829 * Validate sister ports: 2830 * 1. All active ports in an oversub Port Macro must be the same speed 2831 * 2. All ports in a port macro must be derived from a common VCO freq 2832 * 3. Oversub and Line rate ports cannot coexist in one port macro 2833 * 4. Ethernet and HiGig ports cannot coexist in one port macro 2834 */ 2835 BCM_IF_ERROR_RETURN 2836 (_bcmi_xgs5_port_flex_restriction_pm_sister_ports(unit, 2837 port_schedule_state, 2838 restrict_mask)); 2839 } 2840 2841 return BCM_E_NONE; 2842 } 2843 2844 /* 2845 * Function: 2846 * _bcmi_xgs5_port_resource_validate 2847 * Purpose: 2848 * - Check the port mapping is available. 2849 * - Validate that the given FlexPort configuration is valid. 2850 * 2851 * Parameters: 2852 * unit - (IN) Unit number. 2853 * resource - (IN) bcm_port_resource_t 2854 * port_schedule_state - (OUT) soc_port_schedule_state_t. 2855 * Returns: 2856 * BCM_E_XXX 2857 */ 2858 STATIC int 2859 _bcmi_xgs5_port_resource_validate(int unit, 2860 soc_port_schedule_state_t *port_schedule_state) 2861 { 2862 int rv; 2863 2864 LOG_VERBOSE(BSL_LS_BCM_PORT, 2865 (BSL_META_U(unit, 2866 "==== PORT RESOURCE VALIDATE ====\n"))); 2867 2868 /* Check that ports to be 'detached' do not have linkscan mode set. */ 2869 BCM_IF_ERROR_RETURN 2870 (_bcmi_xgs5_port_linkscan_mode_validate(unit, port_schedule_state)); 2871 2872 /* Check logical port and physical port are in same pipe */ 2873 BCM_IF_ERROR_RETURN 2874 (_bcmi_xgs5_port_range_validate(unit, port_schedule_state)); 2875 2876 /* Check that number of logical ports do not exceed maximum allowed */ 2877 BCM_IF_ERROR_RETURN 2878 (_bcmi_xgs5_logic_ports_max_validate(unit, port_schedule_state)); 2879 2880 /* Check port mapping */ 2881 BCM_IF_ERROR_RETURN 2882 (_bcmi_xgs5_port_mapping_validate(unit, port_schedule_state)); 2883 2884 /* Flexport restrictions */ 2885 2886 /* Populate Post Flexport soc info in port_schedule_state->out_port_map, 2887 * which will be used in the following validation. */ 2888 BCM_IF_ERROR_RETURN 2889 (_bcmi_xgs5_port_info_post_flex(unit, port_schedule_state)); 2890 2891 if (BCMI_PORT_DRV_CALL(unit)->port_resource_validate) { 2892 BCM_IF_ERROR_RETURN 2893 (BCMI_PORT_DRV_CALL(unit)->port_resource_validate(unit, 2894 port_schedule_state)); 2895 } 2896 2897 rv = _bcmi_xgs5_port_flex_restriction(unit, port_schedule_state); 2898 2899 /* Clear the port_schedule_state->out_port_map */ 2900 _bcmi_xgs5_port_info_post_flex_clear(unit, port_schedule_state); 2901 2902 BCM_IF_ERROR_RETURN(rv); 2903 2904 return BCM_E_NONE; 2905 } 2906 2907 /* 2908 * Function: 2909 * _bcmi_xgs5_port_pm_reset 2910 * Purpose: 2911 * Reset newly bring up Port Macro 2912 * 2913 * Parameters: 2914 * unit - (IN) Unit number. 2915 * add_bmp_pm - (IN) Bitmap of Port Macros actived by Flexport. 2916 * add_pbm_phy - (IN) Bitmap of Physical ports actived by Flexport. 2917 * Returns: 2918 * BCM_E_XXX 2919 */ 2920 STATIC int 2921 _bcmi_xgs5_port_pm_reset(int unit, SHR_BITDCL *add_bmp_pm, pbmp_t *add_pbm_phy) 2922 { 2923 soc_info_t *si = &SOC_INFO(unit); 2924 int blk, bindex, phy_port, local_phy_port, tmp, block, is_clport, port_idx; 2925 int pipe; 2926 soc_reg_t reg; 2927 uint64 rval64, val64_zero; 2928 uint32 addr; 2929 uint8 at; 2930 int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100; 2931 static soc_field_t port_fields[4] = { 2932 PORT0f, PORT1f, PORT2f, PORT3f 2933 }; 2934 2935 LOG_VERBOSE(BSL_LS_BCM_PORT, 2936 (BSL_META_U(unit, 2937 "--- Port Macro Reset ---\n"))); 2938 COMPILER_64_ZERO(val64_zero); 2939 SHR_BIT_ITER(add_bmp_pm, SOC_MAX_NUM_BLKS, blk) { 2940 block = SOC_BLOCK_INFO(unit, blk).cmic; 2941 is_clport = SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT ? 1 : 0; 2942 2943 /******************************* 2944 * Configure MAC Control 2945 */ 2946 reg = is_clport ? CLPORT_MAC_CONTROLr : XLPORT_MAC_CONTROLr; 2947 COMPILER_64_ZERO(rval64); 2948 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 2949 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at); 2950 SOC_REG_RST_VAL_GET(unit, reg, rval64); 2951 soc_reg64_field32_set(unit, reg, &rval64, XMAC0_RESETf, 1); 2952 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64)); 2953 sal_udelay(10); 2954 soc_reg64_field32_set(unit, reg, &rval64, XMAC0_RESETf, 0); 2955 if (is_clport && 2956 soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) { 2957 /* Set PM interface to 16B */ 2958 soc_reg64_field32_set(unit, reg, &rval64, SYS_16B_INTF_MODEf, 1); 2959 } 2960 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64)); 2961 2962 /******************************* 2963 * Reset TSC 2964 */ 2965 if (soc_feature(unit, soc_feature_pm_refclk_master)) { 2966 /* Port Macros act as refclk master are initialized in system 2967 * init stage, no action during Flexport 2968 */ 2969 if (SHR_BITGET(si->pm_ref_master_bitmap, blk)) { 2970 continue; 2971 } 2972 } 2973 2974 reg = is_clport ? CLPORT_XGXS0_CTRL_REGr : XLPORT_XGXS0_CTRL_REGr; 2975 COMPILER_64_ZERO(rval64); 2976 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 2977 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at); 2978 2979 /* Set TSC in master mode */ 2980 SOC_REG_RST_VAL_GET(unit, reg, rval64); 2981 soc_reg64_field32_set(unit, reg, &rval64, REFIN_ENf, 2982 SAL_BOOT_QUICKTURN ? 0 : 1); 2983 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64)); 2984 2985 /* Deassert power down */ 2986 soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0); 2987 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64)); 2988 sal_usleep(sleep_usec); 2989 2990 /* Reset XGXS */ 2991 soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0); 2992 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64)); 2993 2994 sal_usleep(sleep_usec + 10000); 2995 2996 /* Bring XGXS out of reset */ 2997 soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1); 2998 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64)); 2999 sal_usleep(sleep_usec); 3000 } 3001 3002 for (pipe = 0; pipe < si->num_pipe; pipe++) { 3003 SOC_PBMP_ITER(add_pbm_phy[pipe], local_phy_port) { 3004 phy_port = local_phy_port + 3005 BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe]; 3006 3007 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 3008 port_idx++) { 3009 3010 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 3011 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, port_idx); 3012 if (blk < 0) { /* End of block list of each port */ 3013 break; 3014 } 3015 block = SOC_BLOCK_INFO(unit, blk).cmic; 3016 is_clport = 3017 SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT ? 1 : 0; 3018 3019 /* Initialize PORT MIB counter */ 3020 reg = is_clport ? CLPORT_MIB_RESETr : XLPORT_MIB_RESETr; 3021 COMPILER_64_ZERO(rval64); 3022 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 3023 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at); 3024 soc_reg64_field32_set(unit, reg, &rval64, CLR_CNTf, (1 < bindex)); 3025 BCM_IF_ERROR_RETURN 3026 (_soc_reg64_set(unit, block, at, addr, rval64)); 3027 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, val64_zero)); 3028 3029 /* CLPORT_MODE_REG is programmed in Flexport Tier1 API */ 3030 3031 reg = is_clport ? CLPORT_SOFT_RESETr : XLPORT_SOFT_RESETr; 3032 COMPILER_64_ZERO(rval64); 3033 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 3034 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at); 3035 /* Assert CLPORT/XLPORT soft reset */ 3036 soc_reg64_field32_set(unit, reg, &rval64, port_fields[bindex], 1); 3037 BCM_IF_ERROR_RETURN 3038 (_soc_reg64_set(unit, block, at, addr, rval64)); 3039 /* De-assert CLPORT/XLPORT soft reset */ 3040 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, val64_zero)); 3041 3042 reg = is_clport ? CLPORT_ENABLE_REGr : XLPORT_ENABLE_REGr; 3043 COMPILER_64_ZERO(rval64); 3044 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 3045 SOC_REG_ADDR_OPTION_NONE, &tmp, &at); 3046 BCM_IF_ERROR_RETURN 3047 (_soc_reg64_get(unit, block, at, addr, &rval64)); 3048 soc_reg64_field32_set(unit, reg, &rval64, port_fields[bindex], 1); 3049 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 3050 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at); 3051 BCM_IF_ERROR_RETURN 3052 (_soc_reg64_set(unit, block, at, addr, rval64)); 3053 3054 reg = is_clport ? CLPORT_POWER_SAVEr : XLPORT_POWER_SAVEr; 3055 COMPILER_64_ZERO(rval64); 3056 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 3057 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at); 3058 soc_reg64_field32_set(unit, reg, &rval64, XPORT_CORE0f, 0); 3059 BCM_IF_ERROR_RETURN 3060 (_soc_reg64_set(unit, block, at, addr, rval64)); 3061 } 3062 } 3063 } 3064 return BCM_E_NONE; 3065 } 3066 3067 /* 3068 * Function: 3069 * _bcmi_xgs5_port_ipep_reconfigure 3070 * Purpose: 3071 * Update the port related reg/mem in IP/EP after flexport 3072 * 3073 * Parameters: 3074 * unit - (IN) Unit number. 3075 * add_pbm_log - (IN) Bitmap of newly added logical ports. 3076 * del_pbm_log - (IN) Bitmap of deleted logical ports. 3077 * Returns: 3078 * BCM_E_XXX 3079 */ 3080 STATIC int 3081 _bcmi_xgs5_port_ipep_reconfigure(int unit, 3082 pbmp_t add_pbm_log, 3083 pbmp_t del_pbm_log) 3084 { 3085 int logic_port, is_clport, is_cdport; 3086 soc_reg_t reg; 3087 uint32 rval; 3088 uint32 entry[SOC_MAX_MEM_WORDS]; 3089 pbmp_t pbmp; 3090 int cntmaxsize; 3091 3092 LOG_VERBOSE(BSL_LS_BCM_PORT, 3093 (BSL_META_U(unit, 3094 "--- Port IP/EP Reconfigure ---\n"))); 3095 3096 SOC_PBMP_ITER(add_pbm_log, logic_port) { 3097 is_clport = IS_CL_PORT(unit, logic_port); 3098 is_cdport = IS_CD_PORT(unit, logic_port); 3099 3100 reg = INVALIDr; 3101 if (is_cdport) { 3102 reg = INVALIDr; 3103 } else if (is_clport) { 3104 reg = CLPORT_CNTMAXSIZEr; 3105 } else if (IS_QSGMII_PORT(unit, logic_port)) { 3106 reg = GPORT_CNTMAXSIZEr; 3107 } else { 3108 reg = XLPORT_CNTMAXSIZEr; 3109 } 3110 3111 if (reg != INVALIDr) { 3112 rval = 0; 3113 cntmaxsize = is_clport ? BCMI_PORT_DRV_DEV_INFO(unit)->cntmaxsize_cl : 3114 BCMI_PORT_DRV_DEV_INFO(unit)->cntmaxsize_xl; 3115 soc_reg_field_set(unit, reg, &rval, CNTMAXSIZEf, cntmaxsize); 3116 BCM_IF_ERROR_RETURN 3117 (soc_reg32_set(unit, reg, logic_port, 0, rval)); 3118 } 3119 3120 reg = INVALIDr; 3121 if (is_cdport) { 3122 reg = CDPORT_FLOW_CONTROL_CONFIGr; 3123 } else if (is_clport) { 3124 reg = CLPORT_FLOW_CONTROL_CONFIGr; 3125 } else { 3126 reg = XLPORT_FLOW_CONTROL_CONFIGr; 3127 } 3128 3129 rval = 0; 3130 soc_reg_field_set(unit, reg, &rval, MERGE_MODE_ENf, 1); 3131 BCM_IF_ERROR_RETURN 3132 (soc_reg32_set(unit, reg, logic_port, 0, rval)); 3133 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 3134 if (IS_HG_PORT(unit, logic_port)) { 3135 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 3136 } 3137 BCM_IF_ERROR_RETURN 3138 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, logic_port, 3139 entry)); 3140 #ifdef BCM_TRIDENT2PLUS_SUPPORT 3141 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 3142 if (soc_feature(unit, soc_feature_egr_all_profile)) { 3143 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 3144 logic_port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 1)); 3145 3146 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 3147 logic_port, EGR_VLAN_CONTROL_1m, VT_MISS_UNTAGf, 0)); 3148 3149 } else { 3150 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 3151 EGR_VLAN_CONTROL_1m, logic_port, REMARK_OUTER_DOT1Pf, 1)); 3152 3153 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 3154 EGR_VLAN_CONTROL_1m, logic_port, VT_MISS_UNTAGf, 0)); 3155 } 3156 } else 3157 #endif 3158 { 3159 reg = EGR_VLAN_CONTROL_1r; 3160 rval = 0; 3161 if (SOC_REG_FIELD_VALID(unit, reg, VT_MISS_UNTAGf)) { 3162 soc_reg_field_set(unit, reg, &rval, VT_MISS_UNTAGf, 0); 3163 } 3164 if (SOC_REG_FIELD_VALID(unit, reg, REMARK_OUTER_DOT1Pf)) { 3165 soc_reg_field_set(unit, reg, &rval, REMARK_OUTER_DOT1Pf, 1); 3166 } 3167 BCM_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, logic_port, rval)); 3168 } 3169 } 3170 3171 BCM_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 3172 MEM_BLOCK_ANY, 0, &entry)); 3173 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm, &entry, 3174 BITMAPf, &pbmp); 3175 SOC_PBMP_REMOVE(pbmp, del_pbm_log); 3176 SOC_PBMP_OR(pbmp, add_pbm_log); 3177 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, 3178 BITMAPf, &pbmp); 3179 BCM_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 3180 MEM_BLOCK_ANY, 0, &entry)); 3181 3182 return BCM_E_NONE; 3183 } 3184 3185 #if 0 3186 /* 3187 * Function: 3188 * _bcmi_xgs5_port_soc_info_ptype_update 3189 * Purpose: 3190 * Update the SOC_INFO port type bitmaps and block information. 3191 * Parameters: 3192 * unit - (IN) Unit number. 3193 * port_schedule_state - (IN) port_schedule_state 3194 * 3195 * 3196 * Returns: 3197 * SOC_E_XXX 3198 * Notes: 3199 * Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK 3200 * locks are taken. 3201 */ 3202 STATIC int 3203 _bcmi_xgs5_port_soc_info_ptype_update(int unit) 3204 { 3205 soc_info_t *si = &SOC_INFO(unit); 3206 int logic_port, phy_port, port_idx, max_port; 3207 int blk, bindex; 3208 3209 /* 3210 * Update ptype information 3211 */ 3212 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \ 3213 si->ptype.num = 0; \ 3214 si->ptype.min = si->ptype.max = -1; \ 3215 PBMP_ITER(si->ptype.bitmap, logic_port) { \ 3216 si->port_offset[logic_port] = si->ptype.num; \ 3217 si->ptype.port[si->ptype.num++] = logic_port; \ 3218 if (si->ptype.min < 0) { \ 3219 si->ptype.min = logic_port; \ 3220 } \ 3221 if (logic_port > si->ptype.max) { \ 3222 si->ptype.max = logic_port; \ 3223 } \ 3224 } 3225 3226 RECONFIGURE_PORT_TYPE_INFO(ge); 3227 RECONFIGURE_PORT_TYPE_INFO(xe); 3228 RECONFIGURE_PORT_TYPE_INFO(c); 3229 RECONFIGURE_PORT_TYPE_INFO(ce); 3230 RECONFIGURE_PORT_TYPE_INFO(xl); 3231 RECONFIGURE_PORT_TYPE_INFO(cl); 3232 RECONFIGURE_PORT_TYPE_INFO(gx); 3233 RECONFIGURE_PORT_TYPE_INFO(ether); 3234 RECONFIGURE_PORT_TYPE_INFO(hg); 3235 RECONFIGURE_PORT_TYPE_INFO(st); 3236 RECONFIGURE_PORT_TYPE_INFO(port); 3237 RECONFIGURE_PORT_TYPE_INFO(all); 3238 3239 #undef RECONFIGURE_PORT_TYPE_INFO 3240 3241 3242 /* 3243 * Update block port 3244 * Use first logical port on block (logic follows ESW driver 3245 * soc_info_config(). 3246 */ 3247 for (phy_port = 0; ; phy_port++) { 3248 3249 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 3250 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0); 3251 if (blk < 0 && bindex < 0) { /* End of port list */ 3252 break; 3253 } 3254 3255 logic_port = si->port_p2l_mapping[phy_port]; 3256 if (logic_port < 0) { 3257 continue; 3258 } 3259 3260 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 3261 port_idx++) { 3262 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 3263 if (blk < 0) { /* End of block list of each port */ 3264 break; 3265 } 3266 3267 if (si->block_port[blk] < 0) { 3268 si->block_port[blk] = logic_port; 3269 } 3270 } 3271 } 3272 3273 /* Update MAX_PORT(unit) */ 3274 max_port = -1; 3275 for (phy_port = 0; phy_port < BCMI_PORT_DRV_DEV_INFO(unit)->phy_ports_max; 3276 phy_port++) { 3277 logic_port = si->port_p2l_mapping[phy_port]; 3278 if (logic_port < 0) { 3279 continue; 3280 } 3281 if (max_port < logic_port) { 3282 max_port = logic_port; 3283 } 3284 } 3285 si->port_num = max_port + 1; 3286 3287 /* Update user port mappings (includes port names update) */ 3288 soc_esw_dport_init(unit); 3289 3290 return SOC_E_NONE; 3291 } 3292 #endif 3293 3294 /* 3295 * Function: 3296 * _soc_xgs5_port_soc_info_ptype_block_add 3297 * Purpose: 3298 * Set the port type bitmaps and block information in SOC_INFO 3299 * for ports to be configured during the FlexPort operation. 3300 * Parameters: 3301 * unit - (IN) Unit number. 3302 * post_count - (IN) Array size for post-FlexPort array. 3303 * post_resource - (IN) Pre-FlexPort configuration array. 3304 * Returns: 3305 * SOC_E_XXX 3306 * Notes: 3307 * Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK 3308 * locks are taken. 3309 */ 3310 STATIC int 3311 _bcmi_xgs5_port_soc_info_ptype_block_add(int unit, 3312 soc_port_schedule_state_t *port_schedule_state) 3313 { 3314 soc_info_t *si = &SOC_INFO(unit); 3315 soc_port_resource_t *resource, *pr; 3316 int logic_port, phy_port, port_idx; 3317 int blk, bindex, blktype, old_blktype; 3318 int nport, i; 3319 3320 nport = port_schedule_state->nport; 3321 resource = port_schedule_state->resource; 3322 3323 /* 3324 * Add to port type bitmaps and block information 3325 */ 3326 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 3327 if (pr->physical_port == -1) { 3328 continue; 3329 } 3330 3331 logic_port = pr->logical_port; 3332 phy_port = pr->physical_port; 3333 3334 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 3335 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0); 3336 if (blk < 0 && bindex < 0) { /* End of regsfile port list */ 3337 continue; 3338 } 3339 3340 blktype = -1; 3341 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 3342 port_idx++) { 3343 3344 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 3345 if (blk < 0) { /* End of block list of each port */ 3346 break; 3347 } 3348 3349 old_blktype = blktype; 3350 blktype = SOC_BLOCK_INFO(unit, blk).type; 3351 3352 switch (blktype) { 3353 case SOC_BLK_CDPORT: 3354 SOC_PBMP_PORT_ADD(si->cd.bitmap, logic_port); 3355 if ((pr->encap == SOC_ENCAP_IEEE) && 3356 ((si->port_init_speed[logic_port] == 200000) || 3357 (si->port_init_speed[logic_port] == 400000))) { /* CDE */ 3358 SOC_PBMP_PORT_ADD(si->cde.bitmap, logic_port); 3359 SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port); 3360 SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port); 3361 SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port); 3362 break; 3363 } 3364 /* fall through to case for SOC_BLK_CLPORT */ 3365 3366 case SOC_BLK_CLPORT: 3367 if (blktype == SOC_BLK_CLPORT) { 3368 SOC_PBMP_PORT_ADD(si->cl.bitmap, logic_port); 3369 } 3370 if (si->port_init_speed[logic_port] >= 100000) { 3371 /* Catch both CE and HG ports */ 3372 SOC_PBMP_PORT_ADD(si->c.bitmap, logic_port); 3373 } 3374 if ((pr->encap == SOC_ENCAP_IEEE) && 3375 ((si->port_init_speed[logic_port] == 100000) || 3376 (si->port_init_speed[logic_port] == 120000))) { /* CE */ 3377 SOC_PBMP_PORT_ADD(si->ce.bitmap, logic_port); 3378 SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port); 3379 SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port); 3380 SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port); 3381 break; 3382 } 3383 /* fall through to case for SOC_BLK_XLPORT */ 3384 /* coverity[fallthrough: FALSE] */ 3385 3386 case SOC_BLK_XLPORT: 3387 if (!si->port_init_speed[logic_port]) { 3388 return SOC_E_INTERNAL; 3389 } 3390 3391 /* For 100G or more, use CLPORT block type */ 3392 if ((SOC_BLK_XLPORT == blktype) && 3393 (si->port_init_speed[logic_port] >= 100000)) { 3394 blktype = old_blktype; 3395 break; 3396 } 3397 3398 if (si->port_init_speed[logic_port] < 10000) { /* GE */ 3399 SOC_PBMP_PORT_ADD(si->ge.bitmap, logic_port); 3400 if (pr->encap == SOC_ENCAP_HIGIG2_LITE) { 3401 /* GE in Higig Lite Mode. Higig Like stack capable 3402 * port */ 3403 SOC_PBMP_PORT_ADD(si->st.bitmap, logic_port); 3404 SOC_PBMP_PORT_ADD(si->hl.bitmap, logic_port); 3405 } else { 3406 SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port); 3407 } 3408 } else if (pr->encap == SOC_ENCAP_IEEE) { /* XE */ 3409 SOC_PBMP_PORT_ADD(si->xe.bitmap, logic_port); 3410 SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port); 3411 } else { /* HG */ 3412 SOC_PBMP_PORT_ADD(si->hg.bitmap, logic_port); 3413 SOC_PBMP_PORT_ADD(si->st.bitmap, logic_port); 3414 /* Name is default to hg by lookup above */ 3415 } 3416 3417 SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port); 3418 SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port); 3419 3420 /* 3421 * Part of legacy code to add to these extra bitmaps 3422 */ 3423 if (!IS_CL_PORT(unit, logic_port) && 3424 !IS_CD_PORT(unit, logic_port)) { 3425 SOC_PBMP_PORT_ADD(si->xl.bitmap, logic_port); 3426 } 3427 if (!SOC_IS_HELIX5(unit)) { 3428 SOC_PBMP_PORT_ADD(si->gx.bitmap, logic_port); 3429 } 3430 break; 3431 case SOC_BLK_GXPORT: 3432 SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port); 3433 if (si->port_init_speed[logic_port] < 10000) { 3434 SOC_PBMP_PORT_ADD(si->ge.bitmap, logic_port); 3435 } 3436 SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port); 3437 SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port); 3438 SOC_PBMP_PORT_ADD(si->gx.bitmap, logic_port); 3439 default: 3440 break; 3441 } 3442 3443 /* Update block information */ 3444 si->block_valid[blk] += 1; 3445 3446 if (si->block_port[blk] < 0) { 3447 si->block_port[blk] = logic_port; 3448 } 3449 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], logic_port); 3450 3451 } /* For each block in the given port */ 3452 3453 si->port_type[logic_port] = blktype; 3454 3455 } /* For each port */ 3456 3457 BCM_IF_ERROR_RETURN 3458 (_bcmi_xgs5_port_soc_info_ptype_update(unit)); 3459 3460 return SOC_E_NONE; 3461 } 3462 3463 /* 3464 * Function: 3465 * _soc_xgs5_port_soc_info_ptype_block_delete 3466 * Purpose: 3467 * Clear the port type bitmaps and block information in SOC_INFO 3468 * for ports to be removed during the FlexPort operation. 3469 * Parameters: 3470 * unit - (IN) Unit number. 3471 * Returns: 3472 * SOC_E_XXX 3473 * Notes: 3474 * Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK 3475 * locks are taken. 3476 */ 3477 STATIC int 3478 _bcmi_xgs5_port_soc_info_ptype_block_delete(int unit, 3479 soc_port_schedule_state_t *port_schedule_state) 3480 { 3481 soc_info_t *si = &SOC_INFO(unit); 3482 soc_port_resource_t *resource, *pr; 3483 soc_port_map_type_t *pre_port_map; 3484 int logic_port, phy_port, port_idx; 3485 int blk, bindex; 3486 int nport, i; 3487 3488 nport = port_schedule_state->nport; 3489 resource = port_schedule_state->resource; 3490 pre_port_map = &port_schedule_state->in_port_map; 3491 3492 /* 3493 * Clear port bitmaps and block information 3494 */ 3495 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 3496 /* 3497 * If not a delete entry, don't do anything 3498 * If 'inactive' flag, don't do anything 3499 */ 3500 if (pr->physical_port != -1 || 3501 ((pr->flags & SOC_PORT_RESOURCE_I_MAP) && 3502 (pr->op == BCMI_XGS5_PORT_RESOURCE_OP_DEL))) { 3503 continue; 3504 } 3505 3506 logic_port = pr->logical_port; 3507 phy_port = pre_port_map->port_l2p_mapping[logic_port]; 3508 3509 /* 3510 * Clear port from all possible port bitmaps where a flexed port 3511 * can be a member of. 3512 */ 3513 SOC_PBMP_PORT_REMOVE(si->cde.bitmap, logic_port); 3514 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, logic_port); 3515 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, logic_port); 3516 SOC_PBMP_PORT_REMOVE(si->c.bitmap, logic_port); 3517 SOC_PBMP_PORT_REMOVE(si->ce.bitmap, logic_port); 3518 SOC_PBMP_PORT_REMOVE(si->xl.bitmap, logic_port); 3519 SOC_PBMP_PORT_REMOVE(si->cl.bitmap, logic_port); 3520 SOC_PBMP_PORT_REMOVE(si->gx.bitmap, logic_port); 3521 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, logic_port); 3522 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, logic_port); 3523 SOC_PBMP_PORT_REMOVE(si->st.bitmap, logic_port); 3524 SOC_PBMP_PORT_REMOVE(si->port.bitmap, logic_port); 3525 SOC_PBMP_PORT_REMOVE(si->all.bitmap, logic_port); 3526 3527 if (phy_port == -1) { 3528 continue; 3529 } 3530 3531 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 3532 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0); 3533 if (blk < 0 && bindex < 0) { /* End of regsfile port list */ 3534 continue; 3535 } 3536 3537 /* Clear block information */ 3538 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 3539 port_idx++) { 3540 3541 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 3542 if (blk < 0) { /* End of block list of each port */ 3543 break; 3544 } 3545 3546 /* Update block information */ 3547 if (si->block_valid[blk] > 0) { 3548 si->block_valid[blk] -= 1; 3549 } 3550 if (si->block_port[blk] == logic_port) { 3551 si->block_port[blk] = REG_PORT_ANY; 3552 } 3553 SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk], logic_port); 3554 3555 } /* For each block in the given port */ 3556 3557 si->port_type[logic_port] = 0; 3558 si->port_offset[logic_port] = 0; 3559 3560 } /* For each port */ 3561 3562 return SOC_E_NONE; 3563 } 3564 3565 3566 3567 /* 3568 * Function: 3569 * _soc_xgs5_port_soc_counter_add 3570 * Purpose: 3571 * Add ports to SOC counter map. 3572 * Parameters: 3573 * unit - (IN) Unit number. 3574 * post_count - (IN) Array size. 3575 * post_resource - (IN) Array of ports to add. * Returns: 3576 * SOC_E_XXX * Notes: 3577 * Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK 3578 * locks are taken. 3579 */ 3580 STATIC int 3581 _bcmi_xgs5_port_soc_counter_add(int unit, 3582 soc_port_schedule_state_t *port_schedule_state) 3583 { 3584 soc_control_t *soc = SOC_CONTROL(unit); 3585 soc_port_resource_t *resource, *pr; 3586 soc_counter_non_dma_t *non_dma; 3587 int i, nport, dma_id; 3588 int phy_port; 3589 int logic_port; 3590 int blk; 3591 int bindex; 3592 int blktype; 3593 int port_idx; 3594 soc_ctr_type_t ctype; 3595 int rv = BCM_E_NONE; 3596 3597 nport = port_schedule_state->nport; 3598 resource = port_schedule_state->resource; 3599 3600 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 3601 3602 /* Skip 'delete' ports */ 3603 if (pr->physical_port == -1) { 3604 continue; 3605 } 3606 3607 logic_port = pr->logical_port; 3608 phy_port = pr->physical_port; 3609 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 3610 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0); 3611 if (blk < 0 && bindex < 0) { /* End of regsfile port list */ 3612 continue; 3613 } 3614 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 3615 port_idx++) { 3616 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 3617 if (blk < 0) { /* End of block list of each port */ 3618 break; 3619 } 3620 blktype = SOC_BLOCK_INFO(unit, blk).type; 3621 switch (blktype) { 3622 case SOC_BLK_CDPORT: 3623 ctype = SOC_CTR_TYPE_CD; 3624 break; 3625 case SOC_BLK_CLPORT: 3626 ctype = SOC_CTR_TYPE_CE; 3627 break; 3628 case SOC_BLK_XLPORT: 3629 case SOC_BLK_GXPORT: 3630 if(IS_QSGMII_PORT(unit, logic_port)) { 3631 ctype = SOC_CTR_TYPE_GE; 3632 } else { 3633 ctype = SOC_CTR_TYPE_XE; 3634 } 3635 break; 3636 default: 3637 ctype = -1; 3638 break; 3639 } 3640 if (ctype != -1) { 3641 /* Adding of dma counter descriptors is only necessary when the 3642 * counter thread is running 3643 * this check is necessary to avoid reallocating the dma 3644 * descriptos when the conter thread is stopped running before 3645 * the flex operation 3646 */ 3647 if (soc->counter_interval) { 3648 rv = soc_counter_port_sbusdma_desc_alloc(unit, logic_port); 3649 if (BCM_FAILURE(rv)) { 3650 LOG_ERROR(BSL_LS_BCM_PORT, 3651 (BSL_META_U(unit, 3652 "Error! Unable to allocate SBUS " 3653 "DMA descriptors per logical " 3654 "port %d \n"), 3655 logic_port)); 3656 return rv; 3657 } 3658 } 3659 BCM_IF_ERROR_RETURN 3660 (soc_port_cmap_set(unit, logic_port, ctype)); 3661 SOC_PBMP_PORT_ADD(soc->counter_pbmp, logic_port); 3662 3663 for (dma_id = 0; 3664 dma_id < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START; 3665 dma_id++) { 3666 non_dma = &soc->counter_non_dma[dma_id]; 3667 if (non_dma->entries_per_port > 0) { 3668 SOC_PBMP_PORT_ADD(non_dma->pbmp, logic_port); 3669 } 3670 } 3671 break; 3672 } 3673 } /* For each block in the given port */ 3674 } /* For each port */ 3675 3676 return SOC_E_NONE; 3677 } 3678 3679 /* 3680 * Function: 3681 * _soc_xgs5_port_soc_counter_delete 3682 * Purpose: 3683 * Delete ports from SOC counter map. 3684 * Parameters: 3685 * unit - (IN) Unit number. 3686 * pre_count - (IN) Array size. 3687 * pre_resource - (IN) Array of ports to delete. 3688 * Returns: 3689 * SOC_E_XXX * Notes: 3690 * Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK 3691 * locks are taken. 3692 */ 3693 STATIC int 3694 _bcmi_xgs5_port_soc_counter_delete(int unit, 3695 soc_port_schedule_state_t *port_schedule_state) 3696 { 3697 soc_control_t *soc = SOC_CONTROL(unit); 3698 soc_port_resource_t *resource, *pr; 3699 int i, nport; 3700 int phy_port; 3701 int logic_port; 3702 int rv = BCM_E_NONE; 3703 3704 nport = port_schedule_state->nport; 3705 resource = port_schedule_state->resource; 3706 3707 /* Clear counter */ 3708 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 3709 3710 logic_port = pr->logical_port; 3711 phy_port = port_schedule_state->in_port_map.port_l2p_mapping[logic_port]; 3712 3713 if (phy_port == -1) { 3714 continue; 3715 } 3716 3717 /* Delete the counter dma descriptors */ 3718 rv = soc_counter_port_sbusdma_desc_free(unit, logic_port); 3719 if (BCM_FAILURE(rv)) { 3720 LOG_ERROR(BSL_LS_BCM_PORT, 3721 (BSL_META_U(unit, 3722 "Error! Unable to delete SBUS DMA " 3723 "descriptors per logical port %d \n"), 3724 logic_port)); 3725 return rv; 3726 } 3727 3728 /* 3729 * If 'inactive' flag, don't do anything 3730 */ 3731 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 3732 continue; 3733 } 3734 3735 soc->counter_map[logic_port] = 0; 3736 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, logic_port); 3737 } 3738 3739 return SOC_E_NONE; 3740 } 3741 3742 /* 3743 * Function: 3744 * _bcmi_xgs5_port_software_free 3745 * Purpose: 3746 * Deallocates memory for a given port from the BCM PORT module 3747 * data structure. 3748 * Parameters: 3749 * unit - (IN) Unit number. 3750 * port - (IN) Logical port, BCM format. 3751 * Returns: 3752 * BCM_E_XXX 3753 * Notes: 3754 * - Assumes main BCM PORT module initialization has been executed. 3755 * - Assumes port is valid. 3756 */ 3757 STATIC int 3758 _bcmi_xgs5_port_software_free(int unit, bcm_port_t port) 3759 { 3760 _bcm_port_info_t *pinfo; 3761 3762 /* Get PORT info structure pointer */ 3763 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 3764 if (pinfo == NULL) { 3765 return BCM_E_INTERNAL; 3766 } 3767 3768 /* Proto-based VLAN_DATA state */ 3769 if (pinfo->p_vd_pbvl != NULL) { 3770 sal_free(pinfo->p_vd_pbvl); 3771 pinfo->p_vd_pbvl = NULL; 3772 } 3773 3774 /* End-to-end congestion control configuration */ 3775 if (pinfo->e2ecc_config != NULL) { 3776 sal_free(pinfo->e2ecc_config); 3777 pinfo->e2ecc_config = NULL; 3778 } 3779 3780 /* Reset all fields */ 3781 sal_memset(pinfo, 0, sizeof(_bcm_port_info_t)); 3782 3783 return BCM_E_NONE; 3784 } 3785 3786 /* 3787 * Function: 3788 * _bcmi_xgs5_port_skip_attach_phase 3789 * Purpose: 3790 * Check if the phase in attach should be skipped. 3791 * Parameters: 3792 * unit - (IN) Unit number. 3793 * phase - (IN) Phase number in attach/detach. 3794 * Returns: 3795 * 1: skip the phase 3796 * 0: Don't skip the phase 3797 * Notes: 3798 */ 3799 STATIC int 3800 _bcmi_xgs5_port_skip_attach_phase(int unit, int phase) 3801 { 3802 int skip; 3803 switch (phase) 3804 { 3805 case PORT_ATTACH_EXEC__STG: 3806 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3807 SHR_BPROF_BCM_STG); 3808 break; 3809 case PORT_ATTACH_EXEC__VLAN: 3810 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3811 SHR_BPROF_BCM_VLAN); 3812 break; 3813 case PORT_ATTACH_EXEC__TRUNK: 3814 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3815 SHR_BPROF_BCM_TRUNK); 3816 break; 3817 case PORT_ATTACH_EXEC__COSQ: 3818 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3819 SHR_BPROF_BCM_COSQ); 3820 break; 3821 case PORT_ATTACH_EXEC__LINKSCAN: 3822 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3823 SHR_BPROF_BCM_LINKSCAN); 3824 break; 3825 case PORT_ATTACH_EXEC__STATISTIC: 3826 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3827 SHR_BPROF_BCM_STAT); 3828 break; 3829 case PORT_ATTACH_EXEC__STACK: 3830 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3831 SHR_BPROF_BCM_STK); 3832 break; 3833 case PORT_ATTACH_EXEC__RATE: 3834 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3835 SHR_BPROF_BCM_RATE); 3836 break; 3837 case PORT_ATTACH_EXEC__FIELD: 3838 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3839 SHR_BPROF_BCM_FIELD); 3840 break; 3841 case PORT_ATTACH_EXEC__MIRROR: 3842 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3843 SHR_BPROF_BCM_MIRROR); 3844 break; 3845 case PORT_ATTACH_EXEC__L3: 3846 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3847 SHR_BPROF_BCM_L3); 3848 break; 3849 case PORT_ATTACH_EXEC__IPMC: 3850 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3851 SHR_BPROF_BCM_IPMC); 3852 break; 3853 case PORT_ATTACH_EXEC__IPMC_REPL: 3854 if (SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3855 SHR_BPROF_BCM_IPMC) && 3856 soc_feature(unit, soc_feature_ip_mcast_repl)) { 3857 skip = 0; 3858 } else { 3859 skip = 1; 3860 } 3861 break; 3862 case PORT_ATTACH_EXEC__MPLS: 3863 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3864 SHR_BPROF_BCM_MPLS); 3865 break; 3866 case PORT_ATTACH_EXEC__MIM: 3867 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 3868 SHR_BPROF_BCM_MIM); 3869 break; 3870 default: 3871 skip = 0; 3872 break; 3873 } 3874 return skip; 3875 } 3876 3877 /* 3878 * Function: 3879 * _bcm_xgs5_port_resource_attach 3880 * Purpose: 3881 * Attach ports to the BCM layer and initialize them 3882 * to the default state. 3883 * 3884 * Attach only those ports that are flagged as 'new' or 'remapped'. 3885 * If a port currently exists and the mapping is not changed, this 3886 * does not need to be attached. 3887 * - New: Logical port did not exist before FlexPort. 3888 * - Remapped: Logical port will continue to exist after FlexPort 3889 * but is mapped to a different physical port. 3890 * The port needs to be 'detached' and 'attached'. 3891 * Parameters: 3892 * unit - (IN) Unit number. 3893 * nport - (IN) Number of elements in array resource. 3894 * resource - (IN) Port Resource FlexPort configuration. 3895 * Returns: 3896 * BCM_E_XXX 3897 * Notes: 3898 * - Assumes caller have detached any ports that will be attached 3899 * in this routine (this is for the REMAP case). 3900 * - Assumes this is NOT called during Warmboot. 3901 */ 3902 STATIC int 3903 _bcmi_xgs5_port_resource_attach(int unit, 3904 soc_port_schedule_state_t *port_schedule_state) 3905 { 3906 int rv = BCM_E_NONE; 3907 soc_port_resource_t *pr, *resource; 3908 int i, j, nport, my_modid; 3909 3910 LOG_VERBOSE(BSL_LS_BCM_PORT, 3911 (BSL_META_U(unit, 3912 "--- BCM Attach ---\n"))); 3913 3914 nport = port_schedule_state->nport; 3915 resource = port_schedule_state->resource; 3916 3917 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 3918 3919 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 3920 /* 3921 * If 'inactive' flag, don't do anything 3922 */ 3923 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 3924 continue; 3925 } 3926 3927 /* Skip 'delete' ports */ 3928 if (pr->physical_port == -1) { 3929 continue; 3930 } 3931 3932 if ((pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) || 3933 (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 3934 for(j = 0; j < PORT_ATTACH_EXEC__MAX; j++) { 3935 if(BCMI_PORT_DRV_CALL(unit)->port_attach_exec[j] != NULL) { 3936 3937 if (_bcmi_xgs5_port_skip_attach_phase(unit, j)) { 3938 LOG_VERBOSE(BSL_LS_BCM_PORT, 3939 (BSL_META_U(unit, 3940 "Skip Attach Phase %s\n"), 3941 bcmi_xgs5_port_attach_str[j])); 3942 continue; 3943 } 3944 3945 LOG_VERBOSE(BSL_LS_BCM_PORT, 3946 (BSL_META_U(unit, 3947 "BCM PORT %d (%s) Attach Phase %s\n"), 3948 pr->logical_port, 3949 SOC_PORT_NAME(unit, pr->logical_port), 3950 bcmi_xgs5_port_attach_str[j])); 3951 3952 rv = BCMI_PORT_DRV_CALL(unit)->port_attach_exec[j](unit, 3953 pr->logical_port); 3954 if (BCM_FAILURE(rv)) { 3955 _bcmi_xgs5_port_software_free(unit, pr->logical_port); 3956 LOG_ERROR(BSL_LS_BCM_PORT, 3957 (BSL_META_U(unit, 3958 "Error: Unable to attach BCM port. " 3959 "Failed at phase %d - %s. " 3960 "unit=%d port=%d rv=%d(%s)\n"), 3961 j, bcmi_xgs5_port_attach_str[j], unit, 3962 pr->logical_port, rv, bcm_errmsg(rv))); 3963 return rv; 3964 } 3965 3966 } 3967 } 3968 } 3969 } 3970 3971 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_set(unit, my_modid)); 3972 3973 return BCM_E_NONE; 3974 } 3975 3976 /* 3977 * Function: 3978 * _bcmi_xgs5_port_soc_info_add 3979 * Purpose: 3980 * Add port information in SOC_INFO SW 3981 * 3982 * Parameters: 3983 * unit - (IN) Unit number. 3984 * port_schedule_state - (IN) Port schedule state. 3985 * Returns: 3986 * SOC_E_XXX 3987 */ 3988 STATIC int 3989 _bcmi_xgs5_port_soc_info_add(int unit, 3990 bcm_port_resource_t *resource, 3991 soc_port_schedule_state_t *port_schedule_state) 3992 { 3993 soc_info_t *si = &SOC_INFO(unit); 3994 soc_persist_t *sop = SOC_PERSIST(unit); 3995 soc_port_resource_t *spr, *pr; 3996 soc_pmvco_info_t pm_vco_info; 3997 int i; 3998 int port, phy_port, mmu_port, idb_port; 3999 int nport; 4000 int rv = BCM_E_NONE; 4001 4002 nport = port_schedule_state->nport; 4003 spr = port_schedule_state->resource; 4004 4005 SOC_CONTROL_LOCK(unit); 4006 /* Update mapping */ 4007 for (i = 0, pr = spr; i < nport; i++, pr++) { 4008 port = pr->logical_port; 4009 phy_port = pr->physical_port; 4010 idb_port = pr->idb_port; 4011 mmu_port = pr->mmu_port; 4012 4013 if (phy_port == -1) { 4014 /* Remove port from physical_pbm, which is used to store the port bitmap of 25G 4015 * ports using 50G TDM calendar. 4016 */ 4017 if (SOC_PBMP_MEMBER( 4018 port_schedule_state->in_port_map.physical_pbm, port)){ 4019 SOC_PBMP_PORT_REMOVE( 4020 port_schedule_state->in_port_map.physical_pbm, port); 4021 } 4022 continue; 4023 } 4024 4025 if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD | 4026 BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 4027 4028 /* IPG Configuration per port */ 4029 sop->ipg[port].hd_10 = 96; 4030 sop->ipg[port].hd_100 = 96; 4031 sop->ipg[port].hd_1000 = 96; 4032 sop->ipg[port].hd_2500 = 96; 4033 sop->ipg[port].fd_10 = 96; 4034 sop->ipg[port].fd_100 = 96; 4035 sop->ipg[port].fd_1000 = 96; 4036 sop->ipg[port].fd_2500 = 96; 4037 sop->ipg[port].fd_10000 = 96; 4038 sop->ipg[port].fd_xe = 96; 4039 sop->ipg[port].fd_hg = 64; 4040 sop->ipg[port].fd_hg2 = 96; 4041 4042 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port); 4043 4044 /* Port Mapping related information */ 4045 si->port_l2p_mapping[port] = phy_port; 4046 si->port_p2l_mapping[phy_port] = port; 4047 si->port_l2i_mapping[port] = idb_port; 4048 si->port_p2m_mapping[phy_port] = mmu_port; 4049 if (mmu_port != -1) { 4050 si->port_m2p_mapping[mmu_port] = phy_port; 4051 } 4052 4053 /* Pipe */ 4054 si->port_pipe[port] = pr->pipe; 4055 SOC_PBMP_PORT_ADD(si->pipe_pbm[pr->pipe], port); 4056 4057 si->port_speed_max[port] = resource[i].speed; 4058 si->port_init_speed[port] = resource[i].speed; 4059 si->port_num_lanes[port] = pr->num_lanes; 4060 #if defined(BCM_TOMAHAWK3_SUPPORT) 4061 if (SOC_IS_TOMAHAWK3(unit)) { 4062 si->port_serdes[port] = 4063 (phy_port - 1) / BCMI_XGS5_PORTS_PER_PM8X50_PBLK; 4064 } else 4065 #endif 4066 { 4067 si->port_serdes[port] = (phy_port - 1) / BCMI_XGS5_PORTS_PER_PBLK; 4068 } 4069 4070 si->port_fec_type[port] = resource[i].fec_type; 4071 si->port_phy_lane_config[port] = resource[i].phy_lane_config; 4072 si->port_link_training[port] = resource[i].link_training; 4073 4074 #ifdef BCM_HELIX5_SUPPORT 4075 if (SOC_IS_HELIX5(unit)) { 4076 if (phy_port <= 48) { 4077 si->port_serdes[port] = (phy_port - 1) / _HX5_PORTS_PER_PMQ_PBLK; 4078 } else { 4079 si->port_serdes[port] = ((phy_port - 1) / _HX5_PORTS_PER_PBLK) - 9; 4080 } 4081 } 4082 #endif 4083 4084 /* Oversub */ 4085 if (pr->oversub) { 4086 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 4087 } else { 4088 SOC_PBMP_PORT_REMOVE(si->oversub_pbm, port); 4089 } 4090 4091 /* ENCAP */ 4092 if ((pr->encap == SOC_ENCAP_HIGIG2) || 4093 (pr->encap == SOC_ENCAP_HIGIG2_LITE) || 4094 (pr->encap == SOC_ENCAP_HIGIG2_L2) || 4095 (pr->encap == SOC_ENCAP_HIGIG2_IP_GRE)) { 4096 SOC_PBMP_PORT_ADD(si->hg2_pbm, port); 4097 } else { 4098 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port); 4099 } 4100 4101 /* High Speed Port */ 4102 if (pr->hsp) { 4103 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 4104 } else { 4105 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port); 4106 } 4107 } else { 4108 if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_SPEED | 4109 BCMI_XGS5_PORT_RESOURCE_OP_LANES)) { 4110 if ((si->port_speed_max[pr->logical_port] == 0) || 4111 (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_LANES)){ 4112 si->port_speed_max[pr->logical_port] = resource[i].speed; 4113 } 4114 4115 si->port_init_speed[pr->logical_port] = resource[i].speed; 4116 si->port_num_lanes[port] = pr->num_lanes; 4117 4118 si->port_fec_type[port] = resource[i].fec_type; 4119 si->port_phy_lane_config[port] = resource[i].phy_lane_config; 4120 si->port_link_training[port] = resource[i].link_training; 4121 4122 4123 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port); 4124 if (pr->hsp) { 4125 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 4126 } 4127 4128 /* 4129 * Update bitmaps and port names when switching b/w CE <=> XE ports. 4130 * - Remove port from bitmap first 4131 */ 4132 SOC_PBMP_PORT_REMOVE(si->cde.bitmap, port); 4133 SOC_PBMP_PORT_REMOVE(si->ce.bitmap, port); 4134 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 4135 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port); 4136 } 4137 /* ENCAP */ 4138 if ((pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) || 4139 (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) { 4140 if ((pr->encap == SOC_ENCAP_HIGIG2) || 4141 (pr->encap == SOC_ENCAP_HIGIG2_LITE) || 4142 (pr->encap == SOC_ENCAP_HIGIG2_L2) || 4143 (pr->encap == SOC_ENCAP_HIGIG2_IP_GRE)) { 4144 SOC_PBMP_PORT_ADD(si->hg2_pbm, port); 4145 } else { 4146 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port); 4147 } 4148 } 4149 if (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE) { 4150 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port); 4151 } 4152 } 4153 4154 /* Update physical_pbm, which is used to store the port bitmap of 25G ports using 4155 * 50G TDM calendar. 4156 */ 4157 if (pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR) { 4158 SOC_PBMP_PORT_ADD(port_schedule_state->in_port_map.physical_pbm, 4159 port); 4160 } else if (SOC_PBMP_MEMBER( 4161 port_schedule_state->in_port_map.physical_pbm, port)){ 4162 SOC_PBMP_PORT_REMOVE(port_schedule_state->in_port_map.physical_pbm, 4163 port); 4164 } 4165 #ifdef BCM_TOMAHAWK3_SUPPORT 4166 if (SOC_IS_TOMAHAWK3(unit)) { 4167 soc_tomahawk3_num_cosq_init(unit, port); 4168 } 4169 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4170 } 4171 4172 /* Add port ptype bitmap and block information */ 4173 rv = _bcmi_xgs5_port_soc_info_ptype_block_add(unit, port_schedule_state); 4174 if (BCM_FAILURE(rv)) { 4175 goto cleanup; 4176 } 4177 4178 /* Add counter map */ 4179 rv = _bcmi_xgs5_port_soc_counter_add(unit, port_schedule_state); 4180 if (BCM_FAILURE(rv)) { 4181 goto cleanup; 4182 } 4183 4184 /* Update VCO information for devices that need it */ 4185 for (i = 0; i < SOC_MAX_NUM_BLKS; i++) { 4186 rv = soc_esw_portctrl_pm_vco_fetch(unit, i, &pm_vco_info); 4187 if (BCM_SUCCESS(rv)) { 4188 if (pm_vco_info.is_tvco_new == 1 || 4189 pm_vco_info.is_ovco_new == 1) { 4190 sal_memcpy(&si->pm_vco_info[i], 4191 &pm_vco_info, 4192 sizeof(soc_pmvco_info_t)); 4193 } 4194 } else { 4195 rv = BCM_E_NONE; 4196 } 4197 } 4198 4199 cleanup: 4200 SOC_CONTROL_UNLOCK(unit); 4201 4202 return rv; 4203 } 4204 4205 /* 4206 * Function: 4207 * _bcmi_xgs5_port_skip_detach_phase 4208 * Purpose: 4209 * Check if the phase in detach should be skipped. 4210 * Parameters: 4211 * unit - (IN) Unit number. 4212 * phase - (IN) Phase number in attach/detach. 4213 * Returns: 4214 * 1: skip the phase 4215 * 0: Don't skip the phase 4216 * Notes: 4217 */ 4218 STATIC int 4219 _bcmi_xgs5_port_skip_detach_phase(int unit, int phase) 4220 { 4221 int skip; 4222 switch (phase) 4223 { 4224 case PORT_DETACH_EXEC__STG: 4225 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4226 SHR_BPROF_BCM_STG); 4227 break; 4228 case PORT_DETACH_EXEC__VLAN: 4229 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4230 SHR_BPROF_BCM_VLAN); 4231 break; 4232 case PORT_DETACH_EXEC__TRUNK: 4233 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4234 SHR_BPROF_BCM_TRUNK); 4235 break; 4236 case PORT_DETACH_EXEC__COSQ: 4237 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4238 SHR_BPROF_BCM_COSQ); 4239 break; 4240 case PORT_DETACH_EXEC__STACK: 4241 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4242 SHR_BPROF_BCM_STK); 4243 break; 4244 case PORT_DETACH_EXEC__RATE: 4245 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4246 SHR_BPROF_BCM_RATE); 4247 break; 4248 case PORT_DETACH_EXEC__FIELD: 4249 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4250 SHR_BPROF_BCM_FIELD); 4251 break; 4252 case PORT_DETACH_EXEC__MIRROR: 4253 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4254 SHR_BPROF_BCM_MIRROR); 4255 break; 4256 case PORT_DETACH_EXEC__L3: 4257 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4258 SHR_BPROF_BCM_L3); 4259 break; 4260 case PORT_DETACH_EXEC__IPMC: 4261 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4262 SHR_BPROF_BCM_IPMC); 4263 break; 4264 case PORT_DETACH_EXEC__IPMC_REPL: 4265 if (SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4266 SHR_BPROF_BCM_IPMC) && 4267 soc_feature(unit, soc_feature_ip_mcast_repl)) { 4268 skip = 0; 4269 } else { 4270 skip = 1; 4271 } 4272 break; 4273 case PORT_DETACH_EXEC__MPLS: 4274 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4275 SHR_BPROF_BCM_MPLS); 4276 break; 4277 case PORT_DETACH_EXEC__MIM: 4278 skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond, 4279 SHR_BPROF_BCM_MIM); 4280 break; 4281 default: 4282 skip = 0; 4283 break; 4284 } 4285 return skip; 4286 } 4287 4288 /* 4289 * Function: 4290 * _bcmi_xgs5_port_resource_detach 4291 * Purpose: 4292 * Detach ports from the BCM layer. 4293 * 4294 * Parameters: 4295 * unit - (IN) Unit number. 4296 * port_schedule_state - (IN) Port schedule state. 4297 * Returns: 4298 * SOC_E_XXX 4299 */ 4300 STATIC int 4301 _bcmi_xgs5_port_resource_detach(int unit, 4302 soc_port_schedule_state_t *port_schedule_state) 4303 { 4304 int rv = BCM_E_NONE; 4305 soc_port_resource_t *pr, *resource; 4306 int i, j, nport; 4307 pbmp_t pbmp; 4308 4309 LOG_VERBOSE(BSL_LS_BCM_PORT, 4310 (BSL_META_U(unit, 4311 "--- BCM Detach ---\n"))); 4312 4313 SOC_PBMP_CLEAR(pbmp); 4314 4315 nport = port_schedule_state->nport; 4316 resource = port_schedule_state->resource; 4317 4318 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 4319 /* Skip 'add' ports */ 4320 if (pr->physical_port != -1) { 4321 continue; 4322 } 4323 4324 SOC_PBMP_PORT_ADD(pbmp, pr->logical_port); 4325 4326 /* 4327 * If 'inactive' flag, don't do anything 4328 */ 4329 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 4330 continue; 4331 } 4332 4333 if ((pr->op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) || 4334 (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) { 4335 for(j = 0; j < PORT_DETACH_EXEC__MAX; j++) { 4336 if(BCMI_PORT_DRV_CALL(unit)->port_detach_exec[j] != NULL) { 4337 if (_bcmi_xgs5_port_skip_detach_phase(unit, j)) { 4338 LOG_VERBOSE(BSL_LS_BCM_PORT, 4339 (BSL_META_U(unit, 4340 "Skip Detach Phase %s\n"), 4341 bcmi_xgs5_port_detach_str[j])); 4342 continue; 4343 } 4344 4345 LOG_VERBOSE(BSL_LS_BCM_PORT, 4346 (BSL_META_U(unit, 4347 "BCM PORT %d (%s) Detach Phase %s\n"), 4348 pr->logical_port, 4349 SOC_PORT_NAME(unit, pr->logical_port), 4350 bcmi_xgs5_port_detach_str[j])); 4351 4352 rv = BCMI_PORT_DRV_CALL(unit)->port_detach_exec[j](unit, 4353 pr->logical_port); 4354 if (BCM_FAILURE(rv)) { 4355 LOG_ERROR(BSL_LS_BCM_PORT, 4356 (BSL_META_U(unit, 4357 "Error: Unable to detach BCM port. " 4358 "Failed at phase %d - %s. " 4359 "unit=%d port=%d rv=%d(%s)\n"), 4360 j, bcmi_xgs5_port_detach_str[j], unit, 4361 pr->logical_port, rv, bcm_errmsg(rv))); 4362 return rv; 4363 } 4364 } 4365 } 4366 } 4367 } 4368 4369 /* Clear counters for ports in 'delete' entries */ 4370 BCM_IF_ERROR_RETURN(soc_counter_set32_by_port(unit, pbmp, 0)); 4371 4372 return BCM_E_NONE; 4373 } 4374 4375 /* 4376 * Function: 4377 * _bcmi_xgs5_port_pm_delete 4378 * Purpose: 4379 * Remove port from Port Macro if Portmod enabled. 4380 * Detach PHY if portmod disabled. 4381 * 4382 * Parameters: 4383 * unit - (IN) Unit number. 4384 * pr_bmp - (IN) Bitmaps of port to be added/deleted during flexing. 4385 * Returns: 4386 * SOC_E_XXX 4387 * Notes: 4388 */ 4389 STATIC int 4390 _bcmi_xgs5_port_pm_delete(int unit, 4391 bcmi_xgs5_port_resource_bmp_t *pr_bmp) 4392 { 4393 int delete_count, inact_count, nport, i, rv = BCM_E_NONE; 4394 soc_port_resource_t *del_res; 4395 bcm_port_t port; 4396 int loopback = BCM_PORT_LOOPBACK_NONE; 4397 4398 SOC_PBMP_COUNT(pr_bmp->del_pbm_log, delete_count); 4399 SOC_PBMP_COUNT(pr_bmp->inact_pbm_log, inact_count); 4400 4401 if ((delete_count <= 0) && (inact_count <= 0)) { 4402 return BCM_E_NONE; 4403 } 4404 4405 nport = delete_count + inact_count; 4406 del_res = sal_alloc(sizeof(soc_port_resource_t) * nport, 4407 "Delete_port_resources"); 4408 if (del_res == NULL) { 4409 LOG_ERROR(BSL_LS_SOC_PORT, 4410 (BSL_META_U(unit, 4411 "Unable to allocate memory for delete " 4412 "resource array in FlexPort operation\n"))); 4413 return SOC_E_MEMORY; 4414 } 4415 sal_memset(del_res, 0, sizeof(soc_port_resource_t) * nport); 4416 i = 0; 4417 4418 SOC_PBMP_ITER(pr_bmp->del_pbm_log, port) { 4419 del_res[i].logical_port = port; 4420 i++; 4421 } 4422 SOC_PBMP_ITER(pr_bmp->inact_pbm_log, port) { 4423 del_res[i].logical_port = port; 4424 i++; 4425 } 4426 4427 if (SOC_USE_PORTCTRL(unit)) { 4428 /* Clear loopback */ 4429 for (i = 0; i < nport; i++) { 4430 port = del_res[i].logical_port; 4431 rv = bcm_esw_port_loopback_get(unit, port, &loopback); 4432 if (SOC_SUCCESS(rv) && loopback != BCM_PORT_LOOPBACK_NONE) { 4433 rv = bcmi_esw_portctrl_loopback_set(unit, port, 4434 BCM_PORT_LOOPBACK_NONE); 4435 if (SOC_SUCCESS(rv)) { 4436 rv = bcmi_xgs5_port_enable_set(unit, port, 0); 4437 } 4438 } 4439 if (BCM_FAILURE(rv)) { 4440 sal_free(del_res); 4441 LOG_ERROR(BSL_LS_SOC_PORT, 4442 (BSL_META_U(unit, 4443 "Unable to clear loopback in " 4444 "FlexPort operation\n"))); 4445 return rv; 4446 } 4447 } 4448 rv = soc_esw_portctrl_pm_ports_delete(unit, nport, del_res); 4449 } else { 4450 for (i = 0; i < nport; i++) { 4451 port = del_res[i].logical_port; 4452 rv = soc_phyctrl_detach(unit, port); 4453 if (BCM_FAILURE(rv)) { 4454 break; 4455 } 4456 } 4457 } 4458 4459 sal_free(del_res); 4460 4461 if (BCM_FAILURE(rv)) { 4462 LOG_ERROR(BSL_LS_SOC_PORT, 4463 (BSL_META_U(unit, 4464 "Unable to detach MAC/PHY in " 4465 "FlexPort operation\n"))); 4466 } 4467 return rv; 4468 } 4469 4470 /* 4471 * Function: 4472 * _bcmi_xgs5_port_pm_vco_reconfigure 4473 * Purpose: 4474 * Reconfigure the VCOs of the Port Macros if the device supports 4475 * this and the PMs require reconfiguring. 4476 * 4477 * For now, this calls down to a device specific portctrl 4478 * VCO reconfigure 4479 * 4480 * Parameters: 4481 * unit - (IN) Unit number. 4482 * Returns: 4483 * SOC_E_XXX 4484 * Notes: 4485 * For now, this calls down to a device specific portctrl 4486 * VCO reconfigure 4487 */ 4488 STATIC int 4489 _bcmi_xgs5_port_pm_vco_reconfigure(int unit) 4490 { 4491 4492 #if defined(BCM_TOMAHAWK3_SUPPORT) 4493 if (SOC_IS_TOMAHAWK3(unit)) { 4494 return soc_esw_portctrl_pm_vco_reconfigure(unit); 4495 } else 4496 #endif 4497 { 4498 return BCM_E_NONE; 4499 } 4500 } 4501 4502 /* 4503 * Function: 4504 * _bcmi_xgs5_port_pm_add 4505 * Purpose: 4506 * Add port to Port Macro if portmod enabled. 4507 * Probe MAC/PHY for port if portmod disabled. 4508 * 4509 * Parameters: 4510 * unit - (IN) Unit number. 4511 * pr_bmp - (IN) Bitmaps of port to be added/deleted during flexing. 4512 * Returns: 4513 * SOC_E_XXX 4514 * Notes: 4515 */ 4516 STATIC int 4517 _bcmi_xgs5_port_pm_add(int unit, 4518 bcmi_xgs5_port_resource_bmp_t *pr_bmp) 4519 { 4520 int add_count, act_count, inact_count, nport, i, rv = BCM_E_NONE; 4521 soc_port_resource_t *add_res; 4522 bcm_port_t port, phy_port; 4523 uint32 rval; 4524 int blk, blk_type, is_clport; 4525 pbmp_t inact_pbm; 4526 4527 SOC_PBMP_COUNT(pr_bmp->add_pbm_log, add_count); 4528 SOC_PBMP_COUNT(pr_bmp->act_pbm_log, act_count); 4529 4530 SOC_PBMP_ASSIGN(inact_pbm,pr_bmp->inact_pbm_log); 4531 SOC_PBMP_REMOVE(inact_pbm,pr_bmp->act_pbm_log); 4532 SOC_PBMP_COUNT(inact_pbm, inact_count); 4533 4534 nport = add_count + act_count + inact_count; 4535 4536 if (nport <= 0) { 4537 return BCM_E_NONE; 4538 } 4539 4540 add_res = sal_alloc(sizeof(soc_port_resource_t) * nport, 4541 "Add_port_resources"); 4542 if (add_res == NULL) { 4543 LOG_ERROR(BSL_LS_SOC_PORT, 4544 (BSL_META_U(unit, 4545 "Unable to allocate memory for add " 4546 "resource array in FlexPort operation\n"))); 4547 return SOC_E_MEMORY; 4548 } 4549 sal_memset(add_res, 0, sizeof(soc_port_resource_t) * nport); 4550 i = 0; 4551 4552 SOC_PBMP_ITER(inact_pbm, port) { 4553 add_res[i].logical_port = port; 4554 add_res[i].physical_port = -1; 4555 i++; 4556 } 4557 SOC_PBMP_ITER(pr_bmp->add_pbm_log, port) { 4558 add_res[i].logical_port = port; 4559 add_res[i].physical_port = SOC_INFO(unit).port_l2p_mapping[port]; 4560 i++; 4561 } 4562 SOC_PBMP_ITER(pr_bmp->act_pbm_log, port) { 4563 add_res[i].logical_port = port; 4564 add_res[i].physical_port = SOC_INFO(unit).port_l2p_mapping[port]; 4565 i++; 4566 } 4567 4568 if (SOC_USE_PORTCTRL(unit)) { 4569 rv = soc_esw_portctrl_pm_ports_add(unit, nport, add_res); 4570 } else { 4571 int okay; 4572 for (i = 0; i < nport; i++) { 4573 rv = _bcm_port_probe(unit, add_res[i].logical_port, &okay); 4574 if (BCM_FAILURE(rv) || !okay) { 4575 break; 4576 } 4577 rv = _bcm_port_mode_setup(unit, add_res[i].logical_port, FALSE); 4578 if (BCM_FAILURE(rv)) { 4579 break; 4580 } 4581 } 4582 } 4583 4584 if (BCM_FAILURE(rv)) { 4585 LOG_ERROR(BSL_LS_SOC_PORT, 4586 (BSL_META_U(unit, 4587 "Unable to attach MAC/PHY in " 4588 "FlexPort operation\n"))); 4589 sal_free(add_res); 4590 return rv; 4591 } 4592 4593 /* Set port configured with force_lb to PHY loopback */ 4594 for (i = 0; i < nport; i++) { 4595 if (add_res[i].physical_port == -1) { 4596 continue; 4597 } 4598 port = add_res[i].logical_port; 4599 phy_port = add_res[i].physical_port; 4600 if (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).force_lb) { 4601 rv = bcm_esw_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_PHY); 4602 if (BCM_FAILURE(rv)) { 4603 LOG_ERROR(BSL_LS_SOC_PORT, 4604 (BSL_META_U(unit, 4605 "Fail to set port %d to PHY loopback\n"), 4606 port)); 4607 sal_free(add_res); 4608 return rv; 4609 } 4610 } 4611 } 4612 4613 sal_free(add_res); 4614 4615 /* Set PM interface to 16B, currently this is not covered by PortMod */ 4616 if (soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) { 4617 SHR_BIT_ITER(pr_bmp->add_bmp_pm, SOC_MAX_NUM_BLKS, blk) { 4618 port = SOC_BLOCK_PORT(unit, blk); 4619 blk_type = SOC_BLOCK_INFO(unit, blk).type; 4620 is_clport = blk_type == SOC_BLK_CLPORT ? 1 : 0; 4621 4622 if (is_clport) { 4623 BCM_IF_ERROR_RETURN 4624 (READ_CLPORT_MAC_CONTROLr(unit, port, &rval)); 4625 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, 4626 SYS_16B_INTF_MODEf, 1); 4627 BCM_IF_ERROR_RETURN 4628 (WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 4629 } 4630 } 4631 } 4632 4633 return BCM_E_NONE; 4634 } 4635 4636 /* 4637 * Function: 4638 * _bcmi_xgs5_port_pm_setup 4639 * Purpose: 4640 * Setup port(s) in Port Macro if portmod enabled. 4641 * 4642 * Parameters: 4643 * unit - (IN) Unit number. 4644 * port_schedule_state - (IN) Port schedule state. 4645 * Returns: 4646 * SOC_E_XXX 4647 * Notes: 4648 */ 4649 STATIC int 4650 _bcmi_xgs5_port_pm_setup(int unit, soc_port_schedule_state_t *port_schedule_state) 4651 { 4652 int nport, i; 4653 soc_port_resource_t *resource, *pr; 4654 bcm_port_t port; 4655 soc_info_t *si = &SOC_INFO(unit); 4656 soc_asf_mode_e asf_mode; 4657 int pause; 4658 4659 nport = port_schedule_state->nport; 4660 resource = port_schedule_state->resource; 4661 if (SOC_USE_PORTCTRL(unit)) { 4662 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 4663 /* 4664 * Check if 'delete' port needs to be added (NULL driver). 4665 */ 4666 port = pr->logical_port; 4667 if ((pr->physical_port == -1) && 4668 !SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 4669 /* Port is deleted and is not inactive, nothing to add */ 4670 continue; 4671 } 4672 if (IS_HG_PORT(unit, port)) { 4673 pause = 0; 4674 } else { 4675 pause = 1; 4676 } 4677 asf_mode = port_schedule_state->cutthru_prop.asf_modes[port]; 4678 BCM_IF_ERROR_RETURN 4679 (soc_esw_portctrl_pause_set(unit, port, pause, 4680 asf_mode != _SOC_ASF_MODE_SAF ? 0 : 4681 pause)); 4682 } 4683 } 4684 4685 return BCM_E_NONE; 4686 } 4687 4688 /* 4689 * Function: 4690 * _bcmi_xgs5_pm_enable 4691 * Purpose: 4692 * Power down or power up the port macro by programming 4693 * TOP_TSC_ENABLEr, TOP_TSC_ENABLE_1r 4694 * Parameters: 4695 * unit - (IN) Unit number. 4696 * pr_bmp - (IN) Bitmaps of port/PM to be added/deleted during flexing. 4697 * enable - (IN) 1: enable; 0: disable 4698 * Returns: 4699 * SOC_E_XXX 4700 * Notes: 4701 */ 4702 STATIC int 4703 _bcmi_xgs5_pm_enable(int unit, bcmi_xgs5_port_resource_bmp_t *pr_bmp, 4704 int enable) 4705 { 4706 SHR_BITDCL *pm_bmp; 4707 int blk, pm, i, offset, count[2], pm_max = 64; 4708 soc_reg_t reg[2] = {TOP_TSC_ENABLEr, TOP_TSC_ENABLE_1r}; 4709 uint32 rval[2]; 4710 4711 /* TOP_TSC_ENABLEr cover PM 0-31, TOP_TSC_ENABLE_1r cover PM 32-63 */ 4712 #define PM_NUM_PER_REG 32 4713 4714 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) { 4715 pm_max = 32; 4716 #ifdef BCM_HELIX5_SUPPORT 4717 4718 if (SOC_IS_HELIX5(unit)) { 4719 return BCM_E_NONE; 4720 } 4721 #endif 4722 } 4723 for (i = 0; i < 2; i++) { 4724 count[i] = 0; 4725 rval[i] = 0; 4726 if (SOC_REG_IS_VALID(unit, reg[i])){ 4727 BCM_IF_ERROR_RETURN 4728 (soc_reg32_get(unit, reg[i], REG_PORT_ANY, 0, &rval[i])); 4729 } 4730 } 4731 4732 pm_bmp = enable ? pr_bmp->add_bmp_pm : pr_bmp->del_bmp_pm; 4733 4734 SHR_BIT_ITER(pm_bmp, SOC_MAX_NUM_BLKS, blk) { 4735 if (SHR_BITGET(SOC_INFO(unit).pm_ref_master_bitmap, blk)) { 4736 continue; 4737 } 4738 if (SOC_BLOCK_TYPE(unit, blk) != SOC_BLK_CLPORT && 4739 SOC_BLOCK_TYPE(unit, blk) != SOC_BLK_CDPORT) { 4740 continue; 4741 } 4742 pm = SOC_BLOCK_NUMBER(unit, blk); 4743 if (pm >= pm_max) { 4744 continue; 4745 } 4746 4747 #if defined(BCM_TRIDENT3_SUPPORT) 4748 /* PM31 is the last PM in the LED scan chain in TD3. Since the LED 4749 firmware will always program LAST_PORT=124, we need to ensure that this 4750 PM is always functional and will respond to the LED accumulation logic */ 4751 if (SOC_IS_TRIDENT3(unit) && (pm == 31) && (!enable)) { 4752 continue; 4753 } 4754 #endif /* BCM_TRIDENT3_SUPPORT */ 4755 4756 i = pm / PM_NUM_PER_REG; 4757 offset = pm % PM_NUM_PER_REG; 4758 if (enable) { 4759 rval[i] |= (1 << offset); 4760 } else { 4761 /* Disabling of TOP_TSC_ENABLE for TH3 causes link flapping in 4762 * PMs not being modified, so do not allow TOP_TSC_ENABLE 4763 * to be disabled during TH3 flex 4764 */ 4765 if (!SOC_IS_TOMAHAWK3(unit)) { 4766 rval[i] &= ~(1 << offset); 4767 } 4768 } 4769 count[i]++; 4770 /* If shut down or power up many port blocks at the same time, PCI 4771 * bus would become abnormal and BUS error happened. So update 4772 * TOP_TSC_ENABLEx for 10 blocks change each time. */ 4773 if (count[i] > 10 && SOC_REG_IS_VALID(unit, reg[i])) { 4774 BCM_IF_ERROR_RETURN( 4775 soc_reg32_set(unit, reg[i], REG_PORT_ANY, 0, rval[i])); 4776 count[i] = 0; 4777 sal_usleep(100000); 4778 } 4779 } 4780 for (i = 0; i < 2; i++) { 4781 if (count[i] > 0 && SOC_REG_IS_VALID(unit, reg[i])) { 4782 BCM_IF_ERROR_RETURN( 4783 soc_reg32_set(unit, reg[i], REG_PORT_ANY, 0, rval[i])); 4784 sal_usleep(100000); 4785 } 4786 } 4787 4788 return BCM_E_NONE; 4789 } 4790 4791 /* 4792 * Function: 4793 * _bcmi_xgs5_port_soc_info_delete 4794 * Purpose: 4795 * Clear port information in SOC_INFO SW 4796 * 4797 * Parameters: 4798 * unit - (IN) Unit number. 4799 * port_schedule_state - (IN) Port schedule state. 4800 * Returns: 4801 * SOC_E_XXX 4802 */ 4803 STATIC int 4804 _bcmi_xgs5_port_soc_info_delete(int unit, 4805 soc_port_schedule_state_t *port_schedule_state) 4806 { 4807 soc_info_t *si = &SOC_INFO(unit); 4808 soc_persist_t *sop = SOC_PERSIST(unit); 4809 soc_port_resource_t *resource, *pr; 4810 soc_pmvco_info_t pm_vco_info; 4811 int i, pipe; 4812 int port, phy_port, mmu_port; 4813 int nport; 4814 int rv = BCM_E_NONE; 4815 4816 SOC_CONTROL_LOCK(unit); 4817 /* Clear counter map */ 4818 rv = _bcmi_xgs5_port_soc_counter_delete(unit, port_schedule_state); 4819 if (BCM_FAILURE(rv)) { 4820 goto cleanup; 4821 } 4822 4823 nport = port_schedule_state->nport; 4824 resource = port_schedule_state->resource; 4825 4826 for (i = 0, pr = resource; i < nport; i++, pr++) { 4827 port = pr->logical_port; 4828 phy_port = si->port_l2p_mapping[port]; 4829 mmu_port = si->port_p2m_mapping[phy_port]; 4830 4831 if (pr->physical_port == -1) { 4832 if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL | 4833 BCMI_XGS5_PORT_RESOURCE_OP_REMAP )) { 4834 4835 /* 4836 * If 'inactive' flag, just add port to disabled bitmap. 4837 * This is part of the legacy API behavior. 4838 */ 4839 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 4840 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 4841 continue; 4842 } 4843 4844 /* Clear IPG configuration */ 4845 sal_memset(&sop->ipg[port], 0, sizeof(soc_ipg_t)); 4846 4847 /* Port Mapping related information */ 4848 si->port_l2p_mapping[port] = -1; 4849 si->port_l2i_mapping[port] = -1; 4850 if (phy_port != -1) { 4851 si->port_p2l_mapping[phy_port] = -1; 4852 si->port_p2m_mapping[phy_port] = -1; 4853 #ifdef BCM_HELIX5_SUPPORT 4854 if (SOC_IS_HELIX5(unit) && 4855 !((phy_port <= 60) && !pr->oversub)) { 4856 si->port_p2m_mapping[phy_port] = mmu_port; 4857 } 4858 #endif 4859 } 4860 if (mmu_port != -1) { 4861 si->port_m2p_mapping[mmu_port] = -1; 4862 #ifdef BCM_HELIX5_SUPPORT 4863 if (SOC_IS_HELIX5(unit) && 4864 !((phy_port <= 60) && !pr->oversub)) 4865 si->port_m2p_mapping[mmu_port] = phy_port; 4866 #endif 4867 } 4868 4869 /* Pipeline */ 4870 if (phy_port != -1) { 4871 pipe = si->port_pipe[port]; 4872 SOC_PBMP_PORT_REMOVE(si->pipe_pbm[pipe], port); 4873 si->port_pipe[port] = -1; 4874 } 4875 4876 /* Logical port related information */ 4877 si->port_speed_max[port] = 0; 4878 si->port_init_speed[port] = 0; 4879 si->port_num_lanes[port] = 0; 4880 si->port_group[port] = -1; 4881 si->port_serdes[port] = -1; 4882 4883 si->port_fec_type[port] = _SHR_PORT_PHY_FEC_NONE; 4884 si->port_phy_lane_config[port] = -1; 4885 si->port_link_training[port] = 0; 4886 4887 SOC_PBMP_PORT_REMOVE(si->oversub_pbm, port); 4888 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port); 4889 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port); 4890 4891 continue; 4892 } else if ((pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_SPEED | 4893 BCMI_XGS5_PORT_RESOURCE_OP_LANES)) && 4894 (!(pr->flags & SOC_PORT_RESOURCE_SPEED))) { 4895 si->port_speed_max[pr->logical_port] = 0; 4896 } 4897 } 4898 } 4899 4900 /* Clear out soc info's pm vco info if it's going to change */ 4901 for (i = 0; i < SOC_MAX_NUM_BLKS; i++) { 4902 rv = soc_esw_portctrl_pm_vco_fetch(unit, i, &pm_vco_info); 4903 4904 if (BCM_SUCCESS(rv)) { 4905 if (pm_vco_info.is_tvco_new != 0 || 4906 pm_vco_info.is_ovco_new != 0) { 4907 4908 si->pm_vco_info[i].tvco = -1; 4909 si->pm_vco_info[i].ovco = -1; 4910 si->pm_vco_info[i].is_tvco_new = 0; 4911 si->pm_vco_info[i].is_ovco_new = 0; 4912 } 4913 } 4914 } 4915 4916 /* Clear port ptype bitmap and block information */ 4917 rv = _bcmi_xgs5_port_soc_info_ptype_block_delete(unit, port_schedule_state); 4918 if (BCM_FAILURE(rv)) { 4919 goto cleanup; 4920 } 4921 4922 cleanup: 4923 SOC_CONTROL_UNLOCK(unit); 4924 4925 return rv; 4926 } 4927 4928 /* 4929 * Function: 4930 * _bcmi_xgs5_port_reconfigure_bmp_get 4931 * Purpose: 4932 * Get bitmaps of newly added logical ports, physical ports, port macros 4933 * and deleted logical port, physical port, port macro during Flexport. 4934 * Parameters: 4935 * unit - (IN) Unit number. 4936 * port_schedule_state - (IN) Port schedule state. 4937 * pr_bmp - (OUT) Bitmaps of port, port macro that to be 4938 * added and deleted. 4939 * Returns: 4940 * SOC_E_XXX 4941 * Note: 4942 * Assumes: 4943 * - Basic checks are already performed by caller: 4944 * . Array is in order (deletes are first) 4945 * . Logical and physical ports are addressable 4946 * - Caller has lock. 4947 */ 4948 STATIC int 4949 _bcmi_xgs5_port_reconfigure_bmp_get(int unit, 4950 soc_port_schedule_state_t *port_schedule_state, 4951 bcmi_xgs5_port_resource_bmp_t *pr_bmp) 4952 { 4953 soc_info_t *si = &SOC_INFO(unit); 4954 int nport = port_schedule_state->nport; 4955 soc_port_resource_t *resource = port_schedule_state->resource, *pr; 4956 int blk, logic_port, phy_port, old_phy_port, port_idx, local_phy_port; 4957 int i, pipe; 4958 pbmp_t pbm_and; 4959 char block_valid[SOC_MAX_NUM_BLKS]; 4960 4961 sal_memset(pr_bmp, 0, sizeof(bcmi_xgs5_port_resource_bmp_t)); 4962 4963 for (i = 0, pr = resource; i < nport; i++, pr++) { 4964 /* Legacy speed update API doesn't require port add/del */ 4965 if (pr->flags & SOC_PORT_RESOURCE_SPEED) { 4966 continue; 4967 } 4968 4969 logic_port = pr->logical_port; 4970 phy_port = pr->physical_port; 4971 old_phy_port = si->port_l2p_mapping[logic_port]; 4972 pipe = pr->pipe; 4973 4974 /* If 'inactive' flag, update the inact_pbm_log/act_pbm_log */ 4975 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 4976 if (pr->physical_port == -1) { 4977 SOC_PBMP_PORT_ADD(pr_bmp->inact_pbm_log, logic_port); 4978 } else { 4979 SOC_PBMP_PORT_ADD(pr_bmp->act_pbm_log, logic_port); 4980 } 4981 continue; 4982 } 4983 4984 if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_REMAP | 4985 BCMI_XGS5_PORT_RESOURCE_OP_ADD | 4986 BCMI_XGS5_PORT_RESOURCE_OP_DEL | 4987 BCMI_XGS5_PORT_RESOURCE_OP_LANES | 4988 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX | 4989 BCMI_XGS5_PORT_RESOURCE_OP_SPEED)) { 4990 if (pr->physical_port == -1) { 4991 local_phy_port = old_phy_port - 4992 BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe]; 4993 4994 SOC_PBMP_PORT_ADD(pr_bmp->del_pbm_log, logic_port); 4995 SOC_PBMP_PORT_ADD(pr_bmp->del_pbm_phy[pipe], local_phy_port); 4996 } else { 4997 local_phy_port = phy_port - 4998 BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe]; 4999 5000 if ((pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_REMAP | 5001 BCMI_XGS5_PORT_RESOURCE_OP_ADD | 5002 BCMI_XGS5_PORT_RESOURCE_OP_LANES)) || 5003 SOC_PBMP_MEMBER(pr_bmp->del_pbm_log, logic_port)) { 5004 SOC_PBMP_PORT_ADD(pr_bmp->add_pbm_phy[pipe], 5005 local_phy_port); 5006 SOC_PBMP_PORT_ADD(pr_bmp->add_pbm_log, logic_port); 5007 } 5008 } 5009 } 5010 } 5011 5012 sal_memcpy(block_valid, si->block_valid, SOC_MAX_NUM_BLKS); 5013 for (pipe = 0; pipe < si->num_pipe; pipe++) { 5014 SOC_PBMP_ASSIGN(pbm_and, pr_bmp->add_pbm_phy[pipe]); 5015 SOC_PBMP_AND(pbm_and, pr_bmp->del_pbm_phy[pipe]); 5016 SOC_PBMP_REMOVE(pr_bmp->add_pbm_phy[pipe], pbm_and); 5017 SOC_PBMP_REMOVE(pr_bmp->del_pbm_phy[pipe], pbm_and); 5018 5019 SOC_PBMP_ITER(pr_bmp->add_pbm_phy[pipe], local_phy_port) { 5020 phy_port = local_phy_port + 5021 BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe]; 5022 5023 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 5024 port_idx++) { 5025 5026 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 5027 if (blk < 0) { /* End of block list of each port */ 5028 break; 5029 } 5030 block_valid[blk] ++; 5031 } 5032 } 5033 5034 SOC_PBMP_ITER(pr_bmp->del_pbm_phy[pipe], local_phy_port) { 5035 phy_port = local_phy_port + 5036 BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe]; 5037 5038 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 5039 port_idx++) { 5040 5041 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 5042 if (blk < 0) { /* End of block list of each port */ 5043 break; 5044 } 5045 if (!block_valid[blk]) { 5046 return BCM_E_INTERNAL; 5047 } 5048 block_valid[blk]--; 5049 } 5050 } 5051 } 5052 5053 for (blk = 0; blk < SOC_MAX_NUM_BLKS; blk ++) { 5054 if (block_valid[blk] && (!(si->block_valid[blk]))) { 5055 SHR_BITSET(pr_bmp->add_bmp_pm, blk); 5056 } 5057 if ((!block_valid[blk]) && (si->block_valid[blk])) { 5058 SHR_BITSET(pr_bmp->del_bmp_pm, blk); 5059 } 5060 } 5061 5062 return BCM_E_NONE; 5063 } 5064 5065 /* 5066 * Function: 5067 * _bcmi_xgs5_port_speed_update 5068 * Purpose: 5069 * Update port for the case only speed or lanes change. 5070 * 5071 * Parameters: 5072 * unit - (IN) Unit number. 5073 * port_schedule_state - (IN) Port schedule state. 5074 * Returns: 5075 * SOC_E_XXX 5076 * Note: 5077 * Assumes: 5078 * - Basic checks are already performed by caller: 5079 * . Array is in order (deletes are first) 5080 * . Logical and physical ports are addressable 5081 * - Caller has lock. 5082 */ 5083 STATIC int 5084 _bcmi_xgs5_port_speed_update(int unit, 5085 soc_port_schedule_state_t *port_schedule_state) 5086 { 5087 soc_port_resource_t *resource, *pr; 5088 int i; 5089 int port, phy_port; 5090 int nport; 5091 int count_width; 5092 uint32 regval = 0; 5093 5094 nport = port_schedule_state->nport; 5095 resource = port_schedule_state->resource; 5096 5097 for (i = 0, pr = resource; i < nport; i++, pr++) { 5098 port = pr->logical_port; 5099 phy_port = pr->physical_port; 5100 5101 if (phy_port == -1 || 5102 !(pr->op & BCMI_XGS5_PORT_RESOURCE_OP_SPEED) || 5103 (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD | 5104 BCMI_XGS5_PORT_RESOURCE_OP_REMAP))) { 5105 continue; 5106 } 5107 5108 if (SOC_REG_IS_VALID(unit, PORT_INITIAL_COPY_COUNT_WIDTHr)) { 5109 count_width = pr->hsp ? 1 : 0; 5110 5111 if (!soc_feature(unit, soc_feature_skip_port_initial_copy_count)) { 5112 soc_reg_field_set(unit, PORT_INITIAL_COPY_COUNT_WIDTHr, ®val, 5113 BIT_WIDTHf, count_width); 5114 BCM_IF_ERROR_RETURN(WRITE_PORT_INITIAL_COPY_COUNT_WIDTHr 5115 (unit, port, regval)); 5116 } 5117 } 5118 } 5119 5120 return BCM_E_NONE; 5121 } 5122 5123 /* 5124 * Function: 5125 * _bcmi_xgs5_port_resource_configure 5126 * Purpose: 5127 * Configure device ports based on given FlexPort information. 5128 * 5129 * This routine executes the FlexPort operation. 5130 * Parameters: 5131 * unit - (IN) Unit number. 5132 * port_schedule_state - (IN) Port schedule state. 5133 * Returns: 5134 * SOC_E_XXX 5135 * Note: 5136 * Assumes: 5137 * - Basic checks are already performed by caller: 5138 * . Array is in order (deletes are first) 5139 * . Logical and physical ports are addressable 5140 * - Caller has lock. 5141 */ 5142 STATIC int 5143 _bcmi_xgs5_port_reconfigure(int unit, 5144 bcm_port_resource_t *resource, 5145 soc_port_schedule_state_t *port_schedule_state) 5146 { 5147 soc_info_t *si = &SOC_INFO(unit); 5148 int blk, logic_port; 5149 bcmi_xgs5_port_resource_bmp_t pr_bmp; 5150 int rv = BCM_E_NONE; 5151 5152 _bcmi_xgs5_port_reconfigure_bmp_get(unit, port_schedule_state, &pr_bmp); 5153 5154 /* Enable Port Macro in TOP_TSC_ENABLE */ 5155 BCM_IF_ERROR_RETURN 5156 (_bcmi_xgs5_pm_enable(unit, &pr_bmp, 1)); 5157 5158 if (!SOC_USE_PORTCTRL(unit)) { 5159 /* Port Macro reset */ 5160 BCM_IF_ERROR_RETURN 5161 (_bcmi_xgs5_port_pm_reset(unit, pr_bmp.add_bmp_pm, 5162 pr_bmp.add_pbm_phy)); 5163 } 5164 /*********************************************** 5165 * Because SOC reg/mem read/write functions use l2p_mapping or 5166 * p2m_mapping in SOC_INFO to figuire out the access address of 5167 * registers/memories of ports, SDK MUST follow below guideline 5168 * to handle ADD/DEL/REMAP operations 5169 * 5170 * - HW programming on 'older' ports MUST to be done BEFORE 5171 * the SOC_INFO is updated. 5172 * - HW programming on 'new' ports MUST to be done AFTER 5173 * the SOC_INFO is updated. 5174 */ 5175 5176 5177 /*********************************************** 5178 * DETACH 5179 * 5180 * - Clearing any port references in HW 5181 * - Removing port from Port Macro 5182 * - Clear port information in SOC_INFO SW 5183 */ 5184 COUNTER_UNLOCK(unit); 5185 rv = _bcmi_xgs5_port_resource_detach(unit, port_schedule_state); 5186 COUNTER_LOCK(unit); 5187 if (BCM_FAILURE(rv)) { 5188 return rv; 5189 } 5190 5191 BCM_IF_ERROR_RETURN 5192 (_bcmi_xgs5_port_pm_delete(unit, &pr_bmp)); 5193 if (!SOC_USE_PORTCTRL(unit)) { 5194 /* Power down the tsc that no longer used */ 5195 SHR_BIT_ITER(pr_bmp.del_bmp_pm, SOC_MAX_NUM_BLKS, blk) { 5196 logic_port = si->block_port[blk]; 5197 BCM_IF_ERROR_RETURN 5198 (soc_pm_power_mode_set(unit, logic_port, 0, 1)); 5199 } 5200 } 5201 5202 BCM_IF_ERROR_RETURN 5203 (_bcmi_xgs5_port_soc_info_delete(unit, port_schedule_state)); 5204 5205 /*********************************************** 5206 * Execute FlexPort operation by calling Flexport Tier1 API 5207 * 5208 * Changes are done to the HW. 5209 * If any error occurs the operation, changes cannot be undone. 5210 */ 5211 if (BCMI_PORT_DRV_CALL(unit)->reconfigure_ports) { 5212 BCM_IF_ERROR_RETURN 5213 (BCMI_PORT_DRV_CALL(unit)->reconfigure_ports(unit, 5214 port_schedule_state)); 5215 } 5216 5217 /*********************************************** 5218 * ATTACH 5219 * 5220 * - Add port information in SOC_INFO SW 5221 * - Configure new port in HW 5222 * - Add port to Port Macro 5223 */ 5224 BCM_IF_ERROR_RETURN 5225 (_bcmi_xgs5_port_soc_info_add(unit, resource, port_schedule_state)); 5226 5227 BCM_IF_ERROR_RETURN 5228 (_bcmi_xgs5_port_pm_vco_reconfigure(unit)); 5229 5230 BCM_IF_ERROR_RETURN 5231 (_bcmi_xgs5_port_pm_add(unit, &pr_bmp)); 5232 5233 BCM_IF_ERROR_RETURN 5234 (_bcmi_xgs5_port_pm_setup(unit, port_schedule_state)); 5235 5236 COUNTER_UNLOCK(unit); 5237 rv = _bcmi_xgs5_port_resource_attach(unit, port_schedule_state); 5238 COUNTER_LOCK(unit); 5239 if (BCM_FAILURE(rv)) { 5240 return rv; 5241 } 5242 5243 /* Update for the case that only SPEED or LANES change */ 5244 BCM_IF_ERROR_RETURN 5245 (_bcmi_xgs5_port_speed_update(unit, port_schedule_state)); 5246 5247 /* Update TDM info */ 5248 if (BCMI_PORT_DRV_CALL(unit)->post_flexport_tdm) { 5249 BCM_IF_ERROR_RETURN 5250 (BCMI_PORT_DRV_CALL(unit)->post_flexport_tdm(unit, 5251 port_schedule_state)); 5252 } 5253 5254 /* Update Port Macro */ 5255 if (BCMI_PORT_DRV_CALL(unit)->port_macro_update) { 5256 BCM_IF_ERROR_RETURN 5257 (BCMI_PORT_DRV_CALL(unit)->port_macro_update(unit, 5258 port_schedule_state)); 5259 } 5260 5261 /* Disable Port Macro in TOP_TSC_ENABLE */ 5262 BCM_IF_ERROR_RETURN 5263 (_bcmi_xgs5_pm_enable(unit, &pr_bmp, 0)); 5264 5265 /* Update the port related reg/mem in IP/EP after flexport */ 5266 BCM_IF_ERROR_RETURN 5267 (_bcmi_xgs5_port_ipep_reconfigure(unit, pr_bmp.add_pbm_log, 5268 pr_bmp.del_pbm_log)); 5269 5270 /* Update cos_map info */ 5271 if (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update) { 5272 BCM_IF_ERROR_RETURN 5273 (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update(unit, pr_bmp.del_pbm_log, 0)); 5274 } 5275 5276 /* Update cos_map info */ 5277 if (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update) { 5278 BCM_IF_ERROR_RETURN 5279 (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update(unit, pr_bmp.add_pbm_log, 1)); 5280 } 5281 5282 return BCM_E_NONE; 5283 } 5284 5285 /* 5286 * Function: 5287 * _bcmi_xgs5_port_resource_execute 5288 * Purpose: 5289 * Perform a FlexPort operation. 5290 * This includes changes that involve: 5291 * - Logical to physical port mapping 5292 * - Speed 5293 * - Number of PHY lanes 5294 * Parameters: 5295 * unit - (IN) Unit number. 5296 * nport - (IN) Number of elements in array resource. 5297 * resource - (IN) Port resource configuration array. 5298 * soc_resource - (IN) SOC Port Resource 5299 * port_schedule_state - (IN) SOC port schedule state 5300 * Returns: 5301 * BCM_E_XXX 5302 * Note: 5303 * Assumes caller has lock. 5304 * Assumes BCM data has been validated. 5305 */ 5306 STATIC int 5307 _bcmi_xgs5_port_resource_execute(int unit, int nport, 5308 bcm_port_resource_t *resource, 5309 soc_port_resource_t *soc_resource, 5310 soc_port_schedule_state_t *port_schedule_state) 5311 { 5312 int rv; 5313 int op, i; 5314 5315 5316 /* SOC Port Structure initialization */ 5317 BCM_IF_ERROR_RETURN 5318 (BCMI_PORT_DRV_CALL(unit)->soc_resource_init(unit, nport, resource, 5319 soc_resource)); 5320 /* Check type of FlexPort operations */ 5321 BCM_IF_ERROR_RETURN 5322 (_bcmi_xgs5_port_resource_op_set(unit, nport, resource, soc_resource, 5323 &op)); 5324 5325 LOG_VERBOSE(BSL_LS_BCM_PORT, 5326 (BSL_META_U(unit, 5327 "FlexPort operations 0x%x: %s %s %s %s %s %s %s %s %s\n"), 5328 op, 5329 (op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP) ? "remap" : "", 5330 (op & BCMI_XGS5_PORT_RESOURCE_OP_SPEED) ? "speed" : "", 5331 (op & BCMI_XGS5_PORT_RESOURCE_OP_LANES) ? "lanes" : "", 5332 (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) ? "encap" : "", 5333 (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX) ? "encap_flex" : "", 5334 (op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) ? "add" : "", 5335 (op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) ? "delete": "", 5336 (op & BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE)? "active": "", 5337 (op & BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR)? "calendar": "")); 5338 5339 if (((op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) || 5340 (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) && 5341 (!soc_feature(unit, soc_feature_xport_convertible))) { 5342 LOG_ERROR(BSL_LS_BCM_PORT, 5343 (BSL_META_U(unit, 5344 "Encapsulation converting between HIGIG and IEEE " 5345 "is not allowed.\n"))); 5346 return BCM_E_UNAVAIL; 5347 } 5348 5349 /* 5350 * Operations: 5351 * NONE => Nothing to do 5352 * ADD/DEL/REMAP/SPEED/LANES => FlexPort sequence 5353 * ENCAP => Encap set 5354 */ 5355 if (op == BCMI_XGS5_PORT_RESOURCE_OP_NONE) { 5356 return BCM_E_NONE; /* No changes, just return */ 5357 } 5358 5359 if ((op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) || 5360 (op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) || 5361 (op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP) || 5362 (op & BCMI_XGS5_PORT_RESOURCE_OP_LANES) || 5363 (op & BCMI_XGS5_PORT_RESOURCE_OP_SPEED) || 5364 (op & BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE) || 5365 (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX) || 5366 (op & BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR)) { 5367 5368 LOG_VERBOSE(BSL_LS_BCM_PORT, 5369 (BSL_META_U(unit, 5370 "Execute FlexPort sequence\n"))); 5371 5372 /* port_schedule_state structure initialization */ 5373 BCM_IF_ERROR_RETURN 5374 (_bcmi_xgs5_port_soc_schedule_state_init(unit, nport, op, 5375 soc_resource, 5376 port_schedule_state)); 5377 5378 /* Validate SOC Port Resource data */ 5379 BCM_IF_ERROR_RETURN 5380 (_bcmi_xgs5_port_resource_validate(unit, port_schedule_state)); 5381 5382 /* Pause linkscan */ 5383 soc_linkscan_pause(unit); 5384 5385 /* Pause counter collection */ 5386 COUNTER_LOCK(unit); 5387 5388 /* Flexport operations */ 5389 rv = _bcmi_xgs5_port_reconfigure(unit, resource, port_schedule_state); 5390 5391 /* Resume counter collection */ 5392 COUNTER_UNLOCK(unit); 5393 5394 /* Resume linkscan */ 5395 soc_linkscan_continue(unit); 5396 5397 if (rv != BCM_E_NONE) { 5398 LOG_ERROR(BSL_LS_BCM_PORT, 5399 (BSL_META_U(unit, 5400 "Flexport operations failed: %d (%s)\n"), 5401 rv, bcm_errmsg(rv))); 5402 LOG_ERROR(BSL_LS_BCM_PORT, 5403 (BSL_META_U(unit, 5404 "Changes to device may have been partially " 5405 "executed. System may be unstable.\n"))); 5406 return rv; 5407 } 5408 5409 } 5410 5411 if ((op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) || 5412 (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) { 5413 LOG_VERBOSE(BSL_LS_BCM_PORT, 5414 (BSL_META_U(unit, 5415 "Execute Encap change\n"))); 5416 for (i = 0; i < nport; i++) { 5417 if (!(soc_resource[i].op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) && 5418 !(soc_resource[i].op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) { 5419 continue; 5420 } 5421 BCM_IF_ERROR_RETURN 5422 (bcmi_xgs5_port_encap_speed_check(unit, resource[i].port, 5423 resource[i].encap, 5424 resource[i].speed)); 5425 if (SOC_USE_PORTCTRL(unit)) { 5426 BCM_IF_ERROR_RETURN 5427 (bcmi_esw_portctrl_encap_set(unit, resource[i].port, 5428 resource[i].encap, TRUE)); 5429 } else { 5430 BCM_IF_ERROR_RETURN 5431 (bcmi_esw_port_encap_set(unit, resource[i].port, 5432 resource[i].encap)); 5433 } 5434 } 5435 } 5436 5437 /* Update speed */ 5438 for (i = 0; i < nport; i++) { 5439 if (resource[i].physical_port == -1 || 5440 soc_resource[i].op == BCMI_XGS5_PORT_RESOURCE_OP_ENCAP || 5441 soc_resource[i].op == BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX) { 5442 continue; 5443 } 5444 if (((resource[i].speed < BCMI_PORT_DRV_DEV_INFO(unit)->tdm_speed_min) 5445 #if defined(BCM_TRIDENT3_SUPPORT) 5446 || SOC_IS_TRIDENT3X(unit) 5447 #endif 5448 ) 5449 && 5450 BCMI_PORT_DRV_CALL(unit)->no_tdm_speed_update) { 5451 BCM_IF_ERROR_RETURN 5452 (BCMI_PORT_DRV_CALL(unit)->no_tdm_speed_update(unit, 5453 resource[i].port, 5454 resource[i].speed)); 5455 } 5456 } 5457 5458 /* 5459 * Bring new ports down to ensure port state is proper 5460 */ 5461 for (i = 0; i < nport; i++) { 5462 if ((resource[i].physical_port == -1) || 5463 (resource[i].flags & SOC_PORT_RESOURCE_SPEED)) { 5464 continue; 5465 } 5466 LOG_VERBOSE(BSL_LS_BCM_PORT, 5467 (BSL_META_U(unit, 5468 "Disable port %d\n"), resource[i].port)); 5469 5470 BCM_IF_ERROR_RETURN 5471 (bcm_esw_port_enable_set(unit, resource[i].port, 0)); 5472 } 5473 5474 return BCM_E_NONE; 5475 } 5476 5477 /* 5478 * Function: 5479 * bcmi_xgs5_port_resource_multi_set 5480 * Purpose: 5481 * Modify the following port resources: 5482 * - Logical to physical port mapping 5483 * - Speed 5484 * - Number of PHY lanes 5485 * - Encapsulation mode 5486 * Parameters: 5487 * unit - (IN) Unit number. 5488 * nport - (IN) Number of elements in array resource. 5489 * resource - (IN) Port resource configuration array. 5490 * Returns: 5491 * BCM_E_XXX 5492 * Note: 5493 * Assumes caller has lock. 5494 */ 5495 int 5496 bcmi_xgs5_port_resource_multi_set(int unit, 5497 int nport, bcm_port_resource_t *resource) 5498 { 5499 soc_port_resource_t *soc_resource; 5500 soc_port_schedule_state_t *port_schedule_state; 5501 int rv; 5502 5503 if (resource == NULL) { 5504 return BCM_E_PARAM; 5505 } 5506 5507 if ((BCMI_PORT_DRV_CALL(unit)->reconfigure_ports == NULL) || 5508 (BCMI_PORT_DRV_CALL(unit)->soc_resource_init == NULL)) { 5509 return BCM_E_UNAVAIL; 5510 } 5511 5512 /* 5513 * Validate function input requirements 5514 * 5515 * This steps checks for function semantics and guidelines 5516 * from the API perspective. 5517 */ 5518 BCM_IF_ERROR_RETURN 5519 (_bcmi_xgs5_port_resource_input_validate(unit, nport, resource)); 5520 5521 /* Allocate memory for SOC Port Resource array data structure */ 5522 soc_resource = sal_alloc(sizeof(soc_port_resource_t) * nport, 5523 "port_resource"); 5524 if (soc_resource == NULL) { 5525 return BCM_E_MEMORY; 5526 } 5527 5528 /* Allocate memory for soc_port_schedule_state_t structure */ 5529 port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t), 5530 "port schedule state"); 5531 if (port_schedule_state == NULL) { 5532 sal_free(soc_resource); 5533 return BCM_E_MEMORY; 5534 } 5535 5536 rv = _bcmi_xgs5_port_resource_execute(unit, nport, resource, soc_resource, 5537 port_schedule_state); 5538 5539 if (rv != BCM_E_NONE) { 5540 LOG_ERROR(BSL_LS_BCM_PORT, 5541 (BSL_META_U(unit, 5542 "Port resource execute failed: %d (%s)\n"), 5543 rv, bcm_errmsg(rv))); 5544 } 5545 sal_free(soc_resource); 5546 sal_free(port_schedule_state); 5547 5548 return rv; 5549 } 5550 5551 /* 5552 * Function: 5553 * bcmi_xgs5_port_resource_traverse 5554 * Purpose: 5555 * Iterates over the port resource configurations on a given 5556 * unit and calls user-provided callback for every entry. 5557 * Parameters: 5558 * unit - (IN) Unit number. 5559 * trav_fn - (IN) Callback function to execute. 5560 * user_data - (IN) Pointer to any user data. 5561 * Returns: 5562 * BCM_E_XXX 5563 */ 5564 int 5565 bcmi_xgs5_port_resource_traverse(int unit, 5566 bcm_port_resource_traverse_cb trav_fn, 5567 void *user_data) 5568 { 5569 bcm_port_t port; 5570 bcm_port_resource_t resource; 5571 soc_info_t *si = &SOC_INFO(unit); 5572 5573 PARAM_NULL_CHECK(trav_fn); 5574 5575 for (port = 0; port < SOC_MAX_NUM_PORTS ; port++) { 5576 /* Skip logical ports with no assignment and management ports */ 5577 /* coverity[overrun-local] */ 5578 if ((si->port_l2p_mapping[port] == -1) || 5579 IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 5580 continue; 5581 } 5582 5583 /* Get port information */ 5584 if (BCM_FAILURE(bcmi_xgs5_port_resource_get(unit, port, &resource))) { 5585 continue; 5586 } 5587 5588 /* Call user-provided callback routine */ 5589 BCM_IF_ERROR_RETURN(trav_fn(unit, &resource, user_data)); 5590 } 5591 5592 return BCM_E_NONE; 5593 } 5594 5595 /***************************Legacy API *******************************/ 5596 /* 5597 * Function: 5598 * bcmi_xgs5_port_lanes_set 5599 * Purpose: 5600 * Set the number of PHY lanes for the given port. 5601 * 5602 * This function should only be used to support the legacy 5603 * FlexPort API bcm_port_control_set(... , bcmPortControlLanes). 5604 * 5605 * The legacy API does not delete the port mappings when flexing 5606 * to fewer lanes. Ports which lanes are used by the base 5607 * physical port becomes inactive. 5608 * 5609 * Parameters: 5610 * unit - (IN) Unit number. 5611 * port - (IN) Logical port. 5612 * lanes - (IN) Number of lanes to set on given port. 5613 * Returns: 5614 * BCM_E_XXX 5615 * Notes: 5616 * - Only to be used by legacy API to support flexport behavior 5617 * bcm_port_control_set(... , bcmPortControlLanes). 5618 * - Supports only up to 4 lanes (TSC-4). 5619 * - 'port' must be in BCM port format (non-GPORT) and mapped to 5620 * the base physical port. 5621 * - Several calls to legacy API may be required to 5622 * achieve desired configuration. 5623 */ 5624 5625 int 5626 bcmi_xgs5_port_lanes_set(int unit, bcm_port_t port, int lanes) 5627 { 5628 soc_info_t *si = &SOC_INFO(unit); 5629 bcm_port_resource_t cur_resource, resource[8]; /* Max size to support up to 4 lanes */ 5630 int max_array_cnt; 5631 int i; 5632 int phy_port; 5633 int speed; 5634 int num_ports_clear; 5635 int num_ports_new; 5636 5637 bcm_port_resource_t_init(&cur_resource); 5638 BCM_IF_ERROR_RETURN(bcm_esw_port_resource_get(unit, port, &cur_resource)); 5639 5640 /* 5641 * Select speed based on number of lanes and the encap 5642 */ 5643 switch(lanes) { 5644 case 1: 5645 speed = (cur_resource.encap == BCM_PORT_ENCAP_IEEE) ? 25000 : 27000; 5646 break; 5647 case 2: 5648 speed = (cur_resource.encap == BCM_PORT_ENCAP_IEEE) ? 50000 : 53000; 5649 break; 5650 case 4: 5651 speed = (cur_resource.encap == BCM_PORT_ENCAP_IEEE) ? 100000 : 106000; 5652 break; 5653 default: 5654 /* Support legacy API up to 4 lanes */ 5655 return BCM_E_PARAM; 5656 } 5657 5658 /* Check current number of lanes */ 5659 if (cur_resource.lanes == lanes) { 5660 return BCM_E_NONE; 5661 } 5662 5663 max_array_cnt = COUNTOF(resource); 5664 sal_memset(resource, 0, sizeof(resource)); 5665 5666 /* 5667 * Build port resource array 5668 * Certain information is derived from 'best' guess, 5669 * similar to the legacy behaviour. 5670 */ 5671 switch (cur_resource.lanes) { 5672 case 1: 5673 if (lanes == 2) { 5674 num_ports_clear = 2; 5675 num_ports_new = 1; 5676 } else { 5677 num_ports_clear = 4; 5678 num_ports_new = 1; 5679 } 5680 break; 5681 case 2: 5682 if (lanes == 1) { 5683 num_ports_clear = 2; 5684 num_ports_new = 2; 5685 } else { 5686 num_ports_clear = 4; 5687 num_ports_new = 1; 5688 } 5689 break; 5690 case 4: 5691 if (lanes == 1) { 5692 num_ports_clear = 4; 5693 num_ports_new = 4; 5694 } else { 5695 num_ports_clear = 4; 5696 num_ports_new = 2; 5697 } 5698 break; 5699 default: 5700 return BCM_E_PARAM; 5701 } 5702 5703 if ((num_ports_clear + num_ports_new) > max_array_cnt) { 5704 return BCM_E_INTERNAL; 5705 } 5706 5707 /* 5708 * Clear mapping for physical ports involved in FlexPort operation. 5709 * Assume physical ports are numbered consecutively in device. 5710 */ 5711 phy_port = si->port_l2p_mapping[port]; 5712 for (i = 0; i < num_ports_clear; i++) { 5713 resource[i].flags = SOC_PORT_RESOURCE_I_MAP; 5714 resource[i].port = si->port_p2l_mapping[phy_port++]; 5715 resource[i].physical_port = -1; 5716 } 5717 5718 /* 5719 * Map new ports 5720 * 5721 * Legacy API requires that logical-physical port mapping 5722 * is valid in the SOC_INFO SW data. 5723 */ 5724 phy_port = si->port_l2p_mapping[port]; 5725 for (; i < (num_ports_clear + num_ports_new); i++) { 5726 /* Check valid physical port */ 5727 if (phy_port == -1) { 5728 return BCM_E_INTERNAL; 5729 } 5730 5731 resource[i].flags = SOC_PORT_RESOURCE_I_MAP; 5732 resource[i].port = si->port_p2l_mapping[phy_port]; 5733 resource[i].physical_port = phy_port; 5734 resource[i].lanes = lanes; 5735 resource[i].speed = speed; 5736 resource[i].encap = cur_resource.encap; /* Keep encap the same */ 5737 phy_port += lanes; 5738 } 5739 5740 BCM_IF_ERROR_RETURN 5741 (bcmi_xgs5_port_resource_multi_set(unit, 5742 (num_ports_clear + num_ports_new), 5743 resource)); 5744 5745 return BCM_E_NONE; 5746 } 5747 5748 /* 5749 * Function: 5750 * bcmi_xgs5_port_lanes_get 5751 * Purpose: 5752 * Get the number of PHY lanes for the given port. 5753 * Parameters: 5754 * unit - (IN) Unit number. 5755 * port - (IN) Logical port. 5756 * lanes - (OUT) Returns number of lanes for port. 5757 * Returns: 5758 * BCM_E_XXX 5759 */ 5760 int 5761 bcmi_xgs5_port_lanes_get(int unit, bcm_port_t port, int *lanes) 5762 { 5763 bcm_port_resource_t resource; 5764 5765 BCM_IF_ERROR_RETURN(bcm_esw_port_resource_get(unit, port, &resource)); 5766 5767 *lanes = resource.lanes; 5768 5769 return BCM_E_NONE; 5770 } 5771 5772 /* 5773 * Function: 5774 * bcmi_xgs5_port_speed_set 5775 * Purpose: 5776 * Set the speed for the given port. 5777 * 5778 * This function should only be used to support the legacy 5779 * FlexPort API bcm_port_speed_set(). 5780 * 5781 * 5782 * Parameters: 5783 * unit - (IN) Unit number. 5784 * port - (IN) Logical port. 5785 * speed - (IN) speed for given port. 5786 * Returns: 5787 * BCM_E_XXX 5788 * Notes: 5789 * - Only to be used by legacy API to support flexport behavior 5790 * bcm_port_speed_set(). 5791 * - 'port' must be in BCM port format (non-GPORT) and mapped to 5792 * the base physical port. 5793 * - Several calls to legacy API may be required to 5794 * achieve desired configuration. 5795 */ 5796 5797 int 5798 bcmi_xgs5_port_speed_set(int unit, bcm_port_t port, int speed) 5799 { 5800 soc_info_t *si = &SOC_INFO(unit); 5801 bcm_port_resource_t resource[2]; 5802 int encap, i; 5803 5804 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 5805 LOG_VERBOSE(BSL_LS_BCM_PORT, 5806 (BSL_META_U(unit, 5807 "bcmi_xgs5_port_speed_set: " 5808 "Set speed on disabled port, do nothing\n"))); 5809 return BCM_E_NONE; 5810 } 5811 5812 /* Do nothing except update port type in case auxiliary ports don't 5813 * support flexport */ 5814 if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) && 5815 IS_MANAGEMENT_PORT(unit,port)) { 5816 BCM_IF_ERROR_RETURN 5817 (_bcmi_xgs5_management_port_soc_info_ptype_update(unit, 5818 port, speed)); 5819 return BCM_E_NONE; 5820 } 5821 5822 /* 5823 * No reconfiguration is needed if new speed matches current speed 5824 */ 5825 if (speed == si->port_init_speed[port]) { 5826 LOG_VERBOSE(BSL_LS_BCM_PORT, 5827 (BSL_META_U(unit, 5828 "Speed is already configured as %d\n"), 5829 speed)); 5830 return BCM_E_NONE; 5831 } 5832 5833 for (i = 0; i < 2; i++) { 5834 bcm_port_resource_t_init(&resource[i]); 5835 } 5836 /* 5837 * Build port resource 5838 */ 5839 5840 /* Get current port encap */ 5841 BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap)); 5842 5843 /* Keep encap, lanes, phy_port the same */ 5844 resource[0].flags = SOC_PORT_RESOURCE_I_MAP| SOC_PORT_RESOURCE_SPEED; 5845 resource[0].port = port; 5846 resource[0].physical_port = -1; 5847 5848 resource[1].flags = SOC_PORT_RESOURCE_I_MAP| SOC_PORT_RESOURCE_SPEED; 5849 resource[1].port = port; 5850 resource[1].physical_port = si->port_l2p_mapping[port]; 5851 resource[1].speed = speed; 5852 resource[1].lanes = si->port_num_lanes[port]; 5853 resource[1].encap = encap; 5854 5855 BCM_IF_ERROR_RETURN 5856 (bcmi_xgs5_port_resource_multi_set(unit, 2, resource)); 5857 5858 return BCM_E_NONE; 5859 } 5860 5861 /* 5862 * Function: 5863 * bcmi_xgs5_port_attach_dscp 5864 * Purpose: 5865 * Set default DSCP profile index to port table 5866 * Increase reference count of default DSCP profile 5867 * Parameters: 5868 * unit - (IN) Unit number. 5869 * port - (IN) Logical port. 5870 * Returns: 5871 * SOC_E_XXX 5872 */ 5873 int 5874 bcmi_xgs5_port_attach_dscp(int unit, bcm_port_t port) 5875 { 5876 BCM_IF_ERROR_RETURN 5877 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 5878 TRUST_DSCP_PTRf, 5879 0)); 5880 SOC_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, 0, 5881 64)); 5882 5883 return BCM_E_NONE; 5884 } 5885 5886 /* 5887 * Function: 5888 * bcmi_xgs5_port_attach_software 5889 * Purpose: 5890 * Initialize BCM PORT info structure (bcm_port_info[unit][port]) 5891 * Parameters: 5892 * unit - (IN) Unit number. 5893 * port - (IN) Logical port. 5894 * Returns: 5895 * SOC_E_XXX 5896 * Note: 5897 * Same port related initialization covered in _bcm_port_software_init() 5898 */ 5899 int 5900 bcmi_xgs5_port_attach_software(int unit, bcm_port_t port) 5901 { 5902 _bcm_port_info_t *pinfo; 5903 int index, idxmax; 5904 int inds_bytes; 5905 int enabled; 5906 uint32 value; 5907 5908 /* Free memory in case this is already allocated */ 5909 BCM_IF_ERROR_RETURN(_bcmi_xgs5_port_software_free(unit, port)); 5910 5911 /* Get PORT info structure pointer */ 5912 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 5913 5914 /* 5915 * Initialization of vd_pbvl bitmap in port 5916 */ 5917 idxmax = 0; 5918 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) { 5919 idxmax = soc_mem_index_count(unit, VLAN_PROTOCOLm); 5920 5921 inds_bytes = (idxmax + (_BCM_PORT_VD_PBVL_ESIZE - 1)) / \ 5922 _BCM_PORT_VD_PBVL_ESIZE; /* Round to the next entry */ 5923 5924 pinfo->p_vd_pbvl = sal_alloc(inds_bytes, "vdv_info"); 5925 if (NULL == pinfo->p_vd_pbvl) { 5926 return BCM_E_MEMORY; 5927 } 5928 5929 sal_memset(pinfo->p_vd_pbvl, 0, inds_bytes); 5930 } else { 5931 pinfo->p_vd_pbvl = NULL; 5932 } 5933 5934 /* 5935 * Update TPID reference count 5936 */ 5937 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 5938 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 5939 if (soc_feature(unit, soc_feature_egr_all_profile)) { 5940 BCM_IF_ERROR_RETURN( 5941 bcm_esw_port_egr_lport_field_get( 5942 unit, port, EGR_VLAN_CONTROL_1m, 5943 OUTER_TPID_INDEXf, (uint32 *)&index)); 5944 } else { 5945 BCM_IF_ERROR_RETURN( 5946 READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &value)); 5947 index = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_1m, 5948 &value, OUTER_TPID_INDEXf); 5949 } 5950 } else { 5951 BCM_IF_ERROR_RETURN 5952 (READ_EGR_VLAN_CONTROL_1r(unit, port, &value)); 5953 index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 5954 value, OUTER_TPID_INDEXf); 5955 } 5956 5957 BCM_IF_ERROR_RETURN 5958 (_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1)); 5959 5960 enabled = 0; 5961 BCM_IF_ERROR_RETURN 5962 (_bcm_esw_port_config_get(unit, port, 5963 _bcmPortOuterTpidEnables, &enabled)); 5964 index = 0; 5965 while (enabled) { 5966 if (enabled & 1) { 5967 BCM_IF_ERROR_RETURN 5968 (_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1)); 5969 } 5970 enabled = enabled >> 1; 5971 index++; 5972 } 5973 } 5974 5975 #if defined(BCM_TRIDENT3_SUPPORT) 5976 if (SOC_IS_TRIDENT3X(unit)) { 5977 BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port, 5978 EGR_QOS_PROFILE_INDEXf,0)); 5979 } else 5980 #endif 5981 /* 5982 * Initialize priority map 5983 */ 5984 if (soc_feature(unit, soc_feature_color_prio_map)) { 5985 bcm_color_t color; 5986 bcm_color_t color_array[] = {bcmColorGreen, bcmColorYellow, bcmColorRed}; 5987 int priority; 5988 int cfi; 5989 5990 for (index = 0; index < 3; index++) { 5991 color = color_array[index]; 5992 for (priority = 0; priority <= 7; priority++) { 5993 cfi = (color == bcmColorRed) ? 1 : 0; 5994 BCM_IF_ERROR_RETURN 5995 (bcm_esw_port_vlan_priority_unmap_set(unit, port, priority, 5996 color, priority, cfi)); 5997 } 5998 } 5999 } 6000 6001 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_NONE; 6002 6003 return BCM_E_NONE; 6004 } 6005 6006 /* 6007 * Function: 6008 * bcmi_xgs5_port_attach_egr_vlan_action 6009 * Purpose: 6010 * Set the egress port's default vlan tag actions 6011 * Parameters: 6012 * unit - (IN) Unit number. 6013 * port - (IN) Logical port. 6014 * Returns: 6015 * SOC_E_XXX 6016 */ 6017 int 6018 bcmi_xgs5_port_attach_egr_vlan_action(int unit, bcm_port_t port) 6019 { 6020 bcm_vlan_action_set_t action; 6021 6022 if (soc_feature(unit, soc_feature_vlan_action) && 6023 (!SOC_IS_TRIDENT3X(unit))) { 6024 6025 /* Update Egress VLAN profile table count */ 6026 _bcm_trx_egr_vlan_action_profile_entry_increment(unit, 6027 BCM_TRX_EGR_VLAN_ACTION_PROFILE_DEFAULT); 6028 6029 if (IS_HG_PORT(unit, port)) { 6030 6031 BCM_IF_ERROR_RETURN 6032 (_bcm_trx_vlan_port_egress_default_action_get(unit, 6033 port, &action)); 6034 /* Backward compatible defaults */ 6035 action.ot_outer = bcmVlanActionDelete; 6036 action.dt_outer = bcmVlanActionDelete; 6037 BCM_IF_ERROR_RETURN 6038 (_bcm_trx_vlan_port_egress_default_action_set(unit, 6039 port, &action)); 6040 } 6041 } 6042 return BCM_E_NONE; 6043 } 6044 6045 /* 6046 * Function: 6047 * _bcmi_xgs5_port_bridge_port_init 6048 * Purpose: 6049 * This function initializes PORT_BRIDGE_BMAP memory (for a normal port), 6050 * and/or PORT_BRIDGE_MIRROR_BMAP (for a Higig port). The initialization is 6051 * required for ensuring that port bit in one of the above memories 6052 * (depending on port type), and PORT_TAB.PORT_BRIDGE bit have the same 6053 * value. See notes. 6054 * Parameters: 6055 * unit - (IN) Unit number. 6056 * port - (IN) Logical port, BCM format. 6057 * value - 1 Set bit in PORT_BRIDGE_BMAP and/or PORT_BRIDGE_MIRROR_BMAP 6058 * memory. 6059 * 0 Reset bit in PORT_BRIDGE_BMAP and/or PORT_BRIDGE_MIRROR_BMAP 6060 * memory. 6061 * See Notes. 6062 * Returns: 6063 * BCM_E_XXX 6064 * Notes: 6065 * - PORT_TAB.PORT_BRIDGE is reset in function 6066 * mbcm_driver[unit]->mbcm_port_cfg_init() 6067 * - If this function is called outside of port attach and detach 6068 * functions then the caller must make sure that PORT_TAB.PORT_BRIDGE is 6069 * programmed to the same value as in these memories, for a given port 6070 * Refer to memory description of these two memories for more information 6071 * - Assumes port is valid. 6072 * - Assumes this is NOT called during Warmboot. 6073 */ 6074 STATIC int 6075 _bcmi_xgs5_port_bridge_port_init(int unit, bcm_port_t port, int value) 6076 { 6077 int rv = BCM_E_NONE; 6078 bcm_pbmp_t pbmp; 6079 6080 if ((IS_E_PORT(unit, port) || 6081 IS_CPU_PORT(unit, port) || 6082 IS_HG_PORT(unit, port)) && 6083 SOC_MEM_IS_VALID(unit, PORT_BRIDGE_BMAPm)) { 6084 port_bridge_bmap_entry_t entry; 6085 6086 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_BMAPm, 6087 MEM_BLOCK_ANY, 0, &entry)); 6088 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_BMAPm, &entry, 6089 BITMAPf, &pbmp); 6090 6091 if (value) { 6092 SOC_PBMP_PORT_ADD(pbmp, port); 6093 } else { 6094 SOC_PBMP_PORT_REMOVE(pbmp, port); 6095 } 6096 6097 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry, 6098 BITMAPf, &pbmp); 6099 6100 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm, 6101 MEM_BLOCK_ANY, 0, &entry)); 6102 } 6103 6104 if (IS_HG_PORT(unit, port) && 6105 SOC_MEM_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPm)) { 6106 port_bridge_mirror_bmap_entry_t entry; 6107 6108 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_MIRROR_BMAPm, 6109 MEM_BLOCK_ANY, 0, &entry)); 6110 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry, 6111 BITMAPf, &pbmp); 6112 if (value) { 6113 SOC_PBMP_PORT_ADD(pbmp, port); 6114 } else { 6115 SOC_PBMP_PORT_REMOVE(pbmp, port); 6116 } 6117 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry, 6118 BITMAPf, &pbmp); 6119 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_MIRROR_BMAPm, 6120 MEM_BLOCK_ANY, 0, &entry)); 6121 } 6122 6123 return rv; 6124 } 6125 6126 /* 6127 * Function: 6128 * bcmi_xgs5_port_cfg_init 6129 * Purpose: 6130 * Initialize the port configuration according to Initial System 6131 * Configuration (see init.c) 6132 * Parameters: 6133 * unit - (IN) Unit number. 6134 * port - (IN) Logical port. 6135 * Returns: 6136 * SOC_E_XXX 6137 */ 6138 int 6139 bcmi_xgs5_port_cfg_init(int unit, bcm_port_t port) 6140 { 6141 bcm_pbmp_t port_pbmp; 6142 bcm_vlan_data_t vd; 6143 6144 SOC_PBMP_CLEAR(port_pbmp); 6145 BCM_PBMP_ASSIGN(port_pbmp, PBMP_ALL(unit)); 6146 SOC_PBMP_REMOVE(port_pbmp, PBMP_TDM(unit)); 6147 6148 vd.vlan_tag = BCM_VLAN_DEFAULT; 6149 BCM_PBMP_ASSIGN(vd.port_bitmap, port_pbmp); 6150 BCM_PBMP_ASSIGN(vd.ut_port_bitmap, port_pbmp); 6151 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit)); 6152 6153 BCM_IF_ERROR_RETURN 6154 (mbcm_driver[unit]->mbcm_port_cfg_init(unit, port, &vd)); 6155 6156 BCM_IF_ERROR_RETURN 6157 (_bcmi_xgs5_port_bridge_port_init(unit, port, 0)); 6158 6159 return BCM_E_NONE; 6160 } 6161 6162 /* 6163 * Function: 6164 * bcmi_xgs5_port_attach_port_probe 6165 * Purpose: 6166 * Probe the PHY and set up the PHY and MAC for the specified ports. 6167 * This is purely a discovery routine and does no configuration. 6168 * Parameters: 6169 * unit - (IN) Unit number. 6170 * port - (IN) Logical port. 6171 * Returns: 6172 * SOC_E_XXX 6173 * Notes: 6174 * Only for Non PortMod unit. 6175 * Unit with PortMod enabled probe PHY and MAC via 6176 * _bcmi_xgs5_port_pm_delete/add(). 6177 */ 6178 int 6179 bcmi_xgs5_port_attach_port_probe(int unit, bcm_port_t port) 6180 { 6181 int okay; 6182 6183 if (!SOC_USE_PORTCTRL(unit)) { 6184 6185 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 6186 if (!okay) { 6187 return BCM_E_INTERNAL; 6188 } 6189 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE)); 6190 } 6191 return BCM_E_NONE; 6192 } 6193 6194 /* 6195 * Function: 6196 * bcmi_xgs5_port_attach_frame_length_check 6197 * Purpose: 6198 * Control 802.3 frame length field check in MAC 6199 * Parameters: 6200 * unit - (IN) Unit number. 6201 * port - (IN) Logical port. 6202 * Returns: 6203 * SOC_E_XXX 6204 */ 6205 int 6206 bcmi_xgs5_port_attach_frame_length_check(int unit, bcm_port_t port) 6207 { 6208 int length_check; 6209 soc_reg_t reg = INVALIDr; 6210 uint32 rval; 6211 6212 6213 length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0); 6214 if (IS_CL_PORT(unit, port) && 6215 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 6216 reg = CLPORT_MAC_RSV_MASKr; 6217 } else if (IS_QSGMII_PORT(unit, port)) { 6218 reg = GPORT_RSV_MASKr; 6219 } else if (SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 6220 reg = XLPORT_MAC_RSV_MASKr; 6221 } 6222 6223 if (reg != INVALIDr) { 6224 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 6225 if (length_check) { 6226 rval |= 0x20; /* set bit 5 to enable frame length check */ 6227 } else { 6228 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 6229 } 6230 if (!IS_QSGMII_PORT(unit, port)) { 6231 /* set PFC frame detected indicator 6232 * No RSV[34] bit in GPORT_RSV_MASK 6233 */ 6234 rval |= 1 << 18; 6235 } 6236 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 6237 } 6238 6239 return BCM_E_NONE; 6240 } 6241 6242 /* 6243 * Function: 6244 * bcmi_xgs5_port_attach_rcpu_mtu 6245 * Purpose: 6246 * Set the maximum receive frame size to JUMBO size for RCPU port 6247 * Parameters: 6248 * unit - (IN) Unit number. 6249 * port - (IN) Logical port. 6250 * Returns: 6251 * SOC_E_XXX 6252 */ 6253 int 6254 bcmi_xgs5_port_attach_rcpu_mtu(int unit, bcm_port_t port) 6255 { 6256 #ifdef BCM_RCPU_SUPPORT 6257 if ((uint32)port == soc_property_get(unit, spn_RCPU_PORT, -1)) { 6258 BCM_IF_ERROR_RETURN 6259 (bcm_esw_port_frame_max_set(unit, port, BCM_PORT_JUMBO_MAXSZ)); 6260 } 6261 #endif /* BCM_RCPU_SUPPORT */ 6262 6263 return BCM_E_NONE; 6264 } 6265 6266 /* 6267 * Function: 6268 * bcmi_xgs5_port_attach_outer_tpid 6269 * Purpose: 6270 * Enable the default Outer TPID 6271 * Parameters: 6272 * unit - (IN) Unit number. 6273 * port - (IN) Logical port. 6274 * Returns: 6275 * SOC_E_XXX 6276 */ 6277 int 6278 bcmi_xgs5_port_attach_outer_tpid(int unit, bcm_port_t port) 6279 { 6280 if (soc_feature(unit, soc_feature_egr_all_profile)) { 6281 soc_field_t flds[3] = { 6282 VT_MISS_UNTAGf, 6283 REMARK_OUTER_DOT1Pf, 6284 OUTER_TPID_VALIDf 6285 }; 6286 uint32 vals[3] = {0, 1, 1}; 6287 6288 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(unit, 6289 port, EGR_VLAN_CONTROL_1m, 3, flds, vals)); 6290 } 6291 6292 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 6293 BCM_IF_ERROR_RETURN 6294 (bcm_esw_port_tpid_set(unit, port, 6295 _bcm_fb2_outer_tpid_default_get(unit))); 6296 } 6297 return BCM_E_NONE; 6298 } 6299 6300 /* 6301 * Function: 6302 * bcmi_xgs5_port_egr_block_profile_init 6303 * Purpose: 6304 * Initialize egress block profile pointer to invalid value 6305 * Parameters: 6306 * unit - (IN) Unit number. 6307 * port - (IN) Logical port. 6308 * Returns: 6309 * SOC_E_XXX 6310 */ 6311 int 6312 bcmi_xgs5_port_egr_block_profile_init(int unit, bcm_port_t port) 6313 { 6314 /* Initialize egress block profile pointer to invalid value */ 6315 BCM_IF_ERROR_RETURN 6316 (bcmi_esw_port_egr_prof_ptr_set(unit, port, -1)); 6317 6318 return BCM_E_NONE; 6319 } 6320 6321 /* 6322 * Function: 6323 * bcmi_xgs5_port_attach_vlan_protocol 6324 * Purpose: 6325 * Program the VLAN_PROTOCOL_DATA_INDEX, FP_PORT_FIELD_SEL_INDEX, 6326 * PROTOCOL_PKT_INDEX pointers 6327 * Parameters: 6328 * unit - (IN) Unit number. 6329 * port - (IN) Logical port. 6330 * Returns: 6331 * SOC_E_XXX 6332 */ 6333 int 6334 bcmi_xgs5_port_attach_vlan_protocol(int unit, bcm_port_t port) 6335 { 6336 _bcm_port_info_t *pinfo; 6337 uint32 profile_index; 6338 vlan_protocol_data_entry_t vlan_protocol_data_entries[16]; 6339 uint32 vlan_protocol_data_index =0; 6340 void *entries_buf[1]; 6341 6342 /* Get PORT info structure pointer */ 6343 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 6344 if (pinfo == NULL) { 6345 return BCM_E_INTERNAL; 6346 } 6347 6348 if (!IS_LB_PORT(unit, port) && !IS_TDM_PORT(unit, port)) { 6349 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) { 6350 sal_memset(vlan_protocol_data_entries, 0, 6351 sizeof(vlan_protocol_data_entries)); 6352 6353 entries_buf[0] = &vlan_protocol_data_entries; 6354 #if defined(BCM_TRIDENT3_SUPPORT) 6355 if (SOC_IS_TRIDENT3X(unit)) { 6356 /* Trident3 default profile 0 */ 6357 BCM_IF_ERROR_RETURN( 6358 _bcm_port_vlan_protocol_data_entry_get(unit, 0, 16, entries_buf)); 6359 } 6360 #endif 6361 BCM_IF_ERROR_RETURN( 6362 _bcm_port_vlan_protocol_data_entry_add(unit, entries_buf, 6363 16, (uint32 *)&vlan_protocol_data_index)); 6364 } 6365 6366 if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_NONE) { 6367 if (soc_mem_field_valid(unit, PORT_TABm, 6368 VLAN_PROTOCOL_DATA_INDEXf)) { 6369 BCM_IF_ERROR_RETURN( 6370 _bcm_esw_port_tab_set(unit, port, 6371 _BCM_CPU_TABS_ETHER, 6372 VLAN_PROTOCOL_DATA_INDEXf, 6373 vlan_protocol_data_index/16)); 6374 } 6375 pinfo->vlan_prot_ptr = vlan_protocol_data_index; 6376 } 6377 6378 if (soc_mem_field_valid(unit, PORT_TABm, 6379 FP_PORT_FIELD_SEL_INDEXf)) { 6380 BCM_IF_ERROR_RETURN( 6381 _bcm_esw_port_tab_set(unit, port, 6382 _BCM_CPU_TABS_ETHER, 6383 FP_PORT_FIELD_SEL_INDEXf, port)); 6384 } 6385 if (soc_mem_field_valid(unit, PORT_TABm, 6386 PROTOCOL_PKT_INDEXf)) { 6387 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 6388 soc_portreg) { 6389 BCM_IF_ERROR_RETURN( 6390 _bcm_esw_port_tab_set(unit, port, 6391 _BCM_CPU_TABS_ETHER, 6392 PROTOCOL_PKT_INDEXf, 6393 port)); 6394 } else { 6395 BCM_IF_ERROR_RETURN 6396 (_bcm_prot_pkt_ctrl_add(unit, 0, 0, 6397 &profile_index)); 6398 BCM_IF_ERROR_RETURN 6399 (_bcm_esw_port_tab_set(unit, port, 6400 _BCM_CPU_TABS_ETHER, 6401 PROTOCOL_PKT_INDEXf, 6402 profile_index)); 6403 } 6404 } 6405 } 6406 return BCM_E_NONE; 6407 } 6408 /* 6409 * Function: 6410 * bcmi_xgs5_port_attach_eee 6411 * Purpose: 6412 * EEE config 6413 * Parameters: 6414 * unit - (IN) Unit number. 6415 * port - (IN) Logical port. 6416 * Returns: 6417 * SOC_E_XXX 6418 */ 6419 int 6420 bcmi_xgs5_port_attach_eee(int unit, bcm_port_t port) 6421 { 6422 int value = 0, rv; 6423 _bcm_port_info_t *port_info; 6424 6425 if (soc_feature (unit, soc_feature_eee)) { 6426 if (!IS_LB_PORT(unit, port) && !IS_CPU_PORT (unit, port) && 6427 !IS_TDM_PORT(unit, port) && !IS_RDB_PORT(unit,port)) { 6428 /* EEE standard compliance Work Around: 6429 * Initialize the software state of native eee in MAC 6430 */ 6431 BCM_IF_ERROR_RETURN 6432 (bcmi_esw_port_eee_cfg_set(unit, port, 0)); 6433 /* Check if MAC supports Native EEE and set the value of 6434 * eee_cfg by reading the EEE status from MAC*/ 6435 if (SOC_USE_PORTCTRL(unit)) { 6436 rv = bcmi_esw_portctrl_eee_enable_get(unit, port, &value); 6437 } else { 6438 _bcm_port_info_access(unit, port, &port_info); 6439 rv = MAC_CONTROL_GET(port_info->p_mac, unit, port, 6440 SOC_MAC_CONTROL_EEE_ENABLE, 6441 &value); 6442 } 6443 if (rv != BCM_E_UNAVAIL) { 6444 BCM_IF_ERROR_RETURN 6445 (bcmi_esw_port_eee_cfg_set(unit, port, value)); 6446 } 6447 } 6448 } 6449 return BCM_E_NONE; 6450 } 6451 6452 /* 6453 * Function: 6454 * bcmi_xgs5_port_attach_higig 6455 * Purpose: 6456 * Set Higig/Higig2 mode 6457 * Parameters: 6458 * unit - (IN) Unit number. 6459 * port - (IN) Logical port. 6460 * Returns: 6461 * SOC_E_XXX 6462 */ 6463 int 6464 bcmi_xgs5_port_attach_higig(int unit, bcm_port_t port) 6465 { 6466 /********** 6467 * HIGIG 6468 */ 6469 if (IS_HG_PORT(unit, port)) { 6470 if (SOC_USE_PORTCTRL(unit)) { 6471 BCM_IF_ERROR_RETURN 6472 (bcmi_esw_portctrl_higig_mode_set(unit, port, TRUE)); 6473 } 6474 #ifdef BCM_HIGIG2_SUPPORT 6475 /* soc_feature_higig2 */ 6476 if (soc_feature(unit, soc_feature_higig2)) { 6477 if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 6478 soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) || 6479 SOC_USE_PORTCTRL(unit)) { 6480 BCM_IF_ERROR_RETURN 6481 (_bcm_esw_port_higig2_mode_set(unit, port, TRUE)); 6482 SOC_HG2_ENABLED_PORT_ADD(unit, port); 6483 } 6484 } 6485 #endif /* BCM_HIGIG2_SUPPORT */ 6486 } 6487 6488 return BCM_E_NONE; 6489 } 6490 6491 /* 6492 * Function: 6493 * bcmi_xgs5_port_attach_port_info_cfg 6494 * Purpose: 6495 * Set SW PORT info 6496 * Parameters: 6497 * unit - (IN) Unit number. 6498 * port - (IN) Logical port. 6499 * Returns: 6500 * SOC_E_XXX 6501 */ 6502 int 6503 bcmi_xgs5_port_attach_port_info_cfg(int unit, bcm_port_t port) 6504 { 6505 _bcm_port_info_t *pinfo; 6506 uint32 rx_los; 6507 int enable; 6508 int rv; 6509 6510 /* Get PORT info structure pointer */ 6511 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 6512 if (pinfo == NULL) { 6513 return BCM_E_INTERNAL; 6514 } 6515 6516 /*********** 6517 * SW RX LOS configuration from PHY driver 6518 */ 6519 if (IS_E_PORT(unit, port)) { 6520 rv = bcm_esw_port_phy_control_get(unit, port, 6521 BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, 6522 &rx_los); 6523 if (BCM_SUCCESS(rv)) { 6524 pinfo->rx_los = rx_los; 6525 } 6526 } 6527 6528 /*********** 6529 * SW port enable status from HW 6530 */ 6531 rv = bcm_esw_port_enable_get(unit, port, &enable); 6532 if (BCM_SUCCESS(rv)) { 6533 pinfo->enable = enable; 6534 } 6535 6536 return rv; 6537 } 6538 6539 /* 6540 * Function: 6541 * bcmi_xgs5_port_attach_egr_link_delay 6542 * Purpose: 6543 * Set port link delay 6544 * Parameters: 6545 * unit - (IN) Unit number. 6546 * port - (IN) Logical port. 6547 * Returns: 6548 * SOC_E_XXX 6549 */ 6550 int 6551 bcmi_xgs5_port_attach_egr_link_delay(int unit, bcm_port_t port) 6552 { 6553 int rv; 6554 int speed; 6555 uint64 rval64; 6556 uint32 rval32; 6557 6558 /********** 6559 * Egress Link Delay 6560 */ 6561 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 6562 rval32 = 0; 6563 SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAYr(unit, port, rval32)); 6564 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 6565 COMPILER_64_ZERO(rval64); 6566 SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64)); 6567 } else { 6568 return BCM_E_NONE; 6569 } 6570 6571 rv = bcm_esw_port_speed_get(unit, port, &speed); 6572 if (BCM_SUCCESS(rv)) { 6573 rv = _bcm_esw_port_link_delay_update(unit, port, speed); 6574 } 6575 6576 return rv; 6577 } 6578 6579 /* 6580 * Function: 6581 * bcmi_xgs5_port_attach_stg 6582 * Purpose: 6583 * Set STP state of port to FORWARDING 6584 * Parameters: 6585 * unit - (IN) Unit number. 6586 * port - (IN) Logical port. 6587 * Returns: 6588 * SOC_E_XXX 6589 */ 6590 int 6591 bcmi_xgs5_port_attach_stg(int unit, bcm_port_t port) 6592 { 6593 /* STG */ 6594 BCM_IF_ERROR_RETURN 6595 (bcm_esw_vlan_stp_set(unit, BCM_VLAN_DEFAULT, port, BCM_STG_STP_FORWARD)); 6596 return BCM_E_NONE; 6597 } 6598 6599 /* 6600 * Function: 6601 * bcmi_xgs5_port_attach_vlan 6602 * Purpose: 6603 * Add port into default vlan 1 6604 * Parameters: 6605 * unit - (IN) Unit number. 6606 * port - (IN) Logical port. 6607 * Returns: 6608 * SOC_E_XXX 6609 */ 6610 int 6611 bcmi_xgs5_port_attach_vlan(int unit, bcm_port_t port) 6612 { 6613 #ifndef BCM_VLAN_NO_DEFAULT_ETHER 6614 /* Add ports to default VLAN only if vlan policy allows it */ 6615 bcm_pbmp_t pbmp; 6616 6617 /* VLAN */ 6618 BCM_PBMP_CLEAR(pbmp); 6619 BCM_PBMP_PORT_ADD(pbmp, port); 6620 BCM_IF_ERROR_RETURN 6621 (bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbmp, pbmp)); 6622 #endif 6623 return BCM_E_NONE; 6624 } 6625 6626 /* 6627 * Function: 6628 * bcmi_xgs5_port_attach_trunk 6629 * Purpose: 6630 * Initializes trunk tables for newly added port 6631 * Parameters: 6632 * unit - (IN) Unit number. 6633 * port - (IN) Logical port. 6634 * Returns: 6635 * SOC_E_XXX 6636 */ 6637 int 6638 bcmi_xgs5_port_attach_trunk(int unit, bcm_port_t port) 6639 { 6640 bcm_pbmp_t pbmp; 6641 higig_trunk_control_entry_t entry; 6642 int rv = BCM_E_NONE; 6643 6644 /* TRUNK */ 6645 if (soc_feature(unit, soc_feature_hg_trunking)) { 6646 6647 soc_mem_lock(unit, HIGIG_TRUNK_CONTROLm); 6648 6649 rv = soc_mem_read(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ANY, 0, &entry); 6650 if (BCM_FAILURE(rv)) { 6651 soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm); 6652 return rv; 6653 } 6654 6655 BCM_PBMP_CLEAR(pbmp); 6656 6657 /* Read port bmap from hardware, and add new port to the bitmap */ 6658 soc_mem_pbmp_field_get(unit, HIGIG_TRUNK_CONTROLm, &entry, 6659 ACTIVE_PORT_BITMAPf, &pbmp); 6660 6661 BCM_PBMP_PORT_ADD(pbmp, port); 6662 6663 soc_mem_pbmp_field_set(unit, HIGIG_TRUNK_CONTROLm, &entry, 6664 ACTIVE_PORT_BITMAPf, &pbmp); 6665 6666 rv = soc_mem_write(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ALL, 0, 6667 &entry); 6668 6669 soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm); 6670 } 6671 return rv; 6672 } 6673 6674 /* 6675 * Function: 6676 * bcmi_xgs5_port_attach_linkscan 6677 * Purpose: 6678 * Initializes linkscan on port 6679 * Parameters: 6680 * unit - (IN) Unit number. 6681 * port - (IN) Logical port. 6682 * Returns: 6683 * SOC_E_XXX 6684 */ 6685 int 6686 bcmi_xgs5_port_attach_linkscan(int unit, bcm_port_t port) 6687 { 6688 6689 /* Skip linkscan if module hasn't init */ 6690 if (_bcm_esw_lc_check_init(unit) != BCM_E_NONE) { 6691 return BCM_E_NONE; 6692 } 6693 6694 /* LINKSCAN */ 6695 BCM_IF_ERROR_RETURN 6696 (_soc_linkscan_hw_port_init(unit, port)); 6697 6698 /* Initialze to SW linkscan mode */ 6699 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_port_attach(unit, port)); 6700 6701 return BCM_E_NONE; 6702 } 6703 6704 /* 6705 * Function: 6706 * bcmi_xgs5_port_attach_stack 6707 * Purpose: 6708 * Initializes statistic on port 6709 * Parameters: 6710 * unit - (IN) Unit number. 6711 * port - (IN) Logical port. 6712 * Returns: 6713 * SOC_E_XXX 6714 */ 6715 int 6716 bcmi_xgs5_port_attach_stat(int unit, bcm_port_t port) 6717 { 6718 pbmp_t pbmp; 6719 int config_threshold; 6720 6721 config_threshold = soc_property_get(unit, spn_BCM_STAT_JUMBO, 1518); 6722 if ((config_threshold < 1518) || 6723 (config_threshold > 0x3fff) ) { 6724 config_threshold = 1518; 6725 } 6726 6727 BCM_IF_ERROR_RETURN 6728 (_bcm_esw_stat_ovr_threshold_set(unit, port, config_threshold)); 6729 6730 /* Clear counters */ 6731 SOC_PBMP_CLEAR(pbmp); 6732 SOC_PBMP_PORT_ADD(pbmp, port); 6733 BCM_IF_ERROR_RETURN(soc_counter_set32_by_port(unit, pbmp, 0)); 6734 6735 /* Note: Assuming soc_counter_start would be called later after 6736 all the modules for the new port are initialised */ 6737 6738 return BCM_E_NONE; 6739 } 6740 6741 /* 6742 * Function: 6743 * bcmi_xgs5_port_attach_stack 6744 * Purpose: 6745 * Initializes stack on port 6746 * Parameters: 6747 * unit - (IN) Unit number. 6748 * port - (IN) Logical port. 6749 * Returns: 6750 * SOC_E_XXX 6751 */ 6752 int 6753 bcmi_xgs5_port_attach_stack(int unit, bcm_port_t port) 6754 { 6755 6756 /* Set HG ingress CPU Opcode map to the CPU */ 6757 if (IS_ST_PORT(unit, port)) { 6758 pbmp_t pbmp; 6759 icontrol_opcode_bitmap_entry_t entry; 6760 6761 SOC_PBMP_CLEAR(pbmp); 6762 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 6763 6764 BCM_IF_ERROR_RETURN 6765 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, 6766 &entry)); 6767 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 6768 BITMAPf, &pbmp); 6769 BCM_IF_ERROR_RETURN 6770 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, 6771 &entry)); 6772 } 6773 6774 /* Initialize modport map profiles ptr on port.*/ 6775 if (soc_feature(unit, soc_feature_modport_map_dest_is_port_or_trunk)) { 6776 BCM_IF_ERROR_RETURN 6777 (bcm_td_stk_modport_map_port_attach(unit, port)); 6778 } 6779 6780 return BCM_E_NONE; 6781 } 6782 6783 /* 6784 * Function: 6785 * bcmi_xgs5_port_attach_rate 6786 * Purpose: 6787 * Initialize port related information in the Rate module. 6788 * Parameters: 6789 * unit - (IN) Unit number. 6790 * port - (IN) Logical port. 6791 * Returns: 6792 * SOC_E_XXX 6793 */ 6794 int 6795 bcmi_xgs5_port_attach_rate(int unit, bcm_port_t port) 6796 { 6797 soc_field_t fields[] = {PACKET_QUANTUMf, BYTE_MODEf}; 6798 uint32 values[] = {0x100, 1}; 6799 6800 BCM_IF_ERROR_RETURN 6801 (WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0)); 6802 6803 BCM_IF_ERROR_RETURN 6804 (soc_reg_fields32_modify(unit, 6805 STORM_CONTROL_METER_CONFIGr, 6806 port, COUNTOF(fields), 6807 fields, values)); 6808 6809 return BCM_E_NONE; 6810 } 6811 6812 /* 6813 * Function: 6814 * bcmi_xgs5_port_attach_field 6815 * Purpose: 6816 * Enable filter lookup, ingress filter, egress filter on port 6817 * Parameters: 6818 * unit - (IN) Unit number. 6819 * port - (IN) Logical port. 6820 * Returns: 6821 * SOC_E_XXX 6822 */ 6823 int 6824 bcmi_xgs5_port_attach_field(int unit, bcm_port_t port) 6825 { 6826 #ifdef BCM_FIELD_SUPPORT 6827 /* FIELD */ 6828 if (soc_feature(unit, soc_feature_field)) { 6829 BCM_IF_ERROR_RETURN 6830 (bcm_esw_port_control_set(unit, port, 6831 bcmPortControlFilterLookup, 1)); 6832 BCM_IF_ERROR_RETURN 6833 (bcm_esw_port_control_set(unit, port, 6834 bcmPortControlFilterIngress, 1)); 6835 BCM_IF_ERROR_RETURN 6836 (bcm_esw_port_control_set(unit, port, 6837 bcmPortControlFilterEgress, 1)); 6838 } 6839 BCM_IF_ERROR_RETURN 6840 (_bcm_field_flex_port_attach(unit, port)); 6841 #endif /* BCM_FIELD_SUPPORT */ 6842 6843 return BCM_E_NONE; 6844 } 6845 6846 /* 6847 * Function: 6848 * bcmi_xgs5_port_attach_mirror 6849 * Purpose: 6850 * Initialize the mirror per-port configuration in the runtime 6851 * Parameters: 6852 * unit - (IN) Unit number. 6853 * port - (IN) Logical port. 6854 * Returns: 6855 * SOC_E_XXX 6856 */ 6857 int 6858 bcmi_xgs5_port_attach_mirror(int unit, bcm_port_t port) 6859 { 6860 /* MIRROR */ 6861 BCM_IF_ERROR_RETURN 6862 (bcmi_esw_mirror_port_attach(unit, port)); 6863 6864 return BCM_E_NONE; 6865 } 6866 6867 /* 6868 * Function: 6869 * bcmi_xgs5_port_attach_l3 6870 * Purpose: 6871 * Enable IPv4, IPv6 on port 6872 * Parameters: 6873 * unit - (IN) Unit number. 6874 * port - (IN) Logical port. 6875 * Returns: 6876 * SOC_E_XXX 6877 */ 6878 int 6879 bcmi_xgs5_port_attach_l3(int unit, bcm_port_t port) 6880 { 6881 #ifdef INCLUDE_L3 6882 /* L3 */ 6883 if (soc_feature(unit, soc_feature_l3) && 6884 soc_property_get(unit, spn_L3_ENABLE, 1) && 6885 !IS_ST_PORT(unit, port)) { 6886 6887 BCM_IF_ERROR_RETURN 6888 (bcm_esw_port_control_set(unit, port, bcmPortControlIP4, 1)); 6889 BCM_IF_ERROR_RETURN 6890 (bcm_esw_port_control_set(unit, port, bcmPortControlIP6, 1)); 6891 } 6892 #endif /* INCLUDE_L3 */ 6893 return BCM_E_NONE; 6894 } 6895 6896 /* 6897 * Function: 6898 * bcmi_xgs5_port_attach_ipmc 6899 * Purpose: 6900 * Initialize IPMC per-port configuration 6901 * Parameters: 6902 * unit - (IN) Unit number. 6903 * port - (IN) Logical port. 6904 * Returns: 6905 * SOC_E_XXX 6906 */ 6907 int 6908 bcmi_xgs5_port_attach_ipmc(int unit, bcm_port_t port) 6909 { 6910 #ifdef INCLUDE_L3 6911 soc_field_t fields_lport[3] = {V4IPMC_ENABLEf, V6IPMC_ENABLEf, IPMC_DO_VLANf}; 6912 uint32 field_values[3] = {1, 1, 1}; 6913 /* IPMC */ 6914 if (soc_feature(unit, soc_feature_ip_mcast)) { 6915 6916 int do_vlan = soc_property_get(unit, spn_IPMC_DO_VLAN, 1); 6917 6918 field_values[2] = (do_vlan) ? 1 : 0; 6919 6920 BCM_IF_ERROR_RETURN 6921 (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV4Enable, 1)); 6922 BCM_IF_ERROR_RETURN 6923 (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV6Enable, 1)); 6924 BCM_IF_ERROR_RETURN 6925 (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcVlanKey, 6926 do_vlan ? 1 : 0)); 6927 BCM_IF_ERROR_RETURN( 6928 bcm_esw_port_lport_fields_set(unit, port, LPORT_PROFILE_LPORT_TAB, 3, 6929 fields_lport, field_values)); 6930 6931 if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 6932 return BCM_E_NONE; 6933 } 6934 if (IS_E_PORT(unit,port)) { 6935 BCM_IF_ERROR_RETURN 6936 (bcm_esw_ipmc_egress_port_set(unit, port, _soc_mac_all_zeroes, 6937 0, 0, 0)); 6938 } 6939 } 6940 #endif /* INCLUDE_L3 */ 6941 return BCM_E_NONE; 6942 } 6943 6944 /* 6945 * Function: 6946 * bcmi_xgs5_port_attach_mpls 6947 * Purpose: 6948 * Enable MPLS on port. 6949 * Parameters: 6950 * unit - (IN) Unit number. 6951 * port - (IN) Logical port. 6952 * Returns: 6953 * SOC_E_XXX 6954 */ 6955 int 6956 bcmi_xgs5_port_attach_mpls(int unit, bcm_port_t port) 6957 { 6958 int rv = BCM_E_NONE; 6959 6960 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 6961 /* MPLS */ 6962 if (soc_feature(unit, soc_feature_mpls) && 6963 !IS_ST_PORT(unit, port)) { 6964 BCM_IF_ERROR_RETURN 6965 (bcm_esw_port_control_set(unit, port, bcmPortControlMpls, 1)); 6966 } 6967 #endif /* L3 && BCM_MPLS_SUPPORT */ 6968 return rv; 6969 } 6970 6971 /* 6972 * Function: 6973 * bcmi_xgs5_port_attach_mim 6974 * Purpose: 6975 * Enable MAC-in-MAC frame processing on port. 6976 * Parameters: 6977 * unit - (IN) Unit number. 6978 * port - (IN) Logical port. 6979 * Returns: 6980 * SOC_E_XXX 6981 */ 6982 int 6983 bcmi_xgs5_port_attach_mim(int unit, bcm_port_t port) 6984 { 6985 #ifdef INCLUDE_L3 6986 /* MIM */ 6987 if (soc_feature(unit, soc_feature_mim) && 6988 !IS_ST_PORT(unit, port)) { 6989 BCM_IF_ERROR_RETURN 6990 (bcm_esw_port_control_set(unit, port, bcmPortControlMacInMac, 1)); 6991 } 6992 #endif /* INCLUDE_L3 */ 6993 return BCM_E_NONE; 6994 } 6995 6996 /* 6997 * Function: 6998 * bcmi_xgs5_port_detach_dscp 6999 * Purpose: 7000 * Detach port from default DSCP profile 7001 * Parameters: 7002 * unit - (IN) Unit number. 7003 * port - (IN) Logical port. 7004 * Returns: 7005 * SOC_E_XXX 7006 */ 7007 int 7008 bcmi_xgs5_port_detach_dscp(int unit, bcm_port_t port) 7009 { 7010 int value; 7011 uint32 dscp_index; 7012 7013 BCM_IF_ERROR_RETURN 7014 (_bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf, &value)); 7015 dscp_index = value * 64; 7016 if (0 == dscp_index) { 7017 BCM_IF_ERROR_RETURN 7018 (_bcm_dscp_table_entry_delete(unit, dscp_index)); 7019 } 7020 7021 return BCM_E_NONE; 7022 } 7023 7024 /* 7025 * Function: 7026 * bcmi_xgs5_port_detach_port_info_init 7027 * Purpose: 7028 * Initialize BCM PORT info structure (bcm_port_info[unit][port]) 7029 * Parameters: 7030 * unit - (IN) Unit number. 7031 * port - (IN) Logical port. 7032 * Returns: 7033 * SOC_E_XXX 7034 */ 7035 int 7036 bcmi_xgs5_port_detach_software(int unit, bcm_port_t port) 7037 { 7038 _bcm_port_info_t *pinfo; 7039 int index; 7040 int enabled; 7041 uint32 value; 7042 7043 /* 7044 * Update TPID reference count 7045 */ 7046 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 7047 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 7048 if (soc_feature(unit, soc_feature_egr_all_profile)) { 7049 BCM_IF_ERROR_RETURN( 7050 bcm_esw_port_egr_lport_field_get( 7051 unit, port, EGR_VLAN_CONTROL_1m, 7052 OUTER_TPID_INDEXf, (uint32 *)&index)); 7053 } else { 7054 BCM_IF_ERROR_RETURN( 7055 READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &value)); 7056 index = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_1m, 7057 &value, OUTER_TPID_INDEXf); 7058 } 7059 } else { 7060 BCM_IF_ERROR_RETURN 7061 (READ_EGR_VLAN_CONTROL_1r(unit, port, &value)); 7062 index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 7063 value, OUTER_TPID_INDEXf); 7064 } 7065 7066 /* Ignore error when deleting */ 7067 (void)_bcm_fb2_outer_tpid_entry_delete(unit, index); 7068 7069 enabled = 0; 7070 BCM_IF_ERROR_RETURN 7071 (_bcm_esw_port_config_get(unit, port, 7072 _bcmPortOuterTpidEnables, &enabled)); 7073 index = 0; 7074 while (enabled) { 7075 if (enabled & 1) { 7076 /* Ignore error when deleting */ 7077 (void)_bcm_fb2_outer_tpid_entry_delete(unit, index); 7078 } 7079 enabled = enabled >> 1; 7080 index++; 7081 } 7082 } 7083 7084 /* Clear the Port INFO */ 7085 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 7086 if (pinfo == NULL) { 7087 return BCM_E_INIT; 7088 } 7089 7090 if (pinfo->p_vd_pbvl != NULL) { 7091 sal_free(pinfo->p_vd_pbvl); 7092 pinfo->p_vd_pbvl = NULL; 7093 } 7094 if (pinfo->e2ecc_config != NULL) { 7095 sal_free(pinfo->e2ecc_config); 7096 pinfo->e2ecc_config = NULL; 7097 } 7098 7099 sal_memset(pinfo, 0, sizeof(_bcm_port_info_t)); 7100 7101 7102 return BCM_E_NONE; 7103 } 7104 7105 /* 7106 * Function: 7107 * bcmi_xgs5_port_detach_egr_vlan_action 7108 * Purpose: 7109 * Set the egress port's default vlan tag actions 7110 * Parameters: 7111 * unit - (IN) Unit number. 7112 * port - (IN) Logical port. 7113 * Returns: 7114 * SOC_E_XXX 7115 */ 7116 int 7117 bcmi_xgs5_port_detach_egr_vlan_action(int unit, bcm_port_t port) 7118 { 7119 if (soc_feature(unit, soc_feature_vlan_action)) { 7120 BCM_IF_ERROR_RETURN 7121 (_bcm_trx_vlan_port_egress_default_action_delete(unit, port)); 7122 } 7123 return BCM_E_NONE; 7124 } 7125 7126 /* 7127 * Function: 7128 * bcmi_xgs5_port_detach_phy 7129 * Purpose: 7130 * Probe the PHY and set up the PHY and MAC for the specified ports. 7131 * This is purely a discovery routine and does no configuration. 7132 * Parameters: 7133 * unit - (IN) Unit number. 7134 * port - (IN) Logical port. 7135 * Returns: 7136 * SOC_E_XXX 7137 */ 7138 int 7139 bcmi_xgs5_port_detach_phy(int unit, bcm_port_t port) 7140 { 7141 int rv; 7142 soc_persist_t *sop = SOC_PERSIST(unit); 7143 7144 /* If PortMod enable, detach phy is handled in _bcmi_xgs5_port_pm_delete */ 7145 if (SOC_USE_PORTCTRL(unit)) { 7146 return BCM_E_NONE; 7147 } 7148 7149 BCM_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 7150 7151 PORT_LOCK(unit); 7152 rv = _bcm_port_mode_setup(unit, port, FALSE); 7153 PORT_UNLOCK(unit); 7154 BCM_IF_ERROR_RETURN(rv); 7155 7156 if (SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)) { 7157 /* Bring down the internal PHY */ 7158 BCM_IF_ERROR_RETURN(bcm_esw_port_update(unit, port, FALSE)); 7159 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port); 7160 } 7161 return BCM_E_NONE; 7162 } 7163 7164 /* 7165 * Function: 7166 * bcmi_xgs5_port_detach_vlan_protocol 7167 * Purpose: 7168 * Clear the VLAN_PROTOCOL_DATA_INDEX, FP_PORT_FIELD_SEL_INDEX, 7169 * PROTOCOL_PKT_INDEX pointers 7170 * Parameters: 7171 * unit - (IN) Unit number. 7172 * port - (IN) Logical port. 7173 * Returns: 7174 * SOC_E_XXX 7175 */ 7176 int 7177 bcmi_xgs5_port_detach_vlan_protocol(int unit, bcm_port_t port) 7178 { 7179 _bcm_port_info_t *pinfo; 7180 int value = 0; 7181 7182 /* Get PORT info structure pointer */ 7183 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 7184 if (pinfo == NULL) { 7185 return BCM_E_INTERNAL; 7186 } 7187 7188 if (!IS_LB_PORT(unit, port) && !IS_TDM_PORT(unit, port)) { 7189 7190 if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_NONE) { 7191 if (soc_mem_field_valid(unit, PORT_TABm, 7192 VLAN_PROTOCOL_DATA_INDEXf)) { 7193 BCM_IF_ERROR_RETURN( 7194 _bcm_esw_port_tab_set(unit, port, 7195 _BCM_CPU_TABS_ETHER, 7196 VLAN_PROTOCOL_DATA_INDEXf, 7197 0)); 7198 } 7199 } 7200 7201 if (soc_mem_field_valid(unit, PORT_TABm, 7202 FP_PORT_FIELD_SEL_INDEXf)) { 7203 BCM_IF_ERROR_RETURN( 7204 _bcm_esw_port_tab_set(unit, port, 7205 _BCM_CPU_TABS_ETHER, 7206 FP_PORT_FIELD_SEL_INDEXf, 0)); 7207 } 7208 if (soc_mem_field_valid(unit, PORT_TABm, 7209 PROTOCOL_PKT_INDEXf)) { 7210 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 7211 soc_portreg) { 7212 BCM_IF_ERROR_RETURN( 7213 _bcm_esw_port_tab_set(unit, port, 7214 _BCM_CPU_TABS_ETHER, 7215 PROTOCOL_PKT_INDEXf, 7216 0)); 7217 } else { 7218 BCM_IF_ERROR_RETURN 7219 (_bcm_esw_port_tab_get(unit, port, 7220 PROTOCOL_PKT_INDEXf, 7221 &value)); 7222 BCM_IF_ERROR_RETURN 7223 (_bcm_prot_pkt_ctrl_delete(unit, value)); 7224 BCM_IF_ERROR_RETURN 7225 (_bcm_esw_port_tab_set(unit, port, 7226 _BCM_CPU_TABS_ETHER, 7227 PROTOCOL_PKT_INDEXf, 7228 0)); 7229 } 7230 } 7231 } 7232 BCM_IF_ERROR_RETURN( 7233 _bcm_port_vlan_protocol_data_entry_delete(unit, pinfo->vlan_prot_ptr)); 7234 return BCM_E_NONE; 7235 } 7236 7237 /* 7238 * Function: 7239 * bcmi_xgs5_port_detach_eee 7240 * Purpose: 7241 * EEE config 7242 * Parameters: 7243 * unit - (IN) Unit number. 7244 * port - (IN) Logical port. 7245 * Returns: 7246 * SOC_E_XXX 7247 */ 7248 int 7249 bcmi_xgs5_port_detach_eee(int unit, bcm_port_t port) 7250 { 7251 if (!IS_LB_PORT(unit, port) && !IS_CPU_PORT (unit, port) && 7252 !IS_TDM_PORT(unit, port)) { 7253 BCM_IF_ERROR_RETURN 7254 (bcmi_esw_port_eee_cfg_set(unit, port, 0)); 7255 } 7256 7257 return BCM_E_NONE; 7258 } 7259 7260 /* 7261 * Function: 7262 * bcmi_xgs5_port_detach_higig 7263 * Purpose: 7264 * Remove port from hg2_pbm 7265 * Parameters: 7266 * unit - (IN) Unit number. 7267 * port - (IN) Logical port. 7268 * Returns: 7269 * SOC_E_XXX 7270 */ 7271 int 7272 bcmi_xgs5_port_detach_higig(int unit, bcm_port_t port) 7273 { 7274 /********** 7275 * HIGIG 7276 */ 7277 if (IS_HG_PORT(unit, port)) { 7278 if (SOC_USE_PORTCTRL(unit)) { 7279 BCM_IF_ERROR_RETURN 7280 (bcmi_esw_portctrl_higig_mode_set(unit, port, FALSE)); 7281 } 7282 #ifdef BCM_HIGIG2_SUPPORT 7283 /* soc_feature_higig2 */ 7284 if (soc_feature(unit, soc_feature_higig2)) { 7285 if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 7286 soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) || 7287 SOC_USE_PORTCTRL(unit)) { 7288 BCM_IF_ERROR_RETURN 7289 (_bcm_esw_port_higig2_mode_set(unit, port, FALSE)); 7290 SOC_HG2_ENABLED_PORT_REMOVE(unit, port); 7291 } 7292 } 7293 #endif /* BCM_HIGIG2_SUPPORT */ 7294 } 7295 7296 return BCM_E_NONE; 7297 } 7298 7299 /* 7300 * Function: 7301 * bcmi_xgs5_port_detach_egr_link_delay 7302 * Purpose: 7303 * Clear port link delay 7304 * Parameters: 7305 * unit - (IN) Unit number. 7306 * port - (IN) Logical port. 7307 * Returns: 7308 * SOC_E_XXX 7309 */ 7310 int 7311 bcmi_xgs5_port_detach_egr_link_delay(int unit, bcm_port_t port) 7312 { 7313 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 7314 BCM_IF_ERROR_RETURN 7315 (soc_reg_field32_modify(unit, EGR_1588_LINK_DELAYr, port, 7316 LINK_DELAYf, 0)); 7317 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 7318 BCM_IF_ERROR_RETURN 7319 (soc_reg_above_64_field32_modify(unit, EGR_1588_LINK_DELAY_64r, 7320 port, 0, LINK_DELAYf, 0)); 7321 } 7322 7323 return BCM_E_NONE; 7324 } 7325 7326 /* 7327 * Function: 7328 * bcmi_xgs5_port_detach_stg 7329 * Purpose: 7330 * Set STP state of port to DISABLE 7331 * Parameters: 7332 * unit - (IN) Unit number. 7333 * port - (IN) Logical port. 7334 * Returns: 7335 * SOC_E_XXX 7336 */ 7337 int 7338 bcmi_xgs5_port_detach_stg(int unit, bcm_port_t port) 7339 { 7340 /* STG */ 7341 BCM_IF_ERROR_RETURN 7342 (bcm_esw_vlan_stp_set(unit, BCM_VLAN_DEFAULT, port, BCM_STG_STP_DISABLE)); 7343 return BCM_E_NONE; 7344 } 7345 7346 /* 7347 * Function: 7348 * bcmi_xgs5_port_detach_vlan 7349 * Purpose: 7350 * Remove port from default vlan 1 7351 * Parameters: 7352 * unit - (IN) Unit number. 7353 * port - (IN) Logical port. 7354 * Returns: 7355 * SOC_E_XXX 7356 */ 7357 int 7358 bcmi_xgs5_port_detach_vlan(int unit, bcm_port_t port) 7359 { 7360 bcm_pbmp_t pbmp; 7361 7362 /* VLAN */ 7363 BCM_PBMP_CLEAR(pbmp); 7364 BCM_PBMP_PORT_ADD(pbmp, port); 7365 BCM_IF_ERROR_RETURN 7366 (bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbmp)); 7367 7368 return BCM_E_NONE; 7369 } 7370 7371 /* 7372 * Function: 7373 * bcmi_xgs5_port_detach_trunk 7374 * Purpose: 7375 * Update the trunk tables for a deleted port 7376 * Parameters: 7377 * unit - (IN) Unit number. 7378 * port - (IN) Logical port. 7379 * Returns: 7380 * SOC_E_XXX 7381 */ 7382 int 7383 bcmi_xgs5_port_detach_trunk(int unit, bcm_port_t port) 7384 { 7385 bcm_pbmp_t pbmp; 7386 higig_trunk_control_entry_t entry; 7387 int rv = BCM_E_NONE; 7388 7389 /* TRUNK */ 7390 if (soc_feature(unit, soc_feature_hg_trunking)) { 7391 7392 soc_mem_lock(unit, HIGIG_TRUNK_CONTROLm); 7393 7394 rv = soc_mem_read(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ANY, 0, &entry); 7395 if (BCM_FAILURE(rv)) { 7396 soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm); 7397 return rv; 7398 } 7399 7400 BCM_PBMP_CLEAR(pbmp); 7401 7402 /* Read port bmap from hardware, and remove new port to the bitmap */ 7403 soc_mem_pbmp_field_get(unit, HIGIG_TRUNK_CONTROLm, &entry, 7404 ACTIVE_PORT_BITMAPf, &pbmp); 7405 7406 BCM_PBMP_PORT_REMOVE(pbmp, port); 7407 7408 soc_mem_pbmp_field_set(unit, HIGIG_TRUNK_CONTROLm, &entry, 7409 ACTIVE_PORT_BITMAPf, &pbmp); 7410 7411 rv = soc_mem_write(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ALL, 0, 7412 &entry); 7413 7414 soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm); 7415 } 7416 return rv; 7417 } 7418 7419 /* 7420 * Function: 7421 * bcmi_xgs5_port_detach_stack 7422 * Purpose: 7423 * Clear port related information in the Stack module. 7424 * Parameters: 7425 * unit - (IN) Unit number. 7426 * port - (IN) Logical port. 7427 * Returns: 7428 * SOC_E_XXX 7429 */ 7430 int 7431 bcmi_xgs5_port_detach_stack(int unit, bcm_port_t port) 7432 { 7433 7434 /* Clear HG ingress CPU Opcode bitmap */ 7435 if (IS_ST_PORT(unit, port)) { 7436 pbmp_t pbmp; 7437 icontrol_opcode_bitmap_entry_t entry; 7438 7439 SOC_PBMP_CLEAR(pbmp); 7440 7441 BCM_IF_ERROR_RETURN 7442 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, 7443 &entry)); 7444 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 7445 BITMAPf, &pbmp); 7446 BCM_IF_ERROR_RETURN 7447 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, 7448 &entry)); 7449 } 7450 7451 /* detach port from modport map profiles */ 7452 if (soc_feature(unit, soc_feature_modport_map_dest_is_port_or_trunk)) { 7453 BCM_IF_ERROR_RETURN 7454 (bcm_td_stk_modport_map_port_detach(unit, port)); 7455 } 7456 7457 return BCM_E_NONE; 7458 } 7459 7460 /* 7461 * Function: 7462 * bcmi_xgs5_port_detach_rate 7463 * Purpose: 7464 * Clear port related information in the Rate module. 7465 * Parameters: 7466 * unit - (IN) Unit number. 7467 * port - (IN) Logical port. 7468 * Returns: 7469 * SOC_E_XXX 7470 */ 7471 int 7472 bcmi_xgs5_port_detach_rate(int unit, bcm_port_t port) 7473 { 7474 BCM_IF_ERROR_RETURN 7475 (WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0)); 7476 7477 return BCM_E_NONE; 7478 } 7479 7480 /* 7481 * Function: 7482 * bcmi_xgs5_port_detach_field 7483 * Purpose: 7484 * Disaable filter lookup, ingress filter, egress filter on port 7485 * Parameters: 7486 * unit - (IN) Unit number. 7487 * port - (IN) Logical port. 7488 * Returns: 7489 * SOC_E_XXX 7490 */ 7491 int 7492 bcmi_xgs5_port_detach_field(int unit, bcm_port_t port) 7493 { 7494 #ifdef BCM_FIELD_SUPPORT 7495 /* FIELD */ 7496 if (soc_feature(unit, soc_feature_field)) { 7497 BCM_IF_ERROR_RETURN 7498 (bcm_esw_port_control_set(unit, port, 7499 bcmPortControlFilterLookup, 0)); 7500 BCM_IF_ERROR_RETURN 7501 (bcm_esw_port_control_set(unit, port, 7502 bcmPortControlFilterIngress, 0)); 7503 BCM_IF_ERROR_RETURN 7504 (bcm_esw_port_control_set(unit, port, 7505 bcmPortControlFilterEgress, 0)); 7506 } 7507 BCM_IF_ERROR_RETURN 7508 (_bcm_field_flex_port_detach(unit, port)); 7509 #endif /* BCM_FIELD_SUPPORT */ 7510 7511 return BCM_E_NONE; 7512 } 7513 7514 /* 7515 * Function: 7516 * bcmi_xgs5_port_detach_mirror 7517 * Purpose: 7518 * Clear the mirror per-port configuration in the runtime 7519 * Parameters: 7520 * unit - (IN) Unit number. 7521 * port - (IN) Logical port. 7522 * Returns: 7523 * SOC_E_XXX 7524 */ 7525 int 7526 bcmi_xgs5_port_detach_mirror(int unit, bcm_port_t port) 7527 { 7528 /* MIRROR */ 7529 BCM_IF_ERROR_RETURN 7530 (bcmi_esw_mirror_port_detach(unit, port)); 7531 7532 return BCM_E_NONE; 7533 } 7534 7535 /* 7536 * Function: 7537 * bcmi_xgs5_port_detach_l3 7538 * Purpose: 7539 * Disable IPv4, IPv6 on port 7540 * Parameters: 7541 * unit - (IN) Unit number. 7542 * port - (IN) Logical port. 7543 * Returns: 7544 * SOC_E_XXX 7545 */ 7546 int 7547 bcmi_xgs5_port_detach_l3(int unit, bcm_port_t port) 7548 { 7549 #ifdef INCLUDE_L3 7550 /* L3 */ 7551 if (soc_feature(unit, soc_feature_l3) && 7552 soc_property_get(unit, spn_L3_ENABLE, 1) && 7553 !IS_ST_PORT(unit, port)) { 7554 7555 BCM_IF_ERROR_RETURN 7556 (bcm_esw_port_control_set(unit, port, bcmPortControlIP4, 0)); 7557 BCM_IF_ERROR_RETURN 7558 (bcm_esw_port_control_set(unit, port, bcmPortControlIP6, 0)); 7559 } 7560 #endif /* INCLUDE_L3 */ 7561 return BCM_E_NONE; 7562 } 7563 7564 /* 7565 * Function: 7566 * bcmi_xgs5_port_detach_ipmc 7567 * Purpose: 7568 * Clear IPMC per-port configuration 7569 * Parameters: 7570 * unit - (IN) Unit number. 7571 * port - (IN) Logical port. 7572 * Returns: 7573 * SOC_E_XXX 7574 */ 7575 int 7576 bcmi_xgs5_port_detach_ipmc(int unit, bcm_port_t port) 7577 { 7578 #ifdef INCLUDE_L3 7579 soc_field_t fields_lport[3] = {V4IPMC_ENABLEf, V6IPMC_ENABLEf, IPMC_DO_VLANf}; 7580 uint32 field_values[3] = {0, 0, 0}; 7581 /* IPMC */ 7582 if (soc_feature(unit, soc_feature_ip_mcast)) { 7583 7584 BCM_IF_ERROR_RETURN 7585 (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV4Enable, 0)); 7586 BCM_IF_ERROR_RETURN 7587 (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV6Enable, 0)); 7588 BCM_IF_ERROR_RETURN 7589 (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcVlanKey, 0)); 7590 7591 BCM_IF_ERROR_RETURN( 7592 bcm_esw_port_lport_fields_set(unit, port, LPORT_PROFILE_LPORT_TAB, 3, 7593 fields_lport, field_values)); 7594 if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 7595 return BCM_E_NONE; 7596 } 7597 if (IS_E_PORT(unit,port)) { 7598 BCM_IF_ERROR_RETURN 7599 (bcm_esw_ipmc_egress_port_set(unit, port, _soc_mac_all_zeroes, 7600 0, 0, 0)); 7601 } 7602 } 7603 #endif /* INCLUDE_L3 */ 7604 return BCM_E_NONE; 7605 } 7606 7607 /* 7608 * Function: 7609 * bcmi_xgs5_port_detach_mpls 7610 * Purpose: 7611 * Disable MPLS on port. 7612 * Parameters: 7613 * unit - (IN) Unit number. 7614 * port - (IN) Logical port. 7615 * Returns: 7616 * SOC_E_XXX 7617 */ 7618 int 7619 bcmi_xgs5_port_detach_mpls(int unit, bcm_port_t port) 7620 { 7621 int rv = BCM_E_NONE; 7622 7623 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 7624 /* MPLS */ 7625 if (soc_feature(unit, soc_feature_mpls) && 7626 !IS_ST_PORT(unit, port)) { 7627 BCM_IF_ERROR_RETURN 7628 (bcm_esw_port_control_set(unit, port, bcmPortControlMpls, 0)); 7629 } 7630 #endif /* L3 && BCM_MPLS_SUPPORT */ 7631 return rv; 7632 } 7633 7634 /* 7635 * Function: 7636 * bcmi_xgs5_port_detach_mim 7637 * Purpose: 7638 * Disable MAC-in-MAC frame processing on port. 7639 * Parameters: 7640 * unit - (IN) Unit number. 7641 * port - (IN) Logical port. 7642 * Returns: 7643 * SOC_E_XXX 7644 */ 7645 int 7646 bcmi_xgs5_port_detach_mim(int unit, bcm_port_t port) 7647 { 7648 #ifdef INCLUDE_L3 7649 /* MIM */ 7650 if (soc_feature(unit, soc_feature_mim) && 7651 !IS_ST_PORT(unit, port)) { 7652 BCM_IF_ERROR_RETURN 7653 (bcm_esw_port_control_set(unit, port, bcmPortControlMacInMac, 0)); 7654 } 7655 #endif /* INCLUDE_L3 */ 7656 return BCM_E_NONE; 7657 } 7658 7659 /* 7660 * Function: 7661 * bcmi_xgs5_port_sched_structure 7662 * Purpose: 7663 * Populate port_schedule_state 7664 * Parameters: 7665 * unit - (IN) Unit number. 7666 * nport - (IN) Number of elements in array port 7667 * port - (IN) Array of logical port. 7668 * post - (IN) Indicate populate out_port_map or not 7669 * 1: set out_port_map with post flex info; 7670 * 0: NOT set out_port_map 7671 * port_schedule_state - (OUT) port_schedule_state 7672 * Returns: 7673 * SOC_E_XXX 7674 */ 7675 STATIC int 7676 bcmi_xgs5_port_sched_structure(int unit, int nport, bcm_port_t *port, int post, 7677 soc_port_schedule_state_t *port_schedule_state) 7678 { 7679 soc_info_t *si = &SOC_INFO(unit); 7680 soc_port_resource_t *soc_resource; 7681 int logic_port, phy_port, encap; 7682 int i, rv = BCM_E_NONE; 7683 7684 soc_resource = sal_alloc(sizeof(soc_port_resource_t) * nport, 7685 "soc_port_resource"); 7686 if (soc_resource == NULL) { 7687 return BCM_E_MEMORY; 7688 } 7689 sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport); 7690 7691 for (i = 0; i< nport; i++) { 7692 logic_port = port[i]; 7693 phy_port = si->port_l2p_mapping[logic_port]; 7694 7695 rv = bcm_esw_port_encap_get(unit, logic_port, &encap); 7696 if (BCM_FAILURE(rv)) { 7697 break; 7698 } 7699 soc_resource[i].logical_port = logic_port; 7700 soc_resource[i].physical_port = phy_port; 7701 soc_resource[i].mmu_port = si->port_p2m_mapping[phy_port]; 7702 soc_resource[i].idb_port = si->port_l2i_mapping[logic_port]; 7703 soc_resource[i].pipe = si->port_pipe[logic_port]; 7704 soc_resource[i].speed = si->port_init_speed[logic_port]; 7705 soc_resource[i].encap = encap; 7706 soc_resource[i].num_lanes = si->port_num_lanes[logic_port]; 7707 soc_resource[i].oversub = 7708 SOC_PBMP_MEMBER(si->oversub_pbm, logic_port) ? 1 : 0; 7709 soc_resource[i].hsp = 7710 SOC_PBMP_MEMBER(si->eq_pbm, logic_port) ? 1 : 0; 7711 } 7712 7713 if (BCM_SUCCESS(rv)) { 7714 rv = _bcmi_xgs5_port_soc_schedule_state_init(unit, nport, 7715 BCMI_XGS5_PORT_RESOURCE_OP_ENABLE, 7716 soc_resource, 7717 port_schedule_state); 7718 } 7719 7720 if (BCM_SUCCESS(rv) && post) { 7721 rv = _bcmi_xgs5_port_info_post_flex(unit, port_schedule_state); 7722 } 7723 7724 sal_free(soc_resource); 7725 return rv; 7726 } 7727 7728 /* 7729 * Function: 7730 * bcmi_xgs5_port_enable_set 7731 * Purpose: 7732 * Enable or disable a port. 7733 * 7734 * To reuse the port up/down routines from DV for port enable/disable 7735 * Parameters: 7736 * unit - (IN) Unit number. 7737 * port - (IN) Logical BCM Port number (non-GPORT). 7738 * enable - (IN) Indicates whether to enable or disable port. 7739 * Returns: 7740 * BCM_E_XXX 7741 * Notes: 7742 * Must be called with PORT_LOCK held. 7743 * Must be called with PORTMOD enabled. 7744 */ 7745 int 7746 bcmi_xgs5_port_enable_set(int unit, bcm_port_t port, int enable) 7747 { 7748 soc_port_schedule_state_t *port_schedule_state; 7749 int rv; 7750 7751 /* Allocate memory for soc_port_schedule_state_t structure */ 7752 port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t), 7753 "port schedule state"); 7754 if (port_schedule_state == NULL) { 7755 return BCM_E_MEMORY; 7756 } 7757 sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t)); 7758 7759 rv = bcmi_xgs5_port_sched_structure(unit, 1, &port, 1, port_schedule_state); 7760 if (BCM_FAILURE(rv)) { 7761 sal_free(port_schedule_state); 7762 return rv; 7763 } 7764 7765 if (enable && BCMI_PORT_DRV_CALL(unit)->port_enable) { 7766 /* Port UP */ 7767 rv = BCMI_PORT_DRV_CALL(unit)->port_enable(unit, port_schedule_state); 7768 } else if ((!enable) && BCMI_PORT_DRV_CALL(unit)->port_disable) { 7769 /* Physical_port = -1 indicates bringing down a port */ 7770 port_schedule_state->resource[0].physical_port = -1; 7771 /* Port Down */ 7772 rv = BCMI_PORT_DRV_CALL(unit)->port_disable(unit, port_schedule_state); 7773 } else { 7774 rv = BCM_E_UNAVAIL; 7775 } 7776 7777 sal_free(port_schedule_state); 7778 return rv; 7779 } 7780 7781 /* 7782 * Function: 7783 * bcmi_xgs5_flexport_based_speed_ability_get 7784 * Purpose: 7785 * Retrieve the local port abilities. 7786 * Parameters: 7787 * unit - Unit. 7788 * port - Logical port number. 7789 * mask - (OUT) Mask of BCM_PORT_ABILITY_ values indicating the 7790 * supported speeds of the port. 7791 * Returns: 7792 * BCM_E_NONE 7793 * BCM_E_XXX 7794 */ 7795 int 7796 bcmi_xgs5_flexport_based_speed_ability_get(int unit, bcm_port_t port, 7797 bcm_port_abil_t *mask) 7798 { 7799 if (BCMI_PORT_DRV_CALL(unit)->speed_ability_get) { 7800 BCMI_PORT_DRV_CALL(unit)->speed_ability_get(unit, port, mask); 7801 } else { 7802 *mask = SOC_PA_ABILITY_ALL; 7803 } 7804 return BCM_E_NONE; 7805 } 7806 7807 /* 7808 * Function: 7809 * bcmi_xgs5_port_encap_speed_check 7810 * Purpose: 7811 * Restriction: Higig speed with IEEE encap mode is not supported. 7812 * Parameters: 7813 * unit - (IN) Unit number 7814 * port - (IN) Logical port number 7815 * encap - (IN) encap mode 7816 * speed - (IN) speed 7817 * Returns: 7818 * BCM_E_XXX 7819 */ 7820 int 7821 bcmi_xgs5_port_encap_speed_check(int unit, bcm_port_t port, int encap, 7822 int speed) 7823 { 7824 int is_hg_speed; 7825 uint32 speed_mask; 7826 7827 if (speed == 0) { 7828 BCM_IF_ERROR_RETURN 7829 (bcm_esw_port_speed_get(unit, port, &speed)); 7830 } 7831 7832 speed_mask = SOC_PA_SPEED(speed); 7833 is_hg_speed = SOC_PA_IS_HG_SPEED(speed_mask); 7834 7835 /* Expect non-higig speed for IEEE encapsulation mode. */ 7836 if (is_hg_speed && encap == BCM_PORT_ENCAP_IEEE) { 7837 LOG_ERROR(BSL_LS_BCM_PORT, 7838 (BSL_META_U(unit, 7839 "Speed and encapsulation configuration unmatch " 7840 "for port=%d, speed=%d, encap=%d\n"), 7841 port, speed, encap)); 7842 return BCM_E_PARAM; 7843 } 7844 7845 return BCM_E_NONE; 7846 } 7847 7848 /* 7849 * Function: 7850 * _bcmi_xgs5_port_redirect_config_set 7851 * Purpose: 7852 * Configure the redirection data 7853 * Parameters: 7854 * unit - (IN) device id. 7855 * port - (IN) Port number. 7856 * redirect_config - (IN) Pointer to the redirection config structure 7857 * Returns: 7858 * None 7859 */ 7860 int _bcmi_xgs5_port_redirect_config_set(int unit, bcm_port_t port, 7861 bcm_port_redirect_config_t *redirect_config) 7862 { 7863 bcm_trunk_t trunk_id = -1; 7864 bcm_module_t mod_id = -1; 7865 bcm_port_t port_id = -1; 7866 int id = -1, redirect_set = 1, color = -1; 7867 int curr_dest_type = 0; 7868 int dest_type = _BCM_REDIRECT_DEST_TYPE_NONE, dest_value = -1; 7869 int dest_type_flags = 0; 7870 egr_port_entry_t egr_port_entry; 7871 #if defined(BCM_EP_REDIRECT_VERSION_2) 7872 int redirect_action_value = 0, redirect_source_value = 0; 7873 int buffer_priority = 0; 7874 #endif 7875 7876 /* If the dest_type_field is invalid, this feature is not 7877 supported on this device */ 7878 if(PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type == INVALIDf) { 7879 return BCM_E_UNAVAIL; 7880 } 7881 7882 dest_type_flags = (redirect_config->flags & 7883 (BCM_PORT_REDIRECT_DESTINATION_PORT | 7884 BCM_PORT_REDIRECT_DESTINATION_TRUNK | 7885 BCM_PORT_REDIRECT_DESTINATION_MCAST)); 7886 7887 /* Make sure only one destination type is set */ 7888 if(dest_type_flags & (dest_type_flags - 1)) { 7889 return BCM_E_PARAM; 7890 } 7891 7892 /* Switch based on the destination type */ 7893 switch(dest_type_flags) { 7894 7895 case BCM_PORT_REDIRECT_DESTINATION_PORT: 7896 7897 /* Make sure that the supplied destination is valid */ 7898 if(!BCM_GPORT_IS_MODPORT(redirect_config->destination)) { 7899 return BCM_E_PORT; 7900 } 7901 7902 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, 7903 redirect_config->destination, 7904 &mod_id, &port_id, &trunk_id, &id)); 7905 7906 /* Set the destination type as GPP(Port) */ 7907 dest_type = _BCM_REDIRECT_DEST_TYPE_PORT; 7908 7909 /* Set the (Mod,Port) value as destination */ 7910 BCMI_MOD_PORT_SET(dest_value, mod_id, port_id); 7911 7912 break; 7913 7914 case BCM_PORT_REDIRECT_DESTINATION_TRUNK: 7915 7916 /* Make sure that the supplied destination is valid */ 7917 if(!BCM_GPORT_IS_SET(redirect_config->destination) || 7918 !BCM_GPORT_IS_TRUNK(redirect_config->destination)) { 7919 return BCM_E_PARAM; 7920 } 7921 7922 /* Get the trunk id */ 7923 trunk_id = BCM_GPORT_TRUNK_GET(redirect_config->destination); 7924 7925 /* Check that the trunk id is valid */ 7926 BCM_IF_ERROR_RETURN(_bcm_trunk_id_validate(unit, trunk_id)); 7927 7928 /* Set the destination type as GPP(Port) */ 7929 dest_type = _BCM_REDIRECT_DEST_TYPE_TRUNK; 7930 7931 /* Set the trunk id as the destiantion */ 7932 dest_value = trunk_id; 7933 7934 break; 7935 7936 case BCM_PORT_REDIRECT_DESTINATION_MCAST: 7937 7938 /* Check the destination and make suure it is a valid l2 MC */ 7939 if (_BCM_MULTICAST_IS_SET(redirect_config->destination)) { 7940 if (!_BCM_MULTICAST_IS_L2(redirect_config->destination)) { 7941 return (BCM_E_PARAM); 7942 } 7943 } 7944 7945 /* Set the destination type as GPP(Port) */ 7946 dest_type = _BCM_REDIRECT_DEST_TYPE_MCAST; 7947 7948 /* Set the l2 mc index as the destiantion */ 7949 dest_value = _BCM_MULTICAST_ID_GET(redirect_config->destination); 7950 7951 break; 7952 7953 default: 7954 7955 /* Reset the redirection flag */ 7956 redirect_set = 0; 7957 7958 /* Reset the destination type */ 7959 dest_type = _BCM_REDIRECT_DEST_TYPE_NONE; 7960 7961 /* Reset the destination */ 7962 dest_value = 0; 7963 7964 break; 7965 7966 } /* End switch */ 7967 7968 /* Resolve the gport we are setting the redirection properties on */ 7969 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 7970 &mod_id, &port_id, 7971 &trunk_id, &id)); 7972 7973 /* Get the egr port entry */ 7974 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 7975 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->mem, MEM_BLOCK_ANY, 7976 port_id, &egr_port_entry)); 7977 7978 /* Get the current dest_type */ 7979 curr_dest_type = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 7980 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type); 7981 7982 /* Change the dest-type and dest-value only for non-mtp destinations, 7983 this is because this gets setup in the 'mirror' module */ 7984 if(curr_dest_type != _BCM_REDIRECT_DEST_TYPE_MTP) { 7985 /* Setup the destination type and destination values */ 7986 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 7987 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type, 7988 dest_type); 7989 7990 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 7991 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_value, 7992 dest_value); 7993 } 7994 7995 /* Based on the redirection being set/cleared, set the drop_original flag, 7996 when rediretion is set, we will drop the original packet */ 7997 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 7998 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->drop_original, 7999 (redirect_set ? 1 : 0)); 8000 8001 /* Set the redirected packet color */ 8002 if(soc_feature(unit, soc_feature_ep_redirect_v2)) { 8003 /* If the redirection is being added, set the user provided 8004 color value, if it being disabled force the color to 0, 8005 which is a hardware default */ 8006 if (redirect_set) { 8007 /* Map the external color values to internal ones */ 8008 switch(redirect_config->color) { 8009 case bcmPortRedirectColorGreen: 8010 color = 0; 8011 break; 8012 case bcmPortRedirectColorYellow: 8013 color = 1; 8014 break; 8015 case bcmPortRedirectColorRed: 8016 color = 2; 8017 break; 8018 default: 8019 break; 8020 } 8021 8022 /* Set the color, if a valid value is supplied */ 8023 if (color != -1) { 8024 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8025 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color, color); 8026 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8027 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_color, 8028 1); 8029 } else { 8030 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8031 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_color, 8032 0); 8033 } 8034 } else { 8035 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8036 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color, 8037 0); 8038 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8039 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_color, 8040 0); 8041 } 8042 } else { 8043 /* For the older scheme, the color from enum maps directly */ 8044 if (redirect_set) { 8045 if(redirect_config->color < bcmPortRedirectColorNone) { 8046 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8047 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color, 8048 redirect_config->color); 8049 } 8050 } else { 8051 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8052 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color, 8053 0); 8054 } 8055 } 8056 8057 /* Set the redirected packet priority, if redirection is being disabled, set 8058 to hardware defaults */ 8059 if (redirect_set) { 8060 if(redirect_config->priority >= 0 && redirect_config->priority <= 15) { 8061 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8062 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_priority, 8063 redirect_config->priority); 8064 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8065 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_priority, 1); 8066 } else if (redirect_config->priority == -1){ 8067 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8068 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_priority, 0); 8069 } else { 8070 return BCM_E_PARAM; 8071 } 8072 } else { 8073 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8074 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_priority, 8075 0); 8076 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8077 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_priority, 0); 8078 } 8079 8080 #if defined(BCM_EP_REDIRECT_VERSION_2) 8081 /* For the newer feature, set the additionally supported fields */ 8082 if(soc_feature(unit, soc_feature_ep_redirect_v2)) { 8083 8084 /* Set the trigger strength, if disabling redirection set it to 8085 default */ 8086 if (redirect_set) { 8087 if((redirect_config->strength >= 0) && 8088 (redirect_config->strength < BCMI_MAX_STRENGTH_VALUE)) { 8089 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8090 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->strength, 8091 redirect_config->strength); 8092 } else { 8093 return BCM_E_NONE; 8094 } 8095 } else { 8096 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8097 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->strength, 8098 0); 8099 } 8100 8101 /* Set the buffer priority, if disabling redirection set it to 8102 default */ 8103 if (redirect_set) { 8104 if(redirect_config->buffer_priority & 8105 BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW) { 8106 buffer_priority = _BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW; 8107 } else if(redirect_config->buffer_priority & 8108 BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM) { 8109 buffer_priority = _BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM; 8110 } else if(redirect_config->buffer_priority & 8111 BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH) { 8112 buffer_priority = _BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH; 8113 } 8114 8115 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8116 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->buffer_priority, 8117 buffer_priority); 8118 } else { 8119 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8120 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->buffer_priority, 8121 0); 8122 } 8123 8124 /* Set the redirected packet action, based on the flag. If the 8125 redirection is being disabled, set it to default */ 8126 if (redirect_set) { 8127 if(redirect_config->flags & 8128 BCM_PORT_REDIRECT_DROPPED_PACKET) { 8129 redirect_action_value = _BCM_REDIRECT_IF_DROPPED; 8130 } else if(redirect_config->flags & 8131 BCM_PORT_REDIRECT_NOT_DROPPED_PACKET) { 8132 redirect_action_value = _BCM_REDIRECT_IF_NOT_DROPPED; 8133 } else { 8134 /* Default to always redirect */ 8135 redirect_action_value = _BCM_REDIRECT_ALWAYS; 8136 } 8137 8138 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8139 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->action, 8140 redirect_action_value); 8141 } else { 8142 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8143 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->action, 8144 0); 8145 } 8146 8147 /* Set the redirected packet source to use, based on the flags. 8148 If the redirection is being disabled, set it to default */ 8149 if (redirect_set) { 8150 if(redirect_config->flags & 8151 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION) { 8152 redirect_source_value = 8153 _BCM_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION; 8154 } else if(redirect_config->flags & 8155 _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE) { 8156 redirect_source_value = 8157 _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE; 8158 } else { 8159 /* Default it to original source */ 8160 redirect_source_value = 8161 _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE; 8162 } 8163 8164 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8165 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_source, 8166 redirect_source_value); 8167 } else { 8168 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8169 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_source, 8170 0); 8171 } 8172 8173 /* Set the truncate option, if user has chosen the same. If the 8174 redirection is being disabled, set it to default */ 8175 if (redirect_set) { 8176 if(redirect_config->flags & BCM_PORT_REDIRECT_TRUNCATE) { 8177 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8178 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_truncate, 8179 1); 8180 } 8181 } else { 8182 soc_EGR_PORTm_field32_set(unit, &egr_port_entry, 8183 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_truncate, 8184 0); 8185 } 8186 } /* soc_feature_ep_redirect_v2 */ 8187 #endif /* BCM_EP_REDIRECT_VERSION_2 */ 8188 8189 /* Write the entry to hardware */ 8190 BCM_IF_ERROR_RETURN(soc_mem_write(unit, EGR_PORTm, 8191 MEM_BLOCK_ALL, port_id, 8192 &egr_port_entry)); 8193 return BCM_E_NONE; 8194 } 8195 8196 8197 /* 8198 * Function: 8199 * bcmi_xgs5_port_redirect_config_set 8200 * Purpose: 8201 * Initialize the redirection config structure 8202 * Parameters: 8203 * unit - (IN) device id. 8204 * port - (IN) Port number. 8205 * redirect_config - (IN) Pointer to the redirection config structure 8206 * Returns: 8207 * None 8208 */ 8209 int bcmi_xgs5_port_redirect_config_set(int unit, bcm_gport_t port, 8210 bcm_port_redirect_config_t *redirect_config) 8211 { 8212 int local_port = -1, flags = 0; 8213 8214 /* Sanity check */ 8215 if(redirect_config == NULL) { 8216 return BCM_E_PARAM; 8217 } 8218 8219 /* Check the sanity of flags */ 8220 flags = redirect_config->flags; 8221 if((flags & BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE) && 8222 (flags & BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION)) { 8223 return BCM_E_PARAM; 8224 } 8225 8226 if((flags & BCM_PORT_REDIRECT_DROPPED_PACKET) && 8227 (flags & BCM_PORT_REDIRECT_NOT_DROPPED_PACKET)) { 8228 return BCM_E_PARAM; 8229 } 8230 8231 /* Check flags that are only applicable on the redirection 8232 2.0 */ 8233 if(!soc_feature(unit, soc_feature_ep_redirect_v2)) { 8234 if(flags & (BCM_PORT_REDIRECT_TRUNCATE | 8235 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE | 8236 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION | 8237 BCM_PORT_REDIRECT_DROPPED_PACKET | 8238 BCM_PORT_REDIRECT_NOT_DROPPED_PACKET | 8239 BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW | 8240 BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM | 8241 BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH)) { 8242 return BCM_E_PARAM; 8243 } 8244 } 8245 8246 /* Validate the port and extract the local_port */ 8247 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port)); 8248 8249 /* Set the data */ 8250 BCM_IF_ERROR_RETURN(_bcmi_xgs5_port_redirect_config_set(unit, 8251 port, redirect_config)); 8252 8253 return BCM_E_NONE; 8254 } 8255 8256 /* 8257 * Function: 8258 * _bcmi_xgs5_port_redirect_get 8259 * Purpose: 8260 * Configure the redirection data 8261 * Parameters: 8262 * unit - (IN) device id. 8263 * port - (IN) Port number. 8264 * redirect_config - (OUT) Pointer to the redirection config structure 8265 * Returns: 8266 * None 8267 */ 8268 int _bcmi_xgs5_port_redirect_get(int unit, bcm_port_t port, 8269 bcm_port_redirect_config_t *redirect_config) 8270 { 8271 int color = 0, mod_id = -1, port_id = -1; 8272 int dest_type, dest_value = -1; 8273 egr_port_entry_t egr_port_entry; 8274 #if defined(BCM_EP_REDIRECT_VERSION_2) 8275 int redirect_action_value = 0, redirect_source_value = 0; 8276 int buffer_priority = 0, truncate_flag = 0; 8277 #endif 8278 8279 /* If the dest_type_field is invalid, this feature is not 8280 supported on this device */ 8281 if (PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type == INVALIDf) { 8282 return BCM_E_UNAVAIL; 8283 } 8284 8285 /* Read the given egress port entry */ 8286 BCM_IF_ERROR_RETURN(soc_mem_read(unit, 8287 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->mem, MEM_BLOCK_ANY, 8288 port, &egr_port_entry)); 8289 8290 /* Zero out the outgoing struct */ 8291 sal_memset(redirect_config, 0, sizeof(bcm_port_redirect_config_t)); 8292 8293 /* Reset flags */ 8294 redirect_config->flags = 0; 8295 redirect_config->buffer_priority = 0; 8296 8297 /* Get the dest_type and dest values */ 8298 dest_type = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 8299 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type); 8300 dest_value = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 8301 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_value); 8302 8303 /* Switch based on the destination type */ 8304 switch(dest_type) { 8305 8306 case _BCM_REDIRECT_DEST_TYPE_PORT: 8307 8308 /* Extract the (Mod,Port) value from destination */ 8309 BCMI_MOD_PORT_MODID_GET(dest_value, mod_id); 8310 BCMI_MOD_PORT_PORTID_GET(dest_value, port_id); 8311 8312 BCM_GPORT_MODPORT_SET(redirect_config->destination, 8313 mod_id, port_id); 8314 redirect_config->flags |= BCM_PORT_REDIRECT_DESTINATION_PORT; 8315 8316 break; 8317 8318 case _BCM_REDIRECT_DEST_TYPE_TRUNK: 8319 8320 /* Put together a trunk gport and set the type */ 8321 BCM_GPORT_TRUNK_SET(redirect_config->destination, dest_value); 8322 redirect_config->flags |= BCM_PORT_REDIRECT_DESTINATION_TRUNK; 8323 8324 break; 8325 8326 case _BCM_REDIRECT_DEST_TYPE_MCAST: 8327 8328 /* Put together a trunk gport and set the type */ 8329 _BCM_MULTICAST_GROUP_SET(redirect_config->destination, 8330 _BCM_MULTICAST_TYPE_L2, 8331 redirect_config->destination); 8332 redirect_config->flags |= BCM_PORT_REDIRECT_DESTINATION_MCAST; 8333 8334 break; 8335 8336 default: 8337 8338 /* Reset the destination type */ 8339 dest_type = _BCM_REDIRECT_DEST_TYPE_NONE; 8340 8341 /* Reset the destination */ 8342 dest_value = 0; 8343 8344 break; 8345 8346 } /* End switch */ 8347 8348 /* Get the redirected packet color */ 8349 color = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 8350 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color); 8351 8352 #if defined(BCM_EP_REDIRECT_VERSION_2) 8353 /* Map the internal color values to external ones */ 8354 if(soc_feature(unit, soc_feature_ep_redirect_v2)) { 8355 switch(color) { 8356 case 0: 8357 redirect_config->color = bcmPortRedirectColorGreen; 8358 break; 8359 case 1: 8360 redirect_config->color = bcmPortRedirectColorYellow; 8361 break; 8362 case 2: 8363 redirect_config->color = bcmPortRedirectColorRed; 8364 break; 8365 default: 8366 break; 8367 } 8368 } else { 8369 #endif 8370 switch(color) { 8371 case 0: 8372 redirect_config->color = bcmPortRedirectColorNone; 8373 break; 8374 case 1: 8375 redirect_config->color = bcmPortRedirectColorGreen; 8376 break; 8377 case 2: 8378 redirect_config->color = bcmPortRedirectColorYellow; 8379 break; 8380 case 3: 8381 redirect_config->color = bcmPortRedirectColorRed; 8382 break; 8383 8384 default: 8385 break; 8386 } 8387 #if defined(BCM_EP_REDIRECT_VERSION_2) 8388 } 8389 #endif 8390 8391 /* Get the redirected packet priority */ 8392 redirect_config->priority = soc_EGR_PORTm_field32_get(unit, 8393 &egr_port_entry, 8394 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_priority); 8395 8396 #if defined(BCM_EP_REDIRECT_VERSION_2) 8397 /* For the newer redirection, get the additionally supported fields */ 8398 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 8399 8400 /* Get the redirected packet strength */ 8401 redirect_config->strength = soc_EGR_PORTm_field32_get(unit, 8402 &egr_port_entry, 8403 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->strength); 8404 8405 /* Get the redirected packet buffer priority */ 8406 buffer_priority = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 8407 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->buffer_priority); 8408 8409 if (buffer_priority == 8410 _BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW) { 8411 redirect_config->buffer_priority |= 8412 BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW; 8413 } else if(buffer_priority == 8414 _BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM) { 8415 redirect_config->buffer_priority |= 8416 BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM; 8417 } else if(buffer_priority == 8418 _BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH) { 8419 redirect_config->buffer_priority |= 8420 BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH; 8421 } 8422 8423 /* Get the redirection action value */ 8424 redirect_action_value = soc_EGR_PORTm_field32_get(unit, 8425 &egr_port_entry, 8426 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->action); 8427 8428 /* Set the redirected packet action, based on the flags */ 8429 if(redirect_action_value == _BCM_REDIRECT_IF_DROPPED) { 8430 redirect_config->flags |= BCM_PORT_REDIRECT_DROPPED_PACKET; 8431 } else if(redirect_action_value == 8432 _BCM_REDIRECT_IF_NOT_DROPPED) { 8433 redirect_config->flags |= BCM_PORT_REDIRECT_NOT_DROPPED_PACKET; 8434 } 8435 8436 /* Get the redirection source value */ 8437 redirect_source_value = soc_EGR_PORTm_field32_get(unit, 8438 &egr_port_entry, 8439 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_source); 8440 8441 /* Get the redirected packet source to use and update flags */ 8442 if(redirect_source_value == 8443 _BCM_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION) { 8444 redirect_config->flags |= 8445 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION; 8446 } else if(redirect_source_value == 8447 _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE) { 8448 redirect_config->flags |= 8449 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE; 8450 } 8451 8452 /* Set the redirected packet truncate flag, if it is set */ 8453 truncate_flag = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 8454 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_truncate); 8455 if(truncate_flag) { 8456 redirect_config->flags |= BCM_PORT_REDIRECT_TRUNCATE; 8457 } 8458 } 8459 8460 #endif 8461 8462 return BCM_E_NONE; 8463 } 8464 8465 /* 8466 * Function: 8467 * bcmi_xgs5_port_redirect_config_get 8468 * Purpose: 8469 * Get the redirection config data 8470 * Parameters: 8471 * unit - (IN) device id. 8472 * port - (IN) Port number. 8473 * redirect_config - (OUT) Pointer to the redirection config structure 8474 * Returns: 8475 * None 8476 */ 8477 int bcmi_xgs5_port_redirect_config_get(int unit, bcm_gport_t port, 8478 bcm_port_redirect_config_t *redirect_config) 8479 { 8480 int local_port = -1; 8481 8482 /* Sanity check */ 8483 if(redirect_config == NULL) { 8484 return BCM_E_PARAM; 8485 } 8486 8487 /* Validate the port and extract the local_port */ 8488 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, 8489 port, 8490 &local_port)); 8491 8492 /* Get the data */ 8493 BCM_IF_ERROR_RETURN(_bcmi_xgs5_port_redirect_get(unit, 8494 local_port, 8495 redirect_config)); 8496 8497 return BCM_E_NONE; 8498 } 8499 8500 /* 8501 * Function: 8502 * bcmi_xgs5_port_force_lb_set 8503 * Purpose: 8504 * Force port into internal loopback accroding to bond options. 8505 * Parameters: 8506 * unit - (IN) Unit number. 8507 * Returns: 8508 * BCM_E_XXX 8509 * Notes: 8510 */ 8511 int 8512 bcmi_xgs5_port_force_lb_set(int unit) 8513 { 8514 soc_info_t *si; 8515 int port, phy_port; 8516 8517 si = &SOC_INFO(unit); 8518 8519 PBMP_PORT_ITER(unit, port) { 8520 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) || 8521 IS_MANAGEMENT_PORT(unit,port)) { 8522 continue; 8523 } 8524 phy_port = si->port_l2p_mapping[port]; 8525 if (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).force_lb) { 8526 BCM_IF_ERROR_RETURN 8527 (bcm_esw_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_PHY)); 8528 } 8529 } 8530 8531 return BCM_E_NONE; 8532 } 8533 8534 /* 8535 * Function: 8536 * bcmi_xgs5_port_force_lb_check 8537 * Purpose: 8538 * Check if port should be forced into internal loopback. 8539 * Parameters: 8540 * unit - (IN) Unit number. 8541 * port - (IN) Logical port, BCM format. 8542 * loopback - (IN) one of: 8543 * BCM_PORT_LOOPBACK_NONE 8544 * BCM_PORT_LOOPBACK_MAC 8545 * BCM_PORT_LOOPBACK_PHY 8546 * Returns: 8547 * BCM_E_XXX 8548 * Notes: 8549 */ 8550 int 8551 bcmi_xgs5_port_force_lb_check(int unit, int port, int loopback) 8552 { 8553 soc_info_t *si; 8554 int phy_port, local_port, phy_lane, phyn, sys_side; 8555 8556 si = &SOC_INFO(unit); 8557 local_port = -1; 8558 8559 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 8560 &local_port, &phyn, &phy_lane, &sys_side)); 8561 8562 if (local_port == -1) { 8563 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 8564 } else { 8565 port = local_port; 8566 } 8567 8568 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) || 8569 IS_MANAGEMENT_PORT(unit,port)) { 8570 return BCM_E_NONE; 8571 } 8572 8573 phy_port = si->port_l2p_mapping[port]; 8574 if (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).force_lb && 8575 loopback != BCM_PORT_LOOPBACK_PHY) { 8576 return BCM_E_PARAM; 8577 } 8578 8579 return BCM_E_NONE; 8580 } 8581 8582 /* 8583 * Function: 8584 * bcmi_xgs5_port_resource_status_update 8585 * Purpose: 8586 * Update the port resource status to depedent modules after 8587 * flex operation. 8588 * Parameters: 8589 * unit - (IN) Unit number. 8590 * nport - (IN) Number of elements in array resource. 8591 * resource - (IN) Port resource configuration array. 8592 * Returns: 8593 * BCM_E_XXX 8594 * Note: 8595 * - Assumes caller has lock. 8596 * - This is to be called by the API dispatch driver. 8597 * - Should be invoked from resource_multi_set() routine 8598 * after completion of flex operation. 8599 */ 8600 int 8601 bcmi_xgs5_port_resource_status_update(int unit, 8602 int nport, 8603 bcm_port_resource_t *resource) 8604 { 8605 int i; 8606 bcm_pbmp_t detached_pbmp; 8607 bcm_pbmp_t attached_pbmp; 8608 bcm_port_t local_port; 8609 8610 if (resource == NULL) { 8611 return BCM_E_PARAM; 8612 } 8613 8614 BCM_PBMP_CLEAR(detached_pbmp); 8615 BCM_PBMP_CLEAR(attached_pbmp); 8616 for (i = 0; i < nport; i++) { 8617 /* Check that logical port number is addressable and convert */ 8618 BCM_IF_ERROR_RETURN 8619 (bcmi_xgs5_port_addressable_local_get(unit, 8620 resource[i].port, 8621 &local_port)); 8622 if (resource[i].physical_port == -1) { 8623 BCM_PBMP_PORT_ADD(detached_pbmp, local_port); 8624 } else { 8625 BCM_PBMP_PORT_ADD(attached_pbmp, local_port); 8626 } 8627 } 8628 8629 /* Update SDK field module about the detached and attached ports to the device. */ 8630 return _bcm_field_flex_port_update(unit, detached_pbmp, attached_pbmp); 8631 } 8632 8633 /* Debug functions for Flexport */ 8634 8635 /* 8636 * Function: 8637 * bcmi_xgs5_num_tsc 8638 * Purpose: 8639 * Get number of TSC in the device, not include management TSC 8640 * Parameters: 8641 * unit - (IN) Unit number. 8642 * num - (OUT) NUmber of TSC 8643 * Returns: 8644 * SOC_E_XXX 8645 */ 8646 int 8647 bcmi_xgs5_num_tsc(int unit, int *num) 8648 { 8649 if (BCMI_PORT_DRV(unit) == NULL) { 8650 return BCM_E_UNAVAIL; 8651 } 8652 8653 if (num == NULL) { 8654 return BCM_E_PARAM; 8655 } 8656 8657 *num = BCMI_PORT_DRV_DEV_INFO(unit)->num_tsc; 8658 8659 return SOC_E_NONE; 8660 } 8661 8662 /* 8663 * Function: 8664 * bcmi_xgs5_phy_to_pipe 8665 * Purpose: 8666 * Get pipe from the physical port 8667 * Parameters: 8668 * unit - (IN) Unit number. 8669 * phy_port- (IN) Physical port 8670 * pipe - (OUT) Pipe 8671 * Returns: 8672 * SOC_E_XXX 8673 */ 8674 int 8675 bcmi_xgs5_phy_to_pipe(int unit, int phy_port, int *pipe) 8676 { 8677 if (BCMI_PORT_DRV(unit) == NULL) { 8678 return BCM_E_UNAVAIL; 8679 } 8680 8681 if (pipe == NULL) { 8682 return BCM_E_PARAM; 8683 } 8684 8685 *pipe = BCMI_PORT_DRV_PHY_INFO(unit, phy_port).pipe; 8686 8687 return SOC_E_NONE; 8688 } 8689 8690 /* 8691 * Function: 8692 * bcmi_xgs5_port_range 8693 * Purpose: 8694 * Get logical port range in a pipe 8695 * Parameters: 8696 * unit - (IN) Unit number. 8697 * pipe - (IN) Pipe 8698 * port_start - (OUT) First logical port of the pipe 8699 * port_end - (OUT) Last logical port of the pipe 8700 * Returns: 8701 * SOC_E_XXX 8702 */ 8703 int 8704 bcmi_xgs5_port_range(int unit, int pipe, int *port_start, int *port_end) 8705 { 8706 bcmi_xgs5_dev_info_t *dev_info; 8707 8708 if (BCMI_PORT_DRV(unit) == NULL) { 8709 return BCM_E_UNAVAIL; 8710 } 8711 8712 if ((port_start == NULL) || (port_end == NULL)) { 8713 return BCM_E_PARAM; 8714 } 8715 8716 dev_info = BCMI_PORT_DRV_DEV_INFO(unit); 8717 if (dev_info->pipe_bound) { 8718 *port_start = dev_info->pipe_log_port_base[pipe]; 8719 *port_end = *port_start + dev_info->ports_pipe_max[pipe] - 1; 8720 } else { 8721 *port_start = 0; 8722 *port_end = dev_info->ports_pipe_max[dev_info->num_pipe - 1] - 1; 8723 } 8724 8725 return SOC_E_NONE; 8726 } 8727 8728 /* 8729 * Function: 8730 * bcmi_xgs5_speed_to_lanes 8731 * Purpose: 8732 * Get number of lanes based on ports speed in a PM. 8733 * If a speed have multiple lane mode (eg, 2-lane 40G and 4-lane 40G), 8734 * select as much lanes as possible. 8735 * Example: 8736 * PM need to be configured as 1x40G+2x10G 8737 * Input speed[] = {40000, 0, 10000, 10000} 8738 * Output lanes[] = {2, 0, 1, 1} 8739 * Parameters: 8740 * unit - (IN) Unit number. 8741 * lane_max - (IN) Max lanes in the PM 8742 * speed - (IN) Port speed array in the PM 8743 * lanes - (OUT) Lanes array in the PM 8744 * Returns: 8745 * SOC_E_XXX 8746 */ 8747 int 8748 bcmi_xgs5_speed_to_lanes(int unit, int lane_max, int *speed, int *lanes) 8749 { 8750 int i, j; 8751 int speed_mask[SOC_PORT_RESOURCE_LANES_MAX]; 8752 int port_lanes[SOC_PORT_RESOURCE_LANES_MAX] = {0}; 8753 bcmi_xgs5_dev_info_t *dev_info; 8754 8755 if (BCMI_PORT_DRV(unit) == NULL) { 8756 return BCM_E_UNAVAIL; 8757 } 8758 8759 if ((speed == NULL) || (lanes == NULL)) { 8760 return BCM_E_PARAM; 8761 } 8762 8763 dev_info = BCMI_PORT_DRV_DEV_INFO(unit); 8764 8765 /* calculate max lanes of each port */ 8766 for (i = 0, j = 0; i < lane_max; i ++) { 8767 speed_mask[i] = SOC_PA_SPEED(speed[i]); 8768 if (speed_mask[i] != 0) { 8769 j = i; 8770 } 8771 port_lanes[j] ++; 8772 } 8773 8774 /* select max lanes of a speed */ 8775 for (i = 0; i < lane_max; i ++) { 8776 if (port_lanes[i] > 0) { 8777 for (j = port_lanes[i]; j > 0; j --) { 8778 if (dev_info->speed_valid[j] & speed_mask[i]) { 8779 lanes[i] = j; 8780 break; 8781 } 8782 } 8783 if (j == 0) { 8784 return SOC_E_PARAM; 8785 } 8786 } else { 8787 lanes[i] = 0; 8788 } 8789 } 8790 8791 return SOC_E_NONE; 8792 } 8793 8794 /* End of debug functions for Flexport */ 8795 8796 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */