1 /*- 2 * Copyright (c) 2007-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include "efx.h" 35 #include "efx_impl.h" 36 #if EFSYS_OPT_FALCON 37 #include "falcon_nvram.h" 38 #endif 39 40 #if EFSYS_OPT_MAC_FALCON_XMAC 41 #include "falcon_xmac.h" 42 #endif 43 44 #if EFSYS_OPT_MAC_FALCON_GMAC 45 #include "falcon_gmac.h" 46 #endif 47 48 #if EFSYS_OPT_PHY_NULL 49 #include "nullphy.h" 50 #endif 51 52 #if EFSYS_OPT_PHY_QT2022C2 53 #include "qt2022c2.h" 54 #endif 55 56 #if EFSYS_OPT_PHY_SFX7101 57 #include "sfx7101.h" 58 #endif 59 60 #if EFSYS_OPT_PHY_TXC43128 61 #include "txc43128.h" 62 #endif 63 64 #if EFSYS_OPT_PHY_SFT9001 65 #include "sft9001.h" 66 #endif 67 68 #if EFSYS_OPT_PHY_QT2025C 69 #include "qt2025c.h" 70 #endif 71 72 #if EFSYS_OPT_PHY_NULL 73 static efx_phy_ops_t __efx_phy_null_ops = { 74 NULL, /* epo_power */ 75 nullphy_reset, /* epo_reset */ 76 nullphy_reconfigure, /* epo_reconfigure */ 77 nullphy_verify, /* epo_verify */ 78 NULL, /* epo_uplink_check */ 79 nullphy_downlink_check, /* epo_downlink_check */ 80 nullphy_oui_get, /* epo_oui_get */ 81 #if EFSYS_OPT_PHY_STATS 82 nullphy_stats_update, /* epo_stats_update */ 83 #endif /* EFSYS_OPT_PHY_STATS */ 84 #if EFSYS_OPT_PHY_PROPS 85 #if EFSYS_OPT_NAMES 86 nullphy_prop_name, /* epo_prop_name */ 87 #endif 88 nullphy_prop_get, /* epo_prop_get */ 89 nullphy_prop_set, /* epo_prop_set */ 90 #endif /* EFSYS_OPT_PHY_PROPS */ 91 #if EFSYS_OPT_BIST 92 NULL, /* epo_bist_enable_offline */ 93 NULL, /* epo_bist_start */ 94 NULL, /* epo_bist_poll */ 95 NULL, /* epo_bist_stop */ 96 #endif /* EFSYS_OPT_BIST */ 97 }; 98 #endif /* EFSYS_OPT_PHY_NULL */ 99 100 #if EFSYS_OPT_PHY_QT2022C2 101 static efx_phy_ops_t __efx_phy_qt2022c2_ops = { 102 NULL, /* epo_power */ 103 qt2022c2_reset, /* epo_reset */ 104 qt2022c2_reconfigure, /* epo_reconfigure */ 105 qt2022c2_verify, /* epo_verify */ 106 qt2022c2_uplink_check, /* epo_uplink_check */ 107 qt2022c2_downlink_check, /* epo_downlink_check */ 108 qt2022c2_oui_get, /* epo_oui_get */ 109 #if EFSYS_OPT_PHY_STATS 110 qt2022c2_stats_update, /* epo_stats_update */ 111 #endif /* EFSYS_OPT_PHY_STATS */ 112 #if EFSYS_OPT_PHY_PROPS 113 #if EFSYS_OPT_NAMES 114 qt2022c2_prop_name, /* epo_prop_name */ 115 #endif 116 qt2022c2_prop_get, /* epo_prop_get */ 117 qt2022c2_prop_set, /* epo_prop_set */ 118 #endif /* EFSYS_OPT_PHY_PROPS */ 119 #if EFSYS_OPT_BIST 120 NULL, /* epo_bist_enable_offline */ 121 NULL, /* epo_bist_start */ 122 NULL, /* epo_bist_poll */ 123 NULL, /* epo_bist_stop */ 124 #endif /* EFSYS_OPT_BIST */ 125 }; 126 #endif /* EFSYS_OPT_PHY_QT2022C2 */ 127 128 #if EFSYS_OPT_PHY_SFX7101 129 static efx_phy_ops_t __efx_phy_sfx7101_ops = { 130 sfx7101_power, /* epo_power */ 131 sfx7101_reset, /* epo_reset */ 132 sfx7101_reconfigure, /* epo_reconfigure */ 133 sfx7101_verify, /* epo_verify */ 134 sfx7101_uplink_check, /* epo_uplink_check */ 135 sfx7101_downlink_check, /* epo_downlink_check */ 136 sfx7101_oui_get, /* epo_oui_get */ 137 #if EFSYS_OPT_PHY_STATS 138 sfx7101_stats_update, /* epo_stats_update */ 139 #endif /* EFSYS_OPT_PHY_STATS */ 140 #if EFSYS_OPT_PHY_PROPS 141 #if EFSYS_OPT_NAMES 142 sfx7101_prop_name, /* epo_prop_name */ 143 #endif 144 sfx7101_prop_get, /* epo_prop_get */ 145 sfx7101_prop_set, /* epo_prop_set */ 146 #endif /* EFSYS_OPT_PHY_PROPS */ 147 #if EFSYS_OPT_BIST 148 NULL, /* epo_bist_enable_offline */ 149 NULL, /* epo_bist_start */ 150 NULL, /* epo_bist_poll */ 151 NULL, /* epo_bist_stop */ 152 #endif /* EFSYS_OPT_BIST */ 153 }; 154 #endif /* EFSYS_OPT_PHY_SFX7101 */ 155 156 #if EFSYS_OPT_PHY_TXC43128 157 static efx_phy_ops_t __efx_phy_txc43128_ops = { 158 NULL, /* epo_power */ 159 txc43128_reset, /* epo_reset */ 160 txc43128_reconfigure, /* epo_reconfigure */ 161 txc43128_verify, /* epo_verify */ 162 txc43128_uplink_check, /* epo_uplink_check */ 163 txc43128_downlink_check, /* epo_downlink_check */ 164 txc43128_oui_get, /* epo_oui_get */ 165 #if EFSYS_OPT_PHY_STATS 166 txc43128_stats_update, /* epo_stats_update */ 167 #endif /* EFSYS_OPT_PHY_STATS */ 168 #if EFSYS_OPT_PHY_PROPS 169 #if EFSYS_OPT_NAMES 170 txc43128_prop_name, /* epo_prop_name */ 171 #endif 172 txc43128_prop_get, /* epo_prop_get */ 173 txc43128_prop_set, /* epo_prop_set */ 174 #endif /* EFSYS_OPT_PHY_PROPS */ 175 #if EFSYS_OPT_BIST 176 NULL, /* epo_bist_enable_offline */ 177 NULL, /* epo_bist_start */ 178 NULL, /* epo_bist_poll */ 179 NULL, /* epo_bist_stop */ 180 #endif /* EFSYS_OPT_BIST */ 181 }; 182 #endif /* EFSYS_OPT_PHY_TXC43128 */ 183 184 #if EFSYS_OPT_PHY_SFT9001 185 static efx_phy_ops_t __efx_phy_sft9001_ops = { 186 NULL, /* epo_power */ 187 sft9001_reset, /* epo_reset */ 188 sft9001_reconfigure, /* epo_reconfigure */ 189 sft9001_verify, /* epo_verify */ 190 sft9001_uplink_check, /* epo_uplink_check */ 191 sft9001_downlink_check, /* epo_downlink_check */ 192 sft9001_oui_get, /* epo_oui_get */ 193 #if EFSYS_OPT_PHY_STATS 194 sft9001_stats_update, /* epo_stats_update */ 195 #endif /* EFSYS_OPT_PHY_STATS */ 196 #if EFSYS_OPT_PHY_PROPS 197 #if EFSYS_OPT_NAMES 198 sft9001_prop_name, /* epo_prop_name */ 199 #endif 200 sft9001_prop_get, /* epo_prop_get */ 201 sft9001_prop_set, /* epo_prop_set */ 202 #endif /* EFSYS_OPT_PHY_PROPS */ 203 #if EFSYS_OPT_BIST 204 NULL, /* epo_bist_enable_offline */ 205 sft9001_bist_start, /* epo_bist_start */ 206 sft9001_bist_poll, /* epo_bist_poll */ 207 sft9001_bist_stop, /* epo_bist_stop */ 208 #endif /* EFSYS_OPT_BIST */ 209 }; 210 #endif /* EFSYS_OPT_PHY_SFT9001 */ 211 212 #if EFSYS_OPT_PHY_QT2025C 213 static efx_phy_ops_t __efx_phy_qt2025c_ops = { 214 NULL, /* epo_power */ 215 qt2025c_reset, /* epo_reset */ 216 qt2025c_reconfigure, /* epo_reconfigure */ 217 qt2025c_verify, /* epo_verify */ 218 qt2025c_uplink_check, /* epo_uplink_check */ 219 qt2025c_downlink_check, /* epo_downlink_check */ 220 qt2025c_oui_get, /* epo_oui_get */ 221 #if EFSYS_OPT_PHY_STATS 222 qt2025c_stats_update, /* epo_stats_update */ 223 #endif /* EFSYS_OPT_PHY_STATS */ 224 #if EFSYS_OPT_PHY_PROPS 225 #if EFSYS_OPT_NAMES 226 qt2025c_prop_name, /* epo_prop_name */ 227 #endif 228 qt2025c_prop_get, /* epo_prop_get */ 229 qt2025c_prop_set, /* epo_prop_set */ 230 #endif /* EFSYS_OPT_PHY_PROPS */ 231 #if EFSYS_OPT_BIST 232 NULL, /* epo_bist_enable_offline */ 233 NULL, /* epo_bist_start */ 234 NULL, /* epo_bist_poll */ 235 NULL, /* epo_bist_stop */ 236 #endif /* EFSYS_OPT_BIST */ 237 }; 238 #endif /* EFSYS_OPT_PHY_QT2025C */ 239 240 #if EFSYS_OPT_SIENA 241 static efx_phy_ops_t __efx_phy_siena_ops = { 242 siena_phy_power, /* epo_power */ 243 NULL, /* epo_reset */ 244 siena_phy_reconfigure, /* epo_reconfigure */ 245 siena_phy_verify, /* epo_verify */ 246 NULL, /* epo_uplink_check */ 247 NULL, /* epo_downlink_check */ 248 siena_phy_oui_get, /* epo_oui_get */ 249 #if EFSYS_OPT_PHY_STATS 250 siena_phy_stats_update, /* epo_stats_update */ 251 #endif /* EFSYS_OPT_PHY_STATS */ 252 #if EFSYS_OPT_PHY_PROPS 253 #if EFSYS_OPT_NAMES 254 siena_phy_prop_name, /* epo_prop_name */ 255 #endif 256 siena_phy_prop_get, /* epo_prop_get */ 257 siena_phy_prop_set, /* epo_prop_set */ 258 #endif /* EFSYS_OPT_PHY_PROPS */ 259 #if EFSYS_OPT_BIST 260 NULL, /* epo_bist_enable_offline */ 261 siena_phy_bist_start, /* epo_bist_start */ 262 siena_phy_bist_poll, /* epo_bist_poll */ 263 siena_phy_bist_stop, /* epo_bist_stop */ 264 #endif /* EFSYS_OPT_BIST */ 265 }; 266 #endif /* EFSYS_OPT_SIENA */ 267 268 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 269 static efx_phy_ops_t __efx_phy_ef10_ops = { 270 ef10_phy_power, /* epo_power */ 271 NULL, /* epo_reset */ 272 ef10_phy_reconfigure, /* epo_reconfigure */ 273 ef10_phy_verify, /* epo_verify */ 274 NULL, /* epo_uplink_check */ 275 NULL, /* epo_downlink_check */ 276 ef10_phy_oui_get, /* epo_oui_get */ 277 #if EFSYS_OPT_PHY_STATS 278 ef10_phy_stats_update, /* epo_stats_update */ 279 #endif /* EFSYS_OPT_PHY_STATS */ 280 #if EFSYS_OPT_PHY_PROPS 281 #if EFSYS_OPT_NAMES 282 ef10_phy_prop_name, /* epo_prop_name */ 283 #endif 284 ef10_phy_prop_get, /* epo_prop_get */ 285 ef10_phy_prop_set, /* epo_prop_set */ 286 #endif /* EFSYS_OPT_PHY_PROPS */ 287 #if EFSYS_OPT_BIST 288 /* FIXME: Are these BIST methods appropriate for Medford? */ 289 hunt_bist_enable_offline, /* epo_bist_enable_offline */ 290 hunt_bist_start, /* epo_bist_start */ 291 hunt_bist_poll, /* epo_bist_poll */ 292 hunt_bist_stop, /* epo_bist_stop */ 293 #endif /* EFSYS_OPT_BIST */ 294 }; 295 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 296 297 __checkReturn efx_rc_t 298 efx_phy_probe( 299 __in efx_nic_t *enp) 300 { 301 efx_port_t *epp = &(enp->en_port); 302 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 303 efx_phy_ops_t *epop; 304 efx_rc_t rc; 305 306 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 307 308 epp->ep_port = encp->enc_port; 309 epp->ep_phy_type = encp->enc_phy_type; 310 311 /* Hook in operations structure */ 312 switch (enp->en_family) { 313 #if EFSYS_OPT_FALCON 314 case EFX_FAMILY_FALCON: 315 switch (epp->ep_phy_type) { 316 #if EFSYS_OPT_PHY_NULL 317 case PHY_TYPE_NONE_DECODE: 318 epop = (efx_phy_ops_t *)&__efx_phy_null_ops; 319 break; 320 #endif 321 #if EFSYS_OPT_PHY_QT2022C2 322 case PHY_TYPE_QT2022C2_DECODE: 323 epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops; 324 break; 325 #endif 326 #if EFSYS_OPT_PHY_SFX7101 327 case PHY_TYPE_SFX7101_DECODE: 328 epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops; 329 break; 330 #endif 331 #if EFSYS_OPT_PHY_TXC43128 332 case PHY_TYPE_TXC43128_DECODE: 333 epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops; 334 break; 335 #endif 336 #if EFSYS_OPT_PHY_SFT9001 337 case PHY_TYPE_SFT9001A_DECODE: 338 case PHY_TYPE_SFT9001B_DECODE: 339 epop = (efx_phy_ops_t *)&__efx_phy_sft9001_ops; 340 break; 341 #endif 342 #if EFSYS_OPT_PHY_QT2025C 343 case EFX_PHY_QT2025C: 344 epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops; 345 break; 346 #endif 347 default: 348 rc = ENOTSUP; 349 goto fail1; 350 } 351 break; 352 #endif /* EFSYS_OPT_FALCON */ 353 #if EFSYS_OPT_SIENA 354 case EFX_FAMILY_SIENA: 355 epop = (efx_phy_ops_t *)&__efx_phy_siena_ops; 356 break; 357 #endif /* EFSYS_OPT_SIENA */ 358 #if EFSYS_OPT_HUNTINGTON 359 case EFX_FAMILY_HUNTINGTON: 360 epop = (efx_phy_ops_t *)&__efx_phy_ef10_ops; 361 break; 362 #endif /* EFSYS_OPT_HUNTINGTON */ 363 #if EFSYS_OPT_MEDFORD 364 case EFX_FAMILY_MEDFORD: 365 epop = (efx_phy_ops_t *)&__efx_phy_ef10_ops; 366 break; 367 #endif /* EFSYS_OPT_MEDFORD */ 368 default: 369 rc = ENOTSUP; 370 goto fail1; 371 } 372 373 epp->ep_epop = epop; 374 375 return (0); 376 377 fail1: 378 EFSYS_PROBE1(fail1, efx_rc_t, rc); 379 380 epp->ep_port = 0; 381 epp->ep_phy_type = 0; 382 383 return (rc); 384 } 385 386 __checkReturn efx_rc_t 387 efx_phy_verify( 388 __in efx_nic_t *enp) 389 { 390 efx_port_t *epp = &(enp->en_port); 391 efx_phy_ops_t *epop = epp->ep_epop; 392 393 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 394 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 395 396 return (epop->epo_verify(enp)); 397 } 398 399 #if EFSYS_OPT_PHY_LED_CONTROL 400 401 __checkReturn efx_rc_t 402 efx_phy_led_set( 403 __in efx_nic_t *enp, 404 __in efx_phy_led_mode_t mode) 405 { 406 efx_nic_cfg_t *encp = (&enp->en_nic_cfg); 407 efx_port_t *epp = &(enp->en_port); 408 efx_phy_ops_t *epop = epp->ep_epop; 409 uint32_t mask; 410 efx_rc_t rc; 411 412 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 413 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 414 415 if (epp->ep_phy_led_mode == mode) 416 goto done; 417 418 mask = (1 << EFX_PHY_LED_DEFAULT); 419 mask |= encp->enc_led_mask; 420 421 if (!((1 << mode) & mask)) { 422 rc = ENOTSUP; 423 goto fail1; 424 } 425 426 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES); 427 epp->ep_phy_led_mode = mode; 428 429 if ((rc = epop->epo_reconfigure(enp)) != 0) 430 goto fail2; 431 432 done: 433 return (0); 434 435 fail2: 436 EFSYS_PROBE(fail2); 437 fail1: 438 EFSYS_PROBE1(fail1, efx_rc_t, rc); 439 440 return (rc); 441 } 442 #endif /* EFSYS_OPT_PHY_LED_CONTROL */ 443 444 void 445 efx_phy_adv_cap_get( 446 __in efx_nic_t *enp, 447 __in uint32_t flag, 448 __out uint32_t *maskp) 449 { 450 efx_port_t *epp = &(enp->en_port); 451 452 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 453 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 454 455 switch (flag) { 456 case EFX_PHY_CAP_CURRENT: 457 *maskp = epp->ep_adv_cap_mask; 458 break; 459 case EFX_PHY_CAP_DEFAULT: 460 *maskp = epp->ep_default_adv_cap_mask; 461 break; 462 case EFX_PHY_CAP_PERM: 463 *maskp = epp->ep_phy_cap_mask; 464 break; 465 default: 466 EFSYS_ASSERT(B_FALSE); 467 break; 468 } 469 } 470 471 __checkReturn efx_rc_t 472 efx_phy_adv_cap_set( 473 __in efx_nic_t *enp, 474 __in uint32_t mask) 475 { 476 efx_port_t *epp = &(enp->en_port); 477 efx_phy_ops_t *epop = epp->ep_epop; 478 uint32_t old_mask; 479 efx_rc_t rc; 480 481 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 482 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 483 484 if ((mask & ~epp->ep_phy_cap_mask) != 0) { 485 rc = ENOTSUP; 486 goto fail1; 487 } 488 489 if (epp->ep_adv_cap_mask == mask) 490 goto done; 491 492 old_mask = epp->ep_adv_cap_mask; 493 epp->ep_adv_cap_mask = mask; 494 495 if ((rc = epop->epo_reconfigure(enp)) != 0) 496 goto fail2; 497 498 done: 499 return (0); 500 501 fail2: 502 EFSYS_PROBE(fail2); 503 504 epp->ep_adv_cap_mask = old_mask; 505 /* Reconfigure for robustness */ 506 if (epop->epo_reconfigure(enp) != 0) { 507 /* 508 * We may have an inconsistent view of our advertised speed 509 * capabilities. 510 */ 511 EFSYS_ASSERT(0); 512 } 513 514 fail1: 515 EFSYS_PROBE1(fail1, efx_rc_t, rc); 516 517 return (rc); 518 } 519 520 void 521 efx_phy_lp_cap_get( 522 __in efx_nic_t *enp, 523 __out uint32_t *maskp) 524 { 525 efx_port_t *epp = &(enp->en_port); 526 527 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 528 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 529 530 *maskp = epp->ep_lp_cap_mask; 531 } 532 533 __checkReturn efx_rc_t 534 efx_phy_oui_get( 535 __in efx_nic_t *enp, 536 __out uint32_t *ouip) 537 { 538 efx_port_t *epp = &(enp->en_port); 539 efx_phy_ops_t *epop = epp->ep_epop; 540 541 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 542 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 543 544 return (epop->epo_oui_get(enp, ouip)); 545 } 546 547 void 548 efx_phy_media_type_get( 549 __in efx_nic_t *enp, 550 __out efx_phy_media_type_t *typep) 551 { 552 efx_port_t *epp = &(enp->en_port); 553 554 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 555 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 556 557 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID) 558 *typep = epp->ep_module_type; 559 else 560 *typep = epp->ep_fixed_port_type; 561 } 562 563 __checkReturn efx_rc_t 564 efx_phy_module_get_info( 565 __in efx_nic_t *enp, 566 __in uint8_t dev_addr, 567 __in uint8_t offset, 568 __in uint8_t len, 569 __out_bcount(len) uint8_t *data) 570 { 571 efx_rc_t rc; 572 573 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 574 EFSYS_ASSERT(data != NULL); 575 576 if ((uint32_t)offset + len > 0xff) { 577 rc = EINVAL; 578 goto fail1; 579 } 580 581 if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr, 582 offset, len, data)) != 0) 583 goto fail2; 584 585 return (0); 586 587 fail2: 588 EFSYS_PROBE(fail2); 589 fail1: 590 EFSYS_PROBE1(fail1, efx_rc_t, rc); 591 592 return (rc); 593 } 594 595 #if EFSYS_OPT_PHY_STATS 596 597 #if EFSYS_OPT_NAMES 598 599 /* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */ 600 static const char *__efx_phy_stat_name[] = { 601 "oui", 602 "pma_pmd_link_up", 603 "pma_pmd_rx_fault", 604 "pma_pmd_tx_fault", 605 "pma_pmd_rev_a", 606 "pma_pmd_rev_b", 607 "pma_pmd_rev_c", 608 "pma_pmd_rev_d", 609 "pcs_link_up", 610 "pcs_rx_fault", 611 "pcs_tx_fault", 612 "pcs_ber", 613 "pcs_block_errors", 614 "phy_xs_link_up", 615 "phy_xs_rx_fault", 616 "phy_xs_tx_fault", 617 "phy_xs_align", 618 "phy_xs_sync_a", 619 "phy_xs_sync_b", 620 "phy_xs_sync_c", 621 "phy_xs_sync_d", 622 "an_link_up", 623 "an_master", 624 "an_local_rx_ok", 625 "an_remote_rx_ok", 626 "cl22ext_link_up", 627 "snr_a", 628 "snr_b", 629 "snr_c", 630 "snr_d", 631 "pma_pmd_signal_a", 632 "pma_pmd_signal_b", 633 "pma_pmd_signal_c", 634 "pma_pmd_signal_d", 635 "an_complete", 636 "pma_pmd_rev_major", 637 "pma_pmd_rev_minor", 638 "pma_pmd_rev_micro", 639 "pcs_fw_version_0", 640 "pcs_fw_version_1", 641 "pcs_fw_version_2", 642 "pcs_fw_version_3", 643 "pcs_fw_build_yy", 644 "pcs_fw_build_mm", 645 "pcs_fw_build_dd", 646 "pcs_op_mode", 647 }; 648 649 /* END MKCONFIG GENERATED PhyStatNamesBlock */ 650 651 const char * 652 efx_phy_stat_name( 653 __in efx_nic_t *enp, 654 __in efx_phy_stat_t type) 655 { 656 _NOTE(ARGUNUSED(enp)) 657 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 658 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS); 659 660 return (__efx_phy_stat_name[type]); 661 } 662 663 #endif /* EFSYS_OPT_NAMES */ 664 665 __checkReturn efx_rc_t 666 efx_phy_stats_update( 667 __in efx_nic_t *enp, 668 __in efsys_mem_t *esmp, 669 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) 670 { 671 efx_port_t *epp = &(enp->en_port); 672 efx_phy_ops_t *epop = epp->ep_epop; 673 674 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 675 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 676 677 return (epop->epo_stats_update(enp, esmp, stat)); 678 } 679 680 #endif /* EFSYS_OPT_PHY_STATS */ 681 682 #if EFSYS_OPT_PHY_PROPS 683 684 #if EFSYS_OPT_NAMES 685 const char * 686 efx_phy_prop_name( 687 __in efx_nic_t *enp, 688 __in unsigned int id) 689 { 690 efx_port_t *epp = &(enp->en_port); 691 efx_phy_ops_t *epop = epp->ep_epop; 692 693 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 694 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 695 696 return (epop->epo_prop_name(enp, id)); 697 } 698 #endif /* EFSYS_OPT_NAMES */ 699 700 __checkReturn efx_rc_t 701 efx_phy_prop_get( 702 __in efx_nic_t *enp, 703 __in unsigned int id, 704 __in uint32_t flags, 705 __out uint32_t *valp) 706 { 707 efx_port_t *epp = &(enp->en_port); 708 efx_phy_ops_t *epop = epp->ep_epop; 709 710 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 711 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 712 713 return (epop->epo_prop_get(enp, id, flags, valp)); 714 } 715 716 __checkReturn efx_rc_t 717 efx_phy_prop_set( 718 __in efx_nic_t *enp, 719 __in unsigned int id, 720 __in uint32_t val) 721 { 722 efx_port_t *epp = &(enp->en_port); 723 efx_phy_ops_t *epop = epp->ep_epop; 724 725 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 726 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 727 728 return (epop->epo_prop_set(enp, id, val)); 729 } 730 #endif /* EFSYS_OPT_PHY_STATS */ 731 732 #if EFSYS_OPT_BIST 733 734 __checkReturn efx_rc_t 735 efx_bist_enable_offline( 736 __in efx_nic_t *enp) 737 { 738 efx_port_t *epp = &(enp->en_port); 739 efx_phy_ops_t *epop = epp->ep_epop; 740 efx_rc_t rc; 741 742 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 743 744 if (epop->epo_bist_enable_offline == NULL) { 745 rc = ENOTSUP; 746 goto fail1; 747 } 748 749 if ((rc = epop->epo_bist_enable_offline(enp)) != 0) 750 goto fail2; 751 752 return (0); 753 754 fail2: 755 EFSYS_PROBE(fail2); 756 fail1: 757 EFSYS_PROBE1(fail1, efx_rc_t, rc); 758 759 return (rc); 760 761 } 762 763 __checkReturn efx_rc_t 764 efx_bist_start( 765 __in efx_nic_t *enp, 766 __in efx_bist_type_t type) 767 { 768 efx_port_t *epp = &(enp->en_port); 769 efx_phy_ops_t *epop = epp->ep_epop; 770 efx_rc_t rc; 771 772 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 773 774 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN); 775 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES); 776 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN); 777 778 if (epop->epo_bist_start == NULL) { 779 rc = ENOTSUP; 780 goto fail1; 781 } 782 783 if ((rc = epop->epo_bist_start(enp, type)) != 0) 784 goto fail2; 785 786 epp->ep_current_bist = type; 787 788 return (0); 789 790 fail2: 791 EFSYS_PROBE(fail2); 792 fail1: 793 EFSYS_PROBE1(fail1, efx_rc_t, rc); 794 795 return (rc); 796 } 797 798 __checkReturn efx_rc_t 799 efx_bist_poll( 800 __in efx_nic_t *enp, 801 __in efx_bist_type_t type, 802 __out efx_bist_result_t *resultp, 803 __out_opt uint32_t *value_maskp, 804 __out_ecount_opt(count) unsigned long *valuesp, 805 __in size_t count) 806 { 807 efx_port_t *epp = &(enp->en_port); 808 efx_phy_ops_t *epop = epp->ep_epop; 809 efx_rc_t rc; 810 811 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 812 813 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN); 814 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES); 815 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); 816 817 EFSYS_ASSERT(epop->epo_bist_poll != NULL); 818 if (epop->epo_bist_poll == NULL) { 819 rc = ENOTSUP; 820 goto fail1; 821 } 822 823 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp, 824 valuesp, count)) != 0) 825 goto fail2; 826 827 return (0); 828 829 fail2: 830 EFSYS_PROBE(fail2); 831 fail1: 832 EFSYS_PROBE1(fail1, efx_rc_t, rc); 833 834 return (rc); 835 } 836 837 void 838 efx_bist_stop( 839 __in efx_nic_t *enp, 840 __in efx_bist_type_t type) 841 { 842 efx_port_t *epp = &(enp->en_port); 843 efx_phy_ops_t *epop = epp->ep_epop; 844 845 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 846 847 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN); 848 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES); 849 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); 850 851 EFSYS_ASSERT(epop->epo_bist_stop != NULL); 852 853 if (epop->epo_bist_stop != NULL) 854 epop->epo_bist_stop(enp, type); 855 856 epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN; 857 } 858 859 #endif /* EFSYS_OPT_BIST */ 860 void 861 efx_phy_unprobe( 862 __in efx_nic_t *enp) 863 { 864 efx_port_t *epp = &(enp->en_port); 865 866 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 867 868 epp->ep_epop = NULL; 869 870 epp->ep_adv_cap_mask = 0; 871 872 epp->ep_port = 0; 873 epp->ep_phy_type = 0; 874 } 875