1 /************************************************************************** 2 SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 4 Copyright (c) 2007-2009, Chelsio Inc. 5 All rights reserved. 6 7 Redistribution and use in source and binary forms, with or without 8 modification, are permitted provided that the following conditions are met: 9 10 1. Redistributions of source code must retain the above copyright notice, 11 this list of conditions and the following disclaimer. 12 13 2. Neither the name of the Chelsio Corporation nor the names of its 14 contributors may be used to endorse or promote products derived from 15 this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 POSSIBILITY OF SUCH DAMAGE. 28 29 ***************************************************************************/ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <cxgb_include.h> 35 36 #undef msleep 37 #define msleep t3_os_sleep 38 39 enum { 40 PMD_RSD = 10, /* PMA/PMD receive signal detect register */ 41 PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ 42 PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ 43 XS_LN_STAT = 24 /* XS lane status register */ 44 }; 45 46 enum { 47 AEL100X_TX_DISABLE = 9, 48 AEL100X_TX_CONFIG1 = 0xc002, 49 50 AEL1002_PWR_DOWN_HI = 0xc011, 51 AEL1002_PWR_DOWN_LO = 0xc012, 52 AEL1002_XFI_EQL = 0xc015, 53 AEL1002_LB_EN = 0xc017, 54 55 AEL_OPT_SETTINGS = 0xc017, 56 AEL_I2C_CTRL = 0xc30a, 57 AEL_I2C_DATA = 0xc30b, 58 AEL_I2C_STAT = 0xc30c, 59 60 AEL2005_GPIO_CTRL = 0xc214, 61 AEL2005_GPIO_STAT = 0xc215, 62 63 AEL2020_GPIO_INTR = 0xc103, 64 AEL2020_GPIO_CTRL = 0xc108, 65 AEL2020_GPIO_STAT = 0xc10c, 66 AEL2020_GPIO_CFG = 0xc110, 67 68 AEL2020_GPIO_SDA = 0, 69 AEL2020_GPIO_MODDET = 1, 70 AEL2020_GPIO_0 = 3, 71 AEL2020_GPIO_1 = 2, 72 AEL2020_GPIO_LSTAT = AEL2020_GPIO_1, 73 }; 74 75 enum { edc_none, edc_sr, edc_twinax }; 76 77 /* PHY module I2C device address */ 78 enum { 79 MODULE_DEV_ADDR = 0xa0, 80 SFF_DEV_ADDR = 0xa2, 81 }; 82 83 /* PHY transceiver type */ 84 enum { 85 phy_transtype_unknown = 0, 86 phy_transtype_sfp = 3, 87 phy_transtype_xfp = 6, 88 }; 89 90 #define AEL2005_MODDET_IRQ 4 91 92 struct reg_val { 93 unsigned short mmd_addr; 94 unsigned short reg_addr; 95 unsigned short clear_bits; 96 unsigned short set_bits; 97 }; 98 99 static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms); 100 101 static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) 102 { 103 int err; 104 105 for (err = 0; rv->mmd_addr && !err; rv++) { 106 if (rv->clear_bits == 0xffff) 107 err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, 108 rv->set_bits); 109 else 110 err = t3_mdio_change_bits(phy, rv->mmd_addr, 111 rv->reg_addr, rv->clear_bits, 112 rv->set_bits); 113 } 114 return err; 115 } 116 117 static void ael100x_txon(struct cphy *phy) 118 { 119 int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; 120 121 msleep(100); 122 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); 123 msleep(30); 124 } 125 126 /* 127 * Read an 8-bit word from a device attached to the PHY's i2c bus. 128 */ 129 static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) 130 { 131 int i, err; 132 unsigned int stat, data; 133 134 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, 135 (dev_addr << 8) | (1 << 8) | word_addr); 136 if (err) 137 return err; 138 139 for (i = 0; i < 200; i++) { 140 msleep(1); 141 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); 142 if (err) 143 return err; 144 if ((stat & 3) == 1) { 145 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, 146 &data); 147 if (err) 148 return err; 149 return data >> 8; 150 } 151 } 152 CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %x.%x timed out\n", 153 phy->addr, dev_addr, word_addr); 154 return -ETIMEDOUT; 155 } 156 157 /* 158 * Write an 8-bit word to a device attached to the PHY's i2c bus. 159 */ 160 static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data) 161 { 162 int i, err; 163 unsigned int stat; 164 165 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, data); 166 if (err) 167 return err; 168 169 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, 170 (dev_addr << 8) | word_addr); 171 if (err) 172 return err; 173 174 for (i = 0; i < 200; i++) { 175 msleep(1); 176 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); 177 if (err) 178 return err; 179 if ((stat & 3) == 1) 180 return 0; 181 } 182 CH_WARN(phy->adapter, "PHY %u i2c Write of dev.addr %x.%x = %#x timed out\n", 183 phy->addr, dev_addr, word_addr, data); 184 return -ETIMEDOUT; 185 } 186 187 static int get_phytrans_type(struct cphy *phy) 188 { 189 int v; 190 191 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0); 192 if (v < 0) 193 return phy_transtype_unknown; 194 195 return v; 196 } 197 198 static int ael_laser_down(struct cphy *phy, int enable) 199 { 200 int v, dev_addr; 201 202 v = get_phytrans_type(phy); 203 if (v < 0) 204 return v; 205 206 if (v == phy_transtype_sfp) { 207 /* Check SFF Soft TX disable is supported */ 208 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 93); 209 if (v < 0) 210 return v; 211 212 v &= 0x40; 213 if (!v) 214 return v; 215 216 dev_addr = SFF_DEV_ADDR; 217 } else if (v == phy_transtype_xfp) 218 dev_addr = MODULE_DEV_ADDR; 219 else 220 return v; 221 222 v = ael_i2c_rd(phy, dev_addr, 110); 223 if (v < 0) 224 return v; 225 226 if (enable) 227 v |= 0x40; 228 else 229 v &= ~0x40; 230 231 v = ael_i2c_wr(phy, dev_addr, 110, v); 232 233 return v; 234 } 235 236 static int ael1002_power_down(struct cphy *phy, int enable) 237 { 238 int err; 239 240 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); 241 if (!err) 242 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 243 BMCR_PDOWN, enable ? BMCR_PDOWN : 0); 244 return err; 245 } 246 247 static int ael1002_get_module_type(struct cphy *phy, int delay_ms) 248 { 249 int v; 250 251 if (delay_ms) 252 msleep(delay_ms); 253 254 v = ael2xxx_get_module_type(phy, delay_ms); 255 256 return (v == -ETIMEDOUT ? phy_modtype_none : v); 257 } 258 259 static int ael1002_reset(struct cphy *phy, int wait) 260 { 261 int err; 262 263 if ((err = ael1002_power_down(phy, 0)) || 264 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || 265 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || 266 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || 267 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || 268 (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, 269 0, 1 << 5))) 270 return err; 271 272 err = ael1002_get_module_type(phy, 300); 273 if (err >= 0) 274 phy->modtype = err; 275 276 return 0; 277 } 278 279 static int ael1002_intr_noop(struct cphy *phy) 280 { 281 return 0; 282 } 283 284 /* 285 * Get link status for a 10GBASE-R device. 286 */ 287 static int get_link_status_r(struct cphy *phy, int *link_state, int *speed, 288 int *duplex, int *fc) 289 { 290 if (link_state) { 291 unsigned int stat0, stat1, stat2; 292 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); 293 294 if (!err) 295 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); 296 if (!err) 297 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); 298 if (err) 299 return err; 300 301 stat0 &= 1; 302 stat1 &= 1; 303 stat2 = (stat2 >> 12) & 1; 304 if (stat0 & stat1 & stat2) 305 *link_state = PHY_LINK_UP; 306 else if (stat0 == 1 && stat1 == 0 && stat2 == 1) 307 *link_state = PHY_LINK_PARTIAL; 308 else 309 *link_state = PHY_LINK_DOWN; 310 } 311 if (speed) 312 *speed = SPEED_10000; 313 if (duplex) 314 *duplex = DUPLEX_FULL; 315 return 0; 316 } 317 318 #ifdef C99_NOT_SUPPORTED 319 static struct cphy_ops ael1002_ops = { 320 ael1002_reset, 321 ael1002_intr_noop, 322 ael1002_intr_noop, 323 ael1002_intr_noop, 324 ael1002_intr_noop, 325 NULL, 326 NULL, 327 NULL, 328 NULL, 329 NULL, 330 get_link_status_r, 331 ael1002_power_down, 332 }; 333 #else 334 static struct cphy_ops ael1002_ops = { 335 .reset = ael1002_reset, 336 .intr_enable = ael1002_intr_noop, 337 .intr_disable = ael1002_intr_noop, 338 .intr_clear = ael1002_intr_noop, 339 .intr_handler = ael1002_intr_noop, 340 .get_link_status = get_link_status_r, 341 .power_down = ael1002_power_down, 342 }; 343 #endif 344 345 int t3_ael1002_phy_prep(pinfo_t *pinfo, int phy_addr, 346 const struct mdio_ops *mdio_ops) 347 { 348 int err; 349 struct cphy *phy = &pinfo->phy; 350 351 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1002_ops, mdio_ops, 352 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, 353 "10GBASE-R"); 354 ael100x_txon(phy); 355 ael_laser_down(phy, 0); 356 357 err = ael1002_get_module_type(phy, 0); 358 if (err >= 0) 359 phy->modtype = err; 360 361 return 0; 362 } 363 364 static int ael1006_reset(struct cphy *phy, int wait) 365 { 366 int err; 367 368 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); 369 if (err) 370 return err; 371 372 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 373 F_GPIO6_OUT_VAL, 0); 374 375 msleep(125); 376 377 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 378 F_GPIO6_OUT_VAL, F_GPIO6_OUT_VAL); 379 380 msleep(125); 381 382 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); 383 if (err) 384 return err; 385 386 msleep(125); 387 388 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 1); 389 if (err) 390 return err; 391 392 msleep(125); 393 394 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0); 395 396 return err; 397 398 } 399 400 #ifdef C99_NOT_SUPPORTED 401 static struct cphy_ops ael1006_ops = { 402 ael1006_reset, 403 t3_phy_lasi_intr_enable, 404 t3_phy_lasi_intr_disable, 405 t3_phy_lasi_intr_clear, 406 t3_phy_lasi_intr_handler, 407 NULL, 408 NULL, 409 NULL, 410 NULL, 411 NULL, 412 get_link_status_r, 413 ael1002_power_down, 414 }; 415 #else 416 static struct cphy_ops ael1006_ops = { 417 .reset = ael1006_reset, 418 .intr_enable = t3_phy_lasi_intr_enable, 419 .intr_disable = t3_phy_lasi_intr_disable, 420 .intr_clear = t3_phy_lasi_intr_clear, 421 .intr_handler = t3_phy_lasi_intr_handler, 422 .get_link_status = get_link_status_r, 423 .power_down = ael1002_power_down, 424 }; 425 #endif 426 427 int t3_ael1006_phy_prep(pinfo_t *pinfo, int phy_addr, 428 const struct mdio_ops *mdio_ops) 429 { 430 struct cphy *phy = &pinfo->phy; 431 432 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1006_ops, mdio_ops, 433 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, 434 "10GBASE-SR"); 435 phy->modtype = phy_modtype_sr; 436 ael100x_txon(phy); 437 return 0; 438 } 439 440 /* 441 * Decode our module type. 442 */ 443 static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) 444 { 445 int v; 446 447 if (delay_ms) 448 msleep(delay_ms); 449 450 v = get_phytrans_type(phy); 451 if (v == phy_transtype_sfp) { 452 /* SFP: see SFF-8472 for below */ 453 454 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); 455 if (v < 0) 456 return v; 457 458 if (v == 0x1) 459 goto twinax; 460 if (v == 0x10) 461 return phy_modtype_sr; 462 if (v == 0x20) 463 return phy_modtype_lr; 464 if (v == 0x40) 465 return phy_modtype_lrm; 466 467 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 8); 468 if (v < 0) 469 return v; 470 if (v == 4) { 471 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 60); 472 if (v < 0) 473 return v; 474 if (v & 0x1) 475 goto twinax; 476 } 477 478 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); 479 if (v < 0) 480 return v; 481 if (v != 4) 482 return phy_modtype_unknown; 483 484 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); 485 if (v < 0) 486 return v; 487 488 if (v & 0x80) { 489 twinax: 490 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); 491 if (v < 0) 492 return v; 493 return v > 10 ? phy_modtype_twinax_long : 494 phy_modtype_twinax; 495 } 496 } else if (v == phy_transtype_xfp) { 497 /* XFP: See INF-8077i for details. */ 498 499 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127); 500 if (v < 0) 501 return v; 502 503 if (v != 1) { 504 /* XXX: set page select to table 1 yourself */ 505 return phy_modtype_unknown; 506 } 507 508 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131); 509 if (v < 0) 510 return v; 511 v &= 0xf0; 512 if (v == 0x10) 513 return phy_modtype_lrm; 514 if (v == 0x40) 515 return phy_modtype_lr; 516 if (v == 0x80) 517 return phy_modtype_sr; 518 } 519 520 return phy_modtype_unknown; 521 } 522 523 /* 524 * Code to support the Aeluros/NetLogic 2005 10Gb PHY. 525 */ 526 static int ael2005_setup_sr_edc(struct cphy *phy) 527 { 528 static struct reg_val regs[] = { 529 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, 530 { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, 531 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, 532 { 0, 0, 0, 0 } 533 }; 534 static u16 sr_edc[] = { 535 0xcc00, 0x2ff4, 536 0xcc01, 0x3cd4, 537 0xcc02, 0x2015, 538 0xcc03, 0x3105, 539 0xcc04, 0x6524, 540 0xcc05, 0x27ff, 541 0xcc06, 0x300f, 542 0xcc07, 0x2c8b, 543 0xcc08, 0x300b, 544 0xcc09, 0x4009, 545 0xcc0a, 0x400e, 546 0xcc0b, 0x2f72, 547 0xcc0c, 0x3002, 548 0xcc0d, 0x1002, 549 0xcc0e, 0x2172, 550 0xcc0f, 0x3012, 551 0xcc10, 0x1002, 552 0xcc11, 0x25d2, 553 0xcc12, 0x3012, 554 0xcc13, 0x1002, 555 0xcc14, 0xd01e, 556 0xcc15, 0x27d2, 557 0xcc16, 0x3012, 558 0xcc17, 0x1002, 559 0xcc18, 0x2004, 560 0xcc19, 0x3c84, 561 0xcc1a, 0x6436, 562 0xcc1b, 0x2007, 563 0xcc1c, 0x3f87, 564 0xcc1d, 0x8676, 565 0xcc1e, 0x40b7, 566 0xcc1f, 0xa746, 567 0xcc20, 0x4047, 568 0xcc21, 0x5673, 569 0xcc22, 0x2982, 570 0xcc23, 0x3002, 571 0xcc24, 0x13d2, 572 0xcc25, 0x8bbd, 573 0xcc26, 0x2862, 574 0xcc27, 0x3012, 575 0xcc28, 0x1002, 576 0xcc29, 0x2092, 577 0xcc2a, 0x3012, 578 0xcc2b, 0x1002, 579 0xcc2c, 0x5cc3, 580 0xcc2d, 0x314, 581 0xcc2e, 0x2942, 582 0xcc2f, 0x3002, 583 0xcc30, 0x1002, 584 0xcc31, 0xd019, 585 0xcc32, 0x2032, 586 0xcc33, 0x3012, 587 0xcc34, 0x1002, 588 0xcc35, 0x2a04, 589 0xcc36, 0x3c74, 590 0xcc37, 0x6435, 591 0xcc38, 0x2fa4, 592 0xcc39, 0x3cd4, 593 0xcc3a, 0x6624, 594 0xcc3b, 0x5563, 595 0xcc3c, 0x2d42, 596 0xcc3d, 0x3002, 597 0xcc3e, 0x13d2, 598 0xcc3f, 0x464d, 599 0xcc40, 0x2862, 600 0xcc41, 0x3012, 601 0xcc42, 0x1002, 602 0xcc43, 0x2032, 603 0xcc44, 0x3012, 604 0xcc45, 0x1002, 605 0xcc46, 0x2fb4, 606 0xcc47, 0x3cd4, 607 0xcc48, 0x6624, 608 0xcc49, 0x5563, 609 0xcc4a, 0x2d42, 610 0xcc4b, 0x3002, 611 0xcc4c, 0x13d2, 612 0xcc4d, 0x2ed2, 613 0xcc4e, 0x3002, 614 0xcc4f, 0x1002, 615 0xcc50, 0x2fd2, 616 0xcc51, 0x3002, 617 0xcc52, 0x1002, 618 0xcc53, 0x004, 619 0xcc54, 0x2942, 620 0xcc55, 0x3002, 621 0xcc56, 0x1002, 622 0xcc57, 0x2092, 623 0xcc58, 0x3012, 624 0xcc59, 0x1002, 625 0xcc5a, 0x5cc3, 626 0xcc5b, 0x317, 627 0xcc5c, 0x2f72, 628 0xcc5d, 0x3002, 629 0xcc5e, 0x1002, 630 0xcc5f, 0x2942, 631 0xcc60, 0x3002, 632 0xcc61, 0x1002, 633 0xcc62, 0x22cd, 634 0xcc63, 0x301d, 635 0xcc64, 0x2862, 636 0xcc65, 0x3012, 637 0xcc66, 0x1002, 638 0xcc67, 0x2ed2, 639 0xcc68, 0x3002, 640 0xcc69, 0x1002, 641 0xcc6a, 0x2d72, 642 0xcc6b, 0x3002, 643 0xcc6c, 0x1002, 644 0xcc6d, 0x628f, 645 0xcc6e, 0x2112, 646 0xcc6f, 0x3012, 647 0xcc70, 0x1002, 648 0xcc71, 0x5aa3, 649 0xcc72, 0x2dc2, 650 0xcc73, 0x3002, 651 0xcc74, 0x1312, 652 0xcc75, 0x6f72, 653 0xcc76, 0x1002, 654 0xcc77, 0x2807, 655 0xcc78, 0x31a7, 656 0xcc79, 0x20c4, 657 0xcc7a, 0x3c24, 658 0xcc7b, 0x6724, 659 0xcc7c, 0x1002, 660 0xcc7d, 0x2807, 661 0xcc7e, 0x3187, 662 0xcc7f, 0x20c4, 663 0xcc80, 0x3c24, 664 0xcc81, 0x6724, 665 0xcc82, 0x1002, 666 0xcc83, 0x2514, 667 0xcc84, 0x3c64, 668 0xcc85, 0x6436, 669 0xcc86, 0xdff4, 670 0xcc87, 0x6436, 671 0xcc88, 0x1002, 672 0xcc89, 0x40a4, 673 0xcc8a, 0x643c, 674 0xcc8b, 0x4016, 675 0xcc8c, 0x8c6c, 676 0xcc8d, 0x2b24, 677 0xcc8e, 0x3c24, 678 0xcc8f, 0x6435, 679 0xcc90, 0x1002, 680 0xcc91, 0x2b24, 681 0xcc92, 0x3c24, 682 0xcc93, 0x643a, 683 0xcc94, 0x4025, 684 0xcc95, 0x8a5a, 685 0xcc96, 0x1002, 686 0xcc97, 0x2731, 687 0xcc98, 0x3011, 688 0xcc99, 0x1001, 689 0xcc9a, 0xc7a0, 690 0xcc9b, 0x100, 691 0xcc9c, 0xc502, 692 0xcc9d, 0x53ac, 693 0xcc9e, 0xc503, 694 0xcc9f, 0xd5d5, 695 0xcca0, 0xc600, 696 0xcca1, 0x2a6d, 697 0xcca2, 0xc601, 698 0xcca3, 0x2a4c, 699 0xcca4, 0xc602, 700 0xcca5, 0x111, 701 0xcca6, 0xc60c, 702 0xcca7, 0x5900, 703 0xcca8, 0xc710, 704 0xcca9, 0x700, 705 0xccaa, 0xc718, 706 0xccab, 0x700, 707 0xccac, 0xc720, 708 0xccad, 0x4700, 709 0xccae, 0xc801, 710 0xccaf, 0x7f50, 711 0xccb0, 0xc802, 712 0xccb1, 0x7760, 713 0xccb2, 0xc803, 714 0xccb3, 0x7fce, 715 0xccb4, 0xc804, 716 0xccb5, 0x5700, 717 0xccb6, 0xc805, 718 0xccb7, 0x5f11, 719 0xccb8, 0xc806, 720 0xccb9, 0x4751, 721 0xccba, 0xc807, 722 0xccbb, 0x57e1, 723 0xccbc, 0xc808, 724 0xccbd, 0x2700, 725 0xccbe, 0xc809, 726 0xccbf, 0x000, 727 0xccc0, 0xc821, 728 0xccc1, 0x002, 729 0xccc2, 0xc822, 730 0xccc3, 0x014, 731 0xccc4, 0xc832, 732 0xccc5, 0x1186, 733 0xccc6, 0xc847, 734 0xccc7, 0x1e02, 735 0xccc8, 0xc013, 736 0xccc9, 0xf341, 737 0xccca, 0xc01a, 738 0xcccb, 0x446, 739 0xcccc, 0xc024, 740 0xcccd, 0x1000, 741 0xccce, 0xc025, 742 0xcccf, 0xa00, 743 0xccd0, 0xc026, 744 0xccd1, 0xc0c, 745 0xccd2, 0xc027, 746 0xccd3, 0xc0c, 747 0xccd4, 0xc029, 748 0xccd5, 0x0a0, 749 0xccd6, 0xc030, 750 0xccd7, 0xa00, 751 0xccd8, 0xc03c, 752 0xccd9, 0x01c, 753 0xccda, 0xc005, 754 0xccdb, 0x7a06, 755 0xccdc, 0x000, 756 0xccdd, 0x2731, 757 0xccde, 0x3011, 758 0xccdf, 0x1001, 759 0xcce0, 0xc620, 760 0xcce1, 0x000, 761 0xcce2, 0xc621, 762 0xcce3, 0x03f, 763 0xcce4, 0xc622, 764 0xcce5, 0x000, 765 0xcce6, 0xc623, 766 0xcce7, 0x000, 767 0xcce8, 0xc624, 768 0xcce9, 0x000, 769 0xccea, 0xc625, 770 0xcceb, 0x000, 771 0xccec, 0xc627, 772 0xcced, 0x000, 773 0xccee, 0xc628, 774 0xccef, 0x000, 775 0xccf0, 0xc62c, 776 0xccf1, 0x000, 777 0xccf2, 0x000, 778 0xccf3, 0x2806, 779 0xccf4, 0x3cb6, 780 0xccf5, 0xc161, 781 0xccf6, 0x6134, 782 0xccf7, 0x6135, 783 0xccf8, 0x5443, 784 0xccf9, 0x303, 785 0xccfa, 0x6524, 786 0xccfb, 0x00b, 787 0xccfc, 0x1002, 788 0xccfd, 0x2104, 789 0xccfe, 0x3c24, 790 0xccff, 0x2105, 791 0xcd00, 0x3805, 792 0xcd01, 0x6524, 793 0xcd02, 0xdff4, 794 0xcd03, 0x4005, 795 0xcd04, 0x6524, 796 0xcd05, 0x1002, 797 0xcd06, 0x5dd3, 798 0xcd07, 0x306, 799 0xcd08, 0x2ff7, 800 0xcd09, 0x38f7, 801 0xcd0a, 0x60b7, 802 0xcd0b, 0xdffd, 803 0xcd0c, 0x00a, 804 0xcd0d, 0x1002, 805 0xcd0e, 0 806 }; 807 int i, err; 808 809 err = set_phy_regs(phy, regs); 810 if (err) 811 return err; 812 813 msleep(50); 814 815 for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) 816 err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], 817 sr_edc[i + 1]); 818 if (!err) 819 phy->priv = edc_sr; 820 return err; 821 } 822 823 static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) 824 { 825 static struct reg_val regs[] = { 826 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, 827 { 0, 0, 0, 0 } 828 }; 829 static struct reg_val preemphasis[] = { 830 { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, 831 { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, 832 { 0, 0, 0, 0 } 833 }; 834 static u16 twinax_edc[] = { 835 0xcc00, 0x4009, 836 0xcc01, 0x27ff, 837 0xcc02, 0x300f, 838 0xcc03, 0x40aa, 839 0xcc04, 0x401c, 840 0xcc05, 0x401e, 841 0xcc06, 0x2ff4, 842 0xcc07, 0x3cd4, 843 0xcc08, 0x2035, 844 0xcc09, 0x3145, 845 0xcc0a, 0x6524, 846 0xcc0b, 0x26a2, 847 0xcc0c, 0x3012, 848 0xcc0d, 0x1002, 849 0xcc0e, 0x29c2, 850 0xcc0f, 0x3002, 851 0xcc10, 0x1002, 852 0xcc11, 0x2072, 853 0xcc12, 0x3012, 854 0xcc13, 0x1002, 855 0xcc14, 0x22cd, 856 0xcc15, 0x301d, 857 0xcc16, 0x2e52, 858 0xcc17, 0x3012, 859 0xcc18, 0x1002, 860 0xcc19, 0x28e2, 861 0xcc1a, 0x3002, 862 0xcc1b, 0x1002, 863 0xcc1c, 0x628f, 864 0xcc1d, 0x2ac2, 865 0xcc1e, 0x3012, 866 0xcc1f, 0x1002, 867 0xcc20, 0x5553, 868 0xcc21, 0x2ae2, 869 0xcc22, 0x3002, 870 0xcc23, 0x1302, 871 0xcc24, 0x401e, 872 0xcc25, 0x2be2, 873 0xcc26, 0x3012, 874 0xcc27, 0x1002, 875 0xcc28, 0x2da2, 876 0xcc29, 0x3012, 877 0xcc2a, 0x1002, 878 0xcc2b, 0x2ba2, 879 0xcc2c, 0x3002, 880 0xcc2d, 0x1002, 881 0xcc2e, 0x5ee3, 882 0xcc2f, 0x305, 883 0xcc30, 0x400e, 884 0xcc31, 0x2bc2, 885 0xcc32, 0x3002, 886 0xcc33, 0x1002, 887 0xcc34, 0x2b82, 888 0xcc35, 0x3012, 889 0xcc36, 0x1002, 890 0xcc37, 0x5663, 891 0xcc38, 0x302, 892 0xcc39, 0x401e, 893 0xcc3a, 0x6f72, 894 0xcc3b, 0x1002, 895 0xcc3c, 0x628f, 896 0xcc3d, 0x2be2, 897 0xcc3e, 0x3012, 898 0xcc3f, 0x1002, 899 0xcc40, 0x22cd, 900 0xcc41, 0x301d, 901 0xcc42, 0x2e52, 902 0xcc43, 0x3012, 903 0xcc44, 0x1002, 904 0xcc45, 0x2522, 905 0xcc46, 0x3012, 906 0xcc47, 0x1002, 907 0xcc48, 0x2da2, 908 0xcc49, 0x3012, 909 0xcc4a, 0x1002, 910 0xcc4b, 0x2ca2, 911 0xcc4c, 0x3012, 912 0xcc4d, 0x1002, 913 0xcc4e, 0x2fa4, 914 0xcc4f, 0x3cd4, 915 0xcc50, 0x6624, 916 0xcc51, 0x410b, 917 0xcc52, 0x56b3, 918 0xcc53, 0x3c4, 919 0xcc54, 0x2fb2, 920 0xcc55, 0x3002, 921 0xcc56, 0x1002, 922 0xcc57, 0x220b, 923 0xcc58, 0x303b, 924 0xcc59, 0x56b3, 925 0xcc5a, 0x3c3, 926 0xcc5b, 0x866b, 927 0xcc5c, 0x400c, 928 0xcc5d, 0x23a2, 929 0xcc5e, 0x3012, 930 0xcc5f, 0x1002, 931 0xcc60, 0x2da2, 932 0xcc61, 0x3012, 933 0xcc62, 0x1002, 934 0xcc63, 0x2ca2, 935 0xcc64, 0x3012, 936 0xcc65, 0x1002, 937 0xcc66, 0x2fb4, 938 0xcc67, 0x3cd4, 939 0xcc68, 0x6624, 940 0xcc69, 0x56b3, 941 0xcc6a, 0x3c3, 942 0xcc6b, 0x866b, 943 0xcc6c, 0x401c, 944 0xcc6d, 0x2205, 945 0xcc6e, 0x3035, 946 0xcc6f, 0x5b53, 947 0xcc70, 0x2c52, 948 0xcc71, 0x3002, 949 0xcc72, 0x13c2, 950 0xcc73, 0x5cc3, 951 0xcc74, 0x317, 952 0xcc75, 0x2522, 953 0xcc76, 0x3012, 954 0xcc77, 0x1002, 955 0xcc78, 0x2da2, 956 0xcc79, 0x3012, 957 0xcc7a, 0x1002, 958 0xcc7b, 0x2b82, 959 0xcc7c, 0x3012, 960 0xcc7d, 0x1002, 961 0xcc7e, 0x5663, 962 0xcc7f, 0x303, 963 0xcc80, 0x401e, 964 0xcc81, 0x004, 965 0xcc82, 0x2c42, 966 0xcc83, 0x3012, 967 0xcc84, 0x1002, 968 0xcc85, 0x6f72, 969 0xcc86, 0x1002, 970 0xcc87, 0x628f, 971 0xcc88, 0x2304, 972 0xcc89, 0x3c84, 973 0xcc8a, 0x6436, 974 0xcc8b, 0xdff4, 975 0xcc8c, 0x6436, 976 0xcc8d, 0x2ff5, 977 0xcc8e, 0x3005, 978 0xcc8f, 0x8656, 979 0xcc90, 0xdfba, 980 0xcc91, 0x56a3, 981 0xcc92, 0xd05a, 982 0xcc93, 0x21c2, 983 0xcc94, 0x3012, 984 0xcc95, 0x1392, 985 0xcc96, 0xd05a, 986 0xcc97, 0x56a3, 987 0xcc98, 0xdfba, 988 0xcc99, 0x383, 989 0xcc9a, 0x6f72, 990 0xcc9b, 0x1002, 991 0xcc9c, 0x28c5, 992 0xcc9d, 0x3005, 993 0xcc9e, 0x4178, 994 0xcc9f, 0x5653, 995 0xcca0, 0x384, 996 0xcca1, 0x22b2, 997 0xcca2, 0x3012, 998 0xcca3, 0x1002, 999 0xcca4, 0x2be5, 1000 0xcca5, 0x3005, 1001 0xcca6, 0x41e8, 1002 0xcca7, 0x5653, 1003 0xcca8, 0x382, 1004 0xcca9, 0x002, 1005 0xccaa, 0x4258, 1006 0xccab, 0x2474, 1007 0xccac, 0x3c84, 1008 0xccad, 0x6437, 1009 0xccae, 0xdff4, 1010 0xccaf, 0x6437, 1011 0xccb0, 0x2ff5, 1012 0xccb1, 0x3c05, 1013 0xccb2, 0x8757, 1014 0xccb3, 0xb888, 1015 0xccb4, 0x9787, 1016 0xccb5, 0xdff4, 1017 0xccb6, 0x6724, 1018 0xccb7, 0x866a, 1019 0xccb8, 0x6f72, 1020 0xccb9, 0x1002, 1021 0xccba, 0x2d01, 1022 0xccbb, 0x3011, 1023 0xccbc, 0x1001, 1024 0xccbd, 0xc620, 1025 0xccbe, 0x14e5, 1026 0xccbf, 0xc621, 1027 0xccc0, 0xc53d, 1028 0xccc1, 0xc622, 1029 0xccc2, 0x3cbe, 1030 0xccc3, 0xc623, 1031 0xccc4, 0x4452, 1032 0xccc5, 0xc624, 1033 0xccc6, 0xc5c5, 1034 0xccc7, 0xc625, 1035 0xccc8, 0xe01e, 1036 0xccc9, 0xc627, 1037 0xccca, 0x000, 1038 0xcccb, 0xc628, 1039 0xcccc, 0x000, 1040 0xcccd, 0xc62b, 1041 0xccce, 0x000, 1042 0xcccf, 0xc62c, 1043 0xccd0, 0x000, 1044 0xccd1, 0x000, 1045 0xccd2, 0x2d01, 1046 0xccd3, 0x3011, 1047 0xccd4, 0x1001, 1048 0xccd5, 0xc620, 1049 0xccd6, 0x000, 1050 0xccd7, 0xc621, 1051 0xccd8, 0x000, 1052 0xccd9, 0xc622, 1053 0xccda, 0x0ce, 1054 0xccdb, 0xc623, 1055 0xccdc, 0x07f, 1056 0xccdd, 0xc624, 1057 0xccde, 0x032, 1058 0xccdf, 0xc625, 1059 0xcce0, 0x000, 1060 0xcce1, 0xc627, 1061 0xcce2, 0x000, 1062 0xcce3, 0xc628, 1063 0xcce4, 0x000, 1064 0xcce5, 0xc62b, 1065 0xcce6, 0x000, 1066 0xcce7, 0xc62c, 1067 0xcce8, 0x000, 1068 0xcce9, 0x000, 1069 0xccea, 0x2d01, 1070 0xcceb, 0x3011, 1071 0xccec, 0x1001, 1072 0xcced, 0xc502, 1073 0xccee, 0x609f, 1074 0xccef, 0xc600, 1075 0xccf0, 0x2a6e, 1076 0xccf1, 0xc601, 1077 0xccf2, 0x2a2c, 1078 0xccf3, 0xc60c, 1079 0xccf4, 0x5400, 1080 0xccf5, 0xc710, 1081 0xccf6, 0x700, 1082 0xccf7, 0xc718, 1083 0xccf8, 0x700, 1084 0xccf9, 0xc720, 1085 0xccfa, 0x4700, 1086 0xccfb, 0xc728, 1087 0xccfc, 0x700, 1088 0xccfd, 0xc729, 1089 0xccfe, 0x1207, 1090 0xccff, 0xc801, 1091 0xcd00, 0x7f50, 1092 0xcd01, 0xc802, 1093 0xcd02, 0x7760, 1094 0xcd03, 0xc803, 1095 0xcd04, 0x7fce, 1096 0xcd05, 0xc804, 1097 0xcd06, 0x520e, 1098 0xcd07, 0xc805, 1099 0xcd08, 0x5c11, 1100 0xcd09, 0xc806, 1101 0xcd0a, 0x3c51, 1102 0xcd0b, 0xc807, 1103 0xcd0c, 0x4061, 1104 0xcd0d, 0xc808, 1105 0xcd0e, 0x49c1, 1106 0xcd0f, 0xc809, 1107 0xcd10, 0x3840, 1108 0xcd11, 0xc80a, 1109 0xcd12, 0x000, 1110 0xcd13, 0xc821, 1111 0xcd14, 0x002, 1112 0xcd15, 0xc822, 1113 0xcd16, 0x046, 1114 0xcd17, 0xc844, 1115 0xcd18, 0x182f, 1116 0xcd19, 0xc013, 1117 0xcd1a, 0xf341, 1118 0xcd1b, 0xc01a, 1119 0xcd1c, 0x446, 1120 0xcd1d, 0xc024, 1121 0xcd1e, 0x1000, 1122 0xcd1f, 0xc025, 1123 0xcd20, 0xa00, 1124 0xcd21, 0xc026, 1125 0xcd22, 0xc0c, 1126 0xcd23, 0xc027, 1127 0xcd24, 0xc0c, 1128 0xcd25, 0xc029, 1129 0xcd26, 0x0a0, 1130 0xcd27, 0xc030, 1131 0xcd28, 0xa00, 1132 0xcd29, 0xc03c, 1133 0xcd2a, 0x01c, 1134 0xcd2b, 0x000, 1135 0xcd2c, 0x2b84, 1136 0xcd2d, 0x3c74, 1137 0xcd2e, 0x6435, 1138 0xcd2f, 0xdff4, 1139 0xcd30, 0x6435, 1140 0xcd31, 0x2806, 1141 0xcd32, 0x3006, 1142 0xcd33, 0x8565, 1143 0xcd34, 0x2b24, 1144 0xcd35, 0x3c24, 1145 0xcd36, 0x6436, 1146 0xcd37, 0x1002, 1147 0xcd38, 0x2b24, 1148 0xcd39, 0x3c24, 1149 0xcd3a, 0x6436, 1150 0xcd3b, 0x4045, 1151 0xcd3c, 0x8656, 1152 0xcd3d, 0x1002, 1153 0xcd3e, 0x2807, 1154 0xcd3f, 0x31a7, 1155 0xcd40, 0x20c4, 1156 0xcd41, 0x3c24, 1157 0xcd42, 0x6724, 1158 0xcd43, 0x1002, 1159 0xcd44, 0x2807, 1160 0xcd45, 0x3187, 1161 0xcd46, 0x20c4, 1162 0xcd47, 0x3c24, 1163 0xcd48, 0x6724, 1164 0xcd49, 0x1002, 1165 0xcd4a, 0x2514, 1166 0xcd4b, 0x3c64, 1167 0xcd4c, 0x6436, 1168 0xcd4d, 0xdff4, 1169 0xcd4e, 0x6436, 1170 0xcd4f, 0x1002, 1171 0xcd50, 0x2806, 1172 0xcd51, 0x3cb6, 1173 0xcd52, 0xc161, 1174 0xcd53, 0x6134, 1175 0xcd54, 0x6135, 1176 0xcd55, 0x5443, 1177 0xcd56, 0x303, 1178 0xcd57, 0x6524, 1179 0xcd58, 0x00b, 1180 0xcd59, 0x1002, 1181 0xcd5a, 0xd019, 1182 0xcd5b, 0x2104, 1183 0xcd5c, 0x3c24, 1184 0xcd5d, 0x2105, 1185 0xcd5e, 0x3805, 1186 0xcd5f, 0x6524, 1187 0xcd60, 0xdff4, 1188 0xcd61, 0x4005, 1189 0xcd62, 0x6524, 1190 0xcd63, 0x2e8d, 1191 0xcd64, 0x303d, 1192 0xcd65, 0x5dd3, 1193 0xcd66, 0x306, 1194 0xcd67, 0x2ff7, 1195 0xcd68, 0x38f7, 1196 0xcd69, 0x60b7, 1197 0xcd6a, 0xdffd, 1198 0xcd6b, 0x00a, 1199 0xcd6c, 0x1002, 1200 0xcd6d, 0 1201 }; 1202 int i, err; 1203 1204 err = set_phy_regs(phy, regs); 1205 if (!err && modtype == phy_modtype_twinax_long) 1206 err = set_phy_regs(phy, preemphasis); 1207 if (err) 1208 return err; 1209 1210 msleep(50); 1211 1212 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) 1213 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], 1214 twinax_edc[i + 1]); 1215 if (!err) 1216 phy->priv = edc_twinax; 1217 return err; 1218 } 1219 1220 static int ael2005_get_module_type(struct cphy *phy, int delay_ms) 1221 { 1222 int v; 1223 unsigned int stat; 1224 1225 v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); 1226 if (v) 1227 return v; 1228 1229 if (stat & (1 << 8)) /* module absent */ 1230 return phy_modtype_none; 1231 1232 return ael2xxx_get_module_type(phy, delay_ms); 1233 } 1234 1235 static int ael2005_intr_enable(struct cphy *phy) 1236 { 1237 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); 1238 return err ? err : t3_phy_lasi_intr_enable(phy); 1239 } 1240 1241 static int ael2005_intr_disable(struct cphy *phy) 1242 { 1243 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); 1244 return err ? err : t3_phy_lasi_intr_disable(phy); 1245 } 1246 1247 static int ael2005_intr_clear(struct cphy *phy) 1248 { 1249 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); 1250 return err ? err : t3_phy_lasi_intr_clear(phy); 1251 } 1252 1253 static int ael2005_reset(struct cphy *phy, int wait) 1254 { 1255 static struct reg_val regs0[] = { 1256 { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, 1257 { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, 1258 { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, 1259 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, 1260 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, 1261 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, 1262 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, 1263 { 0, 0, 0, 0 } 1264 }; 1265 static struct reg_val regs1[] = { 1266 { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, 1267 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, 1268 { 0, 0, 0, 0 } 1269 }; 1270 1271 int err; 1272 unsigned int lasi_ctrl; 1273 1274 err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); 1275 if (err) 1276 return err; 1277 1278 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); 1279 if (err) 1280 return err; 1281 1282 msleep(125); 1283 phy->priv = edc_none; 1284 err = set_phy_regs(phy, regs0); 1285 if (err) 1286 return err; 1287 1288 msleep(50); 1289 1290 err = ael2005_get_module_type(phy, 0); 1291 if (err < 0) 1292 return err; 1293 phy->modtype = (u8)err; 1294 1295 if (err == phy_modtype_none) 1296 err = 0; 1297 else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) 1298 err = ael2005_setup_twinax_edc(phy, err); 1299 else 1300 err = ael2005_setup_sr_edc(phy); 1301 if (err) 1302 return err; 1303 1304 err = set_phy_regs(phy, regs1); 1305 if (err) 1306 return err; 1307 1308 /* reset wipes out interrupts, reenable them if they were on */ 1309 if (lasi_ctrl & 1) 1310 err = ael2005_intr_enable(phy); 1311 return err; 1312 } 1313 1314 static int ael2005_intr_handler(struct cphy *phy) 1315 { 1316 unsigned int stat; 1317 int ret, edc_needed, cause = 0; 1318 1319 ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); 1320 if (ret) 1321 return ret; 1322 1323 if (stat & AEL2005_MODDET_IRQ) { 1324 ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 1325 0xd00); 1326 if (ret) 1327 return ret; 1328 1329 /* modules have max 300 ms init time after hot plug */ 1330 ret = ael2005_get_module_type(phy, 300); 1331 if (ret < 0) 1332 return ret; 1333 1334 phy->modtype = (u8)ret; 1335 if (ret == phy_modtype_none) 1336 edc_needed = phy->priv; /* on unplug retain EDC */ 1337 else if (ret == phy_modtype_twinax || 1338 ret == phy_modtype_twinax_long) 1339 edc_needed = edc_twinax; 1340 else 1341 edc_needed = edc_sr; 1342 1343 if (edc_needed != phy->priv) { 1344 ret = ael2005_reset(phy, 0); 1345 return ret ? ret : cphy_cause_module_change; 1346 } 1347 cause = cphy_cause_module_change; 1348 } 1349 1350 ret = t3_phy_lasi_intr_handler(phy); 1351 if (ret < 0) 1352 return ret; 1353 1354 ret |= cause; 1355 if (!ret) 1356 ret |= cphy_cause_link_change; 1357 return ret; 1358 } 1359 1360 static struct cphy_ops ael2005_ops = { 1361 #ifdef C99_NOT_SUPPORTED 1362 ael2005_reset, 1363 ael2005_intr_enable, 1364 ael2005_intr_disable, 1365 ael2005_intr_clear, 1366 ael2005_intr_handler, 1367 NULL, 1368 NULL, 1369 NULL, 1370 NULL, 1371 NULL, 1372 get_link_status_r, 1373 ael1002_power_down, 1374 #else 1375 .reset = ael2005_reset, 1376 .intr_enable = ael2005_intr_enable, 1377 .intr_disable = ael2005_intr_disable, 1378 .intr_clear = ael2005_intr_clear, 1379 .intr_handler = ael2005_intr_handler, 1380 .get_link_status = get_link_status_r, 1381 .power_down = ael1002_power_down, 1382 #endif 1383 }; 1384 1385 int t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr, 1386 const struct mdio_ops *mdio_ops) 1387 { 1388 int err; 1389 struct cphy *phy = &pinfo->phy; 1390 1391 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2005_ops, mdio_ops, 1392 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | 1393 SUPPORTED_IRQ, "10GBASE-R"); 1394 msleep(125); 1395 ael_laser_down(phy, 0); 1396 1397 err = ael2005_get_module_type(phy, 0); 1398 if (err >= 0) 1399 phy->modtype = err; 1400 1401 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, 1402 1 << 5); 1403 } 1404 1405 /* 1406 * Setup EDC and other parameters for operation with an optical module. 1407 */ 1408 static int ael2020_setup_sr_edc(struct cphy *phy) 1409 { 1410 static struct reg_val regs[] = { 1411 { MDIO_DEV_PMA_PMD, 0xcc01, 0xffff, 0x488a }, 1412 1413 { MDIO_DEV_PMA_PMD, 0xcb1b, 0xffff, 0x0200 }, 1414 { MDIO_DEV_PMA_PMD, 0xcb1c, 0xffff, 0x00f0 }, 1415 { MDIO_DEV_PMA_PMD, 0xcc06, 0xffff, 0x00e0 }, 1416 1417 /* end */ 1418 { 0, 0, 0, 0 } 1419 }; 1420 int err; 1421 1422 err = set_phy_regs(phy, regs); 1423 msleep(50); 1424 if (err) 1425 return err; 1426 1427 phy->priv = edc_sr; 1428 return 0; 1429 } 1430 1431 /* 1432 * Setup EDC and other parameters for operation with an TWINAX module. 1433 */ 1434 static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) 1435 { 1436 static struct reg_val uCclock40MHz[] = { 1437 { MDIO_DEV_PMA_PMD, 0xff28, 0xffff, 0x4001 }, 1438 { MDIO_DEV_PMA_PMD, 0xff2a, 0xffff, 0x0002 }, 1439 { 0, 0, 0, 0 } 1440 }; 1441 1442 static struct reg_val uCclockActivate[] = { 1443 { MDIO_DEV_PMA_PMD, 0xd000, 0xffff, 0x5200 }, 1444 { 0, 0, 0, 0 } 1445 }; 1446 1447 static struct reg_val uCactivate[] = { 1448 { MDIO_DEV_PMA_PMD, 0xd080, 0xffff, 0x0100 }, 1449 { MDIO_DEV_PMA_PMD, 0xd092, 0xffff, 0x0000 }, 1450 { 0, 0, 0, 0 } 1451 }; 1452 1453 static u16 twinax_edc[] = { 1454 0xd800, 0x4009, 1455 0xd801, 0x2fff, 1456 0xd802, 0x300f, 1457 0xd803, 0x40aa, 1458 0xd804, 0x401c, 1459 0xd805, 0x401e, 1460 0xd806, 0x20c5, 1461 0xd807, 0x3c05, 1462 0xd808, 0x6536, 1463 0xd809, 0x2fe4, 1464 0xd80a, 0x3dc4, 1465 0xd80b, 0x6624, 1466 0xd80c, 0x2ff4, 1467 0xd80d, 0x3dc4, 1468 0xd80e, 0x2035, 1469 0xd80f, 0x30a5, 1470 0xd810, 0x6524, 1471 0xd811, 0x2ca2, 1472 0xd812, 0x3012, 1473 0xd813, 0x1002, 1474 0xd814, 0x27e2, 1475 0xd815, 0x3022, 1476 0xd816, 0x1002, 1477 0xd817, 0x28d2, 1478 0xd818, 0x3022, 1479 0xd819, 0x1002, 1480 0xd81a, 0x2892, 1481 0xd81b, 0x3012, 1482 0xd81c, 0x1002, 1483 0xd81d, 0x24e2, 1484 0xd81e, 0x3022, 1485 0xd81f, 0x1002, 1486 0xd820, 0x27e2, 1487 0xd821, 0x3012, 1488 0xd822, 0x1002, 1489 0xd823, 0x2422, 1490 0xd824, 0x3022, 1491 0xd825, 0x1002, 1492 0xd826, 0x22cd, 1493 0xd827, 0x301d, 1494 0xd828, 0x28f2, 1495 0xd829, 0x3022, 1496 0xd82a, 0x1002, 1497 0xd82b, 0x5553, 1498 0xd82c, 0x0307, 1499 0xd82d, 0x2572, 1500 0xd82e, 0x3022, 1501 0xd82f, 0x1002, 1502 0xd830, 0x21a2, 1503 0xd831, 0x3012, 1504 0xd832, 0x1002, 1505 0xd833, 0x4016, 1506 0xd834, 0x5e63, 1507 0xd835, 0x0344, 1508 0xd836, 0x21a2, 1509 0xd837, 0x3012, 1510 0xd838, 0x1002, 1511 0xd839, 0x400e, 1512 0xd83a, 0x2572, 1513 0xd83b, 0x3022, 1514 0xd83c, 0x1002, 1515 0xd83d, 0x2b22, 1516 0xd83e, 0x3012, 1517 0xd83f, 0x1002, 1518 0xd840, 0x2842, 1519 0xd841, 0x3022, 1520 0xd842, 0x1002, 1521 0xd843, 0x26e2, 1522 0xd844, 0x3022, 1523 0xd845, 0x1002, 1524 0xd846, 0x2fa4, 1525 0xd847, 0x3dc4, 1526 0xd848, 0x6624, 1527 0xd849, 0x2e8b, 1528 0xd84a, 0x303b, 1529 0xd84b, 0x56b3, 1530 0xd84c, 0x03c6, 1531 0xd84d, 0x866b, 1532 0xd84e, 0x400c, 1533 0xd84f, 0x2782, 1534 0xd850, 0x3012, 1535 0xd851, 0x1002, 1536 0xd852, 0x2c4b, 1537 0xd853, 0x309b, 1538 0xd854, 0x56b3, 1539 0xd855, 0x03c3, 1540 0xd856, 0x866b, 1541 0xd857, 0x400c, 1542 0xd858, 0x22a2, 1543 0xd859, 0x3022, 1544 0xd85a, 0x1002, 1545 0xd85b, 0x2842, 1546 0xd85c, 0x3022, 1547 0xd85d, 0x1002, 1548 0xd85e, 0x26e2, 1549 0xd85f, 0x3022, 1550 0xd860, 0x1002, 1551 0xd861, 0x2fb4, 1552 0xd862, 0x3dc4, 1553 0xd863, 0x6624, 1554 0xd864, 0x56b3, 1555 0xd865, 0x03c3, 1556 0xd866, 0x866b, 1557 0xd867, 0x401c, 1558 0xd868, 0x2c45, 1559 0xd869, 0x3095, 1560 0xd86a, 0x5b53, 1561 0xd86b, 0x23d2, 1562 0xd86c, 0x3012, 1563 0xd86d, 0x13c2, 1564 0xd86e, 0x5cc3, 1565 0xd86f, 0x2782, 1566 0xd870, 0x3012, 1567 0xd871, 0x1312, 1568 0xd872, 0x2b22, 1569 0xd873, 0x3012, 1570 0xd874, 0x1002, 1571 0xd875, 0x2842, 1572 0xd876, 0x3022, 1573 0xd877, 0x1002, 1574 0xd878, 0x2622, 1575 0xd879, 0x3022, 1576 0xd87a, 0x1002, 1577 0xd87b, 0x21a2, 1578 0xd87c, 0x3012, 1579 0xd87d, 0x1002, 1580 0xd87e, 0x628f, 1581 0xd87f, 0x2985, 1582 0xd880, 0x33a5, 1583 0xd881, 0x26e2, 1584 0xd882, 0x3022, 1585 0xd883, 0x1002, 1586 0xd884, 0x5653, 1587 0xd885, 0x03d2, 1588 0xd886, 0x401e, 1589 0xd887, 0x6f72, 1590 0xd888, 0x1002, 1591 0xd889, 0x628f, 1592 0xd88a, 0x2304, 1593 0xd88b, 0x3c84, 1594 0xd88c, 0x6436, 1595 0xd88d, 0xdff4, 1596 0xd88e, 0x6436, 1597 0xd88f, 0x2ff5, 1598 0xd890, 0x3005, 1599 0xd891, 0x8656, 1600 0xd892, 0xdfba, 1601 0xd893, 0x56a3, 1602 0xd894, 0xd05a, 1603 0xd895, 0x29e2, 1604 0xd896, 0x3012, 1605 0xd897, 0x1392, 1606 0xd898, 0xd05a, 1607 0xd899, 0x56a3, 1608 0xd89a, 0xdfba, 1609 0xd89b, 0x0383, 1610 0xd89c, 0x6f72, 1611 0xd89d, 0x1002, 1612 0xd89e, 0x2a64, 1613 0xd89f, 0x3014, 1614 0xd8a0, 0x2005, 1615 0xd8a1, 0x3d75, 1616 0xd8a2, 0xc451, 1617 0xd8a3, 0x29a2, 1618 0xd8a4, 0x3022, 1619 0xd8a5, 0x1002, 1620 0xd8a6, 0x178c, 1621 0xd8a7, 0x1898, 1622 0xd8a8, 0x19a4, 1623 0xd8a9, 0x1ab0, 1624 0xd8aa, 0x1bbc, 1625 0xd8ab, 0x1cc8, 1626 0xd8ac, 0x1dd3, 1627 0xd8ad, 0x1ede, 1628 0xd8ae, 0x1fe9, 1629 0xd8af, 0x20f4, 1630 0xd8b0, 0x21ff, 1631 0xd8b1, 0x0000, 1632 0xd8b2, 0x2741, 1633 0xd8b3, 0x3021, 1634 0xd8b4, 0x1001, 1635 0xd8b5, 0xc620, 1636 0xd8b6, 0x0000, 1637 0xd8b7, 0xc621, 1638 0xd8b8, 0x0000, 1639 0xd8b9, 0xc622, 1640 0xd8ba, 0x00e2, 1641 0xd8bb, 0xc623, 1642 0xd8bc, 0x007f, 1643 0xd8bd, 0xc624, 1644 0xd8be, 0x00ce, 1645 0xd8bf, 0xc625, 1646 0xd8c0, 0x0000, 1647 0xd8c1, 0xc627, 1648 0xd8c2, 0x0000, 1649 0xd8c3, 0xc628, 1650 0xd8c4, 0x0000, 1651 0xd8c5, 0xc90a, 1652 0xd8c6, 0x3a7c, 1653 0xd8c7, 0xc62c, 1654 0xd8c8, 0x0000, 1655 0xd8c9, 0x0000, 1656 0xd8ca, 0x2741, 1657 0xd8cb, 0x3021, 1658 0xd8cc, 0x1001, 1659 0xd8cd, 0xc502, 1660 0xd8ce, 0x53ac, 1661 0xd8cf, 0xc503, 1662 0xd8d0, 0x2cd3, 1663 0xd8d1, 0xc600, 1664 0xd8d2, 0x2a6e, 1665 0xd8d3, 0xc601, 1666 0xd8d4, 0x2a2c, 1667 0xd8d5, 0xc605, 1668 0xd8d6, 0x5557, 1669 0xd8d7, 0xc60c, 1670 0xd8d8, 0x5400, 1671 0xd8d9, 0xc710, 1672 0xd8da, 0x0700, 1673 0xd8db, 0xc711, 1674 0xd8dc, 0x0f06, 1675 0xd8dd, 0xc718, 1676 0xd8de, 0x700, 1677 0xd8df, 0xc719, 1678 0xd8e0, 0x0f06, 1679 0xd8e1, 0xc720, 1680 0xd8e2, 0x4700, 1681 0xd8e3, 0xc721, 1682 0xd8e4, 0x0f06, 1683 0xd8e5, 0xc728, 1684 0xd8e6, 0x0700, 1685 0xd8e7, 0xc729, 1686 0xd8e8, 0x1207, 1687 0xd8e9, 0xc801, 1688 0xd8ea, 0x7f50, 1689 0xd8eb, 0xc802, 1690 0xd8ec, 0x7760, 1691 0xd8ed, 0xc803, 1692 0xd8ee, 0x7fce, 1693 0xd8ef, 0xc804, 1694 0xd8f0, 0x520e, 1695 0xd8f1, 0xc805, 1696 0xd8f2, 0x5c11, 1697 0xd8f3, 0xc806, 1698 0xd8f4, 0x3c51, 1699 0xd8f5, 0xc807, 1700 0xd8f6, 0x4061, 1701 0xd8f7, 0xc808, 1702 0xd8f8, 0x49c1, 1703 0xd8f9, 0xc809, 1704 0xd8fa, 0x3840, 1705 0xd8fb, 0xc80a, 1706 0xd8fc, 0x0000, 1707 0xd8fd, 0xc821, 1708 0xd8fe, 0x0002, 1709 0xd8ff, 0xc822, 1710 0xd900, 0x0046, 1711 0xd901, 0xc844, 1712 0xd902, 0x182f, 1713 0xd903, 0xc849, 1714 0xd904, 0x0400, 1715 0xd905, 0xc84a, 1716 0xd906, 0x0002, 1717 0xd907, 0xc013, 1718 0xd908, 0xf341, 1719 0xd909, 0xc084, 1720 0xd90a, 0x0030, 1721 0xd90b, 0xc904, 1722 0xd90c, 0x1401, 1723 0xd90d, 0xcb0c, 1724 0xd90e, 0x0004, 1725 0xd90f, 0xcb0e, 1726 0xd910, 0xa00a, 1727 0xd911, 0xcb0f, 1728 0xd912, 0xc0c0, 1729 0xd913, 0xcb10, 1730 0xd914, 0xc0c0, 1731 0xd915, 0xcb11, 1732 0xd916, 0x00a0, 1733 0xd917, 0xcb12, 1734 0xd918, 0x0007, 1735 0xd919, 0xc241, 1736 0xd91a, 0xa000, 1737 0xd91b, 0xc243, 1738 0xd91c, 0x7fe0, 1739 0xd91d, 0xc604, 1740 0xd91e, 0x000e, 1741 0xd91f, 0xc609, 1742 0xd920, 0x00f5, 1743 0xd921, 0xc611, 1744 0xd922, 0x000e, 1745 0xd923, 0xc660, 1746 0xd924, 0x9600, 1747 0xd925, 0xc687, 1748 0xd926, 0x0004, 1749 0xd927, 0xc60a, 1750 0xd928, 0x04f5, 1751 0xd929, 0x0000, 1752 0xd92a, 0x2741, 1753 0xd92b, 0x3021, 1754 0xd92c, 0x1001, 1755 0xd92d, 0xc620, 1756 0xd92e, 0x14e5, 1757 0xd92f, 0xc621, 1758 0xd930, 0xc53d, 1759 0xd931, 0xc622, 1760 0xd932, 0x3cbe, 1761 0xd933, 0xc623, 1762 0xd934, 0x4452, 1763 0xd935, 0xc624, 1764 0xd936, 0xc5c5, 1765 0xd937, 0xc625, 1766 0xd938, 0xe01e, 1767 0xd939, 0xc627, 1768 0xd93a, 0x0000, 1769 0xd93b, 0xc628, 1770 0xd93c, 0x0000, 1771 0xd93d, 0xc62c, 1772 0xd93e, 0x0000, 1773 0xd93f, 0xc90a, 1774 0xd940, 0x3a7c, 1775 0xd941, 0x0000, 1776 0xd942, 0x2b84, 1777 0xd943, 0x3c74, 1778 0xd944, 0x6435, 1779 0xd945, 0xdff4, 1780 0xd946, 0x6435, 1781 0xd947, 0x2806, 1782 0xd948, 0x3006, 1783 0xd949, 0x8565, 1784 0xd94a, 0x2b24, 1785 0xd94b, 0x3c24, 1786 0xd94c, 0x6436, 1787 0xd94d, 0x1002, 1788 0xd94e, 0x2b24, 1789 0xd94f, 0x3c24, 1790 0xd950, 0x6436, 1791 0xd951, 0x4045, 1792 0xd952, 0x8656, 1793 0xd953, 0x5663, 1794 0xd954, 0x0302, 1795 0xd955, 0x401e, 1796 0xd956, 0x1002, 1797 0xd957, 0x2807, 1798 0xd958, 0x31a7, 1799 0xd959, 0x20c4, 1800 0xd95a, 0x3c24, 1801 0xd95b, 0x6724, 1802 0xd95c, 0x2ff7, 1803 0xd95d, 0x30f7, 1804 0xd95e, 0x20c4, 1805 0xd95f, 0x3c04, 1806 0xd960, 0x6724, 1807 0xd961, 0x1002, 1808 0xd962, 0x2807, 1809 0xd963, 0x3187, 1810 0xd964, 0x20c4, 1811 0xd965, 0x3c24, 1812 0xd966, 0x6724, 1813 0xd967, 0x2fe4, 1814 0xd968, 0x3dc4, 1815 0xd969, 0x6437, 1816 0xd96a, 0x20c4, 1817 0xd96b, 0x3c04, 1818 0xd96c, 0x6724, 1819 0xd96d, 0x1002, 1820 0xd96e, 0x24f4, 1821 0xd96f, 0x3c64, 1822 0xd970, 0x6436, 1823 0xd971, 0xdff4, 1824 0xd972, 0x6436, 1825 0xd973, 0x1002, 1826 0xd974, 0x2006, 1827 0xd975, 0x3d76, 1828 0xd976, 0xc161, 1829 0xd977, 0x6134, 1830 0xd978, 0x6135, 1831 0xd979, 0x5443, 1832 0xd97a, 0x0303, 1833 0xd97b, 0x6524, 1834 0xd97c, 0x00fb, 1835 0xd97d, 0x1002, 1836 0xd97e, 0x20d4, 1837 0xd97f, 0x3c24, 1838 0xd980, 0x2025, 1839 0xd981, 0x3005, 1840 0xd982, 0x6524, 1841 0xd983, 0x1002, 1842 0xd984, 0xd019, 1843 0xd985, 0x2104, 1844 0xd986, 0x3c24, 1845 0xd987, 0x2105, 1846 0xd988, 0x3805, 1847 0xd989, 0x6524, 1848 0xd98a, 0xdff4, 1849 0xd98b, 0x4005, 1850 0xd98c, 0x6524, 1851 0xd98d, 0x2e8d, 1852 0xd98e, 0x303d, 1853 0xd98f, 0x2408, 1854 0xd990, 0x35d8, 1855 0xd991, 0x5dd3, 1856 0xd992, 0x0307, 1857 0xd993, 0x8887, 1858 0xd994, 0x63a7, 1859 0xd995, 0x8887, 1860 0xd996, 0x63a7, 1861 0xd997, 0xdffd, 1862 0xd998, 0x00f9, 1863 0xd999, 0x1002, 1864 0xd99a, 0x866a, 1865 0xd99b, 0x6138, 1866 0xd99c, 0x5883, 1867 0xd99d, 0x2aa2, 1868 0xd99e, 0x3022, 1869 0xd99f, 0x1302, 1870 0xd9a0, 0x2ff7, 1871 0xd9a1, 0x3007, 1872 0xd9a2, 0x8785, 1873 0xd9a3, 0xb887, 1874 0xd9a4, 0x8786, 1875 0xd9a5, 0xb8c6, 1876 0xd9a6, 0x5a53, 1877 0xd9a7, 0x29b2, 1878 0xd9a8, 0x3022, 1879 0xd9a9, 0x13c2, 1880 0xd9aa, 0x2474, 1881 0xd9ab, 0x3c84, 1882 0xd9ac, 0x64d7, 1883 0xd9ad, 0x64d7, 1884 0xd9ae, 0x2ff5, 1885 0xd9af, 0x3c05, 1886 0xd9b0, 0x8757, 1887 0xd9b1, 0xb886, 1888 0xd9b2, 0x9767, 1889 0xd9b3, 0x67c4, 1890 0xd9b4, 0x6f72, 1891 0xd9b5, 0x1002, 1892 0xd9b6, 0x0000, 1893 }; 1894 int i, err; 1895 1896 /* set uC clock and activate it */ 1897 err = set_phy_regs(phy, uCclock40MHz); 1898 msleep(500); 1899 if (err) 1900 return err; 1901 err = set_phy_regs(phy, uCclockActivate); 1902 msleep(500); 1903 if (err) 1904 return err; 1905 1906 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) 1907 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], 1908 twinax_edc[i + 1]); 1909 /* activate uC */ 1910 err = set_phy_regs(phy, uCactivate); 1911 if (!err) 1912 phy->priv = edc_twinax; 1913 return err; 1914 } 1915 1916 /* 1917 * Return Module Type. 1918 */ 1919 static int ael2020_get_module_type(struct cphy *phy, int delay_ms) 1920 { 1921 int v; 1922 unsigned int stat; 1923 1924 v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_STAT, &stat); 1925 if (v) 1926 return v; 1927 1928 if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) { 1929 /* module absent */ 1930 return phy_modtype_none; 1931 } 1932 1933 return ael2xxx_get_module_type(phy, delay_ms); 1934 } 1935 1936 /* 1937 * Enable PHY interrupts. We enable "Module Detection" interrupts (on any 1938 * state transition) and then generic Link Alarm Status Interrupt (LASI). 1939 */ 1940 static int ael2020_intr_enable(struct cphy *phy) 1941 { 1942 struct reg_val regs[] = { 1943 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, 1944 0xffff, 0x4 }, 1945 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1946 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, 1947 1948 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1949 0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) }, 1950 1951 /* end */ 1952 { 0, 0, 0, 0 } 1953 }; 1954 int err; 1955 1956 err = set_phy_regs(phy, regs); 1957 if (err) 1958 return err; 1959 1960 /* enable standard Link Alarm Status Interrupts */ 1961 err = t3_phy_lasi_intr_enable(phy); 1962 if (err) 1963 return err; 1964 1965 return 0; 1966 } 1967 1968 /* 1969 * Disable PHY interrupts. The mirror of the above ... 1970 */ 1971 static int ael2020_intr_disable(struct cphy *phy) 1972 { 1973 struct reg_val regs[] = { 1974 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1975 0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) }, 1976 1977 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1978 0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) }, 1979 1980 /* end */ 1981 { 0, 0, 0, 0 } 1982 }; 1983 int err; 1984 1985 err = set_phy_regs(phy, regs); 1986 if (err) 1987 return err; 1988 1989 /* disable standard Link Alarm Status Interrupts */ 1990 return t3_phy_lasi_intr_disable(phy); 1991 } 1992 1993 /* 1994 * Clear PHY interrupt state. 1995 */ 1996 static int ael2020_intr_clear(struct cphy *phy) 1997 { 1998 unsigned int stat; 1999 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat); 2000 return err ? err : t3_phy_lasi_intr_clear(phy); 2001 } 2002 2003 /* 2004 * Common register settings for the AEL2020 when it comes out of reset. 2005 */ 2006 static struct reg_val ael2020_reset_regs[] = { 2007 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x3101 }, 2008 2009 { MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 }, 2010 2011 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0x0100 }, 2012 { MDIO_DEV_PMA_PMD, 0xca22, 0xffff, 0x0100 }, 2013 { MDIO_DEV_PMA_PMD, 0xca42, 0xffff, 0x0100 }, 2014 { MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 }, 2015 { MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 }, 2016 { MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 }, 2017 2018 { MDIO_DEV_PMA_PMD, 0xc20d, 0xffff, 0x0002 }, 2019 /* end */ 2020 { 0, 0, 0, 0 } 2021 }; 2022 2023 /* 2024 * Reset the PHY and put it into a canonical operating state. 2025 */ 2026 static int ael2020_reset(struct cphy *phy, int wait) 2027 { 2028 int err; 2029 unsigned int lasi_ctrl; 2030 2031 /* grab current interrupt state */ 2032 err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); 2033 if (err) 2034 return err; 2035 2036 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 125); 2037 if (err) 2038 return err; 2039 msleep(100); 2040 2041 /* basic initialization for all module types */ 2042 phy->priv = edc_none; 2043 err = set_phy_regs(phy, ael2020_reset_regs); 2044 if (err) 2045 return err; 2046 msleep(100); 2047 2048 /* determine module type and perform appropriate initialization */ 2049 err = ael2020_get_module_type(phy, 0); 2050 if (err < 0) 2051 return err; 2052 phy->modtype = (u8)err; 2053 if (err == phy_modtype_none) 2054 err = 0; 2055 else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) 2056 err = ael2020_setup_twinax_edc(phy, err); 2057 else 2058 err = ael2020_setup_sr_edc(phy); 2059 if (err) 2060 return err; 2061 2062 /* reset wipes out interrupts, reenable them if they were on */ 2063 if (lasi_ctrl & 1) 2064 err = ael2020_intr_enable(phy); 2065 return err; 2066 } 2067 2068 /* 2069 * Handle a PHY interrupt. 2070 */ 2071 static int ael2020_intr_handler(struct cphy *phy) 2072 { 2073 unsigned int stat; 2074 int ret, edc_needed, cause = 0; 2075 2076 ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat); 2077 if (ret) 2078 return ret; 2079 2080 if (stat & (0x1 << AEL2020_GPIO_MODDET)) { 2081 /* modules have max 300 ms init time after hot plug */ 2082 ret = ael2020_get_module_type(phy, 300); 2083 if (ret < 0) 2084 return ret; 2085 2086 phy->modtype = (u8)ret; 2087 if (ret == phy_modtype_none) 2088 edc_needed = phy->priv; /* on unplug retain EDC */ 2089 else if (ret == phy_modtype_twinax || 2090 ret == phy_modtype_twinax_long) 2091 edc_needed = edc_twinax; 2092 else 2093 edc_needed = edc_sr; 2094 2095 if (edc_needed != phy->priv) { 2096 ret = ael2020_reset(phy, 0); 2097 return ret ? ret : cphy_cause_module_change; 2098 } 2099 cause = cphy_cause_module_change; 2100 } 2101 2102 ret = t3_phy_lasi_intr_handler(phy); 2103 if (ret < 0) 2104 return ret; 2105 2106 ret |= cause; 2107 if (!ret) 2108 ret |= cphy_cause_link_change; 2109 return ret; 2110 } 2111 2112 static struct cphy_ops ael2020_ops = { 2113 #ifdef C99_NOT_SUPPORTED 2114 ael2020_reset, 2115 ael2020_intr_enable, 2116 ael2020_intr_disable, 2117 ael2020_intr_clear, 2118 ael2020_intr_handler, 2119 NULL, 2120 NULL, 2121 NULL, 2122 NULL, 2123 NULL, 2124 get_link_status_r, 2125 ael1002_power_down, 2126 #else 2127 .reset = ael2020_reset, 2128 .intr_enable = ael2020_intr_enable, 2129 .intr_disable = ael2020_intr_disable, 2130 .intr_clear = ael2020_intr_clear, 2131 .intr_handler = ael2020_intr_handler, 2132 .get_link_status = get_link_status_r, 2133 .power_down = ael1002_power_down, 2134 #endif 2135 }; 2136 2137 int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr, 2138 const struct mdio_ops *mdio_ops) 2139 { 2140 int err; 2141 struct cphy *phy = &pinfo->phy; 2142 2143 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2020_ops, mdio_ops, 2144 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | 2145 SUPPORTED_IRQ, "10GBASE-R"); 2146 msleep(125); 2147 2148 err = set_phy_regs(phy, ael2020_reset_regs); 2149 if (err) 2150 return err; 2151 msleep(100); 2152 2153 err = ael2020_get_module_type(phy, 0); 2154 if (err >= 0) 2155 phy->modtype = err; 2156 2157 ael_laser_down(phy, 0); 2158 return 0; 2159 } 2160 2161 /* 2162 * Get link status for a 10GBASE-X device. 2163 */ 2164 static int get_link_status_x(struct cphy *phy, int *link_state, int *speed, 2165 int *duplex, int *fc) 2166 { 2167 if (link_state) { 2168 unsigned int stat0, stat1, stat2; 2169 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); 2170 2171 if (!err) 2172 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); 2173 if (!err) 2174 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); 2175 if (err) 2176 return err; 2177 if ((stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1) 2178 *link_state = PHY_LINK_UP; 2179 else 2180 *link_state = PHY_LINK_DOWN; 2181 } 2182 if (speed) 2183 *speed = SPEED_10000; 2184 if (duplex) 2185 *duplex = DUPLEX_FULL; 2186 return 0; 2187 } 2188 2189 #ifdef C99_NOT_SUPPORTED 2190 static struct cphy_ops qt2045_ops = { 2191 ael1006_reset, 2192 t3_phy_lasi_intr_enable, 2193 t3_phy_lasi_intr_disable, 2194 t3_phy_lasi_intr_clear, 2195 t3_phy_lasi_intr_handler, 2196 NULL, 2197 NULL, 2198 NULL, 2199 NULL, 2200 NULL, 2201 get_link_status_x, 2202 ael1002_power_down, 2203 }; 2204 #else 2205 static struct cphy_ops qt2045_ops = { 2206 .reset = ael1006_reset, 2207 .intr_enable = t3_phy_lasi_intr_enable, 2208 .intr_disable = t3_phy_lasi_intr_disable, 2209 .intr_clear = t3_phy_lasi_intr_clear, 2210 .intr_handler = t3_phy_lasi_intr_handler, 2211 .get_link_status = get_link_status_x, 2212 .power_down = ael1002_power_down, 2213 }; 2214 #endif 2215 2216 int t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr, 2217 const struct mdio_ops *mdio_ops) 2218 { 2219 unsigned int stat; 2220 struct cphy *phy = &pinfo->phy; 2221 2222 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &qt2045_ops, mdio_ops, 2223 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, 2224 "10GBASE-CX4"); 2225 2226 /* 2227 * Some cards where the PHY is supposed to be at address 0 actually 2228 * have it at 1. 2229 */ 2230 if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && 2231 stat == 0xffff) 2232 phy->addr = 1; 2233 return 0; 2234 } 2235 2236 static int xaui_direct_reset(struct cphy *phy, int wait) 2237 { 2238 return 0; 2239 } 2240 2241 static int xaui_direct_get_link_status(struct cphy *phy, int *link_state, 2242 int *speed, int *duplex, int *fc) 2243 { 2244 if (link_state) { 2245 unsigned int status; 2246 adapter_t *adapter = phy->adapter; 2247 2248 status = t3_read_reg(adapter, 2249 XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | 2250 t3_read_reg(adapter, 2251 XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | 2252 t3_read_reg(adapter, 2253 XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | 2254 t3_read_reg(adapter, 2255 XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); 2256 *link_state = status & F_LOWSIG0 ? PHY_LINK_DOWN : PHY_LINK_UP; 2257 } 2258 if (speed) 2259 *speed = SPEED_10000; 2260 if (duplex) 2261 *duplex = DUPLEX_FULL; 2262 return 0; 2263 } 2264 2265 static int xaui_direct_power_down(struct cphy *phy, int enable) 2266 { 2267 return 0; 2268 } 2269 2270 #ifdef C99_NOT_SUPPORTED 2271 static struct cphy_ops xaui_direct_ops = { 2272 xaui_direct_reset, 2273 ael1002_intr_noop, 2274 ael1002_intr_noop, 2275 ael1002_intr_noop, 2276 ael1002_intr_noop, 2277 NULL, 2278 NULL, 2279 NULL, 2280 NULL, 2281 NULL, 2282 xaui_direct_get_link_status, 2283 xaui_direct_power_down, 2284 }; 2285 #else 2286 static struct cphy_ops xaui_direct_ops = { 2287 .reset = xaui_direct_reset, 2288 .intr_enable = ael1002_intr_noop, 2289 .intr_disable = ael1002_intr_noop, 2290 .intr_clear = ael1002_intr_noop, 2291 .intr_handler = ael1002_intr_noop, 2292 .get_link_status = xaui_direct_get_link_status, 2293 .power_down = xaui_direct_power_down, 2294 }; 2295 #endif 2296 2297 int t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr, 2298 const struct mdio_ops *mdio_ops) 2299 { 2300 cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &xaui_direct_ops, mdio_ops, 2301 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, 2302 "10GBASE-CX4"); 2303 return 0; 2304 } 2305