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