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 ret |= cphy_cause_link_change; 1350 return ret; 1351 } 1352 1353 static struct cphy_ops ael2005_ops = { 1354 #ifdef C99_NOT_SUPPORTED 1355 ael2005_reset, 1356 ael2005_intr_enable, 1357 ael2005_intr_disable, 1358 ael2005_intr_clear, 1359 ael2005_intr_handler, 1360 NULL, 1361 NULL, 1362 NULL, 1363 NULL, 1364 NULL, 1365 get_link_status_r, 1366 ael1002_power_down, 1367 #else 1368 .reset = ael2005_reset, 1369 .intr_enable = ael2005_intr_enable, 1370 .intr_disable = ael2005_intr_disable, 1371 .intr_clear = ael2005_intr_clear, 1372 .intr_handler = ael2005_intr_handler, 1373 .get_link_status = get_link_status_r, 1374 .power_down = ael1002_power_down, 1375 #endif 1376 }; 1377 1378 int t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr, 1379 const struct mdio_ops *mdio_ops) 1380 { 1381 int err; 1382 struct cphy *phy = &pinfo->phy; 1383 1384 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2005_ops, mdio_ops, 1385 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | 1386 SUPPORTED_IRQ, "10GBASE-R"); 1387 msleep(125); 1388 ael_laser_down(phy, 0); 1389 1390 err = ael2005_get_module_type(phy, 0); 1391 if (err >= 0) 1392 phy->modtype = err; 1393 1394 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, 1395 1 << 5); 1396 } 1397 1398 /* 1399 * Setup EDC and other parameters for operation with an optical module. 1400 */ 1401 static int ael2020_setup_sr_edc(struct cphy *phy) 1402 { 1403 static struct reg_val regs[] = { 1404 { MDIO_DEV_PMA_PMD, 0xcc01, 0xffff, 0x488a }, 1405 1406 { MDIO_DEV_PMA_PMD, 0xcb1b, 0xffff, 0x0200 }, 1407 { MDIO_DEV_PMA_PMD, 0xcb1c, 0xffff, 0x00f0 }, 1408 { MDIO_DEV_PMA_PMD, 0xcc06, 0xffff, 0x00e0 }, 1409 1410 /* end */ 1411 { 0, 0, 0, 0 } 1412 }; 1413 int err; 1414 1415 err = set_phy_regs(phy, regs); 1416 msleep(50); 1417 if (err) 1418 return err; 1419 1420 phy->priv = edc_sr; 1421 return 0; 1422 } 1423 1424 /* 1425 * Setup EDC and other parameters for operation with an TWINAX module. 1426 */ 1427 static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) 1428 { 1429 static struct reg_val uCclock40MHz[] = { 1430 { MDIO_DEV_PMA_PMD, 0xff28, 0xffff, 0x4001 }, 1431 { MDIO_DEV_PMA_PMD, 0xff2a, 0xffff, 0x0002 }, 1432 { 0, 0, 0, 0 } 1433 }; 1434 1435 static struct reg_val uCclockActivate[] = { 1436 { MDIO_DEV_PMA_PMD, 0xd000, 0xffff, 0x5200 }, 1437 { 0, 0, 0, 0 } 1438 }; 1439 1440 static struct reg_val uCactivate[] = { 1441 { MDIO_DEV_PMA_PMD, 0xd080, 0xffff, 0x0100 }, 1442 { MDIO_DEV_PMA_PMD, 0xd092, 0xffff, 0x0000 }, 1443 { 0, 0, 0, 0 } 1444 }; 1445 1446 static u16 twinax_edc[] = { 1447 0xd800, 0x4009, 1448 0xd801, 0x2fff, 1449 0xd802, 0x300f, 1450 0xd803, 0x40aa, 1451 0xd804, 0x401c, 1452 0xd805, 0x401e, 1453 0xd806, 0x20c5, 1454 0xd807, 0x3c05, 1455 0xd808, 0x6536, 1456 0xd809, 0x2fe4, 1457 0xd80a, 0x3dc4, 1458 0xd80b, 0x6624, 1459 0xd80c, 0x2ff4, 1460 0xd80d, 0x3dc4, 1461 0xd80e, 0x2035, 1462 0xd80f, 0x30a5, 1463 0xd810, 0x6524, 1464 0xd811, 0x2ca2, 1465 0xd812, 0x3012, 1466 0xd813, 0x1002, 1467 0xd814, 0x27e2, 1468 0xd815, 0x3022, 1469 0xd816, 0x1002, 1470 0xd817, 0x28d2, 1471 0xd818, 0x3022, 1472 0xd819, 0x1002, 1473 0xd81a, 0x2892, 1474 0xd81b, 0x3012, 1475 0xd81c, 0x1002, 1476 0xd81d, 0x24e2, 1477 0xd81e, 0x3022, 1478 0xd81f, 0x1002, 1479 0xd820, 0x27e2, 1480 0xd821, 0x3012, 1481 0xd822, 0x1002, 1482 0xd823, 0x2422, 1483 0xd824, 0x3022, 1484 0xd825, 0x1002, 1485 0xd826, 0x22cd, 1486 0xd827, 0x301d, 1487 0xd828, 0x28f2, 1488 0xd829, 0x3022, 1489 0xd82a, 0x1002, 1490 0xd82b, 0x5553, 1491 0xd82c, 0x0307, 1492 0xd82d, 0x2572, 1493 0xd82e, 0x3022, 1494 0xd82f, 0x1002, 1495 0xd830, 0x21a2, 1496 0xd831, 0x3012, 1497 0xd832, 0x1002, 1498 0xd833, 0x4016, 1499 0xd834, 0x5e63, 1500 0xd835, 0x0344, 1501 0xd836, 0x21a2, 1502 0xd837, 0x3012, 1503 0xd838, 0x1002, 1504 0xd839, 0x400e, 1505 0xd83a, 0x2572, 1506 0xd83b, 0x3022, 1507 0xd83c, 0x1002, 1508 0xd83d, 0x2b22, 1509 0xd83e, 0x3012, 1510 0xd83f, 0x1002, 1511 0xd840, 0x2842, 1512 0xd841, 0x3022, 1513 0xd842, 0x1002, 1514 0xd843, 0x26e2, 1515 0xd844, 0x3022, 1516 0xd845, 0x1002, 1517 0xd846, 0x2fa4, 1518 0xd847, 0x3dc4, 1519 0xd848, 0x6624, 1520 0xd849, 0x2e8b, 1521 0xd84a, 0x303b, 1522 0xd84b, 0x56b3, 1523 0xd84c, 0x03c6, 1524 0xd84d, 0x866b, 1525 0xd84e, 0x400c, 1526 0xd84f, 0x2782, 1527 0xd850, 0x3012, 1528 0xd851, 0x1002, 1529 0xd852, 0x2c4b, 1530 0xd853, 0x309b, 1531 0xd854, 0x56b3, 1532 0xd855, 0x03c3, 1533 0xd856, 0x866b, 1534 0xd857, 0x400c, 1535 0xd858, 0x22a2, 1536 0xd859, 0x3022, 1537 0xd85a, 0x1002, 1538 0xd85b, 0x2842, 1539 0xd85c, 0x3022, 1540 0xd85d, 0x1002, 1541 0xd85e, 0x26e2, 1542 0xd85f, 0x3022, 1543 0xd860, 0x1002, 1544 0xd861, 0x2fb4, 1545 0xd862, 0x3dc4, 1546 0xd863, 0x6624, 1547 0xd864, 0x56b3, 1548 0xd865, 0x03c3, 1549 0xd866, 0x866b, 1550 0xd867, 0x401c, 1551 0xd868, 0x2c45, 1552 0xd869, 0x3095, 1553 0xd86a, 0x5b53, 1554 0xd86b, 0x23d2, 1555 0xd86c, 0x3012, 1556 0xd86d, 0x13c2, 1557 0xd86e, 0x5cc3, 1558 0xd86f, 0x2782, 1559 0xd870, 0x3012, 1560 0xd871, 0x1312, 1561 0xd872, 0x2b22, 1562 0xd873, 0x3012, 1563 0xd874, 0x1002, 1564 0xd875, 0x2842, 1565 0xd876, 0x3022, 1566 0xd877, 0x1002, 1567 0xd878, 0x2622, 1568 0xd879, 0x3022, 1569 0xd87a, 0x1002, 1570 0xd87b, 0x21a2, 1571 0xd87c, 0x3012, 1572 0xd87d, 0x1002, 1573 0xd87e, 0x628f, 1574 0xd87f, 0x2985, 1575 0xd880, 0x33a5, 1576 0xd881, 0x26e2, 1577 0xd882, 0x3022, 1578 0xd883, 0x1002, 1579 0xd884, 0x5653, 1580 0xd885, 0x03d2, 1581 0xd886, 0x401e, 1582 0xd887, 0x6f72, 1583 0xd888, 0x1002, 1584 0xd889, 0x628f, 1585 0xd88a, 0x2304, 1586 0xd88b, 0x3c84, 1587 0xd88c, 0x6436, 1588 0xd88d, 0xdff4, 1589 0xd88e, 0x6436, 1590 0xd88f, 0x2ff5, 1591 0xd890, 0x3005, 1592 0xd891, 0x8656, 1593 0xd892, 0xdfba, 1594 0xd893, 0x56a3, 1595 0xd894, 0xd05a, 1596 0xd895, 0x29e2, 1597 0xd896, 0x3012, 1598 0xd897, 0x1392, 1599 0xd898, 0xd05a, 1600 0xd899, 0x56a3, 1601 0xd89a, 0xdfba, 1602 0xd89b, 0x0383, 1603 0xd89c, 0x6f72, 1604 0xd89d, 0x1002, 1605 0xd89e, 0x2a64, 1606 0xd89f, 0x3014, 1607 0xd8a0, 0x2005, 1608 0xd8a1, 0x3d75, 1609 0xd8a2, 0xc451, 1610 0xd8a3, 0x29a2, 1611 0xd8a4, 0x3022, 1612 0xd8a5, 0x1002, 1613 0xd8a6, 0x178c, 1614 0xd8a7, 0x1898, 1615 0xd8a8, 0x19a4, 1616 0xd8a9, 0x1ab0, 1617 0xd8aa, 0x1bbc, 1618 0xd8ab, 0x1cc8, 1619 0xd8ac, 0x1dd3, 1620 0xd8ad, 0x1ede, 1621 0xd8ae, 0x1fe9, 1622 0xd8af, 0x20f4, 1623 0xd8b0, 0x21ff, 1624 0xd8b1, 0x0000, 1625 0xd8b2, 0x2741, 1626 0xd8b3, 0x3021, 1627 0xd8b4, 0x1001, 1628 0xd8b5, 0xc620, 1629 0xd8b6, 0x0000, 1630 0xd8b7, 0xc621, 1631 0xd8b8, 0x0000, 1632 0xd8b9, 0xc622, 1633 0xd8ba, 0x00e2, 1634 0xd8bb, 0xc623, 1635 0xd8bc, 0x007f, 1636 0xd8bd, 0xc624, 1637 0xd8be, 0x00ce, 1638 0xd8bf, 0xc625, 1639 0xd8c0, 0x0000, 1640 0xd8c1, 0xc627, 1641 0xd8c2, 0x0000, 1642 0xd8c3, 0xc628, 1643 0xd8c4, 0x0000, 1644 0xd8c5, 0xc90a, 1645 0xd8c6, 0x3a7c, 1646 0xd8c7, 0xc62c, 1647 0xd8c8, 0x0000, 1648 0xd8c9, 0x0000, 1649 0xd8ca, 0x2741, 1650 0xd8cb, 0x3021, 1651 0xd8cc, 0x1001, 1652 0xd8cd, 0xc502, 1653 0xd8ce, 0x53ac, 1654 0xd8cf, 0xc503, 1655 0xd8d0, 0x2cd3, 1656 0xd8d1, 0xc600, 1657 0xd8d2, 0x2a6e, 1658 0xd8d3, 0xc601, 1659 0xd8d4, 0x2a2c, 1660 0xd8d5, 0xc605, 1661 0xd8d6, 0x5557, 1662 0xd8d7, 0xc60c, 1663 0xd8d8, 0x5400, 1664 0xd8d9, 0xc710, 1665 0xd8da, 0x0700, 1666 0xd8db, 0xc711, 1667 0xd8dc, 0x0f06, 1668 0xd8dd, 0xc718, 1669 0xd8de, 0x700, 1670 0xd8df, 0xc719, 1671 0xd8e0, 0x0f06, 1672 0xd8e1, 0xc720, 1673 0xd8e2, 0x4700, 1674 0xd8e3, 0xc721, 1675 0xd8e4, 0x0f06, 1676 0xd8e5, 0xc728, 1677 0xd8e6, 0x0700, 1678 0xd8e7, 0xc729, 1679 0xd8e8, 0x1207, 1680 0xd8e9, 0xc801, 1681 0xd8ea, 0x7f50, 1682 0xd8eb, 0xc802, 1683 0xd8ec, 0x7760, 1684 0xd8ed, 0xc803, 1685 0xd8ee, 0x7fce, 1686 0xd8ef, 0xc804, 1687 0xd8f0, 0x520e, 1688 0xd8f1, 0xc805, 1689 0xd8f2, 0x5c11, 1690 0xd8f3, 0xc806, 1691 0xd8f4, 0x3c51, 1692 0xd8f5, 0xc807, 1693 0xd8f6, 0x4061, 1694 0xd8f7, 0xc808, 1695 0xd8f8, 0x49c1, 1696 0xd8f9, 0xc809, 1697 0xd8fa, 0x3840, 1698 0xd8fb, 0xc80a, 1699 0xd8fc, 0x0000, 1700 0xd8fd, 0xc821, 1701 0xd8fe, 0x0002, 1702 0xd8ff, 0xc822, 1703 0xd900, 0x0046, 1704 0xd901, 0xc844, 1705 0xd902, 0x182f, 1706 0xd903, 0xc849, 1707 0xd904, 0x0400, 1708 0xd905, 0xc84a, 1709 0xd906, 0x0002, 1710 0xd907, 0xc013, 1711 0xd908, 0xf341, 1712 0xd909, 0xc084, 1713 0xd90a, 0x0030, 1714 0xd90b, 0xc904, 1715 0xd90c, 0x1401, 1716 0xd90d, 0xcb0c, 1717 0xd90e, 0x0004, 1718 0xd90f, 0xcb0e, 1719 0xd910, 0xa00a, 1720 0xd911, 0xcb0f, 1721 0xd912, 0xc0c0, 1722 0xd913, 0xcb10, 1723 0xd914, 0xc0c0, 1724 0xd915, 0xcb11, 1725 0xd916, 0x00a0, 1726 0xd917, 0xcb12, 1727 0xd918, 0x0007, 1728 0xd919, 0xc241, 1729 0xd91a, 0xa000, 1730 0xd91b, 0xc243, 1731 0xd91c, 0x7fe0, 1732 0xd91d, 0xc604, 1733 0xd91e, 0x000e, 1734 0xd91f, 0xc609, 1735 0xd920, 0x00f5, 1736 0xd921, 0xc611, 1737 0xd922, 0x000e, 1738 0xd923, 0xc660, 1739 0xd924, 0x9600, 1740 0xd925, 0xc687, 1741 0xd926, 0x0004, 1742 0xd927, 0xc60a, 1743 0xd928, 0x04f5, 1744 0xd929, 0x0000, 1745 0xd92a, 0x2741, 1746 0xd92b, 0x3021, 1747 0xd92c, 0x1001, 1748 0xd92d, 0xc620, 1749 0xd92e, 0x14e5, 1750 0xd92f, 0xc621, 1751 0xd930, 0xc53d, 1752 0xd931, 0xc622, 1753 0xd932, 0x3cbe, 1754 0xd933, 0xc623, 1755 0xd934, 0x4452, 1756 0xd935, 0xc624, 1757 0xd936, 0xc5c5, 1758 0xd937, 0xc625, 1759 0xd938, 0xe01e, 1760 0xd939, 0xc627, 1761 0xd93a, 0x0000, 1762 0xd93b, 0xc628, 1763 0xd93c, 0x0000, 1764 0xd93d, 0xc62c, 1765 0xd93e, 0x0000, 1766 0xd93f, 0xc90a, 1767 0xd940, 0x3a7c, 1768 0xd941, 0x0000, 1769 0xd942, 0x2b84, 1770 0xd943, 0x3c74, 1771 0xd944, 0x6435, 1772 0xd945, 0xdff4, 1773 0xd946, 0x6435, 1774 0xd947, 0x2806, 1775 0xd948, 0x3006, 1776 0xd949, 0x8565, 1777 0xd94a, 0x2b24, 1778 0xd94b, 0x3c24, 1779 0xd94c, 0x6436, 1780 0xd94d, 0x1002, 1781 0xd94e, 0x2b24, 1782 0xd94f, 0x3c24, 1783 0xd950, 0x6436, 1784 0xd951, 0x4045, 1785 0xd952, 0x8656, 1786 0xd953, 0x5663, 1787 0xd954, 0x0302, 1788 0xd955, 0x401e, 1789 0xd956, 0x1002, 1790 0xd957, 0x2807, 1791 0xd958, 0x31a7, 1792 0xd959, 0x20c4, 1793 0xd95a, 0x3c24, 1794 0xd95b, 0x6724, 1795 0xd95c, 0x2ff7, 1796 0xd95d, 0x30f7, 1797 0xd95e, 0x20c4, 1798 0xd95f, 0x3c04, 1799 0xd960, 0x6724, 1800 0xd961, 0x1002, 1801 0xd962, 0x2807, 1802 0xd963, 0x3187, 1803 0xd964, 0x20c4, 1804 0xd965, 0x3c24, 1805 0xd966, 0x6724, 1806 0xd967, 0x2fe4, 1807 0xd968, 0x3dc4, 1808 0xd969, 0x6437, 1809 0xd96a, 0x20c4, 1810 0xd96b, 0x3c04, 1811 0xd96c, 0x6724, 1812 0xd96d, 0x1002, 1813 0xd96e, 0x24f4, 1814 0xd96f, 0x3c64, 1815 0xd970, 0x6436, 1816 0xd971, 0xdff4, 1817 0xd972, 0x6436, 1818 0xd973, 0x1002, 1819 0xd974, 0x2006, 1820 0xd975, 0x3d76, 1821 0xd976, 0xc161, 1822 0xd977, 0x6134, 1823 0xd978, 0x6135, 1824 0xd979, 0x5443, 1825 0xd97a, 0x0303, 1826 0xd97b, 0x6524, 1827 0xd97c, 0x00fb, 1828 0xd97d, 0x1002, 1829 0xd97e, 0x20d4, 1830 0xd97f, 0x3c24, 1831 0xd980, 0x2025, 1832 0xd981, 0x3005, 1833 0xd982, 0x6524, 1834 0xd983, 0x1002, 1835 0xd984, 0xd019, 1836 0xd985, 0x2104, 1837 0xd986, 0x3c24, 1838 0xd987, 0x2105, 1839 0xd988, 0x3805, 1840 0xd989, 0x6524, 1841 0xd98a, 0xdff4, 1842 0xd98b, 0x4005, 1843 0xd98c, 0x6524, 1844 0xd98d, 0x2e8d, 1845 0xd98e, 0x303d, 1846 0xd98f, 0x2408, 1847 0xd990, 0x35d8, 1848 0xd991, 0x5dd3, 1849 0xd992, 0x0307, 1850 0xd993, 0x8887, 1851 0xd994, 0x63a7, 1852 0xd995, 0x8887, 1853 0xd996, 0x63a7, 1854 0xd997, 0xdffd, 1855 0xd998, 0x00f9, 1856 0xd999, 0x1002, 1857 0xd99a, 0x866a, 1858 0xd99b, 0x6138, 1859 0xd99c, 0x5883, 1860 0xd99d, 0x2aa2, 1861 0xd99e, 0x3022, 1862 0xd99f, 0x1302, 1863 0xd9a0, 0x2ff7, 1864 0xd9a1, 0x3007, 1865 0xd9a2, 0x8785, 1866 0xd9a3, 0xb887, 1867 0xd9a4, 0x8786, 1868 0xd9a5, 0xb8c6, 1869 0xd9a6, 0x5a53, 1870 0xd9a7, 0x29b2, 1871 0xd9a8, 0x3022, 1872 0xd9a9, 0x13c2, 1873 0xd9aa, 0x2474, 1874 0xd9ab, 0x3c84, 1875 0xd9ac, 0x64d7, 1876 0xd9ad, 0x64d7, 1877 0xd9ae, 0x2ff5, 1878 0xd9af, 0x3c05, 1879 0xd9b0, 0x8757, 1880 0xd9b1, 0xb886, 1881 0xd9b2, 0x9767, 1882 0xd9b3, 0x67c4, 1883 0xd9b4, 0x6f72, 1884 0xd9b5, 0x1002, 1885 0xd9b6, 0x0000, 1886 }; 1887 int i, err; 1888 1889 /* set uC clock and activate it */ 1890 err = set_phy_regs(phy, uCclock40MHz); 1891 msleep(500); 1892 if (err) 1893 return err; 1894 err = set_phy_regs(phy, uCclockActivate); 1895 msleep(500); 1896 if (err) 1897 return err; 1898 1899 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) 1900 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], 1901 twinax_edc[i + 1]); 1902 /* activate uC */ 1903 err = set_phy_regs(phy, uCactivate); 1904 if (!err) 1905 phy->priv = edc_twinax; 1906 return err; 1907 } 1908 1909 /* 1910 * Return Module Type. 1911 */ 1912 static int ael2020_get_module_type(struct cphy *phy, int delay_ms) 1913 { 1914 int v; 1915 unsigned int stat; 1916 1917 v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_STAT, &stat); 1918 if (v) 1919 return v; 1920 1921 if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) { 1922 /* module absent */ 1923 return phy_modtype_none; 1924 } 1925 1926 return ael2xxx_get_module_type(phy, delay_ms); 1927 } 1928 1929 /* 1930 * Enable PHY interrupts. We enable "Module Detection" interrupts (on any 1931 * state transition) and then generic Link Alarm Status Interrupt (LASI). 1932 */ 1933 static int ael2020_intr_enable(struct cphy *phy) 1934 { 1935 struct reg_val regs[] = { 1936 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, 1937 0xffff, 0x4 }, 1938 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1939 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, 1940 1941 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1942 0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) }, 1943 1944 /* end */ 1945 { 0, 0, 0, 0 } 1946 }; 1947 int err; 1948 1949 err = set_phy_regs(phy, regs); 1950 if (err) 1951 return err; 1952 1953 /* enable standard Link Alarm Status Interrupts */ 1954 err = t3_phy_lasi_intr_enable(phy); 1955 if (err) 1956 return err; 1957 1958 return 0; 1959 } 1960 1961 /* 1962 * Disable PHY interrupts. The mirror of the above ... 1963 */ 1964 static int ael2020_intr_disable(struct cphy *phy) 1965 { 1966 struct reg_val regs[] = { 1967 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1968 0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) }, 1969 1970 { MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL, 1971 0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) }, 1972 1973 /* end */ 1974 { 0, 0, 0, 0 } 1975 }; 1976 int err; 1977 1978 err = set_phy_regs(phy, regs); 1979 if (err) 1980 return err; 1981 1982 /* disable standard Link Alarm Status Interrupts */ 1983 return t3_phy_lasi_intr_disable(phy); 1984 } 1985 1986 /* 1987 * Clear PHY interrupt state. 1988 */ 1989 static int ael2020_intr_clear(struct cphy *phy) 1990 { 1991 unsigned int stat; 1992 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat); 1993 return err ? err : t3_phy_lasi_intr_clear(phy); 1994 } 1995 1996 /* 1997 * Common register settings for the AEL2020 when it comes out of reset. 1998 */ 1999 static struct reg_val ael2020_reset_regs[] = { 2000 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x3101 }, 2001 2002 { MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 }, 2003 2004 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0x0100 }, 2005 { MDIO_DEV_PMA_PMD, 0xca22, 0xffff, 0x0100 }, 2006 { MDIO_DEV_PMA_PMD, 0xca42, 0xffff, 0x0100 }, 2007 { MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 }, 2008 { MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 }, 2009 { MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 }, 2010 2011 { MDIO_DEV_PMA_PMD, 0xc20d, 0xffff, 0x0002 }, 2012 /* end */ 2013 { 0, 0, 0, 0 } 2014 }; 2015 2016 /* 2017 * Reset the PHY and put it into a canonical operating state. 2018 */ 2019 static int ael2020_reset(struct cphy *phy, int wait) 2020 { 2021 int err; 2022 unsigned int lasi_ctrl; 2023 2024 /* grab current interrupt state */ 2025 err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); 2026 if (err) 2027 return err; 2028 2029 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 125); 2030 if (err) 2031 return err; 2032 msleep(100); 2033 2034 /* basic initialization for all module types */ 2035 phy->priv = edc_none; 2036 err = set_phy_regs(phy, ael2020_reset_regs); 2037 if (err) 2038 return err; 2039 msleep(100); 2040 2041 /* determine module type and perform appropriate initialization */ 2042 err = ael2020_get_module_type(phy, 0); 2043 if (err < 0) 2044 return err; 2045 phy->modtype = (u8)err; 2046 if (err == phy_modtype_none) 2047 err = 0; 2048 else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) 2049 err = ael2020_setup_twinax_edc(phy, err); 2050 else 2051 err = ael2020_setup_sr_edc(phy); 2052 if (err) 2053 return err; 2054 2055 /* reset wipes out interrupts, reenable them if they were on */ 2056 if (lasi_ctrl & 1) 2057 err = ael2020_intr_enable(phy); 2058 return err; 2059 } 2060 2061 /* 2062 * Handle a PHY interrupt. 2063 */ 2064 static int ael2020_intr_handler(struct cphy *phy) 2065 { 2066 unsigned int stat; 2067 int ret, edc_needed, cause = 0; 2068 2069 ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat); 2070 if (ret) 2071 return ret; 2072 2073 if (stat & (0x1 << AEL2020_GPIO_MODDET)) { 2074 /* modules have max 300 ms init time after hot plug */ 2075 ret = ael2020_get_module_type(phy, 300); 2076 if (ret < 0) 2077 return ret; 2078 2079 phy->modtype = (u8)ret; 2080 if (ret == phy_modtype_none) 2081 edc_needed = phy->priv; /* on unplug retain EDC */ 2082 else if (ret == phy_modtype_twinax || 2083 ret == phy_modtype_twinax_long) 2084 edc_needed = edc_twinax; 2085 else 2086 edc_needed = edc_sr; 2087 2088 if (edc_needed != phy->priv) { 2089 ret = ael2020_reset(phy, 0); 2090 return ret ? ret : cphy_cause_module_change; 2091 } 2092 cause = cphy_cause_module_change; 2093 } 2094 2095 ret = t3_phy_lasi_intr_handler(phy); 2096 if (ret < 0) 2097 return ret; 2098 2099 ret |= cause; 2100 if (!ret) 2101 ret |= cphy_cause_link_change; 2102 return ret; 2103 } 2104 2105 static struct cphy_ops ael2020_ops = { 2106 #ifdef C99_NOT_SUPPORTED 2107 ael2020_reset, 2108 ael2020_intr_enable, 2109 ael2020_intr_disable, 2110 ael2020_intr_clear, 2111 ael2020_intr_handler, 2112 NULL, 2113 NULL, 2114 NULL, 2115 NULL, 2116 NULL, 2117 get_link_status_r, 2118 ael1002_power_down, 2119 #else 2120 .reset = ael2020_reset, 2121 .intr_enable = ael2020_intr_enable, 2122 .intr_disable = ael2020_intr_disable, 2123 .intr_clear = ael2020_intr_clear, 2124 .intr_handler = ael2020_intr_handler, 2125 .get_link_status = get_link_status_r, 2126 .power_down = ael1002_power_down, 2127 #endif 2128 }; 2129 2130 int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr, 2131 const struct mdio_ops *mdio_ops) 2132 { 2133 int err; 2134 struct cphy *phy = &pinfo->phy; 2135 2136 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2020_ops, mdio_ops, 2137 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | 2138 SUPPORTED_IRQ, "10GBASE-R"); 2139 msleep(125); 2140 2141 err = set_phy_regs(phy, ael2020_reset_regs); 2142 if (err) 2143 return err; 2144 msleep(100); 2145 2146 err = ael2020_get_module_type(phy, 0); 2147 if (err >= 0) 2148 phy->modtype = err; 2149 2150 ael_laser_down(phy, 0); 2151 return 0; 2152 } 2153 2154 /* 2155 * Get link status for a 10GBASE-X device. 2156 */ 2157 static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, 2158 int *duplex, int *fc) 2159 { 2160 if (link_ok) { 2161 unsigned int stat0, stat1, stat2; 2162 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); 2163 2164 if (!err) 2165 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); 2166 if (!err) 2167 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); 2168 if (err) 2169 return err; 2170 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; 2171 } 2172 if (speed) 2173 *speed = SPEED_10000; 2174 if (duplex) 2175 *duplex = DUPLEX_FULL; 2176 return 0; 2177 } 2178 2179 #ifdef C99_NOT_SUPPORTED 2180 static struct cphy_ops qt2045_ops = { 2181 ael1006_reset, 2182 t3_phy_lasi_intr_enable, 2183 t3_phy_lasi_intr_disable, 2184 t3_phy_lasi_intr_clear, 2185 t3_phy_lasi_intr_handler, 2186 NULL, 2187 NULL, 2188 NULL, 2189 NULL, 2190 NULL, 2191 get_link_status_x, 2192 ael1002_power_down, 2193 }; 2194 #else 2195 static struct cphy_ops qt2045_ops = { 2196 .reset = ael1006_reset, 2197 .intr_enable = t3_phy_lasi_intr_enable, 2198 .intr_disable = t3_phy_lasi_intr_disable, 2199 .intr_clear = t3_phy_lasi_intr_clear, 2200 .intr_handler = t3_phy_lasi_intr_handler, 2201 .get_link_status = get_link_status_x, 2202 .power_down = ael1002_power_down, 2203 }; 2204 #endif 2205 2206 int t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr, 2207 const struct mdio_ops *mdio_ops) 2208 { 2209 unsigned int stat; 2210 struct cphy *phy = &pinfo->phy; 2211 2212 cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &qt2045_ops, mdio_ops, 2213 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, 2214 "10GBASE-CX4"); 2215 2216 /* 2217 * Some cards where the PHY is supposed to be at address 0 actually 2218 * have it at 1. 2219 */ 2220 if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && 2221 stat == 0xffff) 2222 phy->addr = 1; 2223 return 0; 2224 } 2225 2226 static int xaui_direct_reset(struct cphy *phy, int wait) 2227 { 2228 return 0; 2229 } 2230 2231 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, 2232 int *speed, int *duplex, int *fc) 2233 { 2234 if (link_ok) { 2235 unsigned int status; 2236 adapter_t *adapter = phy->adapter; 2237 2238 status = t3_read_reg(adapter, 2239 XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | 2240 t3_read_reg(adapter, 2241 XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | 2242 t3_read_reg(adapter, 2243 XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | 2244 t3_read_reg(adapter, 2245 XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); 2246 *link_ok = !(status & F_LOWSIG0); 2247 } 2248 if (speed) 2249 *speed = SPEED_10000; 2250 if (duplex) 2251 *duplex = DUPLEX_FULL; 2252 return 0; 2253 } 2254 2255 static int xaui_direct_power_down(struct cphy *phy, int enable) 2256 { 2257 return 0; 2258 } 2259 2260 #ifdef C99_NOT_SUPPORTED 2261 static struct cphy_ops xaui_direct_ops = { 2262 xaui_direct_reset, 2263 ael1002_intr_noop, 2264 ael1002_intr_noop, 2265 ael1002_intr_noop, 2266 ael1002_intr_noop, 2267 NULL, 2268 NULL, 2269 NULL, 2270 NULL, 2271 NULL, 2272 xaui_direct_get_link_status, 2273 xaui_direct_power_down, 2274 }; 2275 #else 2276 static struct cphy_ops xaui_direct_ops = { 2277 .reset = xaui_direct_reset, 2278 .intr_enable = ael1002_intr_noop, 2279 .intr_disable = ael1002_intr_noop, 2280 .intr_clear = ael1002_intr_noop, 2281 .intr_handler = ael1002_intr_noop, 2282 .get_link_status = xaui_direct_get_link_status, 2283 .power_down = xaui_direct_power_down, 2284 }; 2285 #endif 2286 2287 int t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr, 2288 const struct mdio_ops *mdio_ops) 2289 { 2290 cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &xaui_direct_ops, mdio_ops, 2291 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, 2292 "10GBASE-CX4"); 2293 return 0; 2294 } 2295