cxgb_ael1002.c revision 189643
1/************************************************************************** 2 3Copyright (c) 2007-2009, Chelsio Inc. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, 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 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26POSSIBILITY OF SUCH DAMAGE. 27 28***************************************************************************/ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: head/sys/dev/cxgb/common/cxgb_ael1002.c 189643 2009-03-10 19:22:45Z gnn $"); 32 33#include <cxgb_include.h> 34 35#undef msleep 36#define msleep t3_os_sleep 37 38enum { 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 45enum { 46 AEL100X_TX_DISABLE = 9, 47 AEL100X_TX_CONFIG1 = 0xc002, 48 AEL1002_PWR_DOWN_HI = 0xc011, 49 AEL1002_PWR_DOWN_LO = 0xc012, 50 AEL1002_XFI_EQL = 0xc015, 51 AEL1002_LB_EN = 0xc017, 52 AEL_OPT_SETTINGS = 0xc017, 53 AEL_I2C_CTRL = 0xc30a, 54 AEL_I2C_DATA = 0xc30b, 55 AEL_I2C_STAT = 0xc30c, 56 AEL2005_GPIO_CTRL = 0xc214, 57 AEL2005_GPIO_STAT = 0xc215, 58}; 59 60enum { edc_none, edc_sr, edc_twinax }; 61 62/* PHY module I2C device address */ 63enum { 64 MODULE_DEV_ADDR = 0xa0, 65 SFF_DEV_ADDR = 0xa2, 66}; 67 68/* PHY transceiver type */ 69enum { 70 phy_transtype_unknown = 0, 71 phy_transtype_sfp = 3, 72 phy_transtype_xfp = 6, 73}; 74 75#define AEL2005_MODDET_IRQ 4 76 77struct reg_val { 78 unsigned short mmd_addr; 79 unsigned short reg_addr; 80 unsigned short clear_bits; 81 unsigned short set_bits; 82}; 83 84static int get_module_type(struct cphy *phy); 85 86static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) 87{ 88 int err; 89 90 for (err = 0; rv->mmd_addr && !err; rv++) { 91 if (rv->clear_bits == 0xffff) 92 err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, 93 rv->set_bits); 94 else 95 err = t3_mdio_change_bits(phy, rv->mmd_addr, 96 rv->reg_addr, rv->clear_bits, 97 rv->set_bits); 98 } 99 return err; 100} 101 102static void ael100x_txon(struct cphy *phy) 103{ 104 int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; 105 106 msleep(100); 107 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); 108 msleep(30); 109} 110 111static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) 112{ 113 int i, err; 114 unsigned int stat, data; 115 116 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, 117 (dev_addr << 8) | (1 << 8) | word_addr); 118 if (err) 119 return err; 120 121 for (i = 0; i < 200; i++) { 122 msleep(1); 123 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); 124 if (err) 125 return err; 126 if ((stat & 3) == 1) { 127 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, 128 &data); 129 if (err) 130 return err; 131 return data >> 8; 132 } 133 } 134 CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", 135 phy->addr, word_addr); 136 return -ETIMEDOUT; 137} 138 139static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data) 140{ 141 int i, err; 142 unsigned int stat; 143 144 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, data); 145 if (err) 146 return err; 147 148 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, 149 (dev_addr << 8) | word_addr); 150 if (err) 151 return err; 152 153 for (i = 0; i < 200; i++) { 154 msleep(1); 155 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); 156 if (err) 157 return err; 158 if ((stat & 3) == 1) 159 return 0; 160 } 161 CH_WARN(phy->adapter, "PHY %u I2C Write of addr %u timed out\n", 162 phy->addr, word_addr); 163 return -ETIMEDOUT; 164} 165 166static int get_phytrans_type(struct cphy *phy) 167{ 168 int v; 169 170 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0); 171 if (v < 0) 172 return phy_transtype_unknown; 173 174 return v; 175} 176 177static int ael_laser_down(struct cphy *phy, int enable) 178{ 179 int v, dev_addr; 180 181 v = get_phytrans_type(phy); 182 if (v < 0) 183 return v; 184 185 if (v == phy_transtype_sfp) { 186 /* Check SFF Soft TX disable is supported */ 187 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 93); 188 if (v < 0) 189 return v; 190 191 v &= 0x40; 192 if (!v) 193 return v; 194 195 dev_addr = SFF_DEV_ADDR; 196 } else if (v == phy_transtype_xfp) 197 dev_addr = MODULE_DEV_ADDR; 198 else 199 return v; 200 201 v = ael_i2c_rd(phy, dev_addr, 110); 202 if (v < 0) 203 return v; 204 205 if (enable) 206 v |= 0x40; 207 else 208 v &= ~0x40; 209 210 v = ael_i2c_wr(phy, dev_addr, 110, v); 211 212 return v; 213} 214 215static int ael1002_power_down(struct cphy *phy, int enable) 216{ 217 int err; 218 219 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); 220 if (!err) 221 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 222 BMCR_PDOWN, enable ? BMCR_PDOWN : 0); 223 return err; 224} 225 226static int ael1002_get_module_type(struct cphy *phy, int delay_ms) 227{ 228 int v; 229 230 if (delay_ms) 231 msleep(delay_ms); 232 233 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0); 234 235 return v == -ETIMEDOUT ? phy_modtype_none : get_module_type(phy); 236} 237 238static int ael1002_reset(struct cphy *phy, int wait) 239{ 240 int err; 241 242 if ((err = ael1002_power_down(phy, 0)) || 243 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || 244 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || 245 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || 246 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || 247 (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, 248 0, 1 << 5))) 249 return err; 250 251 err = ael1002_get_module_type(phy, 300); 252 if (err >= 0) 253 phy->modtype = err; 254 255 return 0; 256} 257 258static int ael1002_intr_noop(struct cphy *phy) 259{ 260 return 0; 261} 262 263/* 264 * Get link status for a 10GBASE-R device. 265 */ 266static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, 267 int *duplex, int *fc) 268{ 269 if (link_ok) { 270 unsigned int stat0, stat1, stat2; 271 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); 272 273 if (!err) 274 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); 275 if (!err) 276 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); 277 if (err) 278 return err; 279 *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; 280 } 281 if (speed) 282 *speed = SPEED_10000; 283 if (duplex) 284 *duplex = DUPLEX_FULL; 285 return 0; 286} 287 288#ifdef C99_NOT_SUPPORTED 289static struct cphy_ops ael1002_ops = { 290 ael1002_reset, 291 ael1002_intr_noop, 292 ael1002_intr_noop, 293 ael1002_intr_noop, 294 ael1002_intr_noop, 295 NULL, 296 NULL, 297 NULL, 298 NULL, 299 NULL, 300 get_link_status_r, 301 ael1002_power_down, 302}; 303#else 304static struct cphy_ops ael1002_ops = { 305 .reset = ael1002_reset, 306 .intr_enable = ael1002_intr_noop, 307 .intr_disable = ael1002_intr_noop, 308 .intr_clear = ael1002_intr_noop, 309 .intr_handler = ael1002_intr_noop, 310 .get_link_status = get_link_status_r, 311 .power_down = ael1002_power_down, 312}; 313#endif 314 315int t3_ael1002_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, 316 const struct mdio_ops *mdio_ops) 317{ 318 int err; 319 320 cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops, 321 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, 322 "10GBASE-R"); 323 ael100x_txon(phy); 324 ael_laser_down(phy, 0); 325 326 err = ael1002_get_module_type(phy, 0); 327 if (err >= 0) 328 phy->modtype = err; 329 330 return 0; 331} 332 333static int ael1006_reset(struct cphy *phy, int wait) 334{ 335 int err; 336 337 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); 338 if (err) 339 return err; 340 341 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 342 F_GPIO6_OUT_VAL, 0); 343 344 msleep(125); 345 346 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 347 F_GPIO6_OUT_VAL, F_GPIO6_OUT_VAL); 348 349 msleep(125); 350 351 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); 352 if (err) 353 return err; 354 355 msleep(125); 356 357 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 1); 358 if (err) 359 return err; 360 361 msleep(125); 362 363 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0); 364 365 return err; 366 367} 368 369static int ael1006_power_down(struct cphy *phy, int enable) 370{ 371 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 372 BMCR_PDOWN, enable ? BMCR_PDOWN : 0); 373} 374 375#ifdef C99_NOT_SUPPORTED 376static struct cphy_ops ael1006_ops = { 377 ael1006_reset, 378 t3_phy_lasi_intr_enable, 379 t3_phy_lasi_intr_disable, 380 t3_phy_lasi_intr_clear, 381 t3_phy_lasi_intr_handler, 382 NULL, 383 NULL, 384 NULL, 385 NULL, 386 NULL, 387 get_link_status_r, 388 ael1006_power_down, 389}; 390#else 391static struct cphy_ops ael1006_ops = { 392 .reset = ael1006_reset, 393 .intr_enable = t3_phy_lasi_intr_enable, 394 .intr_disable = t3_phy_lasi_intr_disable, 395 .intr_clear = t3_phy_lasi_intr_clear, 396 .intr_handler = t3_phy_lasi_intr_handler, 397 .get_link_status = get_link_status_r, 398 .power_down = ael1006_power_down, 399}; 400#endif 401 402int t3_ael1006_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, 403 const struct mdio_ops *mdio_ops) 404{ 405 cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops, 406 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE, 407 "10GBASE-SR"); 408 ael100x_txon(phy); 409 return 0; 410} 411 412static int ael2005_setup_sr_edc(struct cphy *phy) 413{ 414 static struct reg_val regs[] = { 415 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, 416 { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, 417 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, 418 { 0, 0, 0, 0 } 419 }; 420 static u16 sr_edc[] = { 421 0xcc00, 0x2ff4, 422 0xcc01, 0x3cd4, 423 0xcc02, 0x2015, 424 0xcc03, 0x3105, 425 0xcc04, 0x6524, 426 0xcc05, 0x27ff, 427 0xcc06, 0x300f, 428 0xcc07, 0x2c8b, 429 0xcc08, 0x300b, 430 0xcc09, 0x4009, 431 0xcc0a, 0x400e, 432 0xcc0b, 0x2f72, 433 0xcc0c, 0x3002, 434 0xcc0d, 0x1002, 435 0xcc0e, 0x2172, 436 0xcc0f, 0x3012, 437 0xcc10, 0x1002, 438 0xcc11, 0x25d2, 439 0xcc12, 0x3012, 440 0xcc13, 0x1002, 441 0xcc14, 0xd01e, 442 0xcc15, 0x27d2, 443 0xcc16, 0x3012, 444 0xcc17, 0x1002, 445 0xcc18, 0x2004, 446 0xcc19, 0x3c84, 447 0xcc1a, 0x6436, 448 0xcc1b, 0x2007, 449 0xcc1c, 0x3f87, 450 0xcc1d, 0x8676, 451 0xcc1e, 0x40b7, 452 0xcc1f, 0xa746, 453 0xcc20, 0x4047, 454 0xcc21, 0x5673, 455 0xcc22, 0x2982, 456 0xcc23, 0x3002, 457 0xcc24, 0x13d2, 458 0xcc25, 0x8bbd, 459 0xcc26, 0x2862, 460 0xcc27, 0x3012, 461 0xcc28, 0x1002, 462 0xcc29, 0x2092, 463 0xcc2a, 0x3012, 464 0xcc2b, 0x1002, 465 0xcc2c, 0x5cc3, 466 0xcc2d, 0x314, 467 0xcc2e, 0x2942, 468 0xcc2f, 0x3002, 469 0xcc30, 0x1002, 470 0xcc31, 0xd019, 471 0xcc32, 0x2032, 472 0xcc33, 0x3012, 473 0xcc34, 0x1002, 474 0xcc35, 0x2a04, 475 0xcc36, 0x3c74, 476 0xcc37, 0x6435, 477 0xcc38, 0x2fa4, 478 0xcc39, 0x3cd4, 479 0xcc3a, 0x6624, 480 0xcc3b, 0x5563, 481 0xcc3c, 0x2d42, 482 0xcc3d, 0x3002, 483 0xcc3e, 0x13d2, 484 0xcc3f, 0x464d, 485 0xcc40, 0x2862, 486 0xcc41, 0x3012, 487 0xcc42, 0x1002, 488 0xcc43, 0x2032, 489 0xcc44, 0x3012, 490 0xcc45, 0x1002, 491 0xcc46, 0x2fb4, 492 0xcc47, 0x3cd4, 493 0xcc48, 0x6624, 494 0xcc49, 0x5563, 495 0xcc4a, 0x2d42, 496 0xcc4b, 0x3002, 497 0xcc4c, 0x13d2, 498 0xcc4d, 0x2ed2, 499 0xcc4e, 0x3002, 500 0xcc4f, 0x1002, 501 0xcc50, 0x2fd2, 502 0xcc51, 0x3002, 503 0xcc52, 0x1002, 504 0xcc53, 0x004, 505 0xcc54, 0x2942, 506 0xcc55, 0x3002, 507 0xcc56, 0x1002, 508 0xcc57, 0x2092, 509 0xcc58, 0x3012, 510 0xcc59, 0x1002, 511 0xcc5a, 0x5cc3, 512 0xcc5b, 0x317, 513 0xcc5c, 0x2f72, 514 0xcc5d, 0x3002, 515 0xcc5e, 0x1002, 516 0xcc5f, 0x2942, 517 0xcc60, 0x3002, 518 0xcc61, 0x1002, 519 0xcc62, 0x22cd, 520 0xcc63, 0x301d, 521 0xcc64, 0x2862, 522 0xcc65, 0x3012, 523 0xcc66, 0x1002, 524 0xcc67, 0x2ed2, 525 0xcc68, 0x3002, 526 0xcc69, 0x1002, 527 0xcc6a, 0x2d72, 528 0xcc6b, 0x3002, 529 0xcc6c, 0x1002, 530 0xcc6d, 0x628f, 531 0xcc6e, 0x2112, 532 0xcc6f, 0x3012, 533 0xcc70, 0x1002, 534 0xcc71, 0x5aa3, 535 0xcc72, 0x2dc2, 536 0xcc73, 0x3002, 537 0xcc74, 0x1312, 538 0xcc75, 0x6f72, 539 0xcc76, 0x1002, 540 0xcc77, 0x2807, 541 0xcc78, 0x31a7, 542 0xcc79, 0x20c4, 543 0xcc7a, 0x3c24, 544 0xcc7b, 0x6724, 545 0xcc7c, 0x1002, 546 0xcc7d, 0x2807, 547 0xcc7e, 0x3187, 548 0xcc7f, 0x20c4, 549 0xcc80, 0x3c24, 550 0xcc81, 0x6724, 551 0xcc82, 0x1002, 552 0xcc83, 0x2514, 553 0xcc84, 0x3c64, 554 0xcc85, 0x6436, 555 0xcc86, 0xdff4, 556 0xcc87, 0x6436, 557 0xcc88, 0x1002, 558 0xcc89, 0x40a4, 559 0xcc8a, 0x643c, 560 0xcc8b, 0x4016, 561 0xcc8c, 0x8c6c, 562 0xcc8d, 0x2b24, 563 0xcc8e, 0x3c24, 564 0xcc8f, 0x6435, 565 0xcc90, 0x1002, 566 0xcc91, 0x2b24, 567 0xcc92, 0x3c24, 568 0xcc93, 0x643a, 569 0xcc94, 0x4025, 570 0xcc95, 0x8a5a, 571 0xcc96, 0x1002, 572 0xcc97, 0x2731, 573 0xcc98, 0x3011, 574 0xcc99, 0x1001, 575 0xcc9a, 0xc7a0, 576 0xcc9b, 0x100, 577 0xcc9c, 0xc502, 578 0xcc9d, 0x53ac, 579 0xcc9e, 0xc503, 580 0xcc9f, 0xd5d5, 581 0xcca0, 0xc600, 582 0xcca1, 0x2a6d, 583 0xcca2, 0xc601, 584 0xcca3, 0x2a4c, 585 0xcca4, 0xc602, 586 0xcca5, 0x111, 587 0xcca6, 0xc60c, 588 0xcca7, 0x5900, 589 0xcca8, 0xc710, 590 0xcca9, 0x700, 591 0xccaa, 0xc718, 592 0xccab, 0x700, 593 0xccac, 0xc720, 594 0xccad, 0x4700, 595 0xccae, 0xc801, 596 0xccaf, 0x7f50, 597 0xccb0, 0xc802, 598 0xccb1, 0x7760, 599 0xccb2, 0xc803, 600 0xccb3, 0x7fce, 601 0xccb4, 0xc804, 602 0xccb5, 0x5700, 603 0xccb6, 0xc805, 604 0xccb7, 0x5f11, 605 0xccb8, 0xc806, 606 0xccb9, 0x4751, 607 0xccba, 0xc807, 608 0xccbb, 0x57e1, 609 0xccbc, 0xc808, 610 0xccbd, 0x2700, 611 0xccbe, 0xc809, 612 0xccbf, 0x000, 613 0xccc0, 0xc821, 614 0xccc1, 0x002, 615 0xccc2, 0xc822, 616 0xccc3, 0x014, 617 0xccc4, 0xc832, 618 0xccc5, 0x1186, 619 0xccc6, 0xc847, 620 0xccc7, 0x1e02, 621 0xccc8, 0xc013, 622 0xccc9, 0xf341, 623 0xccca, 0xc01a, 624 0xcccb, 0x446, 625 0xcccc, 0xc024, 626 0xcccd, 0x1000, 627 0xccce, 0xc025, 628 0xcccf, 0xa00, 629 0xccd0, 0xc026, 630 0xccd1, 0xc0c, 631 0xccd2, 0xc027, 632 0xccd3, 0xc0c, 633 0xccd4, 0xc029, 634 0xccd5, 0x0a0, 635 0xccd6, 0xc030, 636 0xccd7, 0xa00, 637 0xccd8, 0xc03c, 638 0xccd9, 0x01c, 639 0xccda, 0xc005, 640 0xccdb, 0x7a06, 641 0xccdc, 0x000, 642 0xccdd, 0x2731, 643 0xccde, 0x3011, 644 0xccdf, 0x1001, 645 0xcce0, 0xc620, 646 0xcce1, 0x000, 647 0xcce2, 0xc621, 648 0xcce3, 0x03f, 649 0xcce4, 0xc622, 650 0xcce5, 0x000, 651 0xcce6, 0xc623, 652 0xcce7, 0x000, 653 0xcce8, 0xc624, 654 0xcce9, 0x000, 655 0xccea, 0xc625, 656 0xcceb, 0x000, 657 0xccec, 0xc627, 658 0xcced, 0x000, 659 0xccee, 0xc628, 660 0xccef, 0x000, 661 0xccf0, 0xc62c, 662 0xccf1, 0x000, 663 0xccf2, 0x000, 664 0xccf3, 0x2806, 665 0xccf4, 0x3cb6, 666 0xccf5, 0xc161, 667 0xccf6, 0x6134, 668 0xccf7, 0x6135, 669 0xccf8, 0x5443, 670 0xccf9, 0x303, 671 0xccfa, 0x6524, 672 0xccfb, 0x00b, 673 0xccfc, 0x1002, 674 0xccfd, 0x2104, 675 0xccfe, 0x3c24, 676 0xccff, 0x2105, 677 0xcd00, 0x3805, 678 0xcd01, 0x6524, 679 0xcd02, 0xdff4, 680 0xcd03, 0x4005, 681 0xcd04, 0x6524, 682 0xcd05, 0x1002, 683 0xcd06, 0x5dd3, 684 0xcd07, 0x306, 685 0xcd08, 0x2ff7, 686 0xcd09, 0x38f7, 687 0xcd0a, 0x60b7, 688 0xcd0b, 0xdffd, 689 0xcd0c, 0x00a, 690 0xcd0d, 0x1002, 691 0xcd0e, 0 692 }; 693 int i, err; 694 695 err = set_phy_regs(phy, regs); 696 if (err) 697 return err; 698 699 msleep(50); 700 701 for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) 702 err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], 703 sr_edc[i + 1]); 704 if (!err) 705 phy->priv = edc_sr; 706 return err; 707} 708 709static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) 710{ 711 static struct reg_val regs[] = { 712 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, 713 { 0, 0, 0, 0 } 714 }; 715 static struct reg_val preemphasis[] = { 716 { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, 717 { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, 718 { 0, 0, 0, 0 } 719 }; 720 static u16 twinax_edc[] = { 721 0xcc00, 0x4009, 722 0xcc01, 0x27ff, 723 0xcc02, 0x300f, 724 0xcc03, 0x40aa, 725 0xcc04, 0x401c, 726 0xcc05, 0x401e, 727 0xcc06, 0x2ff4, 728 0xcc07, 0x3cd4, 729 0xcc08, 0x2035, 730 0xcc09, 0x3145, 731 0xcc0a, 0x6524, 732 0xcc0b, 0x26a2, 733 0xcc0c, 0x3012, 734 0xcc0d, 0x1002, 735 0xcc0e, 0x29c2, 736 0xcc0f, 0x3002, 737 0xcc10, 0x1002, 738 0xcc11, 0x2072, 739 0xcc12, 0x3012, 740 0xcc13, 0x1002, 741 0xcc14, 0x22cd, 742 0xcc15, 0x301d, 743 0xcc16, 0x2e52, 744 0xcc17, 0x3012, 745 0xcc18, 0x1002, 746 0xcc19, 0x28e2, 747 0xcc1a, 0x3002, 748 0xcc1b, 0x1002, 749 0xcc1c, 0x628f, 750 0xcc1d, 0x2ac2, 751 0xcc1e, 0x3012, 752 0xcc1f, 0x1002, 753 0xcc20, 0x5553, 754 0xcc21, 0x2ae2, 755 0xcc22, 0x3002, 756 0xcc23, 0x1302, 757 0xcc24, 0x401e, 758 0xcc25, 0x2be2, 759 0xcc26, 0x3012, 760 0xcc27, 0x1002, 761 0xcc28, 0x2da2, 762 0xcc29, 0x3012, 763 0xcc2a, 0x1002, 764 0xcc2b, 0x2ba2, 765 0xcc2c, 0x3002, 766 0xcc2d, 0x1002, 767 0xcc2e, 0x5ee3, 768 0xcc2f, 0x305, 769 0xcc30, 0x400e, 770 0xcc31, 0x2bc2, 771 0xcc32, 0x3002, 772 0xcc33, 0x1002, 773 0xcc34, 0x2b82, 774 0xcc35, 0x3012, 775 0xcc36, 0x1002, 776 0xcc37, 0x5663, 777 0xcc38, 0x302, 778 0xcc39, 0x401e, 779 0xcc3a, 0x6f72, 780 0xcc3b, 0x1002, 781 0xcc3c, 0x628f, 782 0xcc3d, 0x2be2, 783 0xcc3e, 0x3012, 784 0xcc3f, 0x1002, 785 0xcc40, 0x22cd, 786 0xcc41, 0x301d, 787 0xcc42, 0x2e52, 788 0xcc43, 0x3012, 789 0xcc44, 0x1002, 790 0xcc45, 0x2522, 791 0xcc46, 0x3012, 792 0xcc47, 0x1002, 793 0xcc48, 0x2da2, 794 0xcc49, 0x3012, 795 0xcc4a, 0x1002, 796 0xcc4b, 0x2ca2, 797 0xcc4c, 0x3012, 798 0xcc4d, 0x1002, 799 0xcc4e, 0x2fa4, 800 0xcc4f, 0x3cd4, 801 0xcc50, 0x6624, 802 0xcc51, 0x410b, 803 0xcc52, 0x56b3, 804 0xcc53, 0x3c4, 805 0xcc54, 0x2fb2, 806 0xcc55, 0x3002, 807 0xcc56, 0x1002, 808 0xcc57, 0x220b, 809 0xcc58, 0x303b, 810 0xcc59, 0x56b3, 811 0xcc5a, 0x3c3, 812 0xcc5b, 0x866b, 813 0xcc5c, 0x400c, 814 0xcc5d, 0x23a2, 815 0xcc5e, 0x3012, 816 0xcc5f, 0x1002, 817 0xcc60, 0x2da2, 818 0xcc61, 0x3012, 819 0xcc62, 0x1002, 820 0xcc63, 0x2ca2, 821 0xcc64, 0x3012, 822 0xcc65, 0x1002, 823 0xcc66, 0x2fb4, 824 0xcc67, 0x3cd4, 825 0xcc68, 0x6624, 826 0xcc69, 0x56b3, 827 0xcc6a, 0x3c3, 828 0xcc6b, 0x866b, 829 0xcc6c, 0x401c, 830 0xcc6d, 0x2205, 831 0xcc6e, 0x3035, 832 0xcc6f, 0x5b53, 833 0xcc70, 0x2c52, 834 0xcc71, 0x3002, 835 0xcc72, 0x13c2, 836 0xcc73, 0x5cc3, 837 0xcc74, 0x317, 838 0xcc75, 0x2522, 839 0xcc76, 0x3012, 840 0xcc77, 0x1002, 841 0xcc78, 0x2da2, 842 0xcc79, 0x3012, 843 0xcc7a, 0x1002, 844 0xcc7b, 0x2b82, 845 0xcc7c, 0x3012, 846 0xcc7d, 0x1002, 847 0xcc7e, 0x5663, 848 0xcc7f, 0x303, 849 0xcc80, 0x401e, 850 0xcc81, 0x004, 851 0xcc82, 0x2c42, 852 0xcc83, 0x3012, 853 0xcc84, 0x1002, 854 0xcc85, 0x6f72, 855 0xcc86, 0x1002, 856 0xcc87, 0x628f, 857 0xcc88, 0x2304, 858 0xcc89, 0x3c84, 859 0xcc8a, 0x6436, 860 0xcc8b, 0xdff4, 861 0xcc8c, 0x6436, 862 0xcc8d, 0x2ff5, 863 0xcc8e, 0x3005, 864 0xcc8f, 0x8656, 865 0xcc90, 0xdfba, 866 0xcc91, 0x56a3, 867 0xcc92, 0xd05a, 868 0xcc93, 0x21c2, 869 0xcc94, 0x3012, 870 0xcc95, 0x1392, 871 0xcc96, 0xd05a, 872 0xcc97, 0x56a3, 873 0xcc98, 0xdfba, 874 0xcc99, 0x383, 875 0xcc9a, 0x6f72, 876 0xcc9b, 0x1002, 877 0xcc9c, 0x28c5, 878 0xcc9d, 0x3005, 879 0xcc9e, 0x4178, 880 0xcc9f, 0x5653, 881 0xcca0, 0x384, 882 0xcca1, 0x22b2, 883 0xcca2, 0x3012, 884 0xcca3, 0x1002, 885 0xcca4, 0x2be5, 886 0xcca5, 0x3005, 887 0xcca6, 0x41e8, 888 0xcca7, 0x5653, 889 0xcca8, 0x382, 890 0xcca9, 0x002, 891 0xccaa, 0x4258, 892 0xccab, 0x2474, 893 0xccac, 0x3c84, 894 0xccad, 0x6437, 895 0xccae, 0xdff4, 896 0xccaf, 0x6437, 897 0xccb0, 0x2ff5, 898 0xccb1, 0x3c05, 899 0xccb2, 0x8757, 900 0xccb3, 0xb888, 901 0xccb4, 0x9787, 902 0xccb5, 0xdff4, 903 0xccb6, 0x6724, 904 0xccb7, 0x866a, 905 0xccb8, 0x6f72, 906 0xccb9, 0x1002, 907 0xccba, 0x2d01, 908 0xccbb, 0x3011, 909 0xccbc, 0x1001, 910 0xccbd, 0xc620, 911 0xccbe, 0x14e5, 912 0xccbf, 0xc621, 913 0xccc0, 0xc53d, 914 0xccc1, 0xc622, 915 0xccc2, 0x3cbe, 916 0xccc3, 0xc623, 917 0xccc4, 0x4452, 918 0xccc5, 0xc624, 919 0xccc6, 0xc5c5, 920 0xccc7, 0xc625, 921 0xccc8, 0xe01e, 922 0xccc9, 0xc627, 923 0xccca, 0x000, 924 0xcccb, 0xc628, 925 0xcccc, 0x000, 926 0xcccd, 0xc62b, 927 0xccce, 0x000, 928 0xcccf, 0xc62c, 929 0xccd0, 0x000, 930 0xccd1, 0x000, 931 0xccd2, 0x2d01, 932 0xccd3, 0x3011, 933 0xccd4, 0x1001, 934 0xccd5, 0xc620, 935 0xccd6, 0x000, 936 0xccd7, 0xc621, 937 0xccd8, 0x000, 938 0xccd9, 0xc622, 939 0xccda, 0x0ce, 940 0xccdb, 0xc623, 941 0xccdc, 0x07f, 942 0xccdd, 0xc624, 943 0xccde, 0x032, 944 0xccdf, 0xc625, 945 0xcce0, 0x000, 946 0xcce1, 0xc627, 947 0xcce2, 0x000, 948 0xcce3, 0xc628, 949 0xcce4, 0x000, 950 0xcce5, 0xc62b, 951 0xcce6, 0x000, 952 0xcce7, 0xc62c, 953 0xcce8, 0x000, 954 0xcce9, 0x000, 955 0xccea, 0x2d01, 956 0xcceb, 0x3011, 957 0xccec, 0x1001, 958 0xcced, 0xc502, 959 0xccee, 0x609f, 960 0xccef, 0xc600, 961 0xccf0, 0x2a6e, 962 0xccf1, 0xc601, 963 0xccf2, 0x2a2c, 964 0xccf3, 0xc60c, 965 0xccf4, 0x5400, 966 0xccf5, 0xc710, 967 0xccf6, 0x700, 968 0xccf7, 0xc718, 969 0xccf8, 0x700, 970 0xccf9, 0xc720, 971 0xccfa, 0x4700, 972 0xccfb, 0xc728, 973 0xccfc, 0x700, 974 0xccfd, 0xc729, 975 0xccfe, 0x1207, 976 0xccff, 0xc801, 977 0xcd00, 0x7f50, 978 0xcd01, 0xc802, 979 0xcd02, 0x7760, 980 0xcd03, 0xc803, 981 0xcd04, 0x7fce, 982 0xcd05, 0xc804, 983 0xcd06, 0x520e, 984 0xcd07, 0xc805, 985 0xcd08, 0x5c11, 986 0xcd09, 0xc806, 987 0xcd0a, 0x3c51, 988 0xcd0b, 0xc807, 989 0xcd0c, 0x4061, 990 0xcd0d, 0xc808, 991 0xcd0e, 0x49c1, 992 0xcd0f, 0xc809, 993 0xcd10, 0x3840, 994 0xcd11, 0xc80a, 995 0xcd12, 0x000, 996 0xcd13, 0xc821, 997 0xcd14, 0x002, 998 0xcd15, 0xc822, 999 0xcd16, 0x046, 1000 0xcd17, 0xc844, 1001 0xcd18, 0x182f, 1002 0xcd19, 0xc013, 1003 0xcd1a, 0xf341, 1004 0xcd1b, 0xc01a, 1005 0xcd1c, 0x446, 1006 0xcd1d, 0xc024, 1007 0xcd1e, 0x1000, 1008 0xcd1f, 0xc025, 1009 0xcd20, 0xa00, 1010 0xcd21, 0xc026, 1011 0xcd22, 0xc0c, 1012 0xcd23, 0xc027, 1013 0xcd24, 0xc0c, 1014 0xcd25, 0xc029, 1015 0xcd26, 0x0a0, 1016 0xcd27, 0xc030, 1017 0xcd28, 0xa00, 1018 0xcd29, 0xc03c, 1019 0xcd2a, 0x01c, 1020 0xcd2b, 0x000, 1021 0xcd2c, 0x2b84, 1022 0xcd2d, 0x3c74, 1023 0xcd2e, 0x6435, 1024 0xcd2f, 0xdff4, 1025 0xcd30, 0x6435, 1026 0xcd31, 0x2806, 1027 0xcd32, 0x3006, 1028 0xcd33, 0x8565, 1029 0xcd34, 0x2b24, 1030 0xcd35, 0x3c24, 1031 0xcd36, 0x6436, 1032 0xcd37, 0x1002, 1033 0xcd38, 0x2b24, 1034 0xcd39, 0x3c24, 1035 0xcd3a, 0x6436, 1036 0xcd3b, 0x4045, 1037 0xcd3c, 0x8656, 1038 0xcd3d, 0x1002, 1039 0xcd3e, 0x2807, 1040 0xcd3f, 0x31a7, 1041 0xcd40, 0x20c4, 1042 0xcd41, 0x3c24, 1043 0xcd42, 0x6724, 1044 0xcd43, 0x1002, 1045 0xcd44, 0x2807, 1046 0xcd45, 0x3187, 1047 0xcd46, 0x20c4, 1048 0xcd47, 0x3c24, 1049 0xcd48, 0x6724, 1050 0xcd49, 0x1002, 1051 0xcd4a, 0x2514, 1052 0xcd4b, 0x3c64, 1053 0xcd4c, 0x6436, 1054 0xcd4d, 0xdff4, 1055 0xcd4e, 0x6436, 1056 0xcd4f, 0x1002, 1057 0xcd50, 0x2806, 1058 0xcd51, 0x3cb6, 1059 0xcd52, 0xc161, 1060 0xcd53, 0x6134, 1061 0xcd54, 0x6135, 1062 0xcd55, 0x5443, 1063 0xcd56, 0x303, 1064 0xcd57, 0x6524, 1065 0xcd58, 0x00b, 1066 0xcd59, 0x1002, 1067 0xcd5a, 0xd019, 1068 0xcd5b, 0x2104, 1069 0xcd5c, 0x3c24, 1070 0xcd5d, 0x2105, 1071 0xcd5e, 0x3805, 1072 0xcd5f, 0x6524, 1073 0xcd60, 0xdff4, 1074 0xcd61, 0x4005, 1075 0xcd62, 0x6524, 1076 0xcd63, 0x2e8d, 1077 0xcd64, 0x303d, 1078 0xcd65, 0x5dd3, 1079 0xcd66, 0x306, 1080 0xcd67, 0x2ff7, 1081 0xcd68, 0x38f7, 1082 0xcd69, 0x60b7, 1083 0xcd6a, 0xdffd, 1084 0xcd6b, 0x00a, 1085 0xcd6c, 0x1002, 1086 0xcd6d, 0 1087 }; 1088 int i, err; 1089 1090 err = set_phy_regs(phy, regs); 1091 if (!err && modtype == phy_modtype_twinax_long) 1092 err = set_phy_regs(phy, preemphasis); 1093 if (err) 1094 return err; 1095 1096 msleep(50); 1097 1098 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) 1099 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], 1100 twinax_edc[i + 1]); 1101 if (!err) 1102 phy->priv = edc_twinax; 1103 return err; 1104} 1105 1106static int get_module_type(struct cphy *phy) 1107{ 1108 int v; 1109 1110 v = get_phytrans_type(phy); 1111 if (v == phy_transtype_sfp) { 1112 /* SFP: see SFF-8472 for below */ 1113 1114 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); 1115 if (v < 0) 1116 return v; 1117 1118 if (v == 0x1) 1119 return phy_modtype_twinax; 1120 if (v == 0x10) 1121 return phy_modtype_sr; 1122 if (v == 0x20) 1123 return phy_modtype_lr; 1124 if (v == 0x40) 1125 return phy_modtype_lrm; 1126 1127 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); 1128 if (v < 0) 1129 return v; 1130 if (v != 4) 1131 return phy_modtype_unknown; 1132 1133 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); 1134 if (v < 0) 1135 return v; 1136 1137 if (v & 0x80) { 1138 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); 1139 if (v < 0) 1140 return v; 1141 return v > 10 ? phy_modtype_twinax_long : 1142 phy_modtype_twinax; 1143 } 1144 } else if (v == phy_transtype_xfp) { 1145 /* XFP: See INF-8077i for details. */ 1146 1147 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127); 1148 if (v < 0) 1149 return v; 1150 1151 if (v != 1) { 1152 /* XXX: set page select to table 1 yourself */ 1153 return phy_modtype_unknown; 1154 } 1155 1156 v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131); 1157 if (v < 0) 1158 return v; 1159 if (v == 0x10) 1160 return phy_modtype_lrm; 1161 if (v == 0x40) 1162 return phy_modtype_lr; 1163 if (v == 0x80) 1164 return phy_modtype_sr; 1165 } 1166 1167 return phy_modtype_unknown; 1168} 1169 1170 1171static int ael2005_intr_enable(struct cphy *phy) 1172{ 1173 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); 1174 return err ? err : t3_phy_lasi_intr_enable(phy); 1175} 1176 1177static int ael2005_intr_disable(struct cphy *phy) 1178{ 1179 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); 1180 return err ? err : t3_phy_lasi_intr_disable(phy); 1181} 1182 1183static int ael2005_intr_clear(struct cphy *phy) 1184{ 1185 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); 1186 return err ? err : t3_phy_lasi_intr_clear(phy); 1187} 1188 1189static int ael2005_get_module_type(struct cphy *phy, int delay_ms) 1190{ 1191 int v; 1192 unsigned int stat; 1193 1194 v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); 1195 if (v) 1196 return v; 1197 1198 if (stat & (1 << 8)) /* module absent */ 1199 return phy_modtype_none; 1200 1201 if (delay_ms) 1202 msleep(delay_ms); 1203 1204 return get_module_type(phy); 1205} 1206 1207static int ael2005_reset(struct cphy *phy, int wait) 1208{ 1209 static struct reg_val regs0[] = { 1210 { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, 1211 { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, 1212 { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, 1213 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, 1214 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, 1215 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, 1216 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, 1217 { 0, 0, 0, 0 } 1218 }; 1219 static struct reg_val regs1[] = { 1220 { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, 1221 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, 1222 { 0, 0, 0, 0 } 1223 }; 1224 1225 int err, lasi_ctrl; 1226 1227 err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); 1228 if (err) 1229 return err; 1230 1231 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); 1232 if (err) 1233 return err; 1234 1235 msleep(125); 1236 phy->priv = edc_none; 1237 err = set_phy_regs(phy, regs0); 1238 if (err) 1239 return err; 1240 1241 msleep(50); 1242 1243 err = ael2005_get_module_type(phy, 0); 1244 if (err < 0) 1245 return err; 1246 phy->modtype = (u8)err; 1247 1248 if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) 1249 err = ael2005_setup_twinax_edc(phy, err); 1250 else 1251 err = ael2005_setup_sr_edc(phy); 1252 if (err) 1253 return err; 1254 1255 err = set_phy_regs(phy, regs1); 1256 if (err) 1257 return err; 1258 1259 /* reset wipes out interrupts, reenable them if they were on */ 1260 if (lasi_ctrl & 1) 1261 err = ael2005_intr_enable(phy); 1262 return err; 1263} 1264 1265static int ael2005_intr_handler(struct cphy *phy) 1266{ 1267 unsigned int stat; 1268 int ret, edc_needed, cause = 0; 1269 1270 ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); 1271 if (ret) 1272 return ret; 1273 1274 if (stat & AEL2005_MODDET_IRQ) { 1275 ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 1276 0xd00); 1277 if (ret) 1278 return ret; 1279 1280 /* modules have max 300 ms init time after hot plug */ 1281 ret = ael2005_get_module_type(phy, 300); 1282 if (ret < 0) 1283 return ret; 1284 1285 phy->modtype = (u8)ret; 1286 if (ret == phy_modtype_none) 1287 edc_needed = phy->priv; /* on unplug retain EDC */ 1288 else if (ret == phy_modtype_twinax || 1289 ret == phy_modtype_twinax_long) 1290 edc_needed = edc_twinax; 1291 else 1292 edc_needed = edc_sr; 1293 1294 if (edc_needed != phy->priv) { 1295 ret = ael2005_reset(phy, 0); 1296 return ret ? ret : cphy_cause_module_change; 1297 } 1298 cause = cphy_cause_module_change; 1299 } 1300 1301 ret = t3_phy_lasi_intr_handler(phy); 1302 if (ret < 0) 1303 return ret; 1304 1305 ret |= cause; 1306 if (!ret) 1307 ret |= cphy_cause_link_change; 1308 return ret; 1309} 1310 1311#ifdef C99_NOT_SUPPORTED 1312static struct cphy_ops ael2005_ops = { 1313 ael2005_reset, 1314 ael2005_intr_enable, 1315 ael2005_intr_disable, 1316 ael2005_intr_clear, 1317 ael2005_intr_handler, 1318 NULL, 1319 NULL, 1320 NULL, 1321 NULL, 1322 NULL, 1323 get_link_status_r, 1324 ael1002_power_down, 1325}; 1326#else 1327static struct cphy_ops ael2005_ops = { 1328 .reset = ael2005_reset, 1329 .intr_enable = ael2005_intr_enable, 1330 .intr_disable = ael2005_intr_disable, 1331 .intr_clear = ael2005_intr_clear, 1332 .intr_handler = ael2005_intr_handler, 1333 .get_link_status = get_link_status_r, 1334 .power_down = ael1002_power_down, 1335}; 1336#endif 1337 1338int t3_ael2005_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, 1339 const struct mdio_ops *mdio_ops) 1340{ 1341 int err; 1342 cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops, 1343 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | 1344 SUPPORTED_IRQ, "10GBASE-R"); 1345 msleep(125); 1346 ael_laser_down(phy, 0); 1347 1348 err = ael2005_get_module_type(phy, 0); 1349 if (err >= 0) 1350 phy->modtype = err; 1351 1352 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, 1353 1 << 5); 1354} 1355 1356/* 1357 * Get link status for a 10GBASE-X device. 1358 */ 1359static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, 1360 int *duplex, int *fc) 1361{ 1362 if (link_ok) { 1363 unsigned int stat0, stat1, stat2; 1364 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); 1365 1366 if (!err) 1367 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); 1368 if (!err) 1369 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); 1370 if (err) 1371 return err; 1372 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; 1373 } 1374 if (speed) 1375 *speed = SPEED_10000; 1376 if (duplex) 1377 *duplex = DUPLEX_FULL; 1378 return 0; 1379} 1380 1381#ifdef C99_NOT_SUPPORTED 1382static struct cphy_ops qt2045_ops = { 1383 ael1006_reset, 1384 t3_phy_lasi_intr_enable, 1385 t3_phy_lasi_intr_disable, 1386 t3_phy_lasi_intr_clear, 1387 t3_phy_lasi_intr_handler, 1388 NULL, 1389 NULL, 1390 NULL, 1391 NULL, 1392 NULL, 1393 get_link_status_x, 1394 ael1006_power_down, 1395}; 1396#else 1397static struct cphy_ops qt2045_ops = { 1398 .reset = ael1006_reset, 1399 .intr_enable = t3_phy_lasi_intr_enable, 1400 .intr_disable = t3_phy_lasi_intr_disable, 1401 .intr_clear = t3_phy_lasi_intr_clear, 1402 .intr_handler = t3_phy_lasi_intr_handler, 1403 .get_link_status = get_link_status_x, 1404 .power_down = ael1006_power_down, 1405}; 1406#endif 1407 1408int t3_qt2045_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, 1409 const struct mdio_ops *mdio_ops) 1410{ 1411 unsigned int stat; 1412 1413 cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops, 1414 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, 1415 "10GBASE-CX4"); 1416 1417 /* 1418 * Some cards where the PHY is supposed to be at address 0 actually 1419 * have it at 1. 1420 */ 1421 if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && 1422 stat == 0xffff) 1423 phy->addr = 1; 1424 return 0; 1425} 1426 1427static int xaui_direct_reset(struct cphy *phy, int wait) 1428{ 1429 return 0; 1430} 1431 1432static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, 1433 int *speed, int *duplex, int *fc) 1434{ 1435 if (link_ok) { 1436 unsigned int status; 1437 1438 status = t3_read_reg(phy->adapter, 1439 XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | 1440 t3_read_reg(phy->adapter, 1441 XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | 1442 t3_read_reg(phy->adapter, 1443 XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | 1444 t3_read_reg(phy->adapter, 1445 XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); 1446 *link_ok = !(status & F_LOWSIG0); 1447 } 1448 if (speed) 1449 *speed = SPEED_10000; 1450 if (duplex) 1451 *duplex = DUPLEX_FULL; 1452 return 0; 1453} 1454 1455static int xaui_direct_power_down(struct cphy *phy, int enable) 1456{ 1457 return 0; 1458} 1459 1460#ifdef C99_NOT_SUPPORTED 1461static struct cphy_ops xaui_direct_ops = { 1462 xaui_direct_reset, 1463 ael1002_intr_noop, 1464 ael1002_intr_noop, 1465 ael1002_intr_noop, 1466 ael1002_intr_noop, 1467 NULL, 1468 NULL, 1469 NULL, 1470 NULL, 1471 NULL, 1472 xaui_direct_get_link_status, 1473 xaui_direct_power_down, 1474}; 1475#else 1476static struct cphy_ops xaui_direct_ops = { 1477 .reset = xaui_direct_reset, 1478 .intr_enable = ael1002_intr_noop, 1479 .intr_disable = ael1002_intr_noop, 1480 .intr_clear = ael1002_intr_noop, 1481 .intr_handler = ael1002_intr_noop, 1482 .get_link_status = xaui_direct_get_link_status, 1483 .power_down = xaui_direct_power_down, 1484}; 1485#endif 1486 1487int t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, 1488 const struct mdio_ops *mdio_ops) 1489{ 1490 cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, 1491 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, 1492 "10GBASE-CX4"); 1493 return 0; 1494} 1495