phy543xx.c (91279B)
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 8 /* 9 * File: phy54380.c 10 * Purpose: PHY driver for BCM54380 (MACSec) 11 * 12 * Supported BCM546X Family of PHY devices: 13 * 14 * Device Ports Media MAC Interface 15 * 54380 8 Copper(no Fiber) SGMII 16 * 54382 8 Copper(no Fiber) 2 QSGMII 17 * 54340 4 Copper/Fiber 4 SGMII 18 * 54385 8 Copper/Fiber 2 QSGMII 19 20 * Workarounds: 21 * 22 * 23 * Notes: 24 */ 25 26 27 28 #include <sal/types.h> 29 #include <sal/core/spl.h> 30 #include <shared/bsl.h> 31 #include <soc/drv.h> 32 #include <soc/debug.h> 33 #include <soc/error.h> 34 #include <soc/phyreg.h> 35 36 #include <soc/phy.h> 37 #include <soc/phy/phyctrl.h> 38 #include <soc/phy/drv.h> 39 40 #include "phydefs.h" /* Must include before other phy related includes */ 41 42 43 44 #ifdef INCLUDE_MACSEC 45 #if defined(INCLUDE_PHY_54380) 46 #include "phyconfig.h" /* Must be the first phy include after phydefs.h */ 47 #include "phyident.h" 48 #include "phyreg.h" 49 #include "phyfege.h" 50 #include "phy543xx.h" 51 #include <soc/macsecphy.h> 52 53 #define DISABLE_CLK125 0 /* Disable if unused to reduce */ 54 /* EMI emissions */ 55 56 57 static bmacsec_error_t error_tbl[] = { 58 SOC_E_NONE, 59 SOC_E_INTERNAL, 60 SOC_E_MEMORY, 61 SOC_E_PARAM, 62 SOC_E_EMPTY, 63 SOC_E_FULL, 64 SOC_E_NOT_FOUND, 65 SOC_E_EXISTS, 66 SOC_E_TIMEOUT, 67 SOC_E_FAIL, 68 SOC_E_DISABLED, 69 SOC_E_BADID, 70 SOC_E_RESOURCE, 71 SOC_E_CONFIG, 72 SOC_E_UNAVAIL, 73 SOC_E_INIT, 74 SOC_E_PORT, 75 }; 76 /* 77 * Convert BMACSEC return codes to SOC return code. 78 */ 79 #define SOC_ERROR(e) error_tbl[(-e)] 80 81 82 #define MACSEC_READ_PHY_REG(_unit, _pc, _mdio, _reg, _value) \ 83 ((_pc->read)((_unit), (_mdio), (_reg), (_value))) 84 #define MACSEC_WRITE_PHY_REG(_unit, _pc, _mdio, _reg, _value) \ 85 ((_pc->write)((_unit), (_mdio), (_reg), (_value))) 86 87 /*Copper*/ 88 #define ADVERT_ALL_COPPER_FLOW_CTRL (_SHR_PA_PAUSE_TX | _SHR_PA_PAUSE_RX) 89 #define ADVERT_ALL_COPPER_HD_SPEED (_SHR_PA_SPEED_10MB | _SHR_PA_SPEED_100MB | _SHR_PA_SPEED_1000MB) 90 #define ADVERT_ALL_COPPER_FD_SPEED (_SHR_PA_SPEED_10MB | _SHR_PA_SPEED_100MB | _SHR_PA_SPEED_1000MB) 91 92 /*Fiber*/ 93 #define ADVERT_ALL_FIBER_FLOW_CTRL (_SHR_PA_PAUSE_TX | _SHR_PA_PAUSE_RX) 94 #define ADVERT_ALL_FIBER_FD_SPEED (_SHR_PA_SPEED_100MB | _SHR_PA_SPEED_1000MB) 95 96 97 #define SET_FLOW_CTRL_ABILITY(ability, p) ((ability)->pause |= p) 98 #define SET_HD_SPEED_ABILITY(ability, s) ((ability)->speed_half_duplex |= s) 99 #define SET_FD_SPEED_ABILITY(ability, s) ((ability)->speed_full_duplex |= s) 100 101 #define ADVERT_ALL_COPPER(ability) {\ 102 SET_FLOW_CTRL_ABILITY(ability, ADVERT_ALL_COPPER_FLOW_CTRL);\ 103 SET_HD_SPEED_ABILITY(ability, ADVERT_ALL_COPPER_HD_SPEED);\ 104 SET_FD_SPEED_ABILITY(ability, ADVERT_ALL_COPPER_FD_SPEED);\ 105 } 106 107 #define ADVERT_ALL_FIBER(ability) {\ 108 SET_FLOW_CTRL_ABILITY(ability, ADVERT_ALL_FIBER_FLOW_CTRL);\ 109 SET_FD_SPEED_ABILITY(ability, ADVERT_ALL_FIBER_FD_SPEED);\ 110 } 111 112 #define PHY_IS_BCM54380(_pc) (PHY_MODEL_CHECK((_pc), \ 113 PHY_BCM54380_OUI, \ 114 PHY_BCM54380_MODEL)) 115 116 #define PHY_IS_BCM54382(_pc) (PHY_MODEL_CHECK((_pc), \ 117 PHY_BCM54382_OUI, \ 118 PHY_BCM54382_MODEL) \ 119 && (((_pc)->phy_rev & 0x8))) 120 121 #define PHY_IS_BCM54340(_pc) (PHY_MODEL_CHECK((_pc), \ 122 PHY_BCM54340_OUI, \ 123 PHY_BCM54340_MODEL)) 124 125 #define PHY_IS_BCM54385(_pc) (PHY_MODEL_CHECK((_pc), \ 126 PHY_BCM54385_OUI, \ 127 PHY_BCM54385_MODEL) \ 128 && (!((_pc)->phy_rev & 0x8))) 129 130 #define PHY_IS_BCM54385_B0(_pc) ((PHY_MODEL_CHECK((_pc), \ 131 PHY_BCM54385_OUI, \ 132 PHY_BCM54385_MODEL))\ 133 && ((_pc)->phy_rev == 0x1)) 134 135 #define PHY_BCM54385_B0_REV (0x1) 136 #define PHY_BCM54385_C0_REV (0x2) 137 138 /* 139 Flag(s) to specify config options to mac 140 It should eventually be moved to mac_ctrl.h. 141 */ 142 #define MAC_CTRL_FLAG_MACSEC_FIX_LATENCY_EN (1<<0) 143 144 145 STATIC int _phy_54380_medium_change(int unit, soc_port_t port, 146 int force_update, soc_port_medium_t force_medium); 147 STATIC int phy_54380_duplex_set(int unit, soc_port_t port, int duplex); 148 STATIC int phy_54380_speed_set(int unit, soc_port_t port, int speed); 149 STATIC int phy_54380_master_set(int unit, soc_port_t port, int master); 150 151 #if 0 152 153 STATIC int phy_54380_adv_local_set(int unit, soc_port_t port,i 154 /*soc_port_mode_t mode*/soc_port_ability_t ability); 155 156 #endif 157 158 STATIC int phy_54380_autoneg_get(int unit, soc_port_t port, 159 int *autoneg, int *autoneg_done); 160 STATIC int phy_54380_autoneg_set(int unit, soc_port_t port, int autoneg); 161 STATIC int phy_54380_mdix_set(int unit, soc_port_t port, soc_port_mdix_t mode); 162 STATIC int phy_54380_speed_get(int unit, soc_port_t port, int *speed); 163 STATIC int phy_54380_ability_advert_set(int unit, soc_port_t port, soc_port_ability_t *ability); 164 extern int 165 phy_ecd_cable_diag_init_40nm(int unit, soc_port_t port); 166 extern int 167 phy_ecd_cable_diag_40nm(int unit, soc_port_t port, 168 soc_port_cable_diag_t *status, uint16 ecd_ctrl); 169 170 extern int 171 bmacsec_phy54380_macsec_enable(int phy_id, bmacsec_dev_addr_t bmacsec_addr, int macsec_enable); 172 173 /*********************************************************************** 174 * 175 * HELPER FUNCTIONS 176 */ 177 /* 178 * Function: 179 * _phy_54380_medium_check 180 * Purpose: 181 * Determine if chip should operate in copper or fiber mode. 182 * Parameters: 183 * unit - StrataSwitch unit #. 184 * port - StrataSwitch port #. 185 * medium - (OUT) SOC_PORT_MEDIUM_XXX 186 * Returns: 187 * SOC_E_XXX 188 */ 189 STATIC int 190 _phy_54380_medium_check(int unit, soc_port_t port, int *medium) 191 { 192 193 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 194 bmacsec_dev_addr_t phy_dev_addr; 195 bmacsec_phy_port_medium_t bmacsec_port_medium; 196 197 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 198 199 *medium = SOC_PORT_MEDIUM_COPPER; 200 201 if (pc->automedium) { 202 203 bmacsec_phy54380_medium_get(phy_dev_addr, 204 pc->fiber.preferred, 205 &bmacsec_port_medium); 206 207 if (bmacsec_port_medium == BMACSEC_PHY_MEDIUM_COPPER) { 208 *medium = SOC_PORT_MEDIUM_COPPER; 209 } else { 210 *medium = SOC_PORT_MEDIUM_FIBER; 211 } 212 } else { 213 *medium = pc->fiber.preferred ? SOC_PORT_MEDIUM_FIBER: 214 SOC_PORT_MEDIUM_COPPER; 215 } 216 217 LOG_VERBOSE(BSL_LS_SOC_PHY, 218 (BSL_META_U(unit, 219 "_phy_54380_medium_check: " 220 "u=%d p=%d fiber_pref=%d fiber=%d\n"), 221 unit, port, pc->fiber.preferred, 222 (*medium == SOC_PORT_MEDIUM_FIBER) ? 1 : 0)); 223 224 return SOC_E_NONE; 225 } 226 227 228 /* 229 * Function: 230 * phy_54380_medium_status 231 * Purpose: 232 * Indicate the current active medium 233 * Parameters: 234 * unit - StrataSwitch unit #. 235 * port - StrataSwitch port #. 236 * medium - (OUT) One of: 237 * SOC_PORT_MEDIUM_COPPER 238 * SOC_PORT_MEDIUM_FIBER 239 * Returns: 240 * SOC_E_NONE 241 */ 242 243 STATIC int 244 phy_54380_medium_status(int unit, soc_port_t port, soc_port_medium_t *medium) 245 { 246 if (PHY_COPPER_MODE(unit, port)) { 247 *medium = SOC_PORT_MEDIUM_COPPER; 248 } else { 249 *medium = SOC_PORT_MEDIUM_FIBER; 250 } 251 return SOC_E_NONE; 252 } 253 254 255 /* 256 * Function: 257 * _phy_54380_medium_config_update 258 * Purpose: 259 * Update the PHY with config parameters 260 * Parameters: 261 * unit - StrataSwitch unit #. 262 * port - StrataSwitch port #. 263 * cfg - Config structure. 264 * Returns: 265 * SOC_E_XXX 266 */ 267 268 STATIC int 269 _phy_54380_medium_config_update(int unit, soc_port_t port, 270 soc_phy_config_t *cfg) 271 { 272 SOC_IF_ERROR_RETURN 273 (phy_54380_speed_set(unit, port, cfg->force_speed)); 274 SOC_IF_ERROR_RETURN 275 (phy_54380_duplex_set(unit, port, cfg->force_duplex)); 276 SOC_IF_ERROR_RETURN 277 (phy_54380_master_set(unit, port, cfg->master)); 278 SOC_IF_ERROR_RETURN 279 (phy_54380_ability_advert_set(unit, port, &cfg->advert_ability)); 280 SOC_IF_ERROR_RETURN 281 (phy_54380_autoneg_set(unit, port, cfg->autoneg_enable)); 282 SOC_IF_ERROR_RETURN 283 (phy_54380_mdix_set(unit, port, cfg->mdix)); 284 285 return SOC_E_NONE; 286 } 287 288 289 /* 290 * Function: 291 * phy_54380_pa_2_bmacsec_pa 292 * Purpose: 293 * Translate soc_port_ability to 294 * bmacsec_port_ability 295 * Parameters: 296 * soc_port_ability_t 297 * bmacsec_port_ability_t 298 * Returns: 299 */ 300 static void 301 phy_54380_pa_2_bmacsec_pa( soc_port_ability_t *ability, 302 bmacsec_port_ability_t *bmacsec_ability) 303 { 304 if(ability->speed_full_duplex & SOC_PA_SPEED_1000MB) { 305 bmacsec_ability->speed_full_duplex |= BMACSEC_PA_SPEED_1000MB; 306 } 307 if(ability->speed_full_duplex & SOC_PA_SPEED_100MB) { 308 bmacsec_ability->speed_full_duplex |= BMACSEC_PA_SPEED_100MB; 309 } 310 if(ability->speed_full_duplex & SOC_PA_SPEED_10MB) { 311 bmacsec_ability->speed_full_duplex |= BMACSEC_PA_SPEED_10MB; 312 } 313 if(ability->speed_half_duplex & SOC_PA_SPEED_1000MB) { 314 bmacsec_ability->speed_half_duplex |= BMACSEC_PA_SPEED_1000MB; 315 } 316 if(ability->speed_half_duplex & SOC_PA_SPEED_100MB) { 317 bmacsec_ability->speed_half_duplex |= BMACSEC_PA_SPEED_100MB; 318 } 319 if(ability->speed_half_duplex & SOC_PA_SPEED_10MB) { 320 bmacsec_ability->speed_half_duplex |= BMACSEC_PA_SPEED_10MB; 321 } 322 if(ability->pause & SOC_PA_PAUSE_TX) { 323 bmacsec_ability->pause |= BMACSEC_PA_PAUSE_TX; 324 } 325 if(ability->pause & SOC_PA_PAUSE_RX) { 326 bmacsec_ability->pause |= BMACSEC_PA_PAUSE_RX; 327 } 328 if(ability->pause & SOC_PA_PAUSE_ASYMM) { 329 bmacsec_ability->pause |= BMACSEC_PA_PAUSE_ASYMM; 330 } 331 if(ability->loopback & SOC_PA_LB_NONE) { 332 bmacsec_ability->loopback |= BMACSEC_PA_LB_NONE; 333 } 334 if(ability->loopback & SOC_PA_LB_PHY) { 335 bmacsec_ability->loopback |= BMACSEC_PA_LB_PHY; 336 } 337 if(ability->flags & SOC_PA_AUTONEG) { 338 bmacsec_ability->flags |= BMACSEC_PA_AUTONEG; 339 } 340 if(ability->eee & SOC_PA_EEE_1GB_BASET) { 341 bmacsec_ability->eee |= BMACSEC_PA_EEE_1GB_BASET; 342 } 343 if(ability->eee & SOC_PA_EEE_100MB_BASETX) { 344 bmacsec_ability->eee |= BMACSEC_PA_EEE_100MB_BASETX; 345 } 346 return; 347 } 348 349 350 /* 351 * Function: 352 * phy_54380_bmacsec_pa_2_pa 353 * Purpose: 354 * Translate bmacsecc_port_ability to 355 * soc_port_ability 356 * Parameters: 357 * bmacsec_port_ability_t 358 * soc_port_ability_t 359 * Returns: 360 */ 361 static void 362 phy_54380_bmacsec_pa_2_pa( bmacsec_port_ability_t *bmacsec_ability, 363 soc_port_ability_t *ability) 364 { 365 if(bmacsec_ability->speed_full_duplex & BMACSEC_PA_SPEED_1000MB) { 366 ability->speed_full_duplex |= SOC_PA_SPEED_1000MB; 367 } 368 if(bmacsec_ability->speed_full_duplex & BMACSEC_PA_SPEED_100MB) { 369 ability->speed_full_duplex |= SOC_PA_SPEED_100MB; 370 } 371 if(bmacsec_ability->speed_full_duplex & BMACSEC_PA_SPEED_10MB) { 372 ability->speed_full_duplex |= SOC_PA_SPEED_10MB; 373 } 374 if(bmacsec_ability->speed_half_duplex & BMACSEC_PA_SPEED_1000MB) { 375 ability->speed_half_duplex |= SOC_PA_SPEED_1000MB; 376 } 377 if(bmacsec_ability->speed_half_duplex & BMACSEC_PA_SPEED_100MB) { 378 ability->speed_half_duplex |= SOC_PA_SPEED_100MB; 379 } 380 if(bmacsec_ability->speed_half_duplex & BMACSEC_PA_SPEED_10MB) { 381 ability->speed_half_duplex |= SOC_PA_SPEED_10MB; 382 } 383 if(bmacsec_ability->pause & BMACSEC_PA_PAUSE_TX) { 384 ability->pause |= SOC_PA_PAUSE_TX; 385 } 386 if(bmacsec_ability->pause & BMACSEC_PA_PAUSE_RX) { 387 ability->pause |= SOC_PA_PAUSE_RX; 388 } 389 if(bmacsec_ability->pause & BMACSEC_PA_PAUSE_ASYMM) { 390 ability->pause |= SOC_PA_PAUSE_ASYMM; 391 } 392 if(bmacsec_ability->loopback & BMACSEC_PA_LB_NONE) { 393 ability->loopback |= SOC_PA_LB_NONE; 394 } 395 if(bmacsec_ability->loopback & BMACSEC_PA_LB_PHY) { 396 ability->loopback |= SOC_PA_LB_PHY; 397 } 398 if(bmacsec_ability->flags & BMACSEC_PA_AUTONEG) { 399 ability->flags |= SOC_PA_AUTONEG; 400 } 401 if(bmacsec_ability->eee & BMACSEC_PA_EEE_1GB_BASET) { 402 ability->eee |= SOC_PA_EEE_1GB_BASET; 403 } 404 if(bmacsec_ability->eee & BMACSEC_PA_EEE_100MB_BASETX) { 405 ability->eee |= SOC_PA_EEE_100MB_BASETX; 406 } 407 return; 408 } 409 410 /*********************************************************************** 411 * 412 * PHY54380 DRIVER ROUTINES 413 */ 414 415 416 417 418 419 /* 420 * Function: 421 * phy_54380_medium_config_set 422 * Purpose: 423 * Set the operating parameters that are automatically selected 424 * when medium switches type. 425 * Parameters: 426 * unit - StrataSwitch unit # 427 * port - Port number 428 * medium - SOC_PORT_MEDIUM_COPPER/FIBER 429 * cfg - Operating parameters 430 * Returns: 431 * SOC_E_XXX 432 */ 433 STATIC int 434 phy_54380_medium_config_set(int unit, soc_port_t port, 435 soc_port_medium_t medium, 436 soc_phy_config_t *cfg) 437 { 438 phy_ctrl_t *pc; 439 soc_phy_config_t *active_medium; /* Currently active medium */ 440 soc_phy_config_t *change_medium; /* Requested medium */ 441 soc_phy_config_t *other_medium; /* The other medium */ 442 int medium_update; 443 soc_port_ability_t advert_ability; 444 sal_memset(&advert_ability, 0, sizeof(soc_port_ability_t)); 445 446 if (NULL == cfg) { 447 return SOC_E_PARAM; 448 } 449 450 pc = EXT_PHY_SW_STATE(unit, port); 451 medium_update = FALSE; 452 453 switch (medium) { 454 case SOC_PORT_MEDIUM_COPPER: 455 if (!pc->automedium && !PHY_COPPER_MODE(unit, port)) { 456 return SOC_E_UNAVAIL; 457 } 458 change_medium = &pc->copper; 459 other_medium = &pc->fiber; 460 ADVERT_ALL_COPPER(&advert_ability); 461 break; 462 case SOC_PORT_MEDIUM_FIBER: 463 if (!pc->automedium && !PHY_FIBER_MODE(unit, port)) { 464 return SOC_E_UNAVAIL; 465 } 466 change_medium = &pc->fiber; 467 other_medium = &pc->copper; 468 ADVERT_ALL_FIBER(&advert_ability); 469 break; 470 default: 471 return SOC_E_PARAM; 472 } 473 474 /* 475 * Changes take effect immediately if the target medium is active or 476 * the preferred medium changes. 477 */ 478 if (change_medium->enable != cfg->enable) { 479 medium_update = TRUE; 480 } 481 if (change_medium->preferred != cfg->preferred) { 482 /* Make sure that only one medium is preferred */ 483 other_medium->preferred = !cfg->preferred; 484 medium_update = TRUE; 485 } 486 487 sal_memcpy(change_medium, cfg, sizeof(*change_medium)); 488 change_medium->advert_ability.pause &= advert_ability.pause; 489 change_medium->advert_ability.speed_half_duplex &= advert_ability.speed_half_duplex; 490 change_medium->advert_ability.speed_full_duplex &= advert_ability.speed_full_duplex; 491 change_medium->advert_ability.interface &= advert_ability.interface; 492 change_medium->advert_ability.medium &= advert_ability.medium; 493 change_medium->advert_ability.loopback &= advert_ability.loopback; 494 change_medium->advert_ability.flags &= advert_ability.flags; 495 496 if (medium_update) { 497 /* The new configuration may cause medium change. Check 498 * and update medium. 499 */ 500 SOC_IF_ERROR_RETURN 501 (_phy_54380_medium_change(unit, port, TRUE, medium)); 502 } else { 503 active_medium = (PHY_COPPER_MODE(unit, port)) ? 504 &pc->copper : &pc->fiber; 505 if (active_medium == change_medium) { 506 /* If the medium to update is active, update the configuration */ 507 SOC_IF_ERROR_RETURN 508 (_phy_54380_medium_config_update(unit, port, change_medium)); 509 } 510 } 511 return SOC_E_NONE; 512 } 513 514 515 /* 516 * Function: 517 * phy_54380_medium_config_get 518 * Purpose: 519 * Get the operating parameters that are automatically selected 520 * when medium switches type. 521 * Parameters: 522 * unit - StrataSwitch unit # 523 * port - Port number 524 * medium - SOC_PORT_MEDIUM_COPPER/FIBER 525 * cfg - (OUT) Operating parameters 526 * Returns: 527 * SOC_E_XXX 528 */ 529 530 STATIC int 531 phy_54380_medium_config_get(int unit, soc_port_t port, 532 soc_port_medium_t medium, 533 soc_phy_config_t *cfg) 534 { 535 int rv; 536 phy_ctrl_t *pc; 537 538 pc = EXT_PHY_SW_STATE(unit, port); 539 rv = SOC_E_NONE; 540 541 switch (medium) { 542 case SOC_PORT_MEDIUM_COPPER: 543 if (pc->automedium || PHY_COPPER_MODE(unit, port)) { 544 sal_memcpy(cfg, &pc->copper, sizeof (*cfg)); 545 } else { 546 rv = SOC_E_UNAVAIL; 547 } 548 break; 549 case SOC_PORT_MEDIUM_FIBER: 550 if (pc->automedium || PHY_FIBER_MODE(unit, port)) { 551 sal_memcpy(cfg, &pc->fiber, sizeof (*cfg)); 552 } else { 553 rv = SOC_E_UNAVAIL; 554 } 555 break; 556 default: 557 rv = SOC_E_PARAM; 558 break; 559 } 560 561 return rv; 562 } 563 564 /* 565 * Function: 566 * _phy_54380_no_reset_setup 567 * Purpose: 568 * Setup the operating parameters of the PHY without resetting PHY 569 * Parameters: 570 * unit - StrataSwitch unit # 571 * port - Port number 572 * Returns: 573 * SOC_E_XXX 574 */ 575 576 STATIC int 577 _phy_54380_no_reset_setup(int unit, soc_port_t port) 578 { 579 phy_ctrl_t *pc; 580 bmacsec_dev_addr_t phy_dev_addr; 581 int rv = SOC_E_NONE; 582 583 LOG_INFO(BSL_LS_SOC_PHY, 584 (BSL_META_U(unit, 585 "_phy_54380_no_reset_setup: u=%d p=%d medium=%s\n"), 586 unit, port, 587 PHY_COPPER_MODE(unit, port) ? "COPPER" : "FIBER")); 588 589 pc = EXT_PHY_SW_STATE(unit, port); 590 591 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 592 rv = bmacsec_phy54380_init(phy_dev_addr, pc->macsec_dev_addr, 593 0, 594 pc->automedium, 595 pc->fiber.preferred, 596 pc->fiber_detect, 597 pc->macsec_enable, 598 pc->fiber.enable, 599 pc->copper.enable); 600 601 if (rv != BMACSEC_E_NONE) { 602 return SOC_E_FAIL; 603 } 604 return SOC_E_NONE; 605 } 606 607 /* 608 * Function: 609 * phy_54380_init 610 * Purpose: 611 * Init function for 54380 PHY. 612 * Parameters: 613 * unit - StrataSwitch unit #. 614 * port - StrataSwitch port #. 615 * Returns: 616 * SOC_E_NONE 617 */ 618 619 STATIC int 620 phy_54380_init(int unit, soc_port_t port) 621 { 622 phy_ctrl_t *pc; 623 int fiber_capable = 0, rv; 624 int fiber_preferred; 625 int qsgmii_mdio; 626 bmacsec_dev_addr_t macsec_dev_addr, qsgmii_dev_addr, phy_dev_addr, phy_base_addr; 627 int mmi_mdio_addr, port_index, macsec_enable, macsec_fixed_latency_en; 628 uint32 mac_config_flag = 0, primary_offset; 629 630 LOG_INFO(BSL_LS_SOC_PHY, 631 (BSL_META_U(unit, 632 "phy_54xxx_init: u=%d p=%d\n"), 633 unit, port)); 634 635 /* Only SGMII interface to switch MAC is supported */ 636 if (IS_GMII_PORT(unit, port)) { 637 return SOC_E_CONFIG; 638 } 639 640 pc = EXT_PHY_SW_STATE(unit, port); 641 pc->interface = SOC_PORT_IF_SGMII; 642 643 mmi_mdio_addr = soc_property_port_get(unit, port, spn_MACSEC_DEV_ADDR, -1); 644 645 if (mmi_mdio_addr == -1) { 646 LOG_WARN(BSL_LS_SOC_PHY, 647 (BSL_META_U(unit, 648 "phy_54380_init: " 649 "MACSEC_DEV_ADDR property " 650 "not configured for u=%d p=%d\n"), unit, port)); 651 return SOC_E_CONFIG; 652 } 653 654 port_index = soc_property_port_get(unit, port, spn_MACSEC_PORT_INDEX, -1); 655 656 if (port_index == -1) { 657 LOG_WARN(BSL_LS_SOC_PHY, 658 (BSL_META_U(unit, 659 "phy_54380_init: " 660 "MACSEC_PORT_INDEX property not configured for " 661 "u=%d p=%d\n"), unit, port)); 662 return SOC_E_CONFIG; 663 } 664 665 /* EEE capable */ 666 if ( PHY_IS_BCM54380(pc) || PHY_IS_BCM54382(pc) || 667 PHY_IS_BCM54340(pc) || PHY_IS_BCM54385(pc) ) { 668 PHY_FLAGS_SET(unit, port, PHY_FLAGS_EEE_CAPABLE); 669 } 670 671 pc->macsec_dev_addr = mmi_mdio_addr; 672 pc->macsec_dev_port = port_index; 673 qsgmii_mdio = (pc->phy_id - pc->macsec_dev_port + 8); 674 675 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 676 macsec_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->macsec_dev_addr, 0); 677 qsgmii_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, qsgmii_mdio, 0); 678 phy_base_addr = SOC_MACSECPHY_MDIO_ADDR(unit, ((pc->phy_id) - port_index), 0); 679 680 macsec_enable = soc_property_port_get(unit, port, spn_MACSEC_ENABLE, 0); 681 pc->macsec_enable = macsec_enable; 682 macsec_fixed_latency_en = soc_property_port_get(unit, port, spn_MACSEC_FIXED_LATENCY_ENABLE, -1); 683 684 if(1 == macsec_fixed_latency_en) { 685 mac_config_flag |= MAC_CTRL_FLAG_MACSEC_FIX_LATENCY_EN; 686 } 687 rv = bmacsec_phy54380_phy_mac_addr_set(phy_dev_addr, macsec_dev_addr, 688 qsgmii_dev_addr, phy_base_addr, 689 pc->macsec_dev_port, bmacsec_io_mmi1_quad, 690 mac_config_flag); 691 if(rv != BMACSEC_E_NONE) { 692 LOG_WARN(BSL_LS_SOC_PHY, 693 (BSL_META_U(unit, 694 "phy_54380_init: bmacsec_phy_mac_addr_set " 695 "returned error for u=%d p=%d\n"), unit, port)); 696 return SOC_E_FAIL; 697 } 698 699 /* fiber_capable? */ 700 if(PHY_IS_BCM54340(pc) || PHY_IS_BCM54385(pc)) { 701 fiber_capable = 1; 702 } 703 704 /* Change it to copper prefer for default. */ 705 fiber_preferred = 706 soc_property_port_get(unit, port, spn_PHY_FIBER_PREF, 0); 707 pc->automedium = 708 soc_property_port_get(unit, port, spn_PHY_AUTOMEDIUM, 0); 709 pc->fiber_detect = 710 soc_property_port_get(unit, port, spn_PHY_FIBER_DETECT, -4); 711 712 LOG_INFO(BSL_LS_SOC_PHY, 713 (BSL_META_U(unit, 714 "phy_54380_init: " 715 "u=%d p=%d type=54380%s automedium=%d fiber_pref=%d detect=%d\n"), 716 unit, port, fiber_capable ? "S" : "", 717 pc->automedium, fiber_preferred, pc->fiber_detect)); 718 719 if (fiber_capable == 0) { /* not fiber capable */ 720 fiber_preferred = 0; 721 pc->automedium = 0; 722 pc->fiber_detect = 0; 723 } 724 725 pc->copper.enable = TRUE; 726 pc->copper.preferred = !fiber_preferred; 727 pc->copper.autoneg_enable = TRUE; 728 ADVERT_ALL_COPPER(&pc->copper.advert_ability); 729 pc->copper.force_speed = 1000; 730 pc->copper.force_duplex = TRUE; 731 pc->copper.master = SOC_PORT_MS_AUTO; 732 pc->copper.mdix = SOC_PORT_MDIX_AUTO; 733 734 pc->fiber.enable = fiber_capable; 735 pc->fiber.preferred = fiber_preferred; 736 pc->fiber.autoneg_enable = fiber_capable; 737 ADVERT_ALL_FIBER(&pc->fiber.advert_ability); 738 pc->fiber.force_speed = 1000; 739 pc->fiber.force_duplex = TRUE; 740 pc->fiber.master = SOC_PORT_MS_NONE; 741 pc->fiber.mdix = SOC_PORT_MDIX_NORMAL; 742 743 /* Initially configure for the preferred medium. */ 744 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_COPPER); 745 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER); 746 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_PASSTHRU); 747 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_100FX); 748 if (pc->fiber.preferred) { 749 PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER); 750 } else { 751 PHY_FLAGS_SET(unit, port, PHY_FLAGS_COPPER); 752 } 753 754 /* Get Requested LED selectors (defaults are hardware defaults) */ 755 pc->ledmode[0] = soc_property_port_get(unit, port, spn_PHY_LED1_MODE, 0); 756 pc->ledmode[1] = soc_property_port_get(unit, port, spn_PHY_LED2_MODE, 1); 757 pc->ledmode[2] = soc_property_port_get(unit, port, spn_PHY_LED3_MODE, 3); 758 pc->ledmode[3] = soc_property_port_get(unit, port, spn_PHY_LED4_MODE, 6); 759 pc->ledctrl = soc_property_port_get(unit, port, spn_PHY_LED_CTRL, 0x8); 760 pc->ledselect = soc_property_port_get(unit, port, spn_PHY_LED_SELECT, 0); 761 762 /* default MACSEC MAC policy: MACSEC_SWITCH_FOLLOWS_LINE == 1 */ 763 pc->macsec_mac_policy = soc_property_port_get(unit, port, 764 spn_MACSEC_SWITCH_SIDE_POLICY, 765 BMACSEC_BCM54380_SWITCH_FOLLOWS_LINE); 766 /* set Fixed policy if macsec_mac_policy == BMACSEC_SWITCH_FIXED == 0 */ 767 pc->macsec_switch_fixed = (pc->macsec_mac_policy == 768 BMACSEC_BCM54380_SWITCH_FIXED) ? 1 : 0; 769 /* 770 * Some reasonable defaults 771 */ 772 pc->macsec_switch_fixed_speed = 1000; 773 pc->macsec_switch_fixed_duplex = 1; 774 pc->macsec_switch_fixed_pause = 1; 775 pc->macsec_pause_rx_fwd = 0; 776 pc->macsec_pause_tx_fwd = 0; 777 pc->macsec_line_ipg = 0xc; 778 pc->macsec_switch_ipg = 0xc; 779 780 /* Primary & Offset numbers from the config property */ 781 primary_offset = soc_property_port_get(unit, port, spn_PHY_PORT_PRIMARY_AND_OFFSET, 0x00); 782 rv = soc_phyctrl_primary_set(unit, port, (primary_offset >>8) & 0xff); 783 rv = soc_phyctrl_offset_set( unit, port, primary_offset & 0xff); 784 785 /* Init PHYS and MACs to defaults */ 786 rv = bmacsec_phy54380_init( phy_dev_addr, 787 macsec_dev_addr, 788 1, 789 pc->automedium, 790 fiber_preferred, 791 pc->fiber_detect, 792 pc->macsec_enable, 793 pc->fiber.enable, 794 pc->copper.enable); 795 796 if (rv != BMACSEC_E_NONE) { 797 return SOC_E_FAIL; 798 } 799 800 /* Set LED Modes and Control */ 801 rv = bmacsec_phy54380_set_led_selectors(phy_dev_addr, pc->ledmode[0], 802 pc->ledmode[1], pc->ledmode[2], 803 pc->ledmode[3], pc->ledselect, 804 pc->ledctrl); 805 if (rv != BMACSEC_E_NONE) { 806 return SOC_E_FAIL; 807 } 808 809 SOC_IF_ERROR_RETURN 810 (_phy_54380_medium_config_update(unit, port, 811 PHY_COPPER_MODE(unit, port) ? &pc->copper 812 : &pc->fiber)); 813 if (pc->macsec_enable) { 814 rv = soc_macsecphy_init(unit, port, pc, 815 BMACSEC_CORE_BCM5438X, bmacsec_io_mmi1_quad); 816 if (!SOC_SUCCESS(rv)) { 817 LOG_ERROR(BSL_LS_SOC_PHY, 818 (BSL_META_U(unit, 819 "soc_macsecphy_init: MACSEC init for" 820 " u=%d p=%d FAILED "), unit, port)); 821 } else { 822 LOG_INFO(BSL_LS_SOC_PHY, 823 (BSL_META_U(unit, 824 "soc_macsecphy_init: MACSEC init for" 825 " u=%d p=%d SUCCESS "), unit, port)); 826 } 827 } 828 return SOC_E_NONE; 829 } 830 831 832 /* 833 * Function: 834 * phy_54380_reset 835 * Purpose: 836 * Reset PHY and wait for it to come out of reset. 837 * Parameters: 838 * unit - StrataSwitch unit #. 839 * port - StrataSwitch port #. 840 * Returns: 841 * SOC_E_XXX 842 */ 843 844 STATIC int 845 phy_54380_reset(int unit, soc_port_t port, void *user_arg) 846 { 847 848 int rv; 849 phy_ctrl_t *pc; 850 bmacsec_dev_addr_t phy_dev_addr; 851 852 pc = EXT_PHY_SW_STATE(unit, port); 853 854 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 855 rv = bmacsec_phy54380_reset(phy_dev_addr); 856 857 return (SOC_ERROR(rv)); 858 } 859 860 #define MACSEC_REG_PORT_SHIFT 12 861 #define MACSEC_REG_PORT_MASK (0xFU << MACSEC_REG_PORT_SHIFT) 862 #define UINT16_MASK 0xFFFF 863 864 /* 865 * Function: 866 * phy_54380_reg_read 867 * Purpose: 868 * read a register. 869 * Parameters: 870 * unit - StrataSwitch unit #. 871 * port - StrataSwitch port #. 872 * flags - register type. 873 * phy_reg_addr - register address. 874 * phy_data - data read from the register. 875 * Returns: 876 * SOC_E_XXX 877 */ 878 STATIC int 879 phy_54380_reg_read(int unit, soc_port_t port, uint32 flags, 880 uint32 phy_reg_addr, uint32 *phy_data) 881 { 882 int rv; 883 884 if ( BMACSEC_PHY_REG_MACSEC & flags ) { /* MACSEC registers */ 885 soc_port_t offset; 886 SOC_IF_ERROR_RETURN( soc_phyctrl_offset_get(unit, port, &offset) ); 887 888 phy_reg_addr &= ~(MACSEC_REG_PORT_MASK); 889 phy_reg_addr |= (offset << MACSEC_REG_PORT_SHIFT); 890 rv = bmacsec_phy54380_macsec_reg_read(port, flags, phy_reg_addr, phy_data); 891 892 } else 893 if ( BMACSEC_PHY_REG_DIRECT & flags ) { /* RDB registers */ 894 uint16 data16 = 0; 895 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 896 897 rv = bmacsec_phy54380_direct_reg_read(pc->phy_id, 898 (uint16) (phy_reg_addr & UINT16_MASK), &data16); 899 *phy_data = (uint32) data16; 900 901 } else { /* other registers */ 902 rv = phy_ge_reg_read(unit, port, flags, phy_reg_addr, phy_data); 903 } 904 905 return SOC_ERROR(rv); 906 } 907 908 /* 909 * Function: 910 * phy_54380_reg_write 911 * Purpose: 912 * write a register. 913 * Parameters: 914 * unit - StrataSwitch unit #. 915 * port - StrataSwitch port #. 916 * flags - register type. 917 * phy_reg_addr - register address. 918 * phy_data - data to be written. 919 * Returns: 920 * SOC_E_XXX 921 */ 922 STATIC int 923 phy_54380_reg_write(int unit, soc_port_t port, uint32 flags, 924 uint32 phy_reg_addr, uint32 phy_data) 925 { 926 int rv; 927 928 if ( BMACSEC_PHY_REG_MACSEC & flags ) { /* MACSEC registers */ 929 soc_port_t offset; 930 SOC_IF_ERROR_RETURN( soc_phyctrl_offset_get(unit, port, &offset) ); 931 932 phy_reg_addr &= ~(MACSEC_REG_PORT_MASK); 933 phy_reg_addr |= (offset << MACSEC_REG_PORT_SHIFT); 934 rv = bmacsec_phy54380_macsec_reg_write(port, flags, phy_reg_addr, phy_data); 935 936 } else 937 if ( BMACSEC_PHY_REG_DIRECT & flags ) { /* RDB registers */ 938 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 939 rv = bmacsec_phy54380_direct_reg_write(pc->phy_id, 940 (uint16) (phy_reg_addr & UINT16_MASK), 941 (uint16) (phy_data & UINT16_MASK) ); 942 943 } else { /* other registers */ 944 rv = phy_ge_reg_write(unit, port, flags, phy_reg_addr, phy_data); 945 } 946 947 return SOC_ERROR(rv); 948 } 949 950 /* 951 * Function: 952 * phy_54380_reg_modify 953 * Purpose: 954 * modify a register. 955 * Parameters: 956 * unit - StrataSwitch unit #. 957 * port - StrataSwitch port #. 958 * flags - register type. 959 * phy_reg_addr - register address. 960 * phy_data - data to be modified. 961 * mask - register fields mask. 962 * Returns: 963 * SOC_E_XXX 964 */ 965 STATIC int 966 phy_54380_reg_modify(int unit, soc_port_t port, uint32 flags, 967 uint32 phy_reg_addr, uint32 phy_data, uint32 mask) 968 { 969 int rv; 970 971 if ( BMACSEC_PHY_REG_MACSEC & flags ) { /* MACSEC registers */ 972 soc_port_t offset; 973 SOC_IF_ERROR_RETURN( soc_phyctrl_offset_get(unit, port, &offset) ); 974 975 phy_reg_addr &= ~(MACSEC_REG_PORT_MASK); 976 phy_reg_addr |= (offset << MACSEC_REG_PORT_SHIFT); 977 rv = bmacsec_phy54380_macsec_reg_modify(port, flags, phy_reg_addr, phy_data, mask); 978 979 } else 980 if ( BMACSEC_PHY_REG_DIRECT & flags ) { /* RDB registers */ 981 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 982 rv = bmacsec_phy54380_direct_reg_modify(pc->phy_id, 983 (uint16) (phy_reg_addr & UINT16_MASK), 984 (uint16) (phy_data & UINT16_MASK), 985 (uint16) mask ); 986 987 } else { /* other registers */ 988 rv = phy_ge_reg_modify(unit, port, flags, phy_reg_addr, phy_data, mask); 989 } 990 991 return SOC_ERROR(rv); 992 } 993 994 /* 995 * Function: 996 * phy_54380_enable_set 997 * Purpose: 998 * Enable or disable the physical interface. 999 * Parameters: 1000 * unit - StrataSwitch unit #. 1001 * port - StrataSwitch port #. 1002 * enable - Boolean, true = enable PHY, false = disable. 1003 * Returns: 1004 * SOC_E_XXX 1005 */ 1006 1007 STATIC int 1008 phy_54380_enable_set(int unit, soc_port_t port, int enable) 1009 { 1010 phy_ctrl_t *pc; 1011 int rv = SOC_E_NONE; 1012 bmacsec_dev_addr_t phy_dev_addr; 1013 bmacsec_phy_port_mode_t port_mode = 0; 1014 1015 pc = EXT_PHY_SW_STATE(unit, port); 1016 1017 if(PHY_COPPER_MODE(unit, port)) { 1018 port_mode = BMACSEC_PHY_COPPER; 1019 } else { 1020 if(PHY_FIBER_MODE(unit, port)) { 1021 port_mode = BMACSEC_PHY_FIBER; 1022 } 1023 } 1024 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1025 rv = bmacsec_phy54380_enable_set(phy_dev_addr, pc->automedium, 1026 port_mode, enable); 1027 if(rv != BMACSEC_E_NONE) { 1028 return SOC_E_FAIL; 1029 } 1030 1031 if (pc->automedium || PHY_FIBER_MODE(unit, port)) { 1032 phy_ctrl_t *int_pc; 1033 1034 int_pc = INT_PHY_SW_STATE(unit, port); 1035 if (NULL != int_pc) { 1036 SOC_IF_ERROR_RETURN 1037 (PHY_ENABLE_SET(int_pc->pd, unit, port, enable)); 1038 } 1039 1040 LOG_INFO(BSL_LS_SOC_PHY, 1041 (BSL_META_U(unit, 1042 "phy_54380_enable_set: " 1043 "Power %s fiber medium\n"), (enable) ? "up" : "down")); 1044 } 1045 1046 /* Update software state */ 1047 SOC_IF_ERROR_RETURN(phy_fe_ge_enable_set(unit, port, enable)); 1048 return SOC_E_NONE; 1049 } 1050 1051 /* 1052 * Function: 1053 * phy_54380_enable_get 1054 * Purpose: 1055 * Enable or disable the physical interface for a 54380 device. 1056 * Parameters: 1057 * unit - StrataSwitch unit #. 1058 * port - StrataSwitch port #. 1059 * enable - (OUT) Boolean, true = enable PHY, false = disable. 1060 * Returns: 1061 * SOC_E_XXX 1062 */ 1063 1064 STATIC int 1065 phy_54380_enable_get(int unit, soc_port_t port, int *enable) 1066 { 1067 return phy_fe_ge_enable_get(unit, port, enable); 1068 } 1069 1070 1071 /* 1072 * Function: 1073 * _phy_54380_medium_change 1074 * Purpose: 1075 * Change medium when media change detected or forced 1076 * Parameters: 1077 * unit - StrataSwitch unit #. 1078 * port - StrataSwitch port #. 1079 * force_update - Force update 1080 * force_medium - Force update medium 1081 * Returns: 1082 * SOC_E_XXX 1083 */ 1084 STATIC int 1085 _phy_54380_medium_change(int unit, soc_port_t port, int force_update, 1086 soc_port_medium_t force_medium) 1087 { 1088 phy_ctrl_t *pc; 1089 int medium; 1090 1091 pc = EXT_PHY_SW_STATE(unit, port); 1092 1093 SOC_IF_ERROR_RETURN 1094 (_phy_54380_medium_check(unit, port, &medium)); 1095 1096 if (medium == SOC_PORT_MEDIUM_COPPER) { 1097 if (!PHY_COPPER_MODE(unit, port) || force_update) { /* Was fiber */ 1098 PHY_FLAGS_SET(unit, port, PHY_FLAGS_COPPER); 1099 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER); 1100 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_100FX); 1101 PHY_FLAGS_SET(unit, port, PHY_FLAGS_MEDIUM_CHANGE); 1102 if ( PHY_IS_BCM54380(pc) || PHY_IS_BCM54382(pc) || 1103 PHY_IS_BCM54340(pc) || PHY_IS_BCM54385(pc) ) { 1104 PHY_FLAGS_SET(unit, port, PHY_FLAGS_EEE_CAPABLE); 1105 } 1106 SOC_IF_ERROR_RETURN 1107 (_phy_54380_no_reset_setup(unit, port)); 1108 1109 /* Do Not power up the interface if medium is disabled */ 1110 if (pc->copper.enable) { 1111 SOC_IF_ERROR_RETURN 1112 (_phy_54380_medium_config_update(unit, port, &pc->copper)); 1113 } 1114 LOG_INFO(BSL_LS_SOC_PHY, 1115 (BSL_META_U(unit, 1116 "_phy_54380_link_auto_detect: u=%d p=%d [F->C]\n"), 1117 unit, port)); 1118 } 1119 } else { /* Fiber */ 1120 if (PHY_COPPER_MODE(unit, port) || force_update) { /* Was copper */ 1121 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_COPPER); 1122 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_EEE_CAPABLE); /* no EEE for fiber */ 1123 PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER); 1124 PHY_FLAGS_SET(unit, port, PHY_FLAGS_MEDIUM_CHANGE); 1125 1126 SOC_IF_ERROR_RETURN 1127 (_phy_54380_no_reset_setup(unit, port)); 1128 1129 if (pc->fiber.enable) { 1130 SOC_IF_ERROR_RETURN 1131 (_phy_54380_medium_config_update(unit, port, &pc->fiber)); 1132 } 1133 LOG_INFO(BSL_LS_SOC_PHY, 1134 (BSL_META_U(unit, 1135 "_phy_54380_link_auto_detect: u=%d p=%d [C->F]\n"), 1136 unit, port)); 1137 } 1138 } 1139 1140 return SOC_E_NONE; 1141 } 1142 1143 /* 1144 * Function: 1145 * phy_54380_link_get 1146 * Purpose: 1147 * Determine the current link up/down status for a 54380 device. 1148 * Parameters: 1149 * unit - StrataSwitch unit #. 1150 * port - StrataSwitch port #. 1151 * link - (OUT) Boolean, true indicates link established. 1152 * Returns: 1153 * SOC_E_XXX 1154 * Notes: 1155 * If using automedium, also switches the mode. 1156 */ 1157 STATIC int 1158 phy_54380_link_get(int unit, soc_port_t port, int *link) 1159 { 1160 phy_ctrl_t *pc; 1161 uint16 data; 1162 int rv = SOC_E_NONE; 1163 bmacsec_phy_port_mode_t port_mode = 0; 1164 bmacsec_dev_addr_t phy_dev_addr; 1165 int bmacsec_link; 1166 1167 1168 pc = EXT_PHY_SW_STATE(unit, port); 1169 *link = FALSE; /* Default return */ 1170 1171 if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) { 1172 return SOC_E_NONE; 1173 } 1174 1175 if (!pc->fiber.enable && !pc->copper.enable) { 1176 return SOC_E_NONE; 1177 } 1178 1179 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_MEDIUM_CHANGE); 1180 if (pc->automedium) { 1181 /* Check for medium change and update HW/SW accordingly. */ 1182 SOC_IF_ERROR_RETURN 1183 (_phy_54380_medium_change(unit, port, FALSE, 0)); 1184 } 1185 1186 if(PHY_COPPER_MODE(unit, port)) { 1187 port_mode = BMACSEC_PHY_COPPER; 1188 } else { 1189 if(PHY_FIBER_MODE(unit, port)) { 1190 port_mode = BMACSEC_PHY_FIBER; 1191 } 1192 } 1193 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1194 rv = bmacsec_phy_54380_link_get(phy_dev_addr, port_mode, &bmacsec_link); 1195 if (!BMACSEC_E_SUCCESS(rv)) { 1196 return SOC_E_FAIL; 1197 } 1198 if (bmacsec_link == 1) { 1199 *link = TRUE; 1200 } else { 1201 *link = FALSE; 1202 } 1203 /* If preferred medium is up, disable the other medium 1204 * to prevent false link. */ 1205 if (pc->automedium) { 1206 if (pc->copper.preferred) { 1207 if (pc->fiber.enable) { 1208 /* Power down Serdes if Copper mode is up */ 1209 data = (*link && PHY_COPPER_MODE(unit, port)) ? 0 : 1; 1210 } else { 1211 data = 0; 1212 1213 } 1214 port_mode = BMACSEC_PHY_FIBER; 1215 (void)bmacsec_phy54380_enable_set(phy_dev_addr, pc->automedium, 1216 port_mode, data); 1217 } else { /* pc->fiber.preferred */ 1218 if (pc->copper.enable) { 1219 data = (*link && PHY_FIBER_MODE(unit, port)) ? 0 : 1; 1220 } else { 1221 data = 0; 1222 } 1223 port_mode = BMACSEC_PHY_COPPER; 1224 (void)bmacsec_phy54380_enable_set(phy_dev_addr, pc->automedium, 1225 port_mode, data); 1226 } 1227 } 1228 LOG_VERBOSE(BSL_LS_SOC_PHY, 1229 (BSL_META_U(unit, 1230 "phy_54380_link_get: u=%d p=%d mode=%s%s link=%d\n"), 1231 unit, port, 1232 PHY_COPPER_MODE(unit, port) ? "C" : "F", 1233 PHY_FIBER_100FX_MODE(unit, port)? "(100FX)" : "", 1234 *link)); 1235 1236 return SOC_E_NONE; 1237 } 1238 1239 1240 /* 1241 * Function: 1242 * phy_54380_duplex_set 1243 * Purpose: 1244 * Set the current duplex mode (forced). 1245 * Parameters: 1246 * unit - StrataSwitch unit #. 1247 * port - StrataSwitch port #. 1248 * duplex - Boolean, true indicates full duplex, false indicates half. 1249 * Returns: 1250 * SOC_E_NONE 1251 * SOC_E_UNAVAIL - Half duplex requested, and not supported. 1252 * Notes: 1253 * The duplex is set only for the ACTIVE medium. 1254 * No synchronization performed at this level. 1255 * Autonegotiation is not manipulated. 1256 */ 1257 1258 STATIC int 1259 phy_54380_duplex_set(int unit, soc_port_t port, int duplex) 1260 { 1261 int rv=SOC_E_NONE; 1262 phy_ctrl_t *pc; 1263 bmacsec_phy_port_mode_t port_mode = 0; 1264 bmacsec_dev_addr_t phy_dev_addr; 1265 bmacsec_phy_duplex_t bmacsec_duplex; 1266 1267 pc = EXT_PHY_SW_STATE(unit, port); 1268 rv = SOC_E_NONE; 1269 1270 if(PHY_COPPER_MODE(unit, port)) { 1271 port_mode = BMACSEC_PHY_COPPER; 1272 } else { 1273 if(PHY_FIBER_MODE(unit, port)) { 1274 port_mode = BMACSEC_PHY_FIBER; 1275 if (duplex == 0) { 1276 return SOC_E_UNAVAIL; 1277 } 1278 } 1279 } 1280 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1281 if (duplex) { 1282 bmacsec_duplex = BMACSEC_FULL_DUPLEX; 1283 } else { 1284 bmacsec_duplex = BMACSEC_HALF_DUPLEX; 1285 } 1286 rv = bmacsec_phy54380_duplex_set(phy_dev_addr, port_mode, 1287 bmacsec_duplex); 1288 1289 if(BMACSEC_E_SUCCESS(rv)) { 1290 if(PHY_FIBER_MODE(unit, port)) { 1291 pc->fiber.force_duplex = duplex; 1292 } else { 1293 pc->copper.force_duplex = duplex; 1294 } 1295 } 1296 1297 LOG_INFO(BSL_LS_SOC_PHY, 1298 (BSL_META_U(unit, 1299 "phy_54380_duplex_set: u=%d p=%d d=%d rv=%d\n"), 1300 unit, port, duplex, rv)); 1301 return (SOC_ERROR(rv)); 1302 } 1303 1304 /* 1305 * Function: 1306 * phy_54380_duplex_get 1307 * Purpose: 1308 * Get the current operating duplex mode. If autoneg is enabled, 1309 * then operating mode is returned, otherwise forced mode is returned. 1310 * Parameters: 1311 * unit - StrataSwitch unit #. 1312 * port - StrataSwitch port #. 1313 * duplex - (OUT) Boolean, true indicates full duplex, false 1314 * indicates half. 1315 * Returns: 1316 * SOC_E_NONE 1317 * Notes: 1318 * The duplex is retrieved for the ACTIVE medium. 1319 * No synchronization performed at this level. Autonegotiation is 1320 * not manipulated. 1321 */ 1322 1323 STATIC int 1324 phy_54380_duplex_get(int unit, soc_port_t port, int *duplex) 1325 { 1326 1327 int rv = SOC_E_NONE; 1328 bmacsec_phy_port_mode_t port_mode = 0; 1329 phy_ctrl_t *pc; 1330 bmacsec_dev_addr_t phy_dev_addr; 1331 bmacsec_phy_duplex_t bmacsec_duplex; 1332 1333 pc = EXT_PHY_SW_STATE(unit, port); 1334 1335 if ( PHY_COPPER_MODE(unit, port) ) { 1336 port_mode = BMACSEC_PHY_COPPER; 1337 } else 1338 if ( PHY_FIBER_MODE(unit, port) ) { 1339 port_mode = BMACSEC_PHY_FIBER; 1340 *duplex = TRUE; 1341 return SOC_E_NONE; 1342 } 1343 1344 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1345 rv = bmacsec_phy54380_duplex_get(phy_dev_addr, port_mode, 1346 &bmacsec_duplex); 1347 if (rv != BMACSEC_E_NONE) { 1348 return SOC_E_FAIL; 1349 } 1350 1351 *duplex = (bmacsec_duplex == BMACSEC_FULL_DUPLEX) ? TRUE : FALSE; 1352 return SOC_E_NONE; 1353 } 1354 1355 /* 1356 * Function: 1357 * phy_54380_speed_set 1358 * Purpose: 1359 * Set the current operating speed (forced). 1360 * Parameters: 1361 * unit - StrataSwitch unit #. 1362 * port - StrataSwitch port #. 1363 * speed - Requested speed, only 1000 supported. 1364 * Returns: 1365 * SOC_E_XXX 1366 * Notes: 1367 * The speed is set only for the ACTIVE medium. 1368 */ 1369 1370 STATIC int 1371 phy_54380_speed_set(int unit, soc_port_t port, int speed) 1372 { 1373 int rv = SOC_E_NONE; 1374 phy_ctrl_t *pc; 1375 bmacsec_dev_addr_t phy_dev_addr; 1376 bmacsec_phy_port_mode_t port_mode = 0; 1377 1378 pc = EXT_PHY_SW_STATE(unit, port); 1379 1380 if(PHY_COPPER_MODE(unit, port)) { 1381 port_mode = BMACSEC_PHY_COPPER; 1382 } else { 1383 if(PHY_FIBER_MODE(unit, port)) { 1384 port_mode = BMACSEC_PHY_FIBER; 1385 if (speed == 10) { 1386 return SOC_E_UNAVAIL; 1387 } 1388 } 1389 } 1390 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1391 rv = bmacsec_phy54380_speed_set(phy_dev_addr, port_mode, speed); 1392 1393 if(BMACSEC_E_SUCCESS(rv)) { 1394 if(PHY_COPPER_MODE(unit, port)) { 1395 pc->copper.force_speed = speed; 1396 } else { 1397 if(PHY_FIBER_MODE(unit, port)) { 1398 if (speed == 100) { 1399 PHY_FLAGS_SET(unit, port, PHY_FLAGS_100FX); 1400 pc->fiber.autoneg_enable = FALSE; 1401 phy_54380_autoneg_set(unit, port, 0); 1402 } 1403 1404 if (speed == 1000) { 1405 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_100FX); 1406 pc->fiber.force_duplex = TRUE; 1407 phy_54380_autoneg_set(unit, port, 1408 pc->fiber.autoneg_enable); 1409 } 1410 pc->fiber.force_speed = speed; 1411 } 1412 } 1413 } 1414 LOG_INFO(BSL_LS_SOC_PHY, 1415 (BSL_META_U(unit, 1416 "phy_54380_speed_set: u=%d p=%d s=%d fiber=%d rv=%d\n"), 1417 unit, port, speed, PHY_FIBER_MODE(unit, port), rv)); 1418 return SOC_ERROR(rv); 1419 } 1420 1421 /* 1422 * Function: 1423 * phy_54380_speed_get 1424 * Purpose: 1425 * Get the current operating speed for a 54380 device. 1426 * Parameters: 1427 * unit - StrataSwitch unit #. 1428 * port - StrataSwitch port #. 1429 * duplex - (OUT) Boolean, true indicates full duplex, false 1430 * indicates half. 1431 * Returns: 1432 * SOC_E_NONE 1433 * Notes: 1434 * The speed is retrieved for the ACTIVE medium. 1435 */ 1436 1437 STATIC int 1438 phy_54380_speed_get(int unit, soc_port_t port, int *speed) 1439 { 1440 int rv = SOC_E_NONE; 1441 bmacsec_phy_port_mode_t port_mode = 0; 1442 bmacsec_dev_addr_t phy_dev_addr; 1443 phy_ctrl_t *pc; 1444 1445 pc = EXT_PHY_SW_STATE(unit, port); 1446 1447 if(PHY_COPPER_MODE(unit, port)) { 1448 port_mode = BMACSEC_PHY_COPPER; 1449 } else { 1450 if(PHY_FIBER_MODE(unit, port)) { 1451 port_mode = BMACSEC_PHY_FIBER; 1452 } 1453 } 1454 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1455 rv = bmacsec_phy54380_speed_get(phy_dev_addr, port_mode, speed); 1456 1457 if(!BMACSEC_E_SUCCESS(rv)) { 1458 LOG_WARN(BSL_LS_SOC_PHY, 1459 (BSL_META_U(unit, 1460 "phy_54380_speed_get: u=%d p=%d invalid speed\n"), 1461 unit, port)); 1462 } else { 1463 LOG_INFO(BSL_LS_SOC_PHY, 1464 (BSL_META_U(unit, 1465 "phy_54380_speed_get: u=%d p=%d speed=%d"), 1466 unit, port, *speed)); 1467 } 1468 1469 return SOC_ERROR(rv); 1470 } 1471 1472 /* 1473 * Function: 1474 * phy_54380_master_set 1475 * Purpose: 1476 * Set the current master mode 1477 * Parameters: 1478 * unit - StrataSwitch unit #. 1479 * port - StrataSwitch port #. 1480 * master - SOC_PORT_MS_* 1481 * Returns: 1482 * SOC_E_XXX 1483 * Notes: 1484 * The master mode is set only for the ACTIVE medium. 1485 */ 1486 STATIC int 1487 phy_54380_master_set(int unit, soc_port_t port, int master) 1488 { 1489 int rv = SOC_E_NONE; 1490 phy_ctrl_t *pc; 1491 bmacsec_phy_port_mode_t port_mode = 0; 1492 bmacsec_dev_addr_t phy_dev_addr; 1493 1494 pc = EXT_PHY_SW_STATE(unit, port); 1495 rv = SOC_E_NONE; 1496 1497 if(PHY_COPPER_MODE(unit, port)) { 1498 port_mode = BMACSEC_PHY_COPPER; 1499 } else { 1500 if(PHY_FIBER_MODE(unit, port)) { 1501 port_mode = BMACSEC_PHY_FIBER; 1502 } 1503 } 1504 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1505 rv = bmacsec_phy54380_master_set(phy_dev_addr, port_mode, master); 1506 if(BMACSEC_E_SUCCESS(rv)) { 1507 pc->copper.master = master; 1508 } 1509 1510 LOG_INFO(BSL_LS_SOC_PHY, 1511 (BSL_META_U(unit, 1512 "phy_54380_master_set: u=%d p=%d master=%d fiber=%d rv=%d\n"), 1513 unit, port, master, PHY_FIBER_MODE(unit, port), rv)); 1514 return SOC_ERROR(rv); 1515 } 1516 1517 /* 1518 * Function: 1519 * phy_54380_master_get 1520 * Purpose: 1521 * Get the current master mode for a 54380 device. 1522 * Parameters: 1523 * unit - StrataSwitch unit #. 1524 * port - StrataSwitch port #. 1525 * master - (OUT) SOC_PORT_MS_* 1526 * Returns: 1527 * SOC_E_NONE 1528 * Notes: 1529 * The master mode is retrieved for the ACTIVE medium. 1530 */ 1531 1532 STATIC int 1533 phy_54380_master_get(int unit, soc_port_t port, int *master) 1534 { 1535 int rv; 1536 phy_ctrl_t *pc; 1537 bmacsec_phy_port_mode_t port_mode = 0; 1538 bmacsec_dev_addr_t phy_dev_addr; 1539 1540 pc = EXT_PHY_SW_STATE(unit, port); 1541 rv = SOC_E_NONE; 1542 1543 if(PHY_COPPER_MODE(unit, port)) { 1544 port_mode = BMACSEC_PHY_COPPER; 1545 } else { 1546 if(PHY_FIBER_MODE(unit, port)) { 1547 port_mode = BMACSEC_PHY_FIBER; 1548 *master = SOC_PORT_MS_NONE; 1549 return SOC_E_NONE; 1550 } 1551 } 1552 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1553 rv = bmacsec_phy54380_master_get(phy_dev_addr, port_mode, master); 1554 1555 return SOC_ERROR(rv); 1556 } 1557 1558 /* 1559 * Function: 1560 * phy_54380_autoneg_set 1561 * Purpose: 1562 * Enable or disable auto-negotiation on the specified port. 1563 * Parameters: 1564 * unit - StrataSwitch unit #. 1565 * port - StrataSwitch port #. 1566 * autoneg - Boolean, if true, auto-negotiation is enabled 1567 * (and/or restarted). If false, autonegotiation is disabled. 1568 * Returns: 1569 * SOC_E_XXX 1570 * Notes: 1571 * The autoneg mode is set only for the ACTIVE medium. 1572 */ 1573 1574 STATIC int 1575 phy_54380_autoneg_set(int unit, soc_port_t port, int autoneg) 1576 { 1577 int rv = SOC_E_NONE; 1578 phy_ctrl_t *pc; 1579 bmacsec_port_ability_t *autoneg_advert = 0; 1580 bmacsec_phy_port_mode_t port_mode = 0; 1581 bmacsec_dev_addr_t phy_dev_addr; 1582 1583 1584 pc = EXT_PHY_SW_STATE(unit, port); 1585 rv = SOC_E_NONE; 1586 1587 if(PHY_COPPER_MODE(unit, port)) { 1588 port_mode = BMACSEC_PHY_COPPER; 1589 autoneg_advert = (bmacsec_port_ability_t *)&pc->copper.advert_ability; 1590 } else { 1591 if(PHY_FIBER_MODE(unit, port)) { 1592 port_mode = BMACSEC_PHY_FIBER; 1593 autoneg_advert = (bmacsec_port_ability_t *)&pc->fiber.advert_ability; 1594 } 1595 } 1596 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1597 rv = bmacsec_phy54380_an_set(phy_dev_addr, port_mode, 1598 autoneg, autoneg_advert); 1599 if(BMACSEC_E_SUCCESS(rv)) { 1600 if(PHY_COPPER_MODE(unit, port)) { 1601 pc->copper.autoneg_enable = autoneg ? TRUE : FALSE; 1602 } else { 1603 if(PHY_FIBER_MODE(unit, port)) { 1604 pc->fiber.autoneg_enable = autoneg ? TRUE : FALSE; 1605 } 1606 } 1607 } 1608 1609 LOG_INFO(BSL_LS_SOC_PHY, 1610 (BSL_META_U(unit, 1611 "phy_54380_autoneg_set: u=%d p=%d autoneg=%d rv=%d\n"), 1612 unit, port, autoneg, rv)); 1613 return SOC_ERROR(rv); 1614 } 1615 1616 /* 1617 * Function: 1618 * phy_54380_autoneg_get 1619 * Purpose: 1620 * Get the current auto-negotiation status (enabled/busy). 1621 * Parameters: 1622 * unit - StrataSwitch unit #. 1623 * port - StrataSwitch port #. 1624 * autoneg - (OUT) if true, auto-negotiation is enabled. 1625 * autoneg_done - (OUT) if true, auto-negotiation is complete. This 1626 * value is undefined if autoneg == FALSE. 1627 * Returns: 1628 * SOC_E_XXX 1629 * Notes: 1630 * The autoneg mode is retrieved for the ACTIVE medium. 1631 */ 1632 1633 STATIC int 1634 phy_54380_autoneg_get(int unit, soc_port_t port, 1635 int *autoneg, int *autoneg_done) 1636 { 1637 int rv; 1638 phy_ctrl_t *pc; 1639 bmacsec_phy_port_mode_t port_mode = 0; 1640 bmacsec_dev_addr_t phy_dev_addr; 1641 1642 pc = EXT_PHY_SW_STATE(unit, port); 1643 1644 rv = SOC_E_NONE; 1645 *autoneg = FALSE; 1646 *autoneg_done = FALSE; 1647 1648 if(PHY_COPPER_MODE(unit, port)) { 1649 port_mode = BMACSEC_PHY_COPPER; 1650 } else { 1651 if(PHY_FIBER_MODE(unit, port)) { 1652 port_mode = BMACSEC_PHY_FIBER; 1653 } 1654 } 1655 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1656 rv = bmacsec_phy54380_an_get(phy_dev_addr, port_mode, autoneg, 1657 autoneg_done); 1658 1659 return SOC_ERROR(rv); 1660 } 1661 1662 /* 1663 * Function: 1664 * phy_54380_ability_advert_set 1665 * Purpose: 1666 * Set the current advertisement for auto-negotiation. 1667 * Parameters: 1668 * unit - StrataSwitch unit #. 1669 * port - StrataSwitch port #. 1670 * mode - Port mode mask indicating supported options/speeds. 1671 * Returns: 1672 * SOC_E_XXX 1673 * Notes: 1674 * The advertisement is set only for the ACTIVE medium. 1675 * No synchronization performed at this level. 1676 */ 1677 STATIC int 1678 phy_54380_ability_advert_set(int unit, soc_port_t port, soc_port_ability_t *ability) 1679 { 1680 int rv = SOC_E_NONE; 1681 phy_ctrl_t *pc; 1682 bmacsec_phy_port_mode_t port_mode = 0; 1683 bmacsec_port_ability_t bmacsec_ability ; 1684 bmacsec_dev_addr_t phy_dev_addr; 1685 1686 pc = EXT_PHY_SW_STATE(unit, port); 1687 rv = SOC_E_NONE; 1688 1689 1690 if(PHY_COPPER_MODE(unit, port)) { 1691 port_mode = BMACSEC_PHY_COPPER; 1692 } else { 1693 if(PHY_FIBER_MODE(unit, port)) { 1694 port_mode = BMACSEC_PHY_FIBER; 1695 } 1696 } 1697 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1698 1699 1700 sal_memset(&bmacsec_ability, 0, sizeof(bmacsec_port_ability_t)); 1701 phy_54380_pa_2_bmacsec_pa(ability, &bmacsec_ability); 1702 1703 rv = bmacsec_phy54380_ability_advert_set(phy_dev_addr, port_mode, &bmacsec_ability); 1704 if(BMACSEC_E_SUCCESS(rv)) { 1705 if(PHY_COPPER_MODE(unit, port)) { 1706 pc->copper.advert_ability = *ability; 1707 } else { 1708 if(PHY_FIBER_MODE(unit, port)) { 1709 pc->fiber.advert_ability = *ability; 1710 } else { 1711 } 1712 } 1713 } 1714 1715 LOG_INFO(BSL_LS_SOC_PHY, 1716 (BSL_META_U(unit, 1717 "phy_54380_adv_local_set: u=%d p=%d ability_hd_speed=0x%x, ability_fd_speed=0x%x, ability_pause=0x%x, rv=%d\n"), 1718 unit, port, ability->speed_half_duplex, ability->speed_full_duplex, ability->pause, rv)); 1719 return (SOC_ERROR(rv)); 1720 } 1721 1722 /* 1723 * Function: 1724 * phy_54380_adv_local_get 1725 * Purpose: 1726 * Get the current advertisement for auto-negotiation. 1727 * Parameters: 1728 * unit - StrataSwitch unit #. 1729 * port - StrataSwitch port #. 1730 * mode - (OUT) Port mode mask indicating supported options/speeds. 1731 * Returns: 1732 * SOC_E_XXX 1733 * Notes: 1734 * The advertisement is retrieved for the ACTIVE medium. 1735 * No synchronization performed at this level. 1736 */ 1737 1738 STATIC int 1739 phy_54380_ability_advert_get(int unit, soc_port_t port, soc_port_ability_t *ability) 1740 { 1741 1742 int rv = SOC_E_NONE; 1743 bmacsec_port_ability_t bmacsec_ability; 1744 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 1745 phy_ctrl_t *pc; 1746 bmacsec_dev_addr_t phy_dev_addr; 1747 1748 if (NULL == ability) { 1749 return SOC_E_PARAM; 1750 } 1751 sal_memset(ability, 0, sizeof(soc_port_ability_t)); /* zero initialize */ 1752 1753 pc = EXT_PHY_SW_STATE(unit, port); 1754 rv = SOC_E_NONE; 1755 1756 if(PHY_COPPER_MODE(unit, port)) { 1757 port_mode = BMACSEC_PHY_COPPER; 1758 } else { 1759 if(PHY_FIBER_MODE(unit, port)) { 1760 port_mode = BMACSEC_PHY_FIBER; 1761 } 1762 } 1763 1764 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1765 1766 rv = bmacsec_phy54380_ability_advert_get(phy_dev_addr, port_mode, 1767 &bmacsec_ability); 1768 1769 phy_54380_bmacsec_pa_2_pa( &bmacsec_ability, ability); 1770 1771 LOG_INFO(BSL_LS_SOC_PHY, 1772 (BSL_META_U(unit, 1773 "phy_54380_adv_local_get: u=%d p=%d ability_hd_speed=0x%x, ability_fd_speed=0x%x, ability_pause=0x%x, rv=%d\n"), 1774 unit, port, ability->speed_half_duplex, ability->speed_full_duplex, ability->pause, rv)); 1775 1776 return (SOC_ERROR(rv)); 1777 1778 } 1779 1780 /* 1781 * Function: 1782 * phy_54380_ability_remote_get 1783 * Purpose: 1784 * Get partners current advertisement for auto-negotiation. 1785 * Parameters: 1786 * unit - StrataSwitch unit #. 1787 * port - StrataSwitch port #. 1788 * mode - (OUT) Port mode mask indicating supported options/speeds. 1789 * Returns: 1790 * SOC_E_XXX 1791 * Notes: 1792 * The remote advertisement is retrieved for the ACTIVE medium. 1793 * No synchronization performed at this level. If Autonegotiation is 1794 * disabled or in progress, this routine will return an error. 1795 */ 1796 1797 STATIC int 1798 phy_54380_ability_remote_get(int unit, soc_port_t port, soc_port_ability_t *ability) 1799 { 1800 int rv, eee_enable = FALSE; 1801 phy_ctrl_t *pc; 1802 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 1803 bmacsec_port_ability_t bmacsec_ability; 1804 bmacsec_dev_addr_t phy_dev_addr; 1805 1806 if (NULL == ability) { 1807 return SOC_E_PARAM; 1808 } 1809 1810 sal_memset(ability, 0, sizeof(soc_port_ability_t)); /*zero init*/ 1811 1812 pc = EXT_PHY_SW_STATE(unit, port); 1813 rv = SOC_E_NONE; 1814 1815 if(PHY_COPPER_MODE(unit, port)) { 1816 port_mode = BMACSEC_PHY_COPPER; 1817 } else { 1818 if(PHY_FIBER_MODE(unit, port)) { 1819 port_mode = BMACSEC_PHY_FIBER; 1820 } 1821 } 1822 1823 if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 1824 eee_enable = TRUE; 1825 } 1826 1827 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1828 rv = bmacsec_phy54380_ability_remote_get(phy_dev_addr, port_mode, 1829 &bmacsec_ability, eee_enable); 1830 1831 phy_54380_bmacsec_pa_2_pa( &bmacsec_ability, ability); 1832 1833 LOG_INFO(BSL_LS_SOC_PHY, 1834 (BSL_META_U(unit, 1835 "phy_54380_adv_remote_get: u=%d p=%d ability_hd_speed=0x%x ability_fd_speed=0x%x ability_pause=0x%x rv=%d\n"), unit, port, ability->speed_half_duplex, ability->speed_full_duplex, ability->pause, rv)); 1836 1837 return (SOC_ERROR(rv)); 1838 } 1839 1840 /* 1841 * Function: 1842 * phy_54380_lb_set 1843 * Purpose: 1844 * Set the local PHY loopback mode. 1845 * Parameters: 1846 * unit - StrataSwitch unit #. 1847 * port - StrataSwitch port #. 1848 * loopback - Boolean: true = enable loopback, false = disable. 1849 * Returns: 1850 * SOC_E_XXX 1851 * Notes: 1852 * The loopback mode is set only for the ACTIVE medium. 1853 * No synchronization performed at this level. 1854 */ 1855 1856 STATIC int 1857 phy_54380_lb_set(int unit, soc_port_t port, int enable) 1858 { 1859 int rv = SOC_E_NONE; 1860 phy_ctrl_t *pc; 1861 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 1862 bmacsec_dev_addr_t phy_dev_addr; 1863 1864 pc = EXT_PHY_SW_STATE(unit, port); 1865 rv = SOC_E_NONE; 1866 1867 if(PHY_COPPER_MODE(unit, port)) { 1868 port_mode = BMACSEC_PHY_COPPER; 1869 } else { 1870 if(PHY_FIBER_MODE(unit, port)) { 1871 port_mode = BMACSEC_PHY_FIBER; 1872 } 1873 } 1874 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1875 rv = bmacsec_phy54380_loopback_set(phy_dev_addr, port_mode, enable); 1876 1877 LOG_INFO(BSL_LS_SOC_PHY, 1878 (BSL_META_U(unit, 1879 "phy_54380_lb_set: u=%d p=%d en=%d rv=%d\n"), 1880 unit, port, enable, rv)); 1881 return SOC_ERROR(rv); 1882 } 1883 1884 /* 1885 * Function: 1886 * phy_54380_lb_get 1887 * Purpose: 1888 * Get the local PHY loopback mode. 1889 * Parameters: 1890 * unit - StrataSwitch unit #. 1891 * port - StrataSwitch port #. 1892 * loopback - (OUT) Boolean: true = enable loopback, false = disable. 1893 * Returns: 1894 * SOC_E_XXX 1895 * Notes: 1896 * The loopback mode is retrieved for the ACTIVE medium. 1897 */ 1898 1899 STATIC int 1900 phy_54380_lb_get(int unit, soc_port_t port, int *enable) 1901 { 1902 int rv; 1903 phy_ctrl_t *pc; 1904 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 1905 bmacsec_dev_addr_t phy_dev_addr; 1906 1907 pc = EXT_PHY_SW_STATE(unit, port); 1908 rv = SOC_E_NONE; 1909 1910 if(PHY_COPPER_MODE(unit, port)) { 1911 port_mode = BMACSEC_PHY_COPPER; 1912 } else { 1913 if(PHY_FIBER_MODE(unit, port)) { 1914 port_mode = BMACSEC_PHY_FIBER; 1915 } 1916 } 1917 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 1918 rv = bmacsec_phy54380_loopback_get(phy_dev_addr, port_mode, enable); 1919 1920 return SOC_ERROR(rv); 1921 } 1922 1923 /* 1924 * Function: 1925 * phy_54380_interface_set 1926 * Purpose: 1927 * Set the current operating mode of the PHY. 1928 * Parameters: 1929 * unit - StrataSwitch unit #. 1930 * port - StrataSwitch port #. 1931 * pif - one of SOC_PORT_IF_* 1932 * Returns: 1933 * SOC_E_NONE - success 1934 * SOC_E_UNAVAIL - unsupported interface 1935 */ 1936 1937 STATIC int 1938 phy_54380_interface_set(int unit, soc_port_t port, soc_port_if_t pif) 1939 { 1940 COMPILER_REFERENCE(unit); 1941 COMPILER_REFERENCE(port); 1942 1943 switch (pif) { 1944 case SOC_PORT_IF_SGMII: 1945 case SOC_PORT_IF_GMII: 1946 return SOC_E_NONE; 1947 default: 1948 return SOC_E_UNAVAIL; 1949 } 1950 } 1951 1952 /* 1953 * Function: 1954 * phy_54380_interface_get 1955 * Purpose: 1956 * Get the current operating mode of the PHY. 1957 * Parameters: 1958 * unit - StrataSwitch unit #. 1959 * port - StrataSwitch port #. 1960 * pif - (OUT) one of SOC_PORT_IF_* 1961 * Returns: 1962 * SOC_E_NONE 1963 */ 1964 1965 STATIC int 1966 phy_54380_interface_get(int unit, soc_port_t port, soc_port_if_t *pif) 1967 { 1968 COMPILER_REFERENCE(unit); 1969 COMPILER_REFERENCE(port); 1970 1971 *pif = SOC_PORT_IF_SGMII; 1972 1973 return SOC_E_NONE; 1974 } 1975 1976 /* 1977 * Function: 1978 * phy_54380_ability_local_get 1979 * Purpose: 1980 * Get the abilities of the local gigabit PHY. 1981 * Parameters: 1982 * unit - StrataSwitch unit #. 1983 * port - StrataSwitch port #. 1984 * mode - (OUT) Port mode mask indicating supported options/speeds. 1985 * Returns: 1986 * SOC_E_NONE 1987 * Notes: 1988 * The ability is retrieved only for the ACTIVE medium. 1989 */ 1990 1991 STATIC int 1992 phy_54380_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability) 1993 { 1994 int rv; 1995 phy_ctrl_t *pc; 1996 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 1997 bmacsec_dev_addr_t phy_dev_addr; 1998 bmacsec_port_ability_t bmacsec_ability; 1999 2000 rv = SOC_E_NONE; 2001 2002 if (NULL == ability) { 2003 return SOC_E_PARAM; 2004 } 2005 2006 sal_memset(ability, 0, sizeof(soc_port_ability_t)); /* zero initialize */ 2007 2008 sal_memset(&bmacsec_ability, 0, sizeof(bmacsec_port_ability_t)); /* zero initialize */ 2009 2010 if(PHY_COPPER_MODE(unit, port)) { 2011 port_mode = BMACSEC_PHY_COPPER; 2012 ability->medium = SOC_PA_MEDIUM_COPPER; 2013 } else { 2014 if(PHY_FIBER_MODE(unit, port)) { 2015 port_mode = BMACSEC_PHY_FIBER; 2016 ability->medium = SOC_PA_MEDIUM_FIBER; 2017 } 2018 } 2019 2020 ability->interface = SOC_PA_INTF_SGMII; 2021 2022 pc = EXT_PHY_SW_STATE(unit, port); 2023 2024 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2025 2026 rv = bmacsec_phy54380_ability_get(phy_dev_addr, port_mode, &bmacsec_ability); 2027 if (rv != BMACSEC_E_NONE) { 2028 return SOC_E_FAIL; 2029 } 2030 2031 if(bmacsec_ability.speed_full_duplex & BMACSEC_PA_SPEED_1000MB) { 2032 ability->speed_full_duplex |= SOC_PA_SPEED_1000MB; 2033 } 2034 if(bmacsec_ability.speed_full_duplex & BMACSEC_PA_SPEED_100MB) { 2035 ability->speed_full_duplex |= SOC_PA_SPEED_100MB; 2036 } 2037 if(bmacsec_ability.speed_full_duplex & BMACSEC_PA_SPEED_10MB) { 2038 ability->speed_full_duplex |= SOC_PA_SPEED_10MB; 2039 } 2040 if(bmacsec_ability.speed_half_duplex & BMACSEC_PA_SPEED_1000MB) { 2041 ability->speed_half_duplex |= SOC_PA_SPEED_1000MB; 2042 } 2043 if(bmacsec_ability.speed_half_duplex & BMACSEC_PA_SPEED_100MB) { 2044 ability->speed_half_duplex |= SOC_PA_SPEED_100MB; 2045 } 2046 if(bmacsec_ability.speed_half_duplex & BMACSEC_PA_SPEED_10MB) { 2047 ability->speed_half_duplex |= SOC_PA_SPEED_10MB; 2048 } 2049 if(bmacsec_ability.pause & BMACSEC_PA_PAUSE_TX) { 2050 ability->pause |= SOC_PA_PAUSE_TX; 2051 } 2052 if(bmacsec_ability.pause & BMACSEC_PA_PAUSE_RX) { 2053 ability->pause |= SOC_PA_PAUSE_RX; 2054 } 2055 if(bmacsec_ability.pause & BMACSEC_PA_PAUSE_ASYMM) { 2056 ability->pause |= SOC_PA_PAUSE_ASYMM; 2057 } 2058 if(bmacsec_ability.loopback & BMACSEC_PA_LB_NONE) { 2059 ability->loopback |= SOC_PA_LB_NONE; 2060 } 2061 if(bmacsec_ability.loopback & BMACSEC_PA_LB_PHY) { 2062 ability->loopback |= SOC_PA_LB_PHY; 2063 } 2064 if(bmacsec_ability.flags & BMACSEC_PA_AUTONEG) { 2065 ability->flags |= SOC_PA_AUTONEG; 2066 } 2067 if(bmacsec_ability.eee & BMACSEC_PA_EEE_1GB_BASET) { 2068 ability->eee |= SOC_PA_EEE_1GB_BASET; 2069 } 2070 if(bmacsec_ability.eee & BMACSEC_PA_EEE_100MB_BASETX) { 2071 ability->eee |= SOC_PA_EEE_100MB_BASETX; 2072 } 2073 2074 if (pc->automedium) { 2075 ability->flags |= SOC_PA_COMBO; 2076 } 2077 2078 2079 LOG_INFO(BSL_LS_SOC_PHY, 2080 (BSL_META_U(unit, 2081 "phy_54380_ability_local_get: u=%d p=%d ability_hd_speed=0x%x, ability_fd_speed=0x%x, ability_pause=0x%x, rv=%d\n"), 2082 unit, port, ability->speed_half_duplex, ability->speed_full_duplex, ability->pause, rv)); 2083 return SOC_E_NONE; 2084 } 2085 2086 /* 2087 * Function: 2088 * phy_54380_mdix_set 2089 * Description: 2090 * Set the Auto-MDIX mode of a port/PHY 2091 * Parameters: 2092 * unit - Device number 2093 * port - Port number 2094 * mode - One of: 2095 * SOC_PORT_MDIX_AUTO 2096 * Enable auto-MDIX when autonegotiation is enabled 2097 * SOC_PORT_MDIX_FORCE_AUTO 2098 * Enable auto-MDIX always 2099 * SOC_PORT_MDIX_NORMAL 2100 * Disable auto-MDIX 2101 * SOC_PORT_MDIX_XOVER 2102 * Disable auto-MDIX, and swap cable pairs 2103 * Return Value: 2104 * SOC_E_XXX 2105 */ 2106 STATIC int 2107 phy_54380_mdix_set(int unit, soc_port_t port, soc_port_mdix_t mode) 2108 { 2109 2110 int rv = SOC_E_NONE; 2111 phy_ctrl_t *pc; 2112 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 2113 bmacsec_dev_addr_t phy_dev_addr; 2114 bmacsec_port_mdix_t bmacsec_mode; 2115 2116 pc = EXT_PHY_SW_STATE(unit, port); 2117 2118 if(PHY_COPPER_MODE(unit, port)) { 2119 port_mode = BMACSEC_PHY_COPPER; 2120 } else { 2121 if(PHY_FIBER_MODE(unit, port)) { 2122 port_mode = BMACSEC_PHY_FIBER; 2123 if (mode != SOC_PORT_MDIX_NORMAL) { 2124 return SOC_E_UNAVAIL; 2125 } 2126 } 2127 } 2128 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2129 switch(mode) { 2130 case SOC_PORT_MDIX_AUTO: 2131 bmacsec_mode = BMACSEC_PORT_MDIX_AUTO; 2132 break; 2133 case SOC_PORT_MDIX_FORCE_AUTO: 2134 bmacsec_mode = BMACSEC_PORT_MDIX_FORCE_AUTO; 2135 break; 2136 case SOC_PORT_MDIX_NORMAL: 2137 bmacsec_mode = BMACSEC_PORT_MDIX_NORMAL; 2138 break; 2139 case SOC_PORT_MDIX_XOVER: 2140 bmacsec_mode = BMACSEC_PORT_MDIX_XOVER; 2141 break; 2142 default : 2143 return SOC_E_CONFIG; 2144 } 2145 2146 rv = bmacsec_phy54380_mdix_set(phy_dev_addr, port_mode, bmacsec_mode); 2147 2148 if(BMACSEC_E_SUCCESS(rv)) { 2149 if(PHY_COPPER_MODE(unit, port)) { 2150 pc->copper.mdix = mode; 2151 } 2152 } 2153 return SOC_ERROR(rv); 2154 } 2155 2156 /* 2157 * Function: 2158 * phy_54380_mdix_get 2159 * Description: 2160 * Get the Auto-MDIX mode of a port/PHY 2161 * Parameters: 2162 * unit - Device number 2163 * port - Port number 2164 * mode - (Out) One of: 2165 * SOC_PORT_MDIX_AUTO 2166 * Enable auto-MDIX when autonegotiation is enabled 2167 * SOC_PORT_MDIX_FORCE_AUTO 2168 * Enable auto-MDIX always 2169 * SOC_PORT_MDIX_NORMAL 2170 * Disable auto-MDIX 2171 * SOC_PORT_MDIX_XOVER 2172 * Disable auto-MDIX, and swap cable pairs 2173 * Return Value: 2174 * SOC_E_XXX 2175 */ 2176 STATIC int 2177 phy_54380_mdix_get(int unit, soc_port_t port, soc_port_mdix_t *mode) 2178 { 2179 phy_ctrl_t *pc; 2180 int speed; 2181 2182 if (mode == NULL) { 2183 return SOC_E_PARAM; 2184 } 2185 2186 pc = EXT_PHY_SW_STATE(unit, port); 2187 2188 if (PHY_COPPER_MODE(unit, port)) { 2189 SOC_IF_ERROR_RETURN(phy_54380_speed_get(unit, port, &speed)); 2190 if (speed == 1000) { 2191 *mode = SOC_PORT_MDIX_AUTO; 2192 } else { 2193 *mode = pc->copper.mdix; 2194 } 2195 } else { 2196 *mode = SOC_PORT_MDIX_NORMAL; 2197 } 2198 2199 return SOC_E_NONE; 2200 } 2201 2202 /* 2203 * Function: 2204 * phy_54380_mdix_status_get 2205 * Description: 2206 * Get the current MDIX status on a port/PHY 2207 * Parameters: 2208 * unit - Device number 2209 * port - Port number 2210 * status - (OUT) One of: 2211 * SOC_PORT_MDIX_STATUS_NORMAL 2212 * Straight connection 2213 * SOC_PORT_MDIX_STATUS_XOVER 2214 * Crossover has been performed 2215 * Return Value: 2216 * SOC_E_XXX 2217 */ 2218 STATIC int 2219 phy_54380_mdix_status_get(int unit, soc_port_t port, 2220 soc_port_mdix_status_t *status) 2221 { 2222 int rv; 2223 phy_ctrl_t *pc; 2224 2225 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 2226 bmacsec_dev_addr_t phy_dev_addr; 2227 bmacsec_port_mdix_status_t mdix_status; 2228 2229 if (status == NULL) { 2230 return SOC_E_PARAM; 2231 } 2232 2233 pc = EXT_PHY_SW_STATE(unit, port); 2234 2235 if(PHY_COPPER_MODE(unit, port)) { 2236 port_mode = BMACSEC_PHY_COPPER; 2237 } else { 2238 if(PHY_FIBER_MODE(unit, port)) { 2239 port_mode = BMACSEC_PHY_FIBER; 2240 } 2241 } 2242 2243 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2244 rv = bmacsec_phy54380_mdix_status_get(phy_dev_addr, port_mode, 2245 &mdix_status); 2246 if(BMACSEC_E_SUCCESS(rv)) { 2247 if(mdix_status == BMACSEC_PORT_MDIX_STATUS_NORMAL) { 2248 *status = SOC_PORT_MDIX_STATUS_NORMAL; 2249 } 2250 if(mdix_status == BMACSEC_PORT_MDIX_STATUS_XOVER) { 2251 *status = SOC_PORT_MDIX_STATUS_XOVER; 2252 } 2253 return SOC_E_NONE; 2254 } 2255 2256 return SOC_ERROR(rv); 2257 } 2258 2259 2260 2261 /* 2262 * Function: 2263 * phy_54380_timesync_config_set 2264 * Description: 2265 * 2266 * Parameters: 2267 * 2268 * Return Value: 2269 * SOC_E_XXX 2270 */ 2271 2272 int 2273 phy_54380_timesync_config_set(int unit, soc_port_t port, soc_port_phy_timesync_config_t *timesync_config) 2274 { 2275 int rv; 2276 phy_ctrl_t *pc; 2277 bmacsec_dev_addr_t phy_dev_addr; 2278 2279 pc = EXT_PHY_SW_STATE(unit, port); 2280 rv = SOC_E_NONE; 2281 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2282 2283 rv = bmacsec_phy54380_timesync_config_set(phy_dev_addr, (bmacsec_port_phy_timesync_config_t *)timesync_config); 2284 return (SOC_ERROR(rv)); 2285 2286 } 2287 2288 2289 /* 2290 * Function: 2291 * phy_54380_timesync_config_get 2292 * Description: 2293 * 2294 * Parameters: 2295 * 2296 * Return Value: 2297 * SOC_E_XXX 2298 */ 2299 2300 int 2301 phy_54380_timesync_config_get(int unit, soc_port_t port, soc_port_phy_timesync_config_t *timesync_config) 2302 { 2303 int rv; 2304 phy_ctrl_t *pc; 2305 bmacsec_dev_addr_t phy_dev_addr; 2306 2307 pc = EXT_PHY_SW_STATE(unit, port); 2308 rv = SOC_E_NONE; 2309 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2310 2311 rv = bmacsec_phy54380_timesync_config_get(phy_dev_addr, (bmacsec_port_phy_timesync_config_t *)timesync_config); 2312 return (SOC_ERROR(rv)); 2313 2314 } 2315 2316 2317 /* 2318 * Function: 2319 * phy_54380_timesync_control_set 2320 * Description: 2321 * 2322 * Parameters: 2323 * 2324 * Return Value: 2325 * SOC_E_XXX 2326 */ 2327 2328 int 2329 phy_54380_timesync_control_set(int unit, soc_port_t port, soc_port_control_phy_timesync_t control_type, uint64 value) 2330 { 2331 int rv; 2332 phy_ctrl_t *pc; 2333 bmacsec_dev_addr_t phy_dev_addr; 2334 buint64_t btemp64; 2335 2336 COMPILER_64_SET(btemp64, COMPILER_64_HI(value), COMPILER_64_LO(value)); 2337 2338 pc = EXT_PHY_SW_STATE(unit, port); 2339 rv = SOC_E_NONE; 2340 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2341 2342 rv = bmacsec_phy54380_timesync_control_set(phy_dev_addr, 2343 (bmacsec_port_phy_control_timesync_t) control_type, btemp64); 2344 return (SOC_ERROR(rv)); 2345 2346 } 2347 2348 2349 2350 /* 2351 * Function: 2352 * phy_54380_timesync_control_get 2353 * Description: 2354 * 2355 * Parameters: 2356 * 2357 * Return Value: 2358 * SOC_E_XXX 2359 */ 2360 int 2361 phy_54380_timesync_control_get(int unit, soc_port_t port, soc_port_control_phy_timesync_t control_type, uint64 *value) 2362 { 2363 int rv; 2364 phy_ctrl_t *pc; 2365 bmacsec_dev_addr_t phy_dev_addr; 2366 buint64_t btemp64; 2367 2368 COMPILER_64_ZERO(btemp64); 2369 pc = EXT_PHY_SW_STATE(unit, port); 2370 rv = SOC_E_NONE; 2371 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2372 2373 rv = bmacsec_phy54380_timesync_control_get(phy_dev_addr, 2374 (bmacsec_port_phy_control_timesync_t) control_type, &btemp64); 2375 2376 COMPILER_64_SET(*value, COMPILER_64_HI(btemp64), COMPILER_64_LO(btemp64)); 2377 2378 return (SOC_ERROR(rv)); 2379 2380 } 2381 2382 /* 2383 * Function: 2384 * phy_54380_cable_diag_dispatch 2385 * Purpose: 2386 * Run 54380 cable diagnostics 2387 * Parameters: 2388 * unit - device number 2389 * port - port number 2390 * status - (OUT) cable diagnotic status structure 2391 * Returns: 2392 * SOC_E_XXX 2393 */ 2394 STATIC int 2395 phy_54380_cable_diag_dispatch(int unit, soc_port_t port, 2396 soc_port_cable_diag_t *status) 2397 { 2398 /*ECD_CTRL :break link */ 2399 uint16 ecd_ctrl = 0x1000; 2400 2401 2402 SOC_IF_ERROR_RETURN( 2403 phy_ecd_cable_diag_init_40nm(unit, port)); 2404 2405 SOC_IF_ERROR_RETURN( 2406 phy_ecd_cable_diag_40nm(unit, port, status, ecd_ctrl)); 2407 return SOC_E_NONE; 2408 } 2409 2410 2411 /* 2412 * Function: 2413 * phy_54380_control_set 2414 * Purpose: 2415 * Configure PHY device specific control fucntion. 2416 * Parameters: 2417 * unit - StrataSwitch unit #. 2418 * port - StrataSwitch port #. 2419 * type - Control to update 2420 * value - New setting for the control 2421 * Returns: 2422 * SOC_E_NONE 2423 */ 2424 STATIC int 2425 phy_54380_control_set(int unit, soc_port_t port, 2426 soc_phy_control_t type, uint32 value) 2427 { 2428 int rv, offset; 2429 phy_ctrl_t *pc; 2430 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 2431 bmacsec_dev_addr_t phy_dev_addr; 2432 soc_phy_config_t phy_config; 2433 2434 pc = EXT_PHY_SW_STATE(unit, port); 2435 2436 if(PHY_COPPER_MODE(unit, port)) { 2437 port_mode = BMACSEC_PHY_COPPER; 2438 } else { 2439 if(PHY_FIBER_MODE(unit, port)) { 2440 port_mode = BMACSEC_PHY_FIBER; 2441 } else { 2442 return SOC_E_NONE; 2443 } 2444 } 2445 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2446 2447 rv = BMACSEC_E_NONE; 2448 2449 /* PHY Control types APIs*/ 2450 switch ( type ) { 2451 #if 0 2452 case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED: 2453 pc->macsec_switch_fixed = value; 2454 if ( value ) { 2455 rv = bmacsec_phy54380_switch_side_set_params(phy_dev_addr, 2456 BMACSEC_BCM54380_SWITCH_FIXED, 2457 pc->macsec_switch_fixed_speed, 2458 pc->macsec_switch_fixed_duplex, 2459 pc->macsec_switch_fixed_pause); 2460 } else { /* Switch side follows line side */ 2461 rv = bmacsec_phy54380_switch_side_set_params(phy_dev_addr, 2462 BMACSEC_BCM54380_SWITCH_FOLLOWS_LINE, 2463 -1, -1, -1); 2464 } 2465 break; 2466 #endif 2467 /* CLOCK CONTROLS */ 2468 case SOC_PHY_CONTROL_CLOCK_ENABLE: 2469 SOC_IF_ERROR_RETURN 2470 (soc_phyctrl_offset_get(unit, port, &offset)); 2471 bmacsec_phy54380_clock_enable_set(phy_dev_addr, offset, value); 2472 break; 2473 2474 case SOC_PHY_CONTROL_CLOCK_SECONDARY_ENABLE: 2475 SOC_IF_ERROR_RETURN 2476 (soc_phyctrl_offset_get(unit, port, &offset)); 2477 bmacsec_phy54380_clock_secondary_enable_set(phy_dev_addr, offset, value); 2478 break; 2479 2480 case SOC_PHY_CONTROL_CLOCK_FREQUENCY: 2481 return SOC_E_UNAVAIL; 2482 break; 2483 2484 case SOC_PHY_CONTROL_POWER: 2485 rv = bmacsec_phy54380_power_mode_set(phy_dev_addr, value); 2486 break; 2487 2488 case SOC_PHY_CONTROL_POWER_AUTO_WAKE_TIME: 2489 bmacsec_phy54380_power_auto_wake_time_set(phy_dev_addr, value); 2490 break; 2491 2492 case SOC_PHY_CONTROL_POWER_AUTO_SLEEP_TIME: 2493 bmacsec_phy54380_power_auto_sleep_time_set(phy_dev_addr, value); 2494 break; 2495 2496 case SOC_PHY_CONTROL_PORT_PRIMARY: 2497 SOC_IF_ERROR_RETURN 2498 (soc_phyctrl_primary_set(unit, port, (soc_port_t)value)); 2499 break; 2500 2501 case SOC_PHY_CONTROL_PORT_OFFSET: 2502 SOC_IF_ERROR_RETURN 2503 (soc_phyctrl_offset_set(unit, port, (int)value)); 2504 break; 2505 2506 case SOC_PHY_CONTROL_EEE: 2507 phy_config = pc->copper; 2508 if ( ! PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE) ) { 2509 rv = SOC_E_UNAVAIL; 2510 break; 2511 } 2512 if ( PHY_FIBER_MODE(unit, port) ) { 2513 phy_config = pc->fiber; 2514 /* PHY does not support EEE in fiber mode */ 2515 rv = SOC_E_UNAVAIL; 2516 break; 2517 } 2518 /* enable/disable EEE */ 2519 rv = bmacsec_phy_54380_eee_enable(phy_dev_addr, port_mode, 2520 (bmacsec_port_ability_t*) &phy_config.advert_ability, 2521 (value) ? 1 : 0 ); 2522 break; 2523 2524 case SOC_PHY_CONTROL_EEE_AUTO: 2525 if ( ! PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE) ) { 2526 rv = SOC_E_UNAVAIL; 2527 break; 2528 } 2529 if ( PHY_FIBER_MODE(unit, port) ) { 2530 phy_config = pc->fiber; 2531 /* PHY does not support EEE in fiber mode */ 2532 rv = SOC_E_UNAVAIL; 2533 break; 2534 } 2535 /* enable/disable AutoGrEEEn */ 2536 rv = bmacsec_phy_54380_eee_auto_enable(phy_dev_addr, 2537 (bmacsec_port_t) port, port_mode, 2538 (value) ? 1 : 0 ); 2539 break; 2540 2541 case SOC_PHY_CONTROL_EEE_AUTO_IDLE_THRESHOLD: 2542 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2543 rv = SOC_E_UNAVAIL; 2544 break; 2545 } 2546 SOC_IF_ERROR_RETURN 2547 (bmacsec_phy_54380_eee_control_set(phy_dev_addr, 2548 BMACSEC_PHY_54380_CONTROL_EEE_AUTO_IDLE_THRESHOLD, 2549 value)); 2550 break; 2551 2552 case SOC_PHY_CONTROL_EEE_AUTO_FIXED_LATENCY: 2553 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2554 rv = SOC_E_UNAVAIL; 2555 break; 2556 } 2557 SOC_IF_ERROR_RETURN 2558 (bmacsec_phy_54380_eee_control_set(phy_dev_addr, 2559 BMACSEC_PHY_54380_CONTROL_EEE_AUTO_FIXED_LATENCY, 2560 value)); 2561 break; 2562 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 2563 2564 if(PHY_COPPER_MODE(unit, port)) { 2565 SOC_IF_ERROR_RETURN( 2566 bmacsec_phy54380_remote_loopback_set(phy_dev_addr, port_mode, value)); 2567 }else{ 2568 return SOC_E_UNAVAIL; 2569 2570 } 2571 break; 2572 case SOC_PHY_CONTROL_EEE_AUTO_BUFFER_LIMIT: 2573 /* Buffer limit modification is not allowed */ 2574 case SOC_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME: 2575 case SOC_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME: 2576 case SOC_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME: 2577 case SOC_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME: 2578 case SOC_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME: 2579 case SOC_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME: 2580 case SOC_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME: 2581 return SOC_E_UNAVAIL; 2582 2583 case SOC_PHY_CONTROL_EEE_STATISTICS_CLEAR: 2584 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2585 rv = SOC_E_UNAVAIL; 2586 break; 2587 } 2588 SOC_IF_ERROR_RETURN 2589 (bmacsec_phy_54380_eee_control_set(phy_dev_addr, 2590 BMACSEC_PHY_54380_CONTROL_EEE_STATISTICS_CLEAR, 2591 value)); 2592 break; 2593 2594 case SOC_PHY_CONTROL_SUPER_ISOLATE: 2595 rv = bmacsec_phy54380_super_isolate_set(phy_dev_addr, value); 2596 break; 2597 2598 case SOC_PHY_CONTROL_MACSEC_ENABLE: 2599 rv = bmacsec_phy54380_macsec_enable(phy_dev_addr, 2600 pc->macsec_dev_addr, pc->macsec_enable); 2601 if ( rv != BMACSEC_E_NONE ) { 2602 return SOC_E_FAIL; 2603 } 2604 if ( pc->macsec_enable ) { 2605 rv = soc_macsecphy_init(unit, port, pc, 2606 BMACSEC_CORE_BCM5438X, bmacsec_io_mmi1_quad); 2607 if ( SOC_SUCCESS(rv) ) { 2608 LOG_INFO(BSL_LS_SOC_PHY, (BSL_META_U(unit, 2609 "MACSEC init for u=%d p=%d SUCCESS\n"), unit, port)); 2610 } else { 2611 LOG_ERROR(BSL_ERROR , (BSL_META_U(unit, 2612 "MACSEC init for u=%d p=%d FAIL !!\n"), unit, port)); 2613 } 2614 } 2615 break; 2616 2617 default: 2618 return SOC_E_UNAVAIL; 2619 } /* switch ( type ) */ 2620 2621 return (SOC_ERROR(rv)); 2622 } 2623 2624 /* 2625 * Function: 2626 * phy_54380_control_get 2627 * Purpose: 2628 * Get current control settign of the PHY. 2629 * Parameters: 2630 * unit - StrataSwitch unit #. 2631 * port - StrataSwitch port #. 2632 * type - Control to update 2633 * value - (OUT)Current setting for the control 2634 * Returns: 2635 * SOC_E_NONE 2636 */ 2637 STATIC int 2638 phy_54380_control_get(int unit, soc_port_t port, 2639 soc_phy_control_t type, uint32 *value) 2640 { 2641 int rv = SOC_E_NONE, offset; 2642 phy_ctrl_t *pc; 2643 bmacsec_dev_addr_t phy_dev_addr; 2644 soc_port_t primary; 2645 bmacsec_phy_port_mode_t port_mode = BMACSEC_PHY_COPPER; 2646 2647 pc = EXT_PHY_SW_STATE(unit, port); 2648 if(PHY_COPPER_MODE(unit, port)) { 2649 port_mode = BMACSEC_PHY_COPPER; 2650 } else { 2651 if(PHY_FIBER_MODE(unit, port)) { 2652 port_mode = BMACSEC_PHY_FIBER; 2653 } else { 2654 return SOC_E_NONE; 2655 } 2656 } 2657 2658 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2659 2660 if (NULL == value) { 2661 return SOC_E_PARAM; 2662 } 2663 2664 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 2665 return SOC_E_PARAM; 2666 } 2667 2668 /* PHY Control types APIs*/ 2669 switch ( type ) { 2670 2671 case SOC_PHY_CONTROL_POWER: 2672 *value = pc->power_mode; 2673 break; 2674 2675 case SOC_PHY_CONTROL_POWER_AUTO_SLEEP_TIME: 2676 bmacsec_phy54380_power_auto_sleep_time_get(phy_dev_addr, value); 2677 break; 2678 2679 case SOC_PHY_CONTROL_POWER_AUTO_WAKE_TIME: 2680 bmacsec_phy54380_power_auto_wake_time_get(phy_dev_addr, value); 2681 break; 2682 2683 case SOC_PHY_CONTROL_PORT_PRIMARY: 2684 SOC_IF_ERROR_RETURN 2685 (soc_phyctrl_primary_get(unit, port, &primary)); 2686 *value = (uint32) primary; 2687 break; 2688 2689 case SOC_PHY_CONTROL_PORT_OFFSET: 2690 SOC_IF_ERROR_RETURN 2691 (soc_phyctrl_offset_get(unit, port, &offset)); 2692 *value = (uint32) offset; 2693 break; 2694 2695 case SOC_PHY_CONTROL_CLOCK_ENABLE: 2696 SOC_IF_ERROR_RETURN 2697 (soc_phyctrl_offset_get(unit, port, &offset)); 2698 bmacsec_phy54380_clock_enable_get(phy_dev_addr, offset, value); 2699 break; 2700 2701 case SOC_PHY_CONTROL_CLOCK_SECONDARY_ENABLE: 2702 SOC_IF_ERROR_RETURN 2703 (soc_phyctrl_offset_get(unit, port, &offset)); 2704 bmacsec_phy54380_clock_secondary_enable_get(phy_dev_addr, offset, value); 2705 break; 2706 2707 case SOC_PHY_CONTROL_EEE: 2708 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2709 rv = SOC_E_UNAVAIL; 2710 break; 2711 } 2712 bmacsec_phy_54380_get_eee_control_status(phy_dev_addr, value); 2713 break; 2714 2715 case SOC_PHY_CONTROL_EEE_AUTO: 2716 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2717 rv = SOC_E_UNAVAIL; 2718 break; 2719 } 2720 bmacsec_phy_54380_get_auto_eee_control_status(phy_dev_addr, 2721 (bmacsec_port_t)port, value); 2722 break; 2723 2724 case SOC_PHY_CONTROL_EEE_AUTO_FIXED_LATENCY: 2725 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2726 rv = SOC_E_UNAVAIL; 2727 break; 2728 } 2729 SOC_IF_ERROR_RETURN 2730 (bmacsec_phy_54380_eee_control_get(phy_dev_addr, 2731 BMACSEC_PHY_54380_CONTROL_EEE_AUTO_FIXED_LATENCY, 2732 value)); 2733 break; 2734 2735 case SOC_PHY_CONTROL_EEE_AUTO_IDLE_THRESHOLD: 2736 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2737 rv = SOC_E_UNAVAIL; 2738 break; 2739 } 2740 SOC_IF_ERROR_RETURN 2741 (bmacsec_phy_54380_eee_control_get(phy_dev_addr, 2742 BMACSEC_PHY_54380_CONTROL_EEE_AUTO_IDLE_THRESHOLD, 2743 value)); 2744 break; 2745 2746 case SOC_PHY_CONTROL_EEE_TRANSMIT_EVENTS: 2747 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2748 rv = SOC_E_UNAVAIL; 2749 break; 2750 } 2751 SOC_IF_ERROR_RETURN 2752 (bmacsec_phy_54380_eee_control_get(phy_dev_addr, 2753 BMACSEC_PHY_54380_CONTROL_EEE_TRANSMIT_EVENTS, 2754 value)); 2755 break; 2756 2757 case SOC_PHY_CONTROL_EEE_TRANSMIT_DURATION: 2758 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2759 rv = SOC_E_UNAVAIL; 2760 break; 2761 } 2762 SOC_IF_ERROR_RETURN 2763 (bmacsec_phy_54380_eee_control_get(phy_dev_addr, 2764 BMACSEC_PHY_54380_CONTROL_EEE_TRANSMIT_DURATION, 2765 value)); 2766 break; 2767 2768 case SOC_PHY_CONTROL_EEE_RECEIVE_EVENTS: 2769 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2770 rv = SOC_E_UNAVAIL; 2771 break; 2772 } 2773 SOC_IF_ERROR_RETURN 2774 (bmacsec_phy_54380_eee_control_get(phy_dev_addr, 2775 BMACSEC_PHY_54380_CONTROL_EEE_RECEIVE_EVENTS, 2776 value)); 2777 break; 2778 2779 case SOC_PHY_CONTROL_EEE_RECEIVE_DURATION: 2780 if (!PHY_FLAGS_TST(unit, port, PHY_FLAGS_EEE_CAPABLE)) { 2781 rv = SOC_E_UNAVAIL; 2782 break; 2783 } 2784 SOC_IF_ERROR_RETURN 2785 (bmacsec_phy_54380_eee_control_get(phy_dev_addr, 2786 BMACSEC_PHY_54380_CONTROL_EEE_RECEIVE_DURATION, 2787 value)); 2788 break; 2789 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 2790 2791 if(PHY_COPPER_MODE(unit, port)) { 2792 SOC_IF_ERROR_RETURN( 2793 bmacsec_phy54380_remote_loopback_get(phy_dev_addr, port_mode, value)); 2794 }else{ 2795 return SOC_E_UNAVAIL; 2796 2797 } 2798 break; 2799 2800 default: 2801 return SOC_E_UNAVAIL; 2802 } /* switch ( type ) */ 2803 2804 return rv; 2805 } 2806 2807 STATIC int 2808 phy_54380_probe(int unit, phy_ctrl_t *pc) { 2809 int rv = SOC_E_NONE, oui = 0, model = 0, rev = 0; 2810 soc_phy_info_t *pi; 2811 bmacsec_dev_addr_t phy_dev_addr; 2812 2813 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2814 2815 phy54380_get_model_rev(phy_dev_addr, &oui, &model, &rev); 2816 2817 pi = &SOC_PHY_INFO(unit, pc->port); 2818 2819 switch (model) { 2820 2821 case PHY_BCM54380_MODEL: 2822 case PHY_BCM54340_MODEL: 2823 break; 2824 2825 case PHY_BCM54382_MODEL: 2826 /*case PHY_BCM54385_MODEL (same as PHY_BCM54382_MODEL) 2827 */ 2828 if (rev & 0x8) { 2829 /* 54382 detected - A0/B0/.. */ 2830 pi->phy_name = "BCM54382"; 2831 } else { 2832 /* 54385 detected */ 2833 pi->phy_name = "BCM54385"; 2834 } 2835 break; 2836 default: 2837 return SOC_E_NOT_FOUND; 2838 } 2839 return rv; 2840 } 2841 2842 2843 STATIC int 2844 phy_54380_link_up(int unit, soc_port_t port) 2845 { 2846 int speed; 2847 phy_ctrl_t *pc; 2848 pc = EXT_PHY_SW_STATE(unit, port); 2849 2850 /* get the speed status from line side */ 2851 SOC_IF_ERROR_RETURN 2852 (phy_54380_speed_get(unit, port, &speed)); 2853 2854 /* Notify interface to internal PHY */ 2855 SOC_IF_ERROR_RETURN 2856 (soc_phyctrl_notify(unit, port, phyEventInterface, SOC_PORT_IF_SGMII)); 2857 2858 /* Situation observed with Saber devices XGXS16g1l+BCM54640E 2859 Linkscan is not updating speed for internal phy xgxs16g1l. 2860 It was observed that when speed is set to 100M the int phy 2861 is still set to 1G and traffic does not flow through untill 2862 int phy speed is also update to 100M. This applies to other 2863 speeds as well. 2864 Explicitly send speed notify to int phy from ext phy. 2865 */ 2866 SOC_IF_ERROR_RETURN 2867 (soc_phyctrl_notify(unit, port, phyEventSpeed, speed)); 2868 2869 /* Check if MACSEC_SWITCH_SIDE_POLICY is DUPLEX_GATEWAY mode */ 2870 if ( (pc->macsec_enable) && 2871 (pc->macsec_mac_policy == BMACSEC_BCM54380_SWITCH_DUPLEX_GATEWAY) ) { 2872 int duplex; 2873 bmacsec_dev_addr_t phy_dev_addr; 2874 phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 0); 2875 2876 /* Duplex Gateway mode for supporting half-duplex-free switches: *\ 2877 |* When line-side PHY lilnks up at half-duplex, *| 2878 \* set half-duplex to line-side MAC, full-duplex to switch-side MAC*/ 2879 2880 /* get the duplex status from line side */ 2881 SOC_IF_ERROR_RETURN( 2882 phy_54380_duplex_get(unit, port, &duplex) ); 2883 if ( pc->macsec_switch_fixed_speed == speed && 2884 pc->macsec_switch_fixed_duplex == duplex) { 2885 return SOC_E_NONE; /* speed/duplex unchanged */ 2886 } 2887 2888 pc->macsec_switch_fixed_speed = speed; 2889 pc->macsec_switch_fixed_duplex = duplex; 2890 /* Config duplex Gateway parameters accordingly */ 2891 SOC_IF_ERROR_RETURN( 2892 bmacsec_phy54380_switch_side_set_params(phy_dev_addr, 2893 (bmacsec_phy_mac_policy_t) pc->macsec_mac_policy, 2894 speed, duplex, pc->macsec_switch_fixed_pause) ); 2895 /* under DUPLEX_GATEWAY mode, always Full-Duplex on system side */ 2896 SOC_IF_ERROR_RETURN 2897 (soc_phyctrl_notify(unit, port, phyEventDuplex, TRUE)); 2898 } 2899 2900 return SOC_E_NONE; 2901 } 2902 2903 /* 2904 * Variable: phy_54380drv_ge 2905 * Purpose: PHY driver for 54380 2906 */ 2907 phy_driver_t phy_54380drv_ge = { 2908 "54380 (MACSec PHY) Gigabit PHY Driver", 2909 phy_54380_init, 2910 phy_54380_reset, 2911 phy_54380_link_get, 2912 phy_54380_enable_set, 2913 phy_54380_enable_get, 2914 phy_54380_duplex_set, 2915 phy_54380_duplex_get, 2916 phy_54380_speed_set, 2917 phy_54380_speed_get, 2918 phy_54380_master_set, 2919 phy_54380_master_get, 2920 phy_54380_autoneg_set, 2921 phy_54380_autoneg_get, 2922 NULL, /* pd_adv_local_set */ 2923 NULL, /* pd_adv_local_get */ 2924 NULL, /* pd_adv_remote_get */ 2925 phy_54380_lb_set, 2926 phy_54380_lb_get, 2927 phy_54380_interface_set, 2928 phy_54380_interface_get, 2929 NULL, /* pd_ability */ 2930 phy_54380_link_up, /* pd_linkup */ 2931 NULL, /* pd_linkdn_evt */ 2932 phy_54380_mdix_set, 2933 phy_54380_mdix_get, 2934 phy_54380_mdix_status_get, 2935 phy_54380_medium_config_set, 2936 phy_54380_medium_config_get, 2937 phy_54380_medium_status, 2938 phy_54380_cable_diag_dispatch, 2939 NULL, /* pd_link_change */ 2940 phy_54380_control_set, 2941 phy_54380_control_get, 2942 phy_54380_reg_read, 2943 phy_54380_reg_write, 2944 phy_54380_reg_modify, 2945 NULL, /* pd_notify */ 2946 phy_54380_probe, 2947 phy_54380_ability_advert_set, 2948 phy_54380_ability_advert_get, 2949 phy_54380_ability_remote_get, 2950 phy_54380_ability_local_get, 2951 NULL, /* pd_firmware_set */ 2952 phy_54380_timesync_config_set, 2953 phy_54380_timesync_config_get, 2954 phy_54380_timesync_control_set, 2955 phy_54380_timesync_control_get 2956 }; 2957 2958 2959 #else /* INCLUDE_PHY_54380 */ 2960 int _soc_phy_54380_not_empty; 2961 #endif /* INCLUDE_PHY_54380 */ 2962 #endif /* INCLUDE_MACSEC */ 2963 2964