1227569Sphilip/*- 2227569Sphilip * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved. 3227569Sphilip * 4227569Sphilip * Redistribution and use in source and binary forms, with or without 5227569Sphilip * modification, are permitted provided that the following conditions 6227569Sphilip * are met: 7227569Sphilip * 1. Redistributions of source code must retain the above copyright 8227569Sphilip * notice, this list of conditions and the following disclaimer. 9227569Sphilip * 2. Redistributions in binary form must reproduce the above copyright 10227569Sphilip * notice, this list of conditions and the following disclaimer in the 11227569Sphilip * documentation and/or other materials provided with the distribution. 12227569Sphilip * 13227569Sphilip * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14227569Sphilip * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15227569Sphilip * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16227569Sphilip * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17227569Sphilip * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18227569Sphilip * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19227569Sphilip * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20227569Sphilip * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21227569Sphilip * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22227569Sphilip * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23227569Sphilip * SUCH DAMAGE. 24227569Sphilip */ 25227569Sphilip 26228100Sphilip#include <sys/cdefs.h> 27228100Sphilip__FBSDID("$FreeBSD$"); 28228100Sphilip 29227569Sphilip#include "efsys.h" 30227569Sphilip#include "efx.h" 31227569Sphilip#include "efx_types.h" 32227569Sphilip#include "efx_regs.h" 33227569Sphilip#include "efx_impl.h" 34227569Sphilip#if EFSYS_OPT_FALCON 35227569Sphilip#include "falcon_nvram.h" 36227569Sphilip#endif 37227569Sphilip 38227569Sphilip#if EFSYS_OPT_MAC_FALCON_XMAC 39227569Sphilip#include "falcon_xmac.h" 40227569Sphilip#endif 41227569Sphilip 42227569Sphilip#if EFSYS_OPT_MAC_FALCON_GMAC 43227569Sphilip#include "falcon_gmac.h" 44227569Sphilip#endif 45227569Sphilip 46227569Sphilip#if EFSYS_OPT_PHY_NULL 47227569Sphilip#include "nullphy.h" 48227569Sphilip#endif 49227569Sphilip 50227569Sphilip#if EFSYS_OPT_PHY_QT2022C2 51227569Sphilip#include "qt2022c2.h" 52227569Sphilip#endif 53227569Sphilip 54227569Sphilip#if EFSYS_OPT_PHY_SFX7101 55227569Sphilip#include "sfx7101.h" 56227569Sphilip#endif 57227569Sphilip 58227569Sphilip#if EFSYS_OPT_PHY_TXC43128 59227569Sphilip#include "txc43128.h" 60227569Sphilip#endif 61227569Sphilip 62227569Sphilip#if EFSYS_OPT_PHY_SFT9001 63227569Sphilip#include "sft9001.h" 64227569Sphilip#endif 65227569Sphilip 66227569Sphilip#if EFSYS_OPT_PHY_QT2025C 67227569Sphilip#include "qt2025c.h" 68227569Sphilip#endif 69227569Sphilip 70227569Sphilip#if EFSYS_OPT_PHY_NULL 71227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_null_ops = { 72227569Sphilip NULL, /* epo_power */ 73227569Sphilip nullphy_reset, /* epo_reset */ 74227569Sphilip nullphy_reconfigure, /* epo_reconfigure */ 75227569Sphilip nullphy_verify, /* epo_verify */ 76227569Sphilip NULL, /* epo_uplink_check */ 77227569Sphilip nullphy_downlink_check, /* epo_downlink_check */ 78227569Sphilip nullphy_oui_get, /* epo_oui_get */ 79227569Sphilip#if EFSYS_OPT_PHY_STATS 80227569Sphilip nullphy_stats_update, /* epo_stats_update */ 81227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 82227569Sphilip#if EFSYS_OPT_PHY_PROPS 83227569Sphilip#if EFSYS_OPT_NAMES 84227569Sphilip nullphy_prop_name, /* epo_prop_name */ 85227569Sphilip#endif 86227569Sphilip nullphy_prop_get, /* epo_prop_get */ 87227569Sphilip nullphy_prop_set, /* epo_prop_set */ 88227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 89227569Sphilip#if EFSYS_OPT_PHY_BIST 90227569Sphilip NULL, /* epo_bist_start */ 91227569Sphilip NULL, /* epo_bist_poll */ 92227569Sphilip NULL, /* epo_bist_stop */ 93227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 94227569Sphilip}; 95227569Sphilip#endif /* EFSYS_OPT_PHY_NULL */ 96227569Sphilip 97227569Sphilip#if EFSYS_OPT_PHY_QT2022C2 98227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = { 99227569Sphilip NULL, /* epo_power */ 100227569Sphilip qt2022c2_reset, /* epo_reset */ 101227569Sphilip qt2022c2_reconfigure, /* epo_reconfigure */ 102227569Sphilip qt2022c2_verify, /* epo_verify */ 103227569Sphilip qt2022c2_uplink_check, /* epo_uplink_check */ 104227569Sphilip qt2022c2_downlink_check, /* epo_downlink_check */ 105227569Sphilip qt2022c2_oui_get, /* epo_oui_get */ 106227569Sphilip#if EFSYS_OPT_PHY_STATS 107227569Sphilip qt2022c2_stats_update, /* epo_stats_update */ 108227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 109227569Sphilip#if EFSYS_OPT_PHY_PROPS 110227569Sphilip#if EFSYS_OPT_NAMES 111227569Sphilip qt2022c2_prop_name, /* epo_prop_name */ 112227569Sphilip#endif 113227569Sphilip qt2022c2_prop_get, /* epo_prop_get */ 114227569Sphilip qt2022c2_prop_set, /* epo_prop_set */ 115227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 116227569Sphilip#if EFSYS_OPT_PHY_BIST 117227569Sphilip NULL, /* epo_bist_start */ 118227569Sphilip NULL, /* epo_bist_poll */ 119227569Sphilip NULL, /* epo_bist_stop */ 120227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 121227569Sphilip}; 122227569Sphilip#endif /* EFSYS_OPT_PHY_QT2022C2 */ 123227569Sphilip 124227569Sphilip#if EFSYS_OPT_PHY_SFX7101 125227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_sfx7101_ops = { 126227569Sphilip sfx7101_power, /* epo_power */ 127227569Sphilip sfx7101_reset, /* epo_reset */ 128227569Sphilip sfx7101_reconfigure, /* epo_reconfigure */ 129227569Sphilip sfx7101_verify, /* epo_verify */ 130227569Sphilip sfx7101_uplink_check, /* epo_uplink_check */ 131227569Sphilip sfx7101_downlink_check, /* epo_downlink_check */ 132227569Sphilip sfx7101_oui_get, /* epo_oui_get */ 133227569Sphilip#if EFSYS_OPT_PHY_STATS 134227569Sphilip sfx7101_stats_update, /* epo_stats_update */ 135227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 136227569Sphilip#if EFSYS_OPT_PHY_PROPS 137227569Sphilip#if EFSYS_OPT_NAMES 138227569Sphilip sfx7101_prop_name, /* epo_prop_name */ 139227569Sphilip#endif 140227569Sphilip sfx7101_prop_get, /* epo_prop_get */ 141227569Sphilip sfx7101_prop_set, /* epo_prop_set */ 142227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 143227569Sphilip#if EFSYS_OPT_PHY_BIST 144227569Sphilip NULL, /* epo_bist_start */ 145227569Sphilip NULL, /* epo_bist_poll */ 146227569Sphilip NULL, /* epo_bist_stop */ 147227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 148227569Sphilip}; 149227569Sphilip#endif /* EFSYS_OPT_PHY_SFX7101 */ 150227569Sphilip 151227569Sphilip#if EFSYS_OPT_PHY_TXC43128 152227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_txc43128_ops = { 153227569Sphilip NULL, /* epo_power */ 154227569Sphilip txc43128_reset, /* epo_reset */ 155227569Sphilip txc43128_reconfigure, /* epo_reconfigure */ 156227569Sphilip txc43128_verify, /* epo_verify */ 157227569Sphilip txc43128_uplink_check, /* epo_uplink_check */ 158227569Sphilip txc43128_downlink_check, /* epo_downlink_check */ 159227569Sphilip txc43128_oui_get, /* epo_oui_get */ 160227569Sphilip#if EFSYS_OPT_PHY_STATS 161227569Sphilip txc43128_stats_update, /* epo_stats_update */ 162227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 163227569Sphilip#if EFSYS_OPT_PHY_PROPS 164227569Sphilip#if EFSYS_OPT_NAMES 165227569Sphilip txc43128_prop_name, /* epo_prop_name */ 166227569Sphilip#endif 167227569Sphilip txc43128_prop_get, /* epo_prop_get */ 168227569Sphilip txc43128_prop_set, /* epo_prop_set */ 169227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 170227569Sphilip#if EFSYS_OPT_PHY_BIST 171227569Sphilip NULL, /* epo_bist_start */ 172227569Sphilip NULL, /* epo_bist_poll */ 173227569Sphilip NULL, /* epo_bist_stop */ 174227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 175227569Sphilip}; 176227569Sphilip#endif /* EFSYS_OPT_PHY_TXC43128 */ 177227569Sphilip 178227569Sphilip#if EFSYS_OPT_PHY_SFT9001 179227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_sft9001_ops = { 180227569Sphilip NULL, /* epo_power */ 181227569Sphilip sft9001_reset, /* epo_reset */ 182227569Sphilip sft9001_reconfigure, /* epo_reconfigure */ 183227569Sphilip sft9001_verify, /* epo_verify */ 184227569Sphilip sft9001_uplink_check, /* epo_uplink_check */ 185227569Sphilip sft9001_downlink_check, /* epo_downlink_check */ 186227569Sphilip sft9001_oui_get, /* epo_oui_get */ 187227569Sphilip#if EFSYS_OPT_PHY_STATS 188227569Sphilip sft9001_stats_update, /* epo_stats_update */ 189227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 190227569Sphilip#if EFSYS_OPT_PHY_PROPS 191227569Sphilip#if EFSYS_OPT_NAMES 192227569Sphilip sft9001_prop_name, /* epo_prop_name */ 193227569Sphilip#endif 194227569Sphilip sft9001_prop_get, /* epo_prop_get */ 195227569Sphilip sft9001_prop_set, /* epo_prop_set */ 196227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 197227569Sphilip#if EFSYS_OPT_PHY_BIST 198227569Sphilip sft9001_bist_start, /* epo_bist_start */ 199227569Sphilip sft9001_bist_poll, /* epo_bist_poll */ 200227569Sphilip sft9001_bist_stop, /* epo_bist_stop */ 201227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 202227569Sphilip}; 203227569Sphilip#endif /* EFSYS_OPT_PHY_SFT9001 */ 204227569Sphilip 205227569Sphilip#if EFSYS_OPT_PHY_QT2025C 206227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_qt2025c_ops = { 207227569Sphilip NULL, /* epo_power */ 208227569Sphilip qt2025c_reset, /* epo_reset */ 209227569Sphilip qt2025c_reconfigure, /* epo_reconfigure */ 210227569Sphilip qt2025c_verify, /* epo_verify */ 211227569Sphilip qt2025c_uplink_check, /* epo_uplink_check */ 212227569Sphilip qt2025c_downlink_check, /* epo_downlink_check */ 213227569Sphilip qt2025c_oui_get, /* epo_oui_get */ 214227569Sphilip#if EFSYS_OPT_PHY_STATS 215227569Sphilip qt2025c_stats_update, /* epo_stats_update */ 216227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 217227569Sphilip#if EFSYS_OPT_PHY_PROPS 218227569Sphilip#if EFSYS_OPT_NAMES 219227569Sphilip qt2025c_prop_name, /* epo_prop_name */ 220227569Sphilip#endif 221227569Sphilip qt2025c_prop_get, /* epo_prop_get */ 222227569Sphilip qt2025c_prop_set, /* epo_prop_set */ 223227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 224227569Sphilip#if EFSYS_OPT_PHY_BIST 225227569Sphilip NULL, /* epo_bist_start */ 226227569Sphilip NULL, /* epo_bist_poll */ 227227569Sphilip NULL, /* epo_bist_stop */ 228227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 229227569Sphilip}; 230227569Sphilip#endif /* EFSYS_OPT_PHY_QT2025C */ 231227569Sphilip 232227569Sphilip#if EFSYS_OPT_SIENA 233227569Sphilipstatic efx_phy_ops_t __cs __efx_phy_siena_ops = { 234227569Sphilip siena_phy_power, /* epo_power */ 235227569Sphilip NULL, /* epo_reset */ 236227569Sphilip siena_phy_reconfigure, /* epo_reconfigure */ 237227569Sphilip siena_phy_verify, /* epo_verify */ 238227569Sphilip NULL, /* epo_uplink_check */ 239227569Sphilip NULL, /* epo_downlink_check */ 240227569Sphilip siena_phy_oui_get, /* epo_oui_get */ 241227569Sphilip#if EFSYS_OPT_PHY_STATS 242227569Sphilip siena_phy_stats_update, /* epo_stats_update */ 243227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 244227569Sphilip#if EFSYS_OPT_PHY_PROPS 245227569Sphilip#if EFSYS_OPT_NAMES 246227569Sphilip siena_phy_prop_name, /* epo_prop_name */ 247227569Sphilip#endif 248227569Sphilip siena_phy_prop_get, /* epo_prop_get */ 249227569Sphilip siena_phy_prop_set, /* epo_prop_set */ 250227569Sphilip#endif /* EFSYS_OPT_PHY_PROPS */ 251227569Sphilip#if EFSYS_OPT_PHY_BIST 252227569Sphilip siena_phy_bist_start, /* epo_bist_start */ 253227569Sphilip siena_phy_bist_poll, /* epo_bist_poll */ 254227569Sphilip siena_phy_bist_stop, /* epo_bist_stop */ 255227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 256227569Sphilip}; 257227569Sphilip#endif /* EFSYS_OPT_SIENA */ 258227569Sphilip 259227569Sphilip __checkReturn int 260227569Sphilipefx_phy_probe( 261227569Sphilip __in efx_nic_t *enp) 262227569Sphilip{ 263227569Sphilip efx_port_t *epp = &(enp->en_port); 264227569Sphilip efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 265227569Sphilip efx_phy_ops_t *epop; 266227569Sphilip int rc; 267227569Sphilip 268227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 269227569Sphilip 270227569Sphilip epp->ep_port = encp->enc_port; 271227569Sphilip epp->ep_phy_type = encp->enc_phy_type; 272227569Sphilip 273227569Sphilip /* Hook in operations structure */ 274227569Sphilip switch (enp->en_family) { 275227569Sphilip#if EFSYS_OPT_FALCON 276227569Sphilip case EFX_FAMILY_FALCON: 277227569Sphilip switch (epp->ep_phy_type) { 278227569Sphilip#if EFSYS_OPT_PHY_NULL 279227569Sphilip case PHY_TYPE_NONE_DECODE: 280227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_null_ops; 281227569Sphilip break; 282227569Sphilip#endif 283227569Sphilip#if EFSYS_OPT_PHY_QT2022C2 284227569Sphilip case PHY_TYPE_QT2022C2_DECODE: 285227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops; 286227569Sphilip break; 287227569Sphilip#endif 288227569Sphilip#if EFSYS_OPT_PHY_SFX7101 289227569Sphilip case PHY_TYPE_SFX7101_DECODE: 290227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops; 291227569Sphilip break; 292227569Sphilip#endif 293227569Sphilip#if EFSYS_OPT_PHY_TXC43128 294227569Sphilip case PHY_TYPE_TXC43128_DECODE: 295227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops; 296227569Sphilip break; 297227569Sphilip#endif 298227569Sphilip#if EFSYS_OPT_PHY_SFT9001 299227569Sphilip case PHY_TYPE_SFT9001A_DECODE: 300227569Sphilip case PHY_TYPE_SFT9001B_DECODE: 301227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_sft9001_ops; 302227569Sphilip break; 303227569Sphilip#endif 304227569Sphilip#if EFSYS_OPT_PHY_QT2025C 305227569Sphilip case EFX_PHY_QT2025C: 306227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops; 307227569Sphilip break; 308227569Sphilip#endif 309227569Sphilip default: 310227569Sphilip rc = ENOTSUP; 311227569Sphilip goto fail1; 312227569Sphilip } 313227569Sphilip break; 314227569Sphilip#endif /* EFSYS_OPT_FALCON */ 315227569Sphilip#if EFSYS_OPT_SIENA 316227569Sphilip case EFX_FAMILY_SIENA: 317227569Sphilip epop = (efx_phy_ops_t *)&__efx_phy_siena_ops; 318227569Sphilip break; 319227569Sphilip#endif /* EFSYS_OPT_SIENA */ 320227569Sphilip default: 321227569Sphilip rc = ENOTSUP; 322227569Sphilip goto fail1; 323227569Sphilip } 324227569Sphilip 325227569Sphilip epp->ep_epop = epop; 326227569Sphilip 327227569Sphilip return (0); 328227569Sphilip 329227569Sphilipfail1: 330227569Sphilip EFSYS_PROBE1(fail1, int, rc); 331227569Sphilip 332227569Sphilip epp->ep_port = 0; 333227569Sphilip epp->ep_phy_type = 0; 334227569Sphilip 335227569Sphilip return (rc); 336227569Sphilip} 337227569Sphilip 338227569Sphilip __checkReturn int 339227569Sphilipefx_phy_verify( 340227569Sphilip __in efx_nic_t *enp) 341227569Sphilip{ 342227569Sphilip efx_port_t *epp = &(enp->en_port); 343227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 344227569Sphilip 345227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 346227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 347227569Sphilip 348227569Sphilip return (epop->epo_verify(enp)); 349227569Sphilip} 350227569Sphilip 351227569Sphilip#if EFSYS_OPT_PHY_LED_CONTROL 352227569Sphilip 353227569Sphilip __checkReturn int 354227569Sphilipefx_phy_led_set( 355227569Sphilip __in efx_nic_t *enp, 356227569Sphilip __in efx_phy_led_mode_t mode) 357227569Sphilip{ 358227569Sphilip efx_nic_cfg_t *encp = (&enp->en_nic_cfg); 359227569Sphilip efx_port_t *epp = &(enp->en_port); 360227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 361227569Sphilip uint32_t mask; 362227569Sphilip int rc; 363227569Sphilip 364227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 365227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 366227569Sphilip 367227569Sphilip if (epp->ep_phy_led_mode == mode) 368227569Sphilip goto done; 369227569Sphilip 370227569Sphilip mask = (1 << EFX_PHY_LED_DEFAULT); 371227569Sphilip mask |= encp->enc_led_mask; 372227569Sphilip 373227569Sphilip if (!((1 << mode) & mask)) { 374227569Sphilip rc = ENOTSUP; 375227569Sphilip goto fail1; 376227569Sphilip } 377227569Sphilip 378227569Sphilip EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES); 379227569Sphilip epp->ep_phy_led_mode = mode; 380227569Sphilip 381227569Sphilip if ((rc = epop->epo_reconfigure(enp)) != 0) 382227569Sphilip goto fail2; 383227569Sphilip 384227569Sphilipdone: 385227569Sphilip return (0); 386227569Sphilip 387227569Sphilipfail2: 388227569Sphilip EFSYS_PROBE(fail2); 389227569Sphilipfail1: 390227569Sphilip EFSYS_PROBE1(fail1, int, rc); 391227569Sphilip 392227569Sphilip return (rc); 393227569Sphilip} 394227569Sphilip#endif /* EFSYS_OPT_PHY_LED_CONTROL */ 395227569Sphilip 396227569Sphilip void 397227569Sphilipefx_phy_adv_cap_get( 398227569Sphilip __in efx_nic_t *enp, 399227569Sphilip __in uint32_t flag, 400227569Sphilip __out uint32_t *maskp) 401227569Sphilip{ 402227569Sphilip efx_port_t *epp = &(enp->en_port); 403227569Sphilip 404227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 405227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 406227569Sphilip 407227569Sphilip switch (flag) { 408227569Sphilip case EFX_PHY_CAP_CURRENT: 409227569Sphilip *maskp = epp->ep_adv_cap_mask; 410227569Sphilip break; 411227569Sphilip case EFX_PHY_CAP_DEFAULT: 412227569Sphilip *maskp = epp->ep_default_adv_cap_mask; 413227569Sphilip break; 414227569Sphilip case EFX_PHY_CAP_PERM: 415227569Sphilip *maskp = epp->ep_phy_cap_mask; 416227569Sphilip break; 417227569Sphilip default: 418227569Sphilip EFSYS_ASSERT(B_FALSE); 419227569Sphilip break; 420227569Sphilip } 421227569Sphilip} 422227569Sphilip 423227569Sphilip __checkReturn int 424227569Sphilipefx_phy_adv_cap_set( 425227569Sphilip __in efx_nic_t *enp, 426227569Sphilip __in uint32_t mask) 427227569Sphilip{ 428227569Sphilip efx_port_t *epp = &(enp->en_port); 429227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 430227569Sphilip int rc; 431227569Sphilip 432227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 433227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 434227569Sphilip 435227569Sphilip if ((mask & ~epp->ep_phy_cap_mask) != 0) { 436227569Sphilip rc = ENOTSUP; 437227569Sphilip goto fail1; 438227569Sphilip } 439227569Sphilip 440227569Sphilip if (epp->ep_adv_cap_mask == mask) 441227569Sphilip goto done; 442227569Sphilip 443227569Sphilip epp->ep_adv_cap_mask = mask; 444227569Sphilip 445227569Sphilip if ((rc = epop->epo_reconfigure(enp)) != 0) 446227569Sphilip goto fail2; 447227569Sphilip 448227569Sphilipdone: 449227569Sphilip return (0); 450227569Sphilip 451227569Sphilipfail2: 452227569Sphilip EFSYS_PROBE(fail2); 453227569Sphilipfail1: 454227569Sphilip EFSYS_PROBE1(fail1, int, rc); 455227569Sphilip 456227569Sphilip return (rc); 457227569Sphilip} 458227569Sphilip 459227569Sphilip void 460227569Sphilipefx_phy_lp_cap_get( 461227569Sphilip __in efx_nic_t *enp, 462227569Sphilip __out uint32_t *maskp) 463227569Sphilip{ 464227569Sphilip efx_port_t *epp = &(enp->en_port); 465227569Sphilip 466227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 467227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 468227569Sphilip 469227569Sphilip *maskp = epp->ep_lp_cap_mask; 470227569Sphilip} 471227569Sphilip 472227569Sphilip __checkReturn int 473227569Sphilipefx_phy_oui_get( 474227569Sphilip __in efx_nic_t *enp, 475227569Sphilip __out uint32_t *ouip) 476227569Sphilip{ 477227569Sphilip efx_port_t *epp = &(enp->en_port); 478227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 479227569Sphilip 480227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 481227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 482227569Sphilip 483227569Sphilip return (epop->epo_oui_get(enp, ouip)); 484227569Sphilip} 485227569Sphilip 486227569Sphilip void 487227569Sphilipefx_phy_media_type_get( 488227569Sphilip __in efx_nic_t *enp, 489227569Sphilip __out efx_phy_media_type_t *typep) 490227569Sphilip{ 491227569Sphilip efx_port_t *epp = &(enp->en_port); 492227569Sphilip 493227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 494227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 495227569Sphilip 496227569Sphilip if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID) 497227569Sphilip *typep = epp->ep_module_type; 498227569Sphilip else 499227569Sphilip *typep = epp->ep_fixed_port_type; 500227569Sphilip} 501227569Sphilip 502227569Sphilip#if EFSYS_OPT_PHY_STATS 503227569Sphilip 504227569Sphilip#if EFSYS_OPT_NAMES 505227569Sphilip 506227569Sphilip/* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */ 507227569Sphilipstatic const char __cs * __cs __efx_phy_stat_name[] = { 508227569Sphilip "oui", 509227569Sphilip "pma_pmd_link_up", 510227569Sphilip "pma_pmd_rx_fault", 511227569Sphilip "pma_pmd_tx_fault", 512227569Sphilip "pma_pmd_rev_a", 513227569Sphilip "pma_pmd_rev_b", 514227569Sphilip "pma_pmd_rev_c", 515227569Sphilip "pma_pmd_rev_d", 516227569Sphilip "pcs_link_up", 517227569Sphilip "pcs_rx_fault", 518227569Sphilip "pcs_tx_fault", 519227569Sphilip "pcs_ber", 520227569Sphilip "pcs_block_errors", 521227569Sphilip "phy_xs_link_up", 522227569Sphilip "phy_xs_rx_fault", 523227569Sphilip "phy_xs_tx_fault", 524227569Sphilip "phy_xs_align", 525227569Sphilip "phy_xs_sync_a", 526227569Sphilip "phy_xs_sync_b", 527227569Sphilip "phy_xs_sync_c", 528227569Sphilip "phy_xs_sync_d", 529227569Sphilip "an_link_up", 530227569Sphilip "an_master", 531227569Sphilip "an_local_rx_ok", 532227569Sphilip "an_remote_rx_ok", 533227569Sphilip "cl22ext_link_up", 534227569Sphilip "snr_a", 535227569Sphilip "snr_b", 536227569Sphilip "snr_c", 537227569Sphilip "snr_d", 538227569Sphilip "pma_pmd_signal_a", 539227569Sphilip "pma_pmd_signal_b", 540227569Sphilip "pma_pmd_signal_c", 541227569Sphilip "pma_pmd_signal_d", 542227569Sphilip "an_complete", 543227569Sphilip "pma_pmd_rev_major", 544227569Sphilip "pma_pmd_rev_minor", 545227569Sphilip "pma_pmd_rev_micro", 546227569Sphilip "pcs_fw_version_0", 547227569Sphilip "pcs_fw_version_1", 548227569Sphilip "pcs_fw_version_2", 549227569Sphilip "pcs_fw_version_3", 550227569Sphilip "pcs_fw_build_yy", 551227569Sphilip "pcs_fw_build_mm", 552227569Sphilip "pcs_fw_build_dd", 553227569Sphilip "pcs_op_mode", 554227569Sphilip}; 555227569Sphilip 556227569Sphilip/* END MKCONFIG GENERATED PhyStatNamesBlock */ 557227569Sphilip 558227569Sphilip const char __cs * 559227569Sphilipefx_phy_stat_name( 560227569Sphilip __in efx_nic_t *enp, 561227569Sphilip __in efx_phy_stat_t type) 562227569Sphilip{ 563227569Sphilip _NOTE(ARGUNUSED(enp)) 564227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 565227569Sphilip EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS); 566227569Sphilip 567227569Sphilip return (__efx_phy_stat_name[type]); 568227569Sphilip} 569227569Sphilip 570227569Sphilip#endif /* EFSYS_OPT_NAMES */ 571227569Sphilip 572227569Sphilip __checkReturn int 573227569Sphilipefx_phy_stats_update( 574227569Sphilip __in efx_nic_t *enp, 575227569Sphilip __in efsys_mem_t *esmp, 576227569Sphilip __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) 577227569Sphilip{ 578227569Sphilip efx_port_t *epp = &(enp->en_port); 579227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 580227569Sphilip 581227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 582227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 583227569Sphilip 584227569Sphilip return (epop->epo_stats_update(enp, esmp, stat)); 585227569Sphilip} 586227569Sphilip 587227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 588227569Sphilip 589227569Sphilip#if EFSYS_OPT_PHY_PROPS 590227569Sphilip 591227569Sphilip#if EFSYS_OPT_NAMES 592227569Sphilip const char __cs * 593227569Sphilipefx_phy_prop_name( 594227569Sphilip __in efx_nic_t *enp, 595227569Sphilip __in unsigned int id) 596227569Sphilip{ 597227569Sphilip efx_port_t *epp = &(enp->en_port); 598227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 599227569Sphilip 600227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 601227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 602227569Sphilip 603227569Sphilip return (epop->epo_prop_name(enp, id)); 604227569Sphilip} 605227569Sphilip#endif /* EFSYS_OPT_NAMES */ 606227569Sphilip 607227569Sphilip __checkReturn int 608227569Sphilipefx_phy_prop_get( 609227569Sphilip __in efx_nic_t *enp, 610227569Sphilip __in unsigned int id, 611227569Sphilip __in uint32_t flags, 612227569Sphilip __out uint32_t *valp) 613227569Sphilip{ 614227569Sphilip efx_port_t *epp = &(enp->en_port); 615227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 616227569Sphilip 617227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 618227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 619227569Sphilip 620227569Sphilip return (epop->epo_prop_get(enp, id, flags, valp)); 621227569Sphilip} 622227569Sphilip 623227569Sphilip __checkReturn int 624227569Sphilipefx_phy_prop_set( 625227569Sphilip __in efx_nic_t *enp, 626227569Sphilip __in unsigned int id, 627227569Sphilip __in uint32_t val) 628227569Sphilip{ 629227569Sphilip efx_port_t *epp = &(enp->en_port); 630227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 631227569Sphilip 632227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 633227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 634227569Sphilip 635227569Sphilip return (epop->epo_prop_set(enp, id, val)); 636227569Sphilip} 637227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 638227569Sphilip 639227569Sphilip#if EFSYS_OPT_PHY_BIST 640227569Sphilip 641227569Sphilip __checkReturn int 642227569Sphilipefx_phy_bist_start( 643227569Sphilip __in efx_nic_t *enp, 644227569Sphilip __in efx_phy_bist_type_t type) 645227569Sphilip{ 646227569Sphilip efx_port_t *epp = &(enp->en_port); 647227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 648227569Sphilip int rc; 649227569Sphilip 650227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 651227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 652227569Sphilip 653227569Sphilip EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN); 654227569Sphilip EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES); 655227569Sphilip EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN); 656227569Sphilip 657227569Sphilip if (epop->epo_bist_start == NULL) { 658227569Sphilip rc = ENOTSUP; 659227569Sphilip goto fail1; 660227569Sphilip } 661227569Sphilip 662227569Sphilip if ((rc = epop->epo_bist_start(enp, type)) != 0) 663227569Sphilip goto fail2; 664227569Sphilip 665227569Sphilip epp->ep_current_bist = type; 666227569Sphilip 667227569Sphilip return (0); 668227569Sphilip 669227569Sphilipfail2: 670227569Sphilip EFSYS_PROBE(fail2); 671227569Sphilipfail1: 672227569Sphilip EFSYS_PROBE1(fail1, int, rc); 673227569Sphilip 674227569Sphilip return (rc); 675227569Sphilip} 676227569Sphilip 677227569Sphilip __checkReturn int 678227569Sphilipefx_phy_bist_poll( 679227569Sphilip __in efx_nic_t *enp, 680227569Sphilip __in efx_phy_bist_type_t type, 681227569Sphilip __out efx_phy_bist_result_t *resultp, 682227569Sphilip __out_opt uint32_t *value_maskp, 683227569Sphilip __out_ecount_opt(count) unsigned long *valuesp, 684227569Sphilip __in size_t count) 685227569Sphilip{ 686227569Sphilip efx_port_t *epp = &(enp->en_port); 687227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 688227569Sphilip int rc; 689227569Sphilip 690227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 691227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 692227569Sphilip 693227569Sphilip EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN); 694227569Sphilip EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES); 695227569Sphilip EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); 696227569Sphilip 697227569Sphilip EFSYS_ASSERT(epop->epo_bist_poll != NULL); 698227569Sphilip if (epop->epo_bist_poll == NULL) { 699227569Sphilip rc = ENOTSUP; 700227569Sphilip goto fail1; 701227569Sphilip } 702227569Sphilip 703227569Sphilip if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp, 704227569Sphilip valuesp, count)) != 0) 705227569Sphilip goto fail2; 706227569Sphilip 707227569Sphilip return (0); 708227569Sphilip 709227569Sphilipfail2: 710227569Sphilip EFSYS_PROBE(fail2); 711227569Sphilipfail1: 712227569Sphilip EFSYS_PROBE1(fail1, int, rc); 713227569Sphilip 714227569Sphilip return (rc); 715227569Sphilip} 716227569Sphilip 717227569Sphilip void 718227569Sphilipefx_phy_bist_stop( 719227569Sphilip __in efx_nic_t *enp, 720227569Sphilip __in efx_phy_bist_type_t type) 721227569Sphilip{ 722227569Sphilip efx_port_t *epp = &(enp->en_port); 723227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 724227569Sphilip 725227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 726227569Sphilip EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 727227569Sphilip 728227569Sphilip EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN); 729227569Sphilip EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES); 730227569Sphilip EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); 731227569Sphilip 732227569Sphilip EFSYS_ASSERT(epop->epo_bist_stop != NULL); 733227569Sphilip 734227569Sphilip if (epop->epo_bist_stop != NULL) 735227569Sphilip epop->epo_bist_stop(enp, type); 736227569Sphilip 737227569Sphilip epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN; 738227569Sphilip} 739227569Sphilip 740227569Sphilip#endif /* EFSYS_OPT_PHY_BIST */ 741227569Sphilip void 742227569Sphilipefx_phy_unprobe( 743227569Sphilip __in efx_nic_t *enp) 744227569Sphilip{ 745227569Sphilip efx_port_t *epp = &(enp->en_port); 746227569Sphilip 747227569Sphilip EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 748227569Sphilip 749227569Sphilip epp->ep_epop = NULL; 750227569Sphilip 751227569Sphilip epp->ep_adv_cap_mask = 0; 752227569Sphilip 753227569Sphilip epp->ep_port = 0; 754227569Sphilip epp->ep_phy_type = 0; 755227569Sphilip} 756