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