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