1 /************************************************************************** 2 SPDX-License-Identifier: BSD-2-Clause 3 4 Copyright (c) 2009 Chelsio Inc. 5 All rights reserved. 6 7 Redistribution and use in source and binary forms, with or without 8 modification, are permitted provided that the following conditions are met: 9 10 1. Redistributions of source code must retain the above copyright notice, 11 this list of conditions and the following disclaimer. 12 13 2. Neither the name of the Chelsio Corporation nor the names of its 14 contributors may be used to endorse or promote products derived from 15 this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 POSSIBILITY OF SUCH DAMAGE. 28 29 ***************************************************************************/ 30 31 #include <sys/cdefs.h> 32 #include <cxgb_include.h> 33 34 #undef msleep 35 #define msleep t3_os_sleep 36 37 enum { 38 /* MDIO_DEV_PMA_PMD registers */ 39 AQ_LINK_STAT = 0xe800, 40 41 /* MDIO_DEV_XGXS registers */ 42 AQ_XAUI_RX_CFG = 0xc400, 43 AQ_XAUI_KX_CFG = 0xc440, 44 AQ_XAUI_TX_CFG = 0xe400, 45 46 /* MDIO_DEV_ANEG registers */ 47 AQ_100M_CTRL = 0x0010, 48 AQ_10G_CTRL = 0x0020, 49 AQ_1G_CTRL = 0xc400, 50 AQ_ANEG_STAT = 0xc800, 51 52 /* MDIO_DEV_VEND1 registers */ 53 AQ_FW_VERSION = 0x0020, 54 AQ_THERMAL_THR = 0xc421, 55 AQ_THERMAL1 = 0xc820, 56 AQ_THERMAL2 = 0xc821, 57 AQ_IFLAG_GLOBAL = 0xfc00, 58 AQ_IMASK_GLOBAL = 0xff00, 59 }; 60 61 #define AQBIT(x) (1 << (0x##x)) 62 #define ADV_1G_FULL AQBIT(f) 63 #define ADV_1G_HALF AQBIT(e) 64 #define ADV_10G_FULL AQBIT(c) 65 66 #define AQ_WRITE_REGS(phy, regs) do { \ 67 int i; \ 68 for (i = 0; i < ARRAY_SIZE(regs); i++) { \ 69 (void) mdio_write(phy, regs[i].mmd, regs[i].reg, regs[i].val); \ 70 } \ 71 } while (0) 72 #define AQ_READ_REGS(phy, regs) do { \ 73 unsigned i, v; \ 74 for (i = 0; i < ARRAY_SIZE(regs); i++) { \ 75 (void) mdio_read(phy, regs[i].mmd, regs[i].reg, &v); \ 76 } \ 77 } while (0) 78 79 /* 80 * Return value is temperature in celsius, 0xffff for error or don't know. 81 */ 82 static int 83 aq100x_temperature(struct cphy *phy) 84 { 85 unsigned int v; 86 87 if (mdio_read(phy, MDIO_DEV_VEND1, AQ_THERMAL2, &v) || 88 v == 0xffff || (v & 1) != 1) 89 return (0xffff); 90 91 if (mdio_read(phy, MDIO_DEV_VEND1, AQ_THERMAL1, &v)) 92 return (0xffff); 93 94 return ((int)((signed char)(v >> 8))); 95 } 96 97 static int 98 aq100x_set_defaults(struct cphy *phy) 99 { 100 return mdio_write(phy, MDIO_DEV_VEND1, AQ_THERMAL_THR, 0x6c00); 101 } 102 103 static int 104 aq100x_reset(struct cphy *phy, int wait) 105 { 106 int err; 107 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); 108 if (!err) 109 err = aq100x_set_defaults(phy); 110 return (err); 111 } 112 113 static int 114 aq100x_intr_enable(struct cphy *phy) 115 { 116 struct { 117 int mmd; 118 int reg; 119 int val; 120 } imasks[] = { 121 {MDIO_DEV_VEND1, 0xd400, AQBIT(e)}, 122 {MDIO_DEV_VEND1, 0xff01, AQBIT(2)}, 123 {MDIO_DEV_VEND1, AQ_IMASK_GLOBAL, AQBIT(0)} 124 }; 125 126 AQ_WRITE_REGS(phy, imasks); 127 128 return (0); 129 } 130 131 static int 132 aq100x_intr_disable(struct cphy *phy) 133 { 134 struct { 135 int mmd; 136 int reg; 137 int val; 138 } imasks[] = { 139 {MDIO_DEV_VEND1, 0xd400, 0}, 140 {MDIO_DEV_VEND1, 0xff01, 0}, 141 {MDIO_DEV_VEND1, AQ_IMASK_GLOBAL, 0} 142 }; 143 144 AQ_WRITE_REGS(phy, imasks); 145 146 return (0); 147 } 148 149 static int 150 aq100x_intr_clear(struct cphy *phy) 151 { 152 struct { 153 int mmd; 154 int reg; 155 } iclr[] = { 156 {MDIO_DEV_VEND1, 0xcc00}, 157 {MDIO_DEV_VEND1, AQ_IMASK_GLOBAL} /* needed? */ 158 }; 159 160 AQ_READ_REGS(phy, iclr); 161 162 return (0); 163 } 164 165 static int 166 aq100x_vendor_intr(struct cphy *phy, int *rc) 167 { 168 int err; 169 unsigned int cause, v; 170 171 err = mdio_read(phy, MDIO_DEV_VEND1, 0xfc01, &cause); 172 if (err) 173 return (err); 174 175 if (cause & AQBIT(2)) { 176 err = mdio_read(phy, MDIO_DEV_VEND1, 0xcc00, &v); 177 if (err) 178 return (err); 179 180 if (v & AQBIT(e)) { 181 CH_WARN(phy->adapter, "PHY%d: temperature is now %dC\n", 182 phy->addr, aq100x_temperature(phy)); 183 184 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 185 phy->addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL, 0); 186 187 *rc |= cphy_cause_alarm; 188 } 189 190 cause &= ~4; 191 } 192 193 if (cause) 194 CH_WARN(phy->adapter, "PHY%d: unhandled vendor interrupt" 195 " (0x%x)\n", phy->addr, cause); 196 197 return (0); 198 199 } 200 201 static int 202 aq100x_intr_handler(struct cphy *phy) 203 { 204 int err, rc = 0; 205 unsigned int cause; 206 207 err = mdio_read(phy, MDIO_DEV_VEND1, AQ_IFLAG_GLOBAL, &cause); 208 if (err) 209 return (err); 210 211 if (cause & AQBIT(0)) { 212 err = aq100x_vendor_intr(phy, &rc); 213 if (err) 214 return (err); 215 cause &= ~AQBIT(0); 216 } 217 218 if (cause) 219 CH_WARN(phy->adapter, "PHY%d: unhandled interrupt (0x%x)\n", 220 phy->addr, cause); 221 222 return (rc); 223 } 224 225 static int 226 aq100x_power_down(struct cphy *phy, int off) 227 { 228 int err, wait = 500; 229 unsigned int v; 230 231 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, BMCR_PDOWN, 232 off ? BMCR_PDOWN : 0); 233 if (err || off) 234 return (err); 235 236 msleep(300); 237 do { 238 err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); 239 if (err) 240 return (err); 241 v &= BMCR_RESET; 242 if (v) 243 msleep(10); 244 } while (v && --wait); 245 if (v) { 246 CH_WARN(phy->adapter, "PHY%d: power-up timed out (0x%x).\n", 247 phy->addr, v); 248 return (ETIMEDOUT); 249 } 250 251 return (0); 252 } 253 254 static int 255 aq100x_autoneg_enable(struct cphy *phy) 256 { 257 int err; 258 259 err = aq100x_power_down(phy, 0); 260 if (!err) 261 err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, MII_BMCR, 262 BMCR_RESET, BMCR_ANENABLE | BMCR_ANRESTART); 263 264 return (err); 265 } 266 267 static int 268 aq100x_autoneg_restart(struct cphy *phy) 269 { 270 return aq100x_autoneg_enable(phy); 271 } 272 273 static int 274 aq100x_advertise(struct cphy *phy, unsigned int advertise_map) 275 { 276 unsigned int adv; 277 int err; 278 279 /* 10G advertisement */ 280 adv = 0; 281 if (advertise_map & ADVERTISED_10000baseT_Full) 282 adv |= ADV_10G_FULL; 283 err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, AQ_10G_CTRL, 284 ADV_10G_FULL, adv); 285 if (err) 286 return (err); 287 288 /* 1G advertisement */ 289 adv = 0; 290 if (advertise_map & ADVERTISED_1000baseT_Full) 291 adv |= ADV_1G_FULL; 292 if (advertise_map & ADVERTISED_1000baseT_Half) 293 adv |= ADV_1G_HALF; 294 err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, AQ_1G_CTRL, 295 ADV_1G_FULL | ADV_1G_HALF, adv); 296 if (err) 297 return (err); 298 299 /* 100M, pause advertisement */ 300 adv = 0; 301 if (advertise_map & ADVERTISED_100baseT_Half) 302 adv |= ADVERTISE_100HALF; 303 if (advertise_map & ADVERTISED_100baseT_Full) 304 adv |= ADVERTISE_100FULL; 305 if (advertise_map & ADVERTISED_Pause) 306 adv |= ADVERTISE_PAUSE_CAP; 307 if (advertise_map & ADVERTISED_Asym_Pause) 308 adv |= ADVERTISE_PAUSE_ASYM; 309 err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, AQ_100M_CTRL, 0xfe0, adv); 310 311 return (err); 312 } 313 314 static int 315 aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable) 316 { 317 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 318 BMCR_LOOPBACK, enable ? BMCR_LOOPBACK : 0); 319 } 320 321 static int 322 aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex) 323 { 324 int err, set; 325 326 if (speed == SPEED_100) 327 set = BMCR_SPEED100; 328 else if (speed == SPEED_1000) 329 set = BMCR_SPEED1000; 330 else if (speed == SPEED_10000) 331 set = BMCR_SPEED1000 | BMCR_SPEED100; 332 else 333 return (EINVAL); 334 335 if (duplex != DUPLEX_FULL) 336 return (EINVAL); 337 338 err = t3_mdio_change_bits(phy, MDIO_DEV_ANEG, MII_BMCR, 339 BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART, 0); 340 if (err) 341 return (err); 342 343 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 344 BMCR_SPEED1000 | BMCR_SPEED100, set); 345 if (err) 346 return (err); 347 348 return (0); 349 } 350 351 static int 352 aq100x_get_link_status(struct cphy *phy, int *link_state, int *speed, int *duplex, 353 int *fc) 354 { 355 int err; 356 unsigned int v, link = 0; 357 358 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AQ_LINK_STAT, &v); 359 if (err) 360 return (err); 361 if (v == 0xffff || !(v & 1)) 362 goto done; 363 364 err = mdio_read(phy, MDIO_DEV_ANEG, MII_BMCR, &v); 365 if (err) 366 return (err); 367 if (v & 0x8000) 368 goto done; 369 if (v & BMCR_ANENABLE) { 370 371 err = mdio_read(phy, MDIO_DEV_ANEG, 1, &v); 372 if (err) 373 return (err); 374 if ((v & 0x20) == 0) 375 goto done; 376 377 err = mdio_read(phy, MDIO_DEV_ANEG, AQ_ANEG_STAT, &v); 378 if (err) 379 return (err); 380 381 if (speed) { 382 switch (v & 0x6) { 383 case 0x6: *speed = SPEED_10000; 384 break; 385 case 0x4: *speed = SPEED_1000; 386 break; 387 case 0x2: *speed = SPEED_100; 388 break; 389 case 0x0: *speed = SPEED_10; 390 break; 391 } 392 } 393 394 if (duplex) 395 *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF; 396 397 if (fc) { 398 unsigned int lpa, adv; 399 err = mdio_read(phy, MDIO_DEV_ANEG, 0x13, &lpa); 400 if (!err) 401 err = mdio_read(phy, MDIO_DEV_ANEG, 402 AQ_100M_CTRL, &adv); 403 if (err) 404 return err; 405 406 if (lpa & adv & ADVERTISE_PAUSE_CAP) 407 *fc = PAUSE_RX | PAUSE_TX; 408 else if (lpa & ADVERTISE_PAUSE_CAP && 409 lpa & ADVERTISE_PAUSE_ASYM && 410 adv & ADVERTISE_PAUSE_ASYM) 411 *fc = PAUSE_TX; 412 else if (lpa & ADVERTISE_PAUSE_ASYM && 413 adv & ADVERTISE_PAUSE_CAP) 414 *fc = PAUSE_RX; 415 else 416 *fc = 0; 417 } 418 419 } else { 420 err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); 421 if (err) 422 return (err); 423 424 v &= BMCR_SPEED1000 | BMCR_SPEED100; 425 if (speed) { 426 if (v == (BMCR_SPEED1000 | BMCR_SPEED100)) 427 *speed = SPEED_10000; 428 else if (v == BMCR_SPEED1000) 429 *speed = SPEED_1000; 430 else if (v == BMCR_SPEED100) 431 *speed = SPEED_100; 432 else 433 *speed = SPEED_10; 434 } 435 436 if (duplex) 437 *duplex = DUPLEX_FULL; 438 } 439 440 link = 1; 441 done: 442 if (link_state) 443 *link_state = link ? PHY_LINK_UP : PHY_LINK_DOWN; 444 return (0); 445 } 446 447 static struct cphy_ops aq100x_ops = { 448 .reset = aq100x_reset, 449 .intr_enable = aq100x_intr_enable, 450 .intr_disable = aq100x_intr_disable, 451 .intr_clear = aq100x_intr_clear, 452 .intr_handler = aq100x_intr_handler, 453 .autoneg_enable = aq100x_autoneg_enable, 454 .autoneg_restart = aq100x_autoneg_restart, 455 .advertise = aq100x_advertise, 456 .set_loopback = aq100x_set_loopback, 457 .set_speed_duplex = aq100x_set_speed_duplex, 458 .get_link_status = aq100x_get_link_status, 459 .power_down = aq100x_power_down, 460 }; 461 462 int 463 t3_aq100x_phy_prep(pinfo_t *pinfo, int phy_addr, 464 const struct mdio_ops *mdio_ops) 465 { 466 struct cphy *phy = &pinfo->phy; 467 unsigned int v, v2, gpio, wait; 468 int err; 469 adapter_t *adapter = pinfo->adapter; 470 471 cphy_init(&pinfo->phy, adapter, pinfo, phy_addr, &aq100x_ops, mdio_ops, 472 SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | 473 SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI | 474 SUPPORTED_MISC_IRQ, "1000/10GBASE-T"); 475 476 /* 477 * Hard reset the PHY. 478 */ 479 gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; 480 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); 481 msleep(1); 482 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); 483 484 /* 485 * Give it enough time to load the firmware and get ready for mdio. 486 */ 487 msleep(1000); 488 wait = 500; /* in 10ms increments */ 489 do { 490 err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); 491 if (err || v == 0xffff) { 492 493 /* Allow prep_adapter to succeed when ffff is read */ 494 495 CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", 496 phy_addr, err, v); 497 goto done; 498 } 499 500 v &= BMCR_RESET; 501 if (v) 502 msleep(10); 503 } while (v && --wait); 504 if (v) { 505 CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", 506 phy_addr, v); 507 508 goto done; /* let prep_adapter succeed */ 509 } 510 511 /* Firmware version check. */ 512 (void) mdio_read(phy, MDIO_DEV_VEND1, AQ_FW_VERSION, &v); 513 if (v < 0x115) 514 CH_WARN(adapter, "PHY%d: unknown firmware %d.%d\n", phy_addr, 515 v >> 8, v & 0xff); 516 517 /* The PHY should start in really-low-power mode. */ 518 (void) mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMCR, &v); 519 if ((v & BMCR_PDOWN) == 0) 520 CH_WARN(adapter, "PHY%d does not start in low power mode.\n", 521 phy_addr); 522 523 /* 524 * Verify XAUI and 1000-X settings, but let prep succeed no matter what. 525 */ 526 v = v2 = 0; 527 (void) mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_RX_CFG, &v); 528 (void) mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_TX_CFG, &v2); 529 if (v != 0x1b || v2 != 0x1b) 530 CH_WARN(adapter, "PHY%d: incorrect XAUI settings " 531 "(0x%x, 0x%x).\n", phy_addr, v, v2); 532 v = 0; 533 (void) mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_KX_CFG, &v); 534 if ((v & 0xf) != 0xf) 535 CH_WARN(adapter, "PHY%d: incorrect 1000-X settings " 536 "(0x%x).\n", phy_addr, v); 537 538 (void) aq100x_set_defaults(phy); 539 done: 540 return (err); 541 } 542