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