phyreg.c (37969B)
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: phy5482.c 8 * Purpose: PHY driver for BCM5482 and BCM5482S 9 */ 10 11 #include <sal/types.h> 12 #include <shared/bsl.h> 13 #include <soc/drv.h> 14 #include <soc/debug.h> 15 #include <soc/error.h> 16 #include <soc/phyreg.h> 17 18 #include <soc/ll.h> 19 #include <soc/phy/phyctrl.h> 20 21 #include "phydefs.h" /* Must include before other phy related includes */ 22 23 #include "phyreg.h" 24 25 #define _SOC_PHY_REG_DIRECT \ 26 ((SOC_PHY_REG_1000X << 1) | (SOC_PHY_REG_1000X >> 1)) 27 28 29 #define PHY_MODEL_CHECK(_pc, _oui, _model) \ 30 (((_pc)->phy_oui == (_oui)) && \ 31 ((_pc)->phy_model == (_model))) 32 33 34 /* SHAD_EXPD for 54640E (macros) */ 35 #define PHY_IS_BCM54640E(_pc) (PHY_MODEL_CHECK((_pc), \ 36 0x001be9, \ 37 0x27) \ 38 && (((_pc)->phy_rev & 0x8) == 0)) 39 40 uint16 phy54640e_save = 0; 41 #define BCM54640E_SHAD_EXPD_PRE(_unit, _pc, _reg_bank)\ 42 if (PHY_IS_BCM54640E((_pc)) && \ 43 ((_pc)->flags & PHYCTRL_IS_PORT0) && \ 44 (_reg_bank) != 0x0d01 && \ 45 ((_reg_bank) & 0xff00) == 0x0d00 ) { \ 46 SOC_IF_ERROR_RETURN \ 47 (WRITE_PHY_REG((_unit), (_pc), 0x17, 0x0d01)); \ 48 SOC_IF_ERROR_RETURN \ 49 (READ_PHY_REG((_unit), (_pc), 0x15, &phy54640e_save)); \ 50 } else { \ 51 phy54640e_save = 0; \ 52 } 53 54 #define BCM54640E_SHAD_EXPD_POST(_unit, _pc, _rv)\ 55 if ((SOC_SUCCESS(_rv)) && phy54640e_save != 0) { \ 56 _rv = WRITE_PHY_REG((_unit), (_pc), 0x17, 0x0d01); \ 57 if ((SOC_SUCCESS(_rv)) ) { \ 58 _rv = WRITE_PHY_REG((_unit), (_pc), 0x15, phy54640e_save); \ 59 } \ 60 phy54640e_save = 0; \ 61 } 62 63 64 int 65 phy_reg_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr, 66 uint16 reg_data, uint16 reg_mask) 67 { 68 uint16 tmp, otmp; 69 70 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 71 return SOC_E_NONE; 72 } 73 74 reg_data = reg_data & reg_mask; 75 76 SOC_IF_ERROR_RETURN 77 (READ_PHY_REG(unit, pc, reg_addr, &tmp)); 78 otmp = tmp; 79 tmp &= ~(reg_mask); 80 tmp |= reg_data; 81 82 if (otmp != tmp) { 83 SOC_IF_ERROR_RETURN 84 (WRITE_PHY_REG(unit, pc, reg_addr, tmp)); 85 } 86 return SOC_E_NONE; 87 } 88 int 89 phy_reg_fe_read(int unit, phy_ctrl_t *pc, uint16 reg_bank, 90 uint8 reg_addr, uint16 *data) 91 { 92 uint16 test_reg; 93 94 if (reg_bank) { 95 SOC_IF_ERROR_RETURN 96 (READ_PHY_REG(unit, pc, 0x1f, &test_reg)); 97 SOC_IF_ERROR_RETURN 98 (WRITE_PHY_REG(unit, pc, 0x1f, test_reg | 0x0080)); 99 100 SOC_IF_ERROR_RETURN 101 (READ_PHY_REG(unit, pc, reg_addr, data)); 102 SOC_IF_ERROR_RETURN 103 (WRITE_PHY_REG(unit, pc, 0x1f, test_reg)); 104 } else { 105 SOC_IF_ERROR_RETURN 106 (READ_PHY_REG(unit, pc, reg_addr, data)); 107 } 108 return SOC_E_NONE; 109 } 110 111 int 112 phy_reg_fe_write(int unit, phy_ctrl_t *pc, uint16 reg_bank, 113 uint8 reg_addr, uint16 data) 114 { 115 uint16 test_reg; 116 117 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 118 return SOC_E_NONE; 119 } 120 121 if (reg_bank) { 122 SOC_IF_ERROR_RETURN 123 (READ_PHY_REG(unit, pc, 0x1f, &test_reg)); 124 SOC_IF_ERROR_RETURN 125 (WRITE_PHY_REG(unit, pc, 0x1f, test_reg | 0x0080)); 126 127 SOC_IF_ERROR_RETURN 128 (WRITE_PHY_REG(unit, pc, reg_addr, data)); 129 SOC_IF_ERROR_RETURN 130 (WRITE_PHY_REG(unit, pc, 0x1f, test_reg)); 131 } else { 132 SOC_IF_ERROR_RETURN 133 (WRITE_PHY_REG(unit, pc, reg_addr, data)); 134 } 135 return SOC_E_NONE; 136 } 137 138 int 139 phy_reg_fe_modify(int unit, phy_ctrl_t *pc, uint16 reg_bank, 140 uint8 reg_addr, uint16 data, uint16 mask) 141 { 142 uint16 test_reg; 143 144 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 145 return SOC_E_NONE; 146 } 147 148 if (reg_bank) { 149 SOC_IF_ERROR_RETURN 150 (READ_PHY_REG(unit, pc, 0x1f, &test_reg)); 151 SOC_IF_ERROR_RETURN 152 (WRITE_PHY_REG(unit, pc, 0x1f, test_reg | 0x0080)); 153 154 SOC_IF_ERROR_RETURN 155 (MODIFY_PHY_REG(unit, pc, reg_addr, data, mask)); 156 SOC_IF_ERROR_RETURN 157 (WRITE_PHY_REG(unit, pc, 0x1f, test_reg)); 158 } else { 159 SOC_IF_ERROR_RETURN 160 (MODIFY_PHY_REG(unit, pc, reg_addr, data, mask)); 161 } 162 163 return SOC_E_NONE; 164 } 165 166 int 167 phy_reg_ge_read(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 168 uint8 reg_addr, uint16 *data) 169 { 170 int rv; 171 172 rv = SOC_E_NONE; 173 174 if (flags & SOC_PHY_REG_1000X) { 175 if (reg_addr <= 0x000f) { 176 uint16 blk_sel; 177 178 /* Map 1000X page */ 179 SOC_IF_ERROR_RETURN 180 (WRITE_PHY_REG(unit, pc, 0x1c, 0x7c00)); 181 SOC_IF_ERROR_RETURN 182 (READ_PHY_REG(unit, pc, 0x1c, &blk_sel)); 183 SOC_IF_ERROR_RETURN 184 (WRITE_PHY_REG(unit, pc, 0x1c, blk_sel | 0x8001)); 185 186 /* Read 1000X IEEE register */ 187 SOC_IF_ERROR_RETURN 188 (READ_PHY_REG(unit, pc, reg_addr, data)); 189 190 /* Restore IEEE mapping */ 191 SOC_IF_ERROR_RETURN 192 (WRITE_PHY_REG(unit, pc, 0x1c, 193 (blk_sel & 0xfffe) | 0x8000)); 194 } else { 195 rv = SOC_E_PARAM; 196 } 197 } else { 198 switch(reg_addr) { 199 /* Map shadow registers */ 200 case 0x15: 201 SOC_IF_ERROR_RETURN 202 (WRITE_PHY_REG(unit, pc, 0x17, reg_bank)); 203 break; 204 case 0x18: 205 if (reg_bank <= 0x0007) { 206 SOC_IF_ERROR_RETURN 207 (WRITE_PHY_REG(unit, pc, reg_addr, 208 (reg_bank << 12) | 0x7)); 209 } else { 210 rv = SOC_E_PARAM; 211 } 212 break; 213 case 0x1C: 214 if (reg_bank <= 0x001F) { 215 SOC_IF_ERROR_RETURN 216 (WRITE_PHY_REG(unit, pc, reg_addr, 217 (reg_bank << 10))); 218 } else { 219 rv = SOC_E_PARAM; 220 } 221 break; 222 case 0x1D: 223 if (reg_bank <= 0x0001) { 224 SOC_IF_ERROR_RETURN 225 (WRITE_PHY_REG(unit, pc, reg_addr, reg_bank << 15)); 226 } else { 227 rv = SOC_E_PARAM; 228 } 229 break; 230 default: 231 if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { 232 /* Must not read from reserved registers */ 233 if (reg_addr > 0x001e) { 234 rv = SOC_E_PARAM; 235 } 236 } 237 break; 238 } 239 if (SOC_SUCCESS(rv)) { 240 rv = READ_PHY_REG(unit, pc, reg_addr, data); 241 } 242 } 243 if (SOC_FAILURE(rv)) { 244 LOG_ERROR(BSL_LS_SOC_PHY, 245 (BSL_META_U(unit, 246 "phy_reg_ge_read failed:" 247 " u=%d phy_id=0x%2x reg_bank=0x%04x reg_addr=0x%02x " 248 " rv=%d\n"), unit, pc->phy_id, reg_bank, reg_addr, rv)); 249 } 250 return rv; 251 } 252 253 254 STATIC int 255 check_if_necessary_then_fix(int unit, 256 phy_ctrl_t *pc, 257 uint32 flags, 258 uint8 reg_addr, 259 uint16 reg_bank, 260 uint16 data, 261 int chk) 262 { 263 uint16 chk_data = 0; 264 int rv = 0; 265 266 267 if (reg_bank == 0xd01) return 0; 268 269 rv = phy_reg_ge_read(unit, pc, flags,reg_bank, reg_addr, &chk_data); 270 271 if (chk_data != data ) { 272 /* 273 bsl_printf("%s: data= 0x%08x, chk_data %x, reg_addr=%x, bank=%x, counter %d\n", 274 __FUNCTION__, data, chk_data, reg_addr, reg_bank, chk); 275 */ 276 277 if(!chk) return 1; 278 279 flags |= SOC_PHY_REG_NO_RETRY_ACCESS; 280 rv = phy_reg_ge_write(unit, pc, flags, reg_bank, reg_addr, data); 281 282 if (!rv ) { 283 return check_if_necessary_then_fix( 284 unit, pc, flags, reg_addr, reg_bank, data, --chk); 285 } else { 286 return rv; 287 } 288 289 } else { 290 return rv; 291 } 292 293 return 0; 294 } 295 296 int 297 phy_reg_ge_write(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 298 uint8 reg_addr, uint16 data) 299 { 300 int rv; 301 302 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 303 return SOC_E_NONE; 304 } 305 306 rv = SOC_E_NONE; 307 308 if (flags & SOC_PHY_REG_1000X) { 309 if (reg_addr <= 0x000f) { 310 uint16 blk_sel; 311 312 /* Map 1000X page */ 313 SOC_IF_ERROR_RETURN 314 (WRITE_PHY_REG(unit, pc, 0x1c, 0x7c00)); 315 SOC_IF_ERROR_RETURN 316 (READ_PHY_REG(unit, pc, 0x1c, &blk_sel)); 317 SOC_IF_ERROR_RETURN 318 (WRITE_PHY_REG(unit, pc, 0x1c, blk_sel | 0x8001)); 319 320 /* Write 1000X IEEE register */ 321 SOC_IF_ERROR_RETURN 322 (WRITE_PHY_REG(unit, pc, reg_addr, data)); 323 324 /* Restore IEEE mapping */ 325 SOC_IF_ERROR_RETURN 326 (WRITE_PHY_REG(unit, pc, 0x1c, 327 (blk_sel & 0xfffe) | 0x8000)); 328 } else if (flags & _SOC_PHY_REG_DIRECT) { 329 SOC_IF_ERROR_RETURN 330 (WRITE_PHY_REG(unit, pc, reg_addr, data)); 331 } else { 332 rv = SOC_E_PARAM; 333 } 334 } else { 335 switch(reg_addr) { 336 /* Map shadow registers */ 337 case 0x15: 338 /* SHAD_EXPD for 54640E */ 339 BCM54640E_SHAD_EXPD_PRE(unit, pc, reg_bank); 340 341 SOC_IF_ERROR_RETURN 342 (WRITE_PHY_REG(unit, pc, 0x17, reg_bank)); 343 break; 344 case 0x18: 345 if (reg_bank <= 0x0007) { 346 if (reg_bank == 0x0007) { 347 data |= 0x8000; 348 } 349 data = (data & ~(0x0007)) | reg_bank; 350 } else { 351 rv = SOC_E_PARAM; 352 } 353 break; 354 case 0x1C: 355 if (reg_bank <= 0x001F) { 356 data = 0x8000 | (reg_bank << 10) | (data & 0x03FF); 357 } else { 358 rv = SOC_E_PARAM; 359 } 360 break; 361 case 0x1D: 362 if (reg_bank == 0x0000) { 363 data = data & 0x07FFF; 364 } else { 365 rv = SOC_E_PARAM; 366 } 367 break; 368 default: 369 if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { 370 /* Must not write to reserved registers */ 371 if (reg_addr > 0x001e) { 372 rv = SOC_E_PARAM; 373 } 374 } 375 break; 376 } 377 if (SOC_SUCCESS(rv)) { 378 rv = WRITE_PHY_REG(unit, pc, reg_addr, data); 379 380 /* SHAD_EXPD for 54640E */ 381 BCM54640E_SHAD_EXPD_POST(unit, pc, rv); 382 383 if (!(flags & SOC_PHY_REG_NO_RETRY_ACCESS )) { 384 if (SOC_SUCCESS(rv) && PHY_IS_BCM54640E(pc) && (reg_addr==0x15 && ((reg_bank&0x0f00) == 0x0d00))) { 385 rv = check_if_necessary_then_fix( 386 unit, pc, flags, reg_addr, reg_bank, data, 387 SOC_PHY_SHAD_RETRY_CNT); 388 } 389 } 390 } 391 } 392 393 if (SOC_FAILURE(rv)) { 394 LOG_ERROR(BSL_LS_SOC_PHY, 395 (BSL_META_U(unit, 396 "phy_reg_ge_write failed:" 397 " u=%d phy_id=0x%2x reg_bank=0x%04x reg_addr=0x%02x " 398 " rv=%d\n"), unit, pc->phy_id, reg_bank, reg_addr, rv)); 399 } 400 401 return rv; 402 } 403 404 int 405 phy_reg_ge_modify(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 406 uint8 reg_addr, uint16 data, uint16 mask) 407 { 408 int rv; 409 410 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 411 return SOC_E_NONE; 412 } 413 414 rv = SOC_E_NONE; 415 416 if (flags & SOC_PHY_REG_1000X) { 417 if (reg_addr <= 0x000f) { 418 uint16 blk_sel; 419 420 /* Map 1000X page */ 421 SOC_IF_ERROR_RETURN 422 (WRITE_PHY_REG(unit, pc, 0x1c, 0x7c00)); 423 SOC_IF_ERROR_RETURN 424 (READ_PHY_REG(unit, pc, 0x1c, &blk_sel)); 425 SOC_IF_ERROR_RETURN 426 (WRITE_PHY_REG(unit, pc, 0x1c, blk_sel | 0x8001)); 427 428 /* Modify 1000X IEEE register */ 429 SOC_IF_ERROR_RETURN 430 (MODIFY_PHY_REG(unit, pc, reg_addr, data, mask)); 431 432 /* Restore IEEE mapping */ 433 SOC_IF_ERROR_RETURN 434 (WRITE_PHY_REG(unit, pc, 0x1c, 435 (blk_sel & 0xfffe) | 0x8000)); 436 } else { 437 rv = SOC_E_PARAM; 438 } 439 } else { 440 switch(reg_addr) { 441 /* Map shadow registers */ 442 case 0x15: 443 /* SHAD_EXPD for 54640E */ 444 BCM54640E_SHAD_EXPD_PRE(unit, pc, reg_bank); 445 446 SOC_IF_ERROR_RETURN 447 (WRITE_PHY_REG(unit, pc, 0x17, reg_bank)); 448 break; 449 case 0x18: 450 if (reg_bank <= 0x0007) { 451 SOC_IF_ERROR_RETURN 452 (WRITE_PHY_REG(unit, pc, reg_addr, 453 (reg_bank << 12) | 0x7)); 454 455 if (reg_bank == 0x0007) { 456 data |= 0x8000; 457 mask |= 0x8000; 458 } 459 mask &= ~(0x0007); 460 } else { 461 rv = SOC_E_PARAM; 462 } 463 break; 464 case 0x1C: 465 if (reg_bank <= 0x001F) { 466 SOC_IF_ERROR_RETURN 467 (WRITE_PHY_REG(unit, pc, reg_addr, (reg_bank << 10))); 468 data |= 0x8000; 469 mask |= 0x8000; 470 mask &= ~(0x1F << 10); 471 } else { 472 rv = SOC_E_PARAM; 473 } 474 break; 475 case 0x1D: 476 if (reg_bank == 0x0000) { 477 mask &= 0x07FFF; 478 } else { 479 rv = SOC_E_PARAM; 480 } 481 break; 482 default: 483 if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { 484 /* Must not write to reserved registers */ 485 if (reg_addr > 0x001e) { 486 rv = SOC_E_PARAM; 487 } 488 } 489 break; 490 } 491 if (SOC_SUCCESS(rv)) { 492 rv = MODIFY_PHY_REG(unit, pc, reg_addr, data, mask); 493 494 /* SHAD_EXPD for 54640E */ 495 BCM54640E_SHAD_EXPD_POST(unit, pc, rv); 496 497 if (!(flags & SOC_PHY_REG_NO_RETRY_ACCESS )) { 498 499 if (SOC_SUCCESS(rv) && PHY_IS_BCM54640E(pc) && (reg_addr==0x15 && ((reg_bank&0x0F00) == 0x0d00))) { 500 501 uint16 tmp; 502 503 rv = READ_PHY_REG(unit, pc, reg_addr, &tmp); 504 505 if (SOC_SUCCESS(rv)) { 506 507 tmp &= ~(mask); 508 tmp |= (data & mask); 509 510 rv = check_if_necessary_then_fix( 511 unit, pc, flags, reg_addr, reg_bank, tmp, 512 SOC_PHY_SHAD_RETRY_CNT); 513 } 514 515 } 516 } 517 518 } 519 } 520 521 if (SOC_FAILURE(rv)) { 522 LOG_ERROR(BSL_LS_SOC_PHY, 523 (BSL_META_U(unit, 524 "phy_reg_ge_modify failed:" 525 " u=%d phy_id=0x%2x reg_bank=0x%04x reg_addr=0x%02x " 526 " rv=%d\n"), unit, pc->phy_id, reg_bank, reg_addr, rv)); 527 } 528 return rv; 529 } 530 531 int 532 phy_reg_xge_read(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 533 uint8 dev_addr, uint16 reg_addr, uint16 *data) 534 { 535 int rv; 536 uint32 value; 537 uint16 tmp, tmp2; 538 rv = SOC_E_NONE; 539 540 { 541 switch(reg_addr) { 542 /* Map shadow registers */ 543 case 0xfff5: 544 SOC_IF_ERROR_RETURN 545 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, 0xfff7), reg_bank)); 546 break; 547 case 0xfff8: 548 if (reg_bank <= 0x0007) { 549 SOC_IF_ERROR_RETURN 550 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), 551 (reg_bank << 12) | 0x7)); 552 } else { 553 rv = SOC_E_PARAM; 554 } 555 break; 556 case 0xfffc: 557 if (reg_bank <= 0x001F) { 558 SOC_IF_ERROR_RETURN 559 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), 560 (reg_bank << 10))); 561 } else { 562 rv = SOC_E_PARAM; 563 } 564 break; 565 case 0xfffd: 566 if (reg_bank <= 0x0001) { 567 SOC_IF_ERROR_RETURN 568 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), reg_bank << 15)); 569 } else { 570 rv = SOC_E_PARAM; 571 } 572 break; 573 default: 574 if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { 575 /* Must not read from reserved registers */ 576 if (reg_addr > 0xfffe) { 577 rv = SOC_E_PARAM; 578 } 579 } 580 break; 581 } 582 if (SOC_SUCCESS(rv)) { 583 if(!(flags & SOC_PHY_REG_DUMMY_ACCESS)) { 584 rv = READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), data); 585 } 586 else { 587 /* Do two dummy reads. Read #3 and #4 gives values */ 588 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp); /* Dummy read #1 */ 589 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp); /* Dummy read #2 */ 590 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp); /* Lower count */ 591 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp2); /* Upper count */ 592 value = tmp2; 593 value <<= 16; /*upper count*/ 594 value |= tmp; 595 * ((uint32 *) data) = value; 596 } 597 } 598 } 599 if (SOC_FAILURE(rv)) { 600 LOG_ERROR(BSL_LS_SOC_PHY, 601 (BSL_META_U(unit, 602 "phy_reg_ge_read failed:" 603 " u=%d phy_id=0x%2x dev_addr=0x%02x reg_bank=0x%04x reg_addr=0x%02x " 604 " rv=%d\n"), unit, pc->phy_id, dev_addr, reg_bank, reg_addr, rv)); 605 } 606 return rv; 607 } 608 609 int 610 phy_reg_xge_write(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 611 uint8 dev_addr, uint16 reg_addr, uint16 data) 612 { 613 int rv; 614 615 rv = SOC_E_NONE; 616 617 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)) { 618 return rv; 619 } 620 621 { 622 switch(reg_addr) { 623 /* Map shadow registers */ 624 case 0xfff5: 625 SOC_IF_ERROR_RETURN 626 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, 0xfff7), reg_bank)); 627 break; 628 case 0xfff8: 629 if (reg_bank <= 0x0007) { 630 if (reg_bank == 0x0007) { 631 data |= 0x8000; 632 } 633 data = (data & ~(0x0007)) | reg_bank; 634 } else { 635 rv = SOC_E_PARAM; 636 } 637 break; 638 case 0xfffc: 639 if (reg_bank <= 0x001F) { 640 data = 0x8000 | (reg_bank << 10) | (data & 0x03FF); 641 } else { 642 rv = SOC_E_PARAM; 643 } 644 break; 645 case 0xfffd: 646 if (reg_bank == 0x0000) { 647 data = data & 0x07FFF; 648 } else { 649 rv = SOC_E_PARAM; 650 } 651 break; 652 default: 653 if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { 654 /* Must not write to reserved registers */ 655 if (reg_addr > 0xfffe) { 656 rv = SOC_E_PARAM; 657 } 658 } 659 break; 660 } 661 if (SOC_SUCCESS(rv)) { 662 rv = WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), data); 663 } 664 } 665 666 if (SOC_FAILURE(rv)) { 667 LOG_ERROR(BSL_LS_SOC_PHY, 668 (BSL_META_U(unit, 669 "phy_reg_ge_write failed:" 670 " u=%d phy_id=0x%2x dev_addr=0x%02x reg_bank=0x%04x reg_addr=0x%02x " 671 " rv=%d\n"), unit, pc->phy_id, dev_addr, reg_bank, reg_addr, rv)); 672 } 673 674 return rv; 675 } 676 677 int 678 phy_reg_xge_modify(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 679 uint8 dev_addr, uint16 reg_addr, uint16 data, uint16 mask) 680 { 681 int rv; 682 683 rv = SOC_E_NONE; 684 685 { 686 switch(reg_addr) { 687 /* Map shadow registers */ 688 case 0xfff5: 689 SOC_IF_ERROR_RETURN 690 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, 0xfff7), reg_bank)); 691 break; 692 case 0xfff8: 693 if (reg_bank <= 0x0007) { 694 SOC_IF_ERROR_RETURN 695 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), 696 (reg_bank << 12) | 0x7)); 697 698 if (reg_bank == 0x0007) { 699 data |= 0x8000; 700 mask |= 0x8000; 701 } 702 mask &= ~(0x0007); 703 } else { 704 rv = SOC_E_PARAM; 705 } 706 break; 707 case 0xfffc: 708 if (reg_bank <= 0x001F) { 709 SOC_IF_ERROR_RETURN 710 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), (reg_bank << 10))); 711 data |= 0x8000; 712 mask |= 0x8000; 713 mask &= ~(0x1F << 10); 714 } else { 715 rv = SOC_E_PARAM; 716 } 717 break; 718 case 0xfffd: 719 if (reg_bank == 0x0000) { 720 mask &= 0x07FFF; 721 } else { 722 rv = SOC_E_PARAM; 723 } 724 break; 725 default: 726 if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { 727 /* Must not write to reserved registers */ 728 if (reg_addr > 0xfffe) { 729 rv = SOC_E_PARAM; 730 } 731 } 732 break; 733 } 734 if (SOC_SUCCESS(rv)) { 735 rv = MODIFY_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), data, mask); 736 } 737 } 738 739 if (SOC_FAILURE(rv)) { 740 LOG_ERROR(BSL_LS_SOC_PHY, 741 (BSL_META_U(unit, 742 "phy_reg_ge_modify failed:" 743 " u=%d phy_id=0x%2x dev_addr=0x%02x reg_bank=0x%04x reg_addr=0x%02x " 744 " rv=%d\n"), unit, pc->phy_id, dev_addr, reg_bank, reg_addr, rv)); 745 } 746 return rv; 747 } 748 749 int 750 phy_reg_serdes_read(int unit, phy_ctrl_t *pc, uint16 reg_bank, 751 uint8 reg_addr, uint16 *phy_rd_data) 752 { 753 int rv; 754 755 rv = SOC_E_NONE; 756 757 #ifdef INCLUDE_PHY_XGXS6 758 if (soc_feature(unit, soc_feature_xgxs_v6)) { 759 if ((reg_bank != 0) || (reg_addr >= 0x0010)) { 760 reg_bank = 0x300 + (reg_bank << 4); 761 } 762 } 763 #endif /* INCLUDE_PHY_XGXS6 */ 764 765 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 766 767 if (SOC_SUCCESS(rv)) { 768 rv = READ_PHY_REG(unit, pc, reg_addr, phy_rd_data); 769 } 770 771 return rv; 772 } 773 774 int 775 phy_reg_serdes_write(int unit, phy_ctrl_t *pc, uint16 reg_bank, 776 uint8 reg_addr, uint16 phy_wr_data) 777 { 778 int rv; 779 780 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 781 return SOC_E_NONE; 782 } 783 784 rv = SOC_E_NONE; 785 786 #ifdef INCLUDE_PHY_XGXS6 787 if (soc_feature(unit, soc_feature_xgxs_v6)) { 788 if ((reg_bank != 0) || (reg_addr >= 0x0010)) { 789 reg_bank = 0x300 + (reg_bank << 4); 790 } 791 } 792 #endif /* INCLUDE_PHY_XGXS6 */ 793 794 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 795 796 if (SOC_SUCCESS(rv)) { 797 rv = WRITE_PHY_REG(unit, pc, reg_addr, phy_wr_data); 798 } 799 800 return rv; 801 } 802 803 int 804 phy_reg_serdes_modify(int unit, phy_ctrl_t *pc, 805 uint16 reg_bank, uint8 reg_addr, 806 uint16 phy_mo_data, uint16 phy_mo_mask) 807 { 808 int rv; 809 810 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 811 return SOC_E_NONE; 812 } 813 814 rv = SOC_E_NONE; 815 816 #ifdef INCLUDE_PHY_XGXS6 817 if (soc_feature(unit, soc_feature_xgxs_v6)) { 818 if ((reg_bank != 0) || (reg_addr >= 0x0010)) { 819 reg_bank = 0x300 + (reg_bank << 4); 820 } 821 } 822 #endif /* INCLUDE_PHY_XGXS6 */ 823 824 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 825 826 if (SOC_SUCCESS(rv)) { 827 rv = MODIFY_PHY_REG(unit, pc, reg_addr, phy_mo_data, phy_mo_mask); 828 } 829 830 return rv; 831 } 832 833 #if defined(INCLUDE_PHY_XGXS) 834 int 835 phy_reg_xgxs_read(int unit, phy_ctrl_t *pc, uint16 reg_bank, 836 uint8 reg_addr, uint16 *data) 837 { 838 int rv; 839 840 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 841 842 if (SOC_SUCCESS(rv)) { 843 rv = READ_PHY_REG(unit, pc, reg_addr, data); 844 } 845 846 return rv; 847 } 848 849 int 850 phy_reg_xgxs_write(int unit, phy_ctrl_t *pc, uint16 reg_bank, 851 uint8 reg_addr, uint16 data) 852 { 853 int rv; 854 855 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 856 return SOC_E_NONE; 857 } 858 859 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 860 861 if (SOC_SUCCESS(rv)) { 862 rv = WRITE_PHY_REG(unit, pc, reg_addr, data); 863 } 864 865 return rv; 866 } 867 868 int 869 phy_reg_xgxs_modify(int unit, phy_ctrl_t *pc, uint16 reg_bank, 870 uint8 reg_addr, uint16 data, uint16 mask) 871 { 872 int rv; 873 874 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 875 return SOC_E_NONE; 876 } 877 878 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 879 880 if (SOC_SUCCESS(rv)) { 881 rv = MODIFY_PHY_REG(unit, pc, reg_addr, data, mask); 882 } 883 884 return rv; 885 } 886 #endif /* INCLUDE_PHY_XGXS */ 887 888 #if defined(INCLUDE_PHY_XGXS6) 889 int 890 phy_reg_xgxs6_read(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 891 uint8 reg_addr, uint16 *data) 892 { 893 int rv; 894 895 rv = SOC_E_NONE; 896 897 if (reg_addr < 0x10) { 898 /* Select between SerDes and XAUI mapping */ 899 SOC_IF_ERROR_RETURN 900 (WRITE_PHY_REG(unit, pc, 0x1f, 0x0000)); 901 SOC_IF_ERROR_RETURN 902 (MODIFY_PHY_REG(unit, pc, 0x1e, 903 (flags & SOC_PHY_REG_1000X) ? 0x0000 : 0x0001, 904 0x0001)); 905 } 906 907 if (SOC_SUCCESS(rv)) { 908 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 909 } 910 911 if (SOC_SUCCESS(rv)) { 912 rv = READ_PHY_REG(unit, pc, reg_addr, data); 913 } 914 915 return rv; 916 } 917 918 int 919 phy_reg_xgxs6_write(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 920 uint8 reg_addr, uint16 data) 921 { 922 int rv; 923 924 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 925 return SOC_E_NONE; 926 } 927 928 rv = SOC_E_NONE; 929 930 if (reg_addr < 0x10) { 931 /* Select between SerDes and XAUI mapping */ 932 SOC_IF_ERROR_RETURN 933 (WRITE_PHY_REG(unit, pc, 0x1f, 0x0000)); 934 SOC_IF_ERROR_RETURN 935 (MODIFY_PHY_REG(unit, pc, 0x1e, 936 (flags & SOC_PHY_REG_1000X) ? 0x0000 : 0x0001, 937 0x0001)); 938 } 939 940 if (SOC_SUCCESS(rv)) { 941 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 942 } 943 944 if (SOC_SUCCESS(rv)) { 945 rv = WRITE_PHY_REG(unit, pc, reg_addr, data); 946 } 947 948 return rv; 949 } 950 951 int 952 phy_reg_xgxs6_modify(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank, 953 uint8 reg_addr, uint16 data, uint16 mask) 954 { 955 int rv; 956 957 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 958 return SOC_E_NONE; 959 } 960 961 rv = SOC_E_NONE; 962 963 if (reg_addr < 0x10) { 964 /* Select between SerDes and XAUI mapping */ 965 SOC_IF_ERROR_RETURN 966 (WRITE_PHY_REG(unit, pc, 0x1f, 0x0000)); 967 SOC_IF_ERROR_RETURN 968 (MODIFY_PHY_REG(unit, pc, 0x1e, 969 (flags & SOC_PHY_REG_1000X) ? 0x0000 : 0x0001, 970 0x0001)); 971 } 972 973 if (SOC_SUCCESS(rv)) { 974 rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 975 } 976 977 if (SOC_SUCCESS(rv)) { 978 rv = MODIFY_PHY_REG(unit, pc, reg_addr, data, mask); 979 } 980 981 return rv; 982 } 983 #endif /* INCLUDE_PHY_XGXS6 */ 984 985 STATIC int 986 _phy_reg_aer_cl45_read(int unit, phy_ctrl_t *pc, uint32 reg_addr, 987 uint16 *data) 988 { 989 uint16 phy_reg_addr; 990 int cl45_devid; 991 992 phy_reg_addr = PHY_AER_REG_ADDR_CL45_REGAD(reg_addr); 993 cl45_devid = PHY_AER_REG_ADDR_CL45_DEVID(reg_addr); 994 995 if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) { 996 /* write the lane number to the AER if lane specific */ 997 SOC_IF_ERROR_RETURN 998 (WRITE_PHY_REG(unit, pc, 999 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG), 1000 PHY_AER_REG_ADDR_LANE_NUM(reg_addr))); 1001 } 1002 SOC_IF_ERROR_RETURN 1003 (READ_PHY_REG(unit, pc, 1004 SOC_PHY_CLAUSE45_ADDR(cl45_devid,phy_reg_addr), data)); 1005 1006 if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) { 1007 /* restore back the lane number to 0 */ 1008 SOC_IF_ERROR_RETURN 1009 (WRITE_PHY_REG(unit, pc, 1010 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG), 1011 0)); 1012 } 1013 return SOC_E_NONE; 1014 } 1015 1016 STATIC int 1017 _phy_reg_aer_cl45_write(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1018 uint16 data) 1019 { 1020 uint16 phy_reg_addr; 1021 int cl45_devid; 1022 1023 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 1024 return SOC_E_NONE; 1025 } 1026 1027 phy_reg_addr = PHY_AER_REG_ADDR_CL45_REGAD(reg_addr); 1028 cl45_devid = PHY_AER_REG_ADDR_CL45_DEVID(reg_addr); 1029 1030 if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) { 1031 /* write the lane number to the AER if lane specific */ 1032 SOC_IF_ERROR_RETURN 1033 (WRITE_PHY_REG(unit, pc, 1034 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG), 1035 PHY_AER_REG_ADDR_LANE_NUM(reg_addr))); 1036 } 1037 SOC_IF_ERROR_RETURN 1038 (WRITE_PHY_REG(unit, pc, 1039 SOC_PHY_CLAUSE45_ADDR(cl45_devid,phy_reg_addr), data)); 1040 1041 if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) { 1042 /* write the lane number 0 to the AER */ 1043 SOC_IF_ERROR_RETURN 1044 (WRITE_PHY_REG(unit, pc, 1045 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG), 1046 0)); 1047 } 1048 return SOC_E_NONE; 1049 } 1050 1051 STATIC int 1052 _phy_reg_aer_cl45_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1053 uint16 data,uint16 mask) 1054 { 1055 uint16 phy_reg_addr; 1056 int cl45_devid; 1057 1058 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 1059 return SOC_E_NONE; 1060 } 1061 1062 phy_reg_addr = PHY_AER_REG_ADDR_CL45_REGAD(reg_addr); 1063 cl45_devid = PHY_AER_REG_ADDR_CL45_DEVID(reg_addr); 1064 1065 if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) { 1066 /* write the lane number to the AER if lane specific */ 1067 SOC_IF_ERROR_RETURN 1068 (WRITE_PHY_REG(unit, pc, 1069 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG), 1070 PHY_AER_REG_ADDR_LANE_NUM(reg_addr))); 1071 } 1072 SOC_IF_ERROR_RETURN 1073 (MODIFY_PHY_REG(unit, pc, 1074 SOC_PHY_CLAUSE45_ADDR(cl45_devid,phy_reg_addr), data,mask)); 1075 1076 if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) { 1077 /* write the lane number 0 to the AER */ 1078 SOC_IF_ERROR_RETURN 1079 (WRITE_PHY_REG(unit, pc, 1080 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG), 1081 0)); 1082 } 1083 return SOC_E_NONE; 1084 } 1085 1086 STATIC int 1087 _phy_reg_aer_cl22_read(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1088 uint16 *data) 1089 { 1090 uint16 phy_reg_aer; 1091 uint16 phy_reg_blk; 1092 uint16 phy_reg_addr; 1093 int rv; 1094 1095 rv = SOC_E_UNAVAIL; 1096 1097 phy_reg_aer = PHY_AER_REG_ADDR_AER(reg_addr); 1098 phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg_addr); 1099 phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg_addr); 1100 if (phy_reg_aer == 0) { 1101 rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk); 1102 1103 if (SOC_SUCCESS(rv)) { 1104 rv = READ_PHY_REG(unit, pc, phy_reg_addr, data); 1105 } 1106 } else { 1107 /* Set desired AER */ 1108 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0); 1109 if (SOC_SUCCESS(rv)) { 1110 rv = WRITE_PHY_REG(unit, pc, 0x1e, phy_reg_aer); 1111 } 1112 1113 /* Map requested block */ 1114 if (SOC_SUCCESS(rv)) { 1115 rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk); 1116 } 1117 1118 /* Read from the requested register */ 1119 if (SOC_SUCCESS(rv)) { 1120 rv = READ_PHY_REG(unit, pc, phy_reg_addr, data); 1121 } 1122 1123 /* Set AER back to 0 */ 1124 if (SOC_SUCCESS(rv)) { 1125 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0); 1126 } 1127 if (SOC_SUCCESS(rv)) { 1128 rv = WRITE_PHY_REG(unit, pc, 0x1e, 0); 1129 } 1130 if (SOC_SUCCESS(rv)) { 1131 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0x0); 1132 } 1133 } 1134 return rv; 1135 } 1136 1137 STATIC int 1138 _phy_reg_aer_cl22_write(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1139 uint16 data) 1140 { 1141 uint16 phy_reg_aer; 1142 uint16 phy_reg_blk; 1143 uint16 phy_reg_addr; 1144 int rv; 1145 1146 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 1147 return SOC_E_NONE; 1148 } 1149 1150 rv = SOC_E_UNAVAIL; 1151 1152 phy_reg_aer = PHY_AER_REG_ADDR_AER(reg_addr); 1153 phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg_addr); 1154 phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg_addr); 1155 if (phy_reg_aer == 0) { 1156 rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk); 1157 1158 if (SOC_SUCCESS(rv)) { 1159 rv = WRITE_PHY_REG(unit, pc, phy_reg_addr, data); 1160 } 1161 } else { 1162 /* Set desired AER */ 1163 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0); 1164 if (SOC_SUCCESS(rv)) { 1165 rv = WRITE_PHY_REG(unit, pc, 0x1e, phy_reg_aer); 1166 } 1167 1168 /* Map requested block */ 1169 if (SOC_SUCCESS(rv)) { 1170 rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk); 1171 } 1172 1173 /* Write to requested register */ 1174 if (SOC_SUCCESS(rv)) { 1175 rv = WRITE_PHY_REG(unit, pc, phy_reg_addr, data); 1176 } 1177 1178 /* Set AER back to 0 */ 1179 if (SOC_SUCCESS(rv)) { 1180 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0); 1181 } 1182 if (SOC_SUCCESS(rv)) { 1183 rv = WRITE_PHY_REG(unit, pc, 0x1e, 0); 1184 } 1185 } 1186 return rv; 1187 } 1188 1189 STATIC int 1190 _phy_reg_aer_cl22_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1191 uint16 data, uint16 mask) 1192 { 1193 uint16 phy_reg_aer; 1194 uint16 phy_reg_blk; 1195 uint16 phy_reg_addr; 1196 int rv; 1197 1198 if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){ 1199 return SOC_E_NONE; 1200 } 1201 1202 rv = SOC_E_UNAVAIL; 1203 1204 phy_reg_aer = PHY_AER_REG_ADDR_AER(reg_addr); 1205 phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg_addr); 1206 phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg_addr); 1207 if (phy_reg_aer == 0) { 1208 /* Only support AER = 0 for now */ 1209 rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk); 1210 1211 if (SOC_SUCCESS(rv)) { 1212 rv = MODIFY_PHY_REG(unit, pc, phy_reg_addr, data, mask); 1213 } 1214 } else { 1215 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0); 1216 if (SOC_SUCCESS(rv)) { 1217 rv = WRITE_PHY_REG(unit, pc, 0x1e, phy_reg_aer); 1218 } 1219 1220 /* Map requested block */ 1221 if (SOC_SUCCESS(rv)) { 1222 rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk); 1223 } 1224 1225 /* Modify requested register */ 1226 if (SOC_SUCCESS(rv)) { 1227 rv = MODIFY_PHY_REG(unit, pc, phy_reg_addr, data, mask); 1228 } 1229 1230 /* Set AER back to 0 */ 1231 if (SOC_SUCCESS(rv)) { 1232 rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0); 1233 } 1234 if (SOC_SUCCESS(rv)) { 1235 rv = WRITE_PHY_REG(unit, pc, 0x1e, 0); 1236 } 1237 1238 } 1239 return rv; 1240 1241 } 1242 1243 int 1244 phy_reg_aer_read(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1245 uint16 *data) 1246 { 1247 int rv; 1248 if (pc->flags & PHYCTRL_MDIO_CL45) { 1249 rv = _phy_reg_aer_cl45_read(unit,pc,reg_addr,data); 1250 } else { 1251 rv = _phy_reg_aer_cl22_read(unit,pc,reg_addr,data); 1252 } 1253 return rv; 1254 } 1255 1256 int 1257 phy_reg_aer_write(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1258 uint16 data) 1259 { 1260 int rv; 1261 if (pc->flags & PHYCTRL_MDIO_CL45) { 1262 rv = _phy_reg_aer_cl45_write(unit,pc,reg_addr,data); 1263 } else { 1264 rv = _phy_reg_aer_cl22_write(unit,pc,reg_addr,data); 1265 } 1266 return rv; 1267 } 1268 1269 int 1270 phy_reg_aer_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1271 uint16 data,uint16 mask) 1272 { 1273 int rv; 1274 if (pc->flags & PHYCTRL_MDIO_CL45) { 1275 rv = _phy_reg_aer_cl45_modify(unit,pc,reg_addr,data,mask); 1276 } else { 1277 rv = _phy_reg_aer_cl22_modify(unit,pc,reg_addr,data,mask); 1278 } 1279 return rv; 1280 } 1281 1282 #if defined(INCLUDE_XGXS_QSGMII65) 1283 int 1284 phy_reg_qsgmii_aer_read(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1285 uint16 *data) 1286 { 1287 int rv = SOC_E_UNAVAIL; 1288 1289 reg_addr = reg_addr | (pc->lane_num << 16); 1290 1291 rv = phy_reg_aer_read(unit, pc, reg_addr, data); 1292 return rv; 1293 } 1294 1295 int 1296 phy_reg_qsgmii_aer_write(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1297 uint16 data) 1298 { 1299 int rv = SOC_E_UNAVAIL; 1300 1301 reg_addr = reg_addr | (pc->lane_num << 16); 1302 1303 rv = phy_reg_aer_write(unit, pc, reg_addr, data); 1304 return rv; 1305 } 1306 1307 int 1308 phy_reg_qsgmii_aer_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr, 1309 uint16 data, uint16 mask) 1310 { 1311 int rv = SOC_E_UNAVAIL; 1312 1313 reg_addr = reg_addr | (pc->lane_num << 16); 1314 1315 rv = phy_reg_aer_modify(unit, pc, reg_addr, data, mask); 1316 return rv; 1317 } 1318 #endif /* INCLUDE_XGXS_QSGMII65 */