siena_nic.c revision 311481
1227569Sphilip/*- 2300607Sarybchik * Copyright (c) 2009-2016 Solarflare Communications Inc. 3283514Sarybchik * All rights reserved. 4227569Sphilip * 5227569Sphilip * Redistribution and use in source and binary forms, with or without 6283514Sarybchik * modification, are permitted provided that the following conditions are met: 7227569Sphilip * 8283514Sarybchik * 1. Redistributions of source code must retain the above copyright notice, 9283514Sarybchik * this list of conditions and the following disclaimer. 10283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice, 11283514Sarybchik * this list of conditions and the following disclaimer in the documentation 12283514Sarybchik * and/or other materials provided with the distribution. 13283514Sarybchik * 14283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15283514Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16283514Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17283514Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18283514Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19283514Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20283514Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21283514Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22283514Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23283514Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24283514Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25283514Sarybchik * 26283514Sarybchik * The views and conclusions contained in the software and documentation are 27283514Sarybchik * those of the authors and should not be interpreted as representing official 28283514Sarybchik * policies, either expressed or implied, of the FreeBSD Project. 29227569Sphilip */ 30228078Sphilip 31228078Sphilip#include <sys/cdefs.h> 32228078Sphilip__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/siena_nic.c 311481 2017-01-06 07:05:02Z arybchik $"); 33228078Sphilip 34227569Sphilip#include "efx.h" 35227569Sphilip#include "efx_impl.h" 36283514Sarybchik#include "mcdi_mon.h" 37227569Sphilip 38227569Sphilip#if EFSYS_OPT_SIENA 39227569Sphilip 40310933Sarybchik#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 41310933Sarybchik 42291436Sarybchikstatic __checkReturn efx_rc_t 43227569Sphilipsiena_nic_get_partn_mask( 44227569Sphilip __in efx_nic_t *enp, 45227569Sphilip __out unsigned int *maskp) 46227569Sphilip{ 47227569Sphilip efx_mcdi_req_t req; 48283514Sarybchik uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN, 49283514Sarybchik MC_CMD_NVRAM_TYPES_OUT_LEN)]; 50291436Sarybchik efx_rc_t rc; 51227569Sphilip 52283514Sarybchik (void) memset(payload, 0, sizeof (payload)); 53227569Sphilip req.emr_cmd = MC_CMD_NVRAM_TYPES; 54283514Sarybchik req.emr_in_buf = payload; 55283514Sarybchik req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN; 56283514Sarybchik req.emr_out_buf = payload; 57283514Sarybchik req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN; 58227569Sphilip 59227569Sphilip efx_mcdi_execute(enp, &req); 60227569Sphilip 61227569Sphilip if (req.emr_rc != 0) { 62227569Sphilip rc = req.emr_rc; 63227569Sphilip goto fail1; 64227569Sphilip } 65227569Sphilip 66227569Sphilip if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) { 67227569Sphilip rc = EMSGSIZE; 68227569Sphilip goto fail2; 69227569Sphilip } 70227569Sphilip 71227569Sphilip *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES); 72227569Sphilip 73227569Sphilip return (0); 74227569Sphilip 75227569Sphilipfail2: 76227569Sphilip EFSYS_PROBE(fail2); 77227569Sphilipfail1: 78291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 79227569Sphilip 80227569Sphilip return (rc); 81227569Sphilip} 82227569Sphilip 83310933Sarybchik#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */ 84310933Sarybchik 85291436Sarybchikstatic __checkReturn efx_rc_t 86227569Sphilipsiena_board_cfg( 87227569Sphilip __in efx_nic_t *enp) 88227569Sphilip{ 89227569Sphilip efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 90283514Sarybchik uint8_t mac_addr[6]; 91283514Sarybchik efx_dword_t capabilities; 92283514Sarybchik uint32_t board_type; 93283514Sarybchik uint32_t nevq, nrxq, ntxq; 94291436Sarybchik efx_rc_t rc; 95227569Sphilip 96283514Sarybchik /* External port identifier using one-based port numbering */ 97283514Sarybchik encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port; 98283514Sarybchik 99227569Sphilip /* Board configuration */ 100283514Sarybchik if ((rc = efx_mcdi_get_board_cfg(enp, &board_type, 101283514Sarybchik &capabilities, mac_addr)) != 0) 102227569Sphilip goto fail1; 103227569Sphilip 104279048Sarybchik EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 105227569Sphilip 106283514Sarybchik encp->enc_board_type = board_type; 107227569Sphilip 108311016Sarybchik /* 109311016Sarybchik * There is no possibility to determine the number of PFs on Siena 110311016Sarybchik * by issuing MCDI request, and it is not an easy task to find the 111311016Sarybchik * value based on the board type, so 'enc_hw_pf_count' is set to 1 112311016Sarybchik */ 113311016Sarybchik encp->enc_hw_pf_count = 1; 114311016Sarybchik 115279048Sarybchik /* Additional capabilities */ 116279048Sarybchik encp->enc_clk_mult = 1; 117283514Sarybchik if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) { 118279048Sarybchik enp->en_features |= EFX_FEATURE_TURBO; 119279048Sarybchik 120283514Sarybchik if (EFX_DWORD_FIELD(capabilities, 121283514Sarybchik MC_CMD_CAPABILITIES_TURBO_ACTIVE)) { 122279048Sarybchik encp->enc_clk_mult = 2; 123283514Sarybchik } 124279048Sarybchik } 125279048Sarybchik 126279182Sarybchik encp->enc_evq_timer_quantum_ns = 127279182Sarybchik EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult; 128279182Sarybchik encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 129279182Sarybchik FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000; 130279048Sarybchik 131283514Sarybchik /* When hash header insertion is enabled, Siena inserts 16 bytes */ 132283514Sarybchik encp->enc_rx_prefix_size = 16; 133227569Sphilip 134283514Sarybchik /* Alignment for receive packet DMA buffers */ 135283514Sarybchik encp->enc_rx_buf_align_start = 1; 136283514Sarybchik encp->enc_rx_buf_align_end = 1; 137227569Sphilip 138283514Sarybchik /* Alignment for WPTR updates */ 139283514Sarybchik encp->enc_rx_push_align = 1; 140227569Sphilip 141283514Sarybchik /* Resource limits */ 142283514Sarybchik rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq); 143283514Sarybchik if (rc != 0) { 144283514Sarybchik if (rc != ENOTSUP) 145283514Sarybchik goto fail2; 146283514Sarybchik 147283514Sarybchik nevq = 1024; 148283514Sarybchik nrxq = EFX_RXQ_LIMIT_TARGET; 149283514Sarybchik ntxq = EFX_TXQ_LIMIT_TARGET; 150227569Sphilip } 151283514Sarybchik encp->enc_evq_limit = nevq; 152283514Sarybchik encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq); 153283514Sarybchik encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq); 154227569Sphilip 155227569Sphilip encp->enc_buftbl_limit = SIENA_SRAM_ROWS - 156279098Sarybchik (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) - 157279098Sarybchik (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE)); 158227569Sphilip 159283514Sarybchik encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 160283514Sarybchik encp->enc_fw_assisted_tso_enabled = B_FALSE; 161293891Sarybchik encp->enc_fw_assisted_tso_v2_enabled = B_FALSE; 162311015Sarybchik encp->enc_fw_assisted_tso_v2_n_contexts = 0; 163291922Sarybchik encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 164283514Sarybchik 165299904Sarybchik /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */ 166299904Sarybchik encp->enc_required_pcie_bandwidth_mbps = 2 * 10000; 167299904Sarybchik encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2; 168299904Sarybchik 169311481Sarybchik encp->enc_fw_verified_nvram_update_required = B_FALSE; 170311481Sarybchik 171227569Sphilip return (0); 172227569Sphilip 173227569Sphilipfail2: 174227569Sphilip EFSYS_PROBE(fail2); 175227569Sphilipfail1: 176291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 177227569Sphilip 178227569Sphilip return (rc); 179227569Sphilip} 180227569Sphilip 181291436Sarybchikstatic __checkReturn efx_rc_t 182227569Sphilipsiena_phy_cfg( 183227569Sphilip __in efx_nic_t *enp) 184227569Sphilip{ 185227569Sphilip efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 186291436Sarybchik efx_rc_t rc; 187227569Sphilip 188283514Sarybchik /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 189283514Sarybchik if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 190227569Sphilip goto fail1; 191227569Sphilip 192227569Sphilip#if EFSYS_OPT_PHY_STATS 193227569Sphilip /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */ 194283514Sarybchik siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask, 195227569Sphilip NULL, &encp->enc_phy_stat_mask, NULL); 196227569Sphilip#endif /* EFSYS_OPT_PHY_STATS */ 197227569Sphilip 198227569Sphilip return (0); 199227569Sphilip 200227569Sphilipfail1: 201291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 202227569Sphilip 203227569Sphilip return (rc); 204227569Sphilip} 205227569Sphilip 206291436Sarybchik __checkReturn efx_rc_t 207227569Sphilipsiena_nic_probe( 208227569Sphilip __in efx_nic_t *enp) 209227569Sphilip{ 210227569Sphilip efx_port_t *epp = &(enp->en_port); 211227569Sphilip efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 212227569Sphilip siena_link_state_t sls; 213227569Sphilip unsigned int mask; 214283514Sarybchik efx_oword_t oword; 215291436Sarybchik efx_rc_t rc; 216227569Sphilip 217227569Sphilip EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 218227569Sphilip 219283514Sarybchik /* Test BIU */ 220283514Sarybchik if ((rc = efx_nic_biu_test(enp)) != 0) 221227569Sphilip goto fail1; 222227569Sphilip 223283514Sarybchik /* Clear the region register */ 224283514Sarybchik EFX_POPULATE_OWORD_4(oword, 225283514Sarybchik FRF_AZ_ADR_REGION0, 0, 226283514Sarybchik FRF_AZ_ADR_REGION1, (1 << 16), 227283514Sarybchik FRF_AZ_ADR_REGION2, (2 << 16), 228283514Sarybchik FRF_AZ_ADR_REGION3, (3 << 16)); 229283514Sarybchik EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); 230283514Sarybchik 231283514Sarybchik /* Read clear any assertion state */ 232283514Sarybchik if ((rc = efx_mcdi_read_assertion(enp)) != 0) 233227569Sphilip goto fail2; 234227569Sphilip 235283514Sarybchik /* Exit the assertion handler */ 236283514Sarybchik if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 237227569Sphilip goto fail3; 238227569Sphilip 239283514Sarybchik /* Wrestle control from the BMC */ 240283514Sarybchik if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 241227569Sphilip goto fail4; 242227569Sphilip 243283514Sarybchik if ((rc = siena_board_cfg(enp)) != 0) 244227569Sphilip goto fail5; 245227569Sphilip 246283514Sarybchik if ((rc = siena_phy_cfg(enp)) != 0) 247283514Sarybchik goto fail6; 248283514Sarybchik 249227569Sphilip /* Obtain the default PHY advertised capabilities */ 250227569Sphilip if ((rc = siena_nic_reset(enp)) != 0) 251283514Sarybchik goto fail7; 252227569Sphilip if ((rc = siena_phy_get_link(enp, &sls)) != 0) 253283514Sarybchik goto fail8; 254227569Sphilip epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask; 255227569Sphilip epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; 256227569Sphilip 257227569Sphilip#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 258227569Sphilip if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0) 259283514Sarybchik goto fail9; 260227569Sphilip enp->en_u.siena.enu_partn_mask = mask; 261227569Sphilip#endif 262227569Sphilip 263227569Sphilip#if EFSYS_OPT_MAC_STATS 264227569Sphilip /* Wipe the MAC statistics */ 265283514Sarybchik if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 266283514Sarybchik goto fail10; 267227569Sphilip#endif 268227569Sphilip 269227569Sphilip#if EFSYS_OPT_LOOPBACK 270283514Sarybchik if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 271283514Sarybchik goto fail11; 272227569Sphilip#endif 273227569Sphilip 274227569Sphilip#if EFSYS_OPT_MON_STATS 275283514Sarybchik if ((rc = mcdi_mon_cfg_build(enp)) != 0) 276283514Sarybchik goto fail12; 277227569Sphilip#endif 278227569Sphilip 279227569Sphilip encp->enc_features = enp->en_features; 280227569Sphilip 281227569Sphilip return (0); 282227569Sphilip 283227569Sphilip#if EFSYS_OPT_MON_STATS 284283514Sarybchikfail12: 285283514Sarybchik EFSYS_PROBE(fail12); 286283514Sarybchik#endif 287283514Sarybchik#if EFSYS_OPT_LOOPBACK 288227569Sphilipfail11: 289227569Sphilip EFSYS_PROBE(fail11); 290227569Sphilip#endif 291283514Sarybchik#if EFSYS_OPT_MAC_STATS 292227569Sphilipfail10: 293227569Sphilip EFSYS_PROBE(fail10); 294227569Sphilip#endif 295283514Sarybchik#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 296227569Sphilipfail9: 297227569Sphilip EFSYS_PROBE(fail9); 298227569Sphilip#endif 299227569Sphilipfail8: 300227569Sphilip EFSYS_PROBE(fail8); 301227569Sphilipfail7: 302227569Sphilip EFSYS_PROBE(fail7); 303227569Sphilipfail6: 304227569Sphilip EFSYS_PROBE(fail6); 305227569Sphilipfail5: 306227569Sphilip EFSYS_PROBE(fail5); 307227569Sphilipfail4: 308227569Sphilip EFSYS_PROBE(fail4); 309227569Sphilipfail3: 310227569Sphilip EFSYS_PROBE(fail3); 311227569Sphilipfail2: 312227569Sphilip EFSYS_PROBE(fail2); 313227569Sphilipfail1: 314291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 315227569Sphilip 316227569Sphilip return (rc); 317227569Sphilip} 318227569Sphilip 319291436Sarybchik __checkReturn efx_rc_t 320227569Sphilipsiena_nic_reset( 321227569Sphilip __in efx_nic_t *enp) 322227569Sphilip{ 323227569Sphilip efx_mcdi_req_t req; 324291436Sarybchik efx_rc_t rc; 325227569Sphilip 326227569Sphilip EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 327227569Sphilip 328227569Sphilip /* siena_nic_reset() is called to recover from BADASSERT failures. */ 329283514Sarybchik if ((rc = efx_mcdi_read_assertion(enp)) != 0) 330227569Sphilip goto fail1; 331283514Sarybchik if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 332227569Sphilip goto fail2; 333227569Sphilip 334283514Sarybchik /* 335283514Sarybchik * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied 336283514Sarybchik * for backwards compatibility with PORT_RESET_IN_LEN. 337283514Sarybchik */ 338283514Sarybchik EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0); 339283514Sarybchik 340283514Sarybchik req.emr_cmd = MC_CMD_ENTITY_RESET; 341227569Sphilip req.emr_in_buf = NULL; 342227569Sphilip req.emr_in_length = 0; 343227569Sphilip req.emr_out_buf = NULL; 344227569Sphilip req.emr_out_length = 0; 345227569Sphilip 346227569Sphilip efx_mcdi_execute(enp, &req); 347227569Sphilip 348227569Sphilip if (req.emr_rc != 0) { 349227569Sphilip rc = req.emr_rc; 350227569Sphilip goto fail3; 351227569Sphilip } 352227569Sphilip 353227569Sphilip return (0); 354227569Sphilip 355227569Sphilipfail3: 356227569Sphilip EFSYS_PROBE(fail3); 357227569Sphilipfail2: 358227569Sphilip EFSYS_PROBE(fail2); 359227569Sphilipfail1: 360291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 361227569Sphilip 362227569Sphilip return (0); 363227569Sphilip} 364227569Sphilip 365227569Sphilipstatic void 366227569Sphilipsiena_nic_rx_cfg( 367227569Sphilip __in efx_nic_t *enp) 368227569Sphilip{ 369227569Sphilip efx_oword_t oword; 370227569Sphilip 371227569Sphilip /* 372227569Sphilip * RX_INGR_EN is always enabled on Siena, because we rely on 373227569Sphilip * the RX parser to be resiliant to missing SOP/EOP. 374227569Sphilip */ 375227569Sphilip EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); 376227569Sphilip EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1); 377227569Sphilip EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); 378227569Sphilip 379227569Sphilip /* Disable parsing of additional 802.1Q in Q packets */ 380227569Sphilip EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 381227569Sphilip EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0); 382227569Sphilip EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 383227569Sphilip} 384227569Sphilip 385227569Sphilipstatic void 386227569Sphilipsiena_nic_usrev_dis( 387227569Sphilip __in efx_nic_t *enp) 388227569Sphilip{ 389227569Sphilip efx_oword_t oword; 390227569Sphilip 391227569Sphilip EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1); 392227569Sphilip EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword); 393227569Sphilip} 394227569Sphilip 395291436Sarybchik __checkReturn efx_rc_t 396227569Sphilipsiena_nic_init( 397227569Sphilip __in efx_nic_t *enp) 398227569Sphilip{ 399291436Sarybchik efx_rc_t rc; 400227569Sphilip 401227569Sphilip EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 402227569Sphilip 403283514Sarybchik /* Enable reporting of some events (e.g. link change) */ 404283514Sarybchik if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 405227569Sphilip goto fail1; 406227569Sphilip 407227569Sphilip siena_sram_init(enp); 408227569Sphilip 409227569Sphilip /* Configure Siena's RX block */ 410227569Sphilip siena_nic_rx_cfg(enp); 411227569Sphilip 412227569Sphilip /* Disable USR_EVents for now */ 413227569Sphilip siena_nic_usrev_dis(enp); 414227569Sphilip 415227569Sphilip /* bug17057: Ensure set_link is called */ 416227569Sphilip if ((rc = siena_phy_reconfigure(enp)) != 0) 417227569Sphilip goto fail2; 418227569Sphilip 419291923Sarybchik enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1; 420291923Sarybchik 421227569Sphilip return (0); 422227569Sphilip 423227569Sphilipfail2: 424227569Sphilip EFSYS_PROBE(fail2); 425227569Sphilipfail1: 426291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 427227569Sphilip 428227569Sphilip return (rc); 429227569Sphilip} 430227569Sphilip 431227569Sphilip void 432227569Sphilipsiena_nic_fini( 433227569Sphilip __in efx_nic_t *enp) 434227569Sphilip{ 435227569Sphilip _NOTE(ARGUNUSED(enp)) 436227569Sphilip} 437227569Sphilip 438227569Sphilip void 439227569Sphilipsiena_nic_unprobe( 440227569Sphilip __in efx_nic_t *enp) 441227569Sphilip{ 442283514Sarybchik#if EFSYS_OPT_MON_STATS 443283514Sarybchik mcdi_mon_cfg_free(enp); 444283514Sarybchik#endif /* EFSYS_OPT_MON_STATS */ 445283514Sarybchik (void) efx_mcdi_drv_attach(enp, B_FALSE); 446227569Sphilip} 447227569Sphilip 448227569Sphilip#if EFSYS_OPT_DIAG 449227569Sphilip 450283514Sarybchikstatic efx_register_set_t __siena_registers[] = { 451227569Sphilip { FR_AZ_ADR_REGION_REG_OFST, 0, 1 }, 452227569Sphilip { FR_CZ_USR_EV_CFG_OFST, 0, 1 }, 453227569Sphilip { FR_AZ_RX_CFG_REG_OFST, 0, 1 }, 454227569Sphilip { FR_AZ_TX_CFG_REG_OFST, 0, 1 }, 455227569Sphilip { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 }, 456227569Sphilip { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 }, 457227569Sphilip { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 }, 458227569Sphilip { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 }, 459227569Sphilip { FR_AZ_DP_CTRL_REG_OFST, 0, 1 }, 460227569Sphilip { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1}, 461227569Sphilip { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1}, 462227569Sphilip { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1}, 463227569Sphilip { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1} 464227569Sphilip}; 465227569Sphilip 466283514Sarybchikstatic const uint32_t __siena_register_masks[] = { 467227569Sphilip 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 468227569Sphilip 0x000103FF, 0x00000000, 0x00000000, 0x00000000, 469227569Sphilip 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000, 470227569Sphilip 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF, 471227569Sphilip 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF, 472227569Sphilip 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000, 473227569Sphilip 0x00000003, 0x00000000, 0x00000000, 0x00000000, 474227569Sphilip 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 475227569Sphilip 0x00000FFF, 0x00000000, 0x00000000, 0x00000000, 476227569Sphilip 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 477227569Sphilip 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 478227569Sphilip 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 479227569Sphilip 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000 480227569Sphilip}; 481227569Sphilip 482283514Sarybchikstatic efx_register_set_t __siena_tables[] = { 483227569Sphilip { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP, 484227569Sphilip FR_AZ_RX_FILTER_TBL0_ROWS }, 485227569Sphilip { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP, 486227569Sphilip FR_CZ_RX_MAC_FILTER_TBL0_ROWS }, 487227569Sphilip { FR_AZ_RX_DESC_PTR_TBL_OFST, 488227569Sphilip FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS }, 489227569Sphilip { FR_AZ_TX_DESC_PTR_TBL_OFST, 490227569Sphilip FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS }, 491227569Sphilip { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS }, 492227569Sphilip { FR_CZ_TX_FILTER_TBL0_OFST, 493227569Sphilip FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS }, 494227569Sphilip { FR_CZ_TX_MAC_FILTER_TBL0_OFST, 495227569Sphilip FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS } 496227569Sphilip}; 497227569Sphilip 498283514Sarybchikstatic const uint32_t __siena_table_masks[] = { 499227569Sphilip 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF, 500227569Sphilip 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000, 501279095Sarybchik 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000, 502227569Sphilip 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000, 503227569Sphilip 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000, 504227569Sphilip 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF, 505227569Sphilip 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000, 506227569Sphilip}; 507227569Sphilip 508291436Sarybchik __checkReturn efx_rc_t 509227569Sphilipsiena_nic_register_test( 510227569Sphilip __in efx_nic_t *enp) 511227569Sphilip{ 512227569Sphilip efx_register_set_t *rsp; 513227569Sphilip const uint32_t *dwordp; 514227569Sphilip unsigned int nitems; 515227569Sphilip unsigned int count; 516291436Sarybchik efx_rc_t rc; 517227569Sphilip 518227569Sphilip /* Fill out the register mask entries */ 519227569Sphilip EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks) 520227569Sphilip == EFX_ARRAY_SIZE(__siena_registers) * 4); 521227569Sphilip 522227569Sphilip nitems = EFX_ARRAY_SIZE(__siena_registers); 523227569Sphilip dwordp = __siena_register_masks; 524227569Sphilip for (count = 0; count < nitems; ++count) { 525227569Sphilip rsp = __siena_registers + count; 526227569Sphilip rsp->mask.eo_u32[0] = *dwordp++; 527227569Sphilip rsp->mask.eo_u32[1] = *dwordp++; 528227569Sphilip rsp->mask.eo_u32[2] = *dwordp++; 529227569Sphilip rsp->mask.eo_u32[3] = *dwordp++; 530227569Sphilip } 531227569Sphilip 532227569Sphilip /* Fill out the register table entries */ 533227569Sphilip EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks) 534227569Sphilip == EFX_ARRAY_SIZE(__siena_tables) * 4); 535227569Sphilip 536227569Sphilip nitems = EFX_ARRAY_SIZE(__siena_tables); 537227569Sphilip dwordp = __siena_table_masks; 538227569Sphilip for (count = 0; count < nitems; ++count) { 539227569Sphilip rsp = __siena_tables + count; 540227569Sphilip rsp->mask.eo_u32[0] = *dwordp++; 541227569Sphilip rsp->mask.eo_u32[1] = *dwordp++; 542227569Sphilip rsp->mask.eo_u32[2] = *dwordp++; 543227569Sphilip rsp->mask.eo_u32[3] = *dwordp++; 544227569Sphilip } 545227569Sphilip 546227569Sphilip if ((rc = efx_nic_test_registers(enp, __siena_registers, 547227569Sphilip EFX_ARRAY_SIZE(__siena_registers))) != 0) 548227569Sphilip goto fail1; 549227569Sphilip 550227569Sphilip if ((rc = efx_nic_test_tables(enp, __siena_tables, 551227569Sphilip EFX_PATTERN_BYTE_ALTERNATE, 552227569Sphilip EFX_ARRAY_SIZE(__siena_tables))) != 0) 553227569Sphilip goto fail2; 554227569Sphilip 555227569Sphilip if ((rc = efx_nic_test_tables(enp, __siena_tables, 556227569Sphilip EFX_PATTERN_BYTE_CHANGING, 557227569Sphilip EFX_ARRAY_SIZE(__siena_tables))) != 0) 558227569Sphilip goto fail3; 559227569Sphilip 560227569Sphilip if ((rc = efx_nic_test_tables(enp, __siena_tables, 561227569Sphilip EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0) 562227569Sphilip goto fail4; 563227569Sphilip 564227569Sphilip return (0); 565227569Sphilip 566227569Sphilipfail4: 567227569Sphilip EFSYS_PROBE(fail4); 568227569Sphilipfail3: 569227569Sphilip EFSYS_PROBE(fail3); 570227569Sphilipfail2: 571227569Sphilip EFSYS_PROBE(fail2); 572227569Sphilipfail1: 573291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 574227569Sphilip 575227569Sphilip return (rc); 576227569Sphilip} 577227569Sphilip 578227569Sphilip#endif /* EFSYS_OPT_DIAG */ 579227569Sphilip 580227569Sphilip#endif /* EFSYS_OPT_SIENA */ 581