1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2009-2016 Solarflare Communications 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 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * The views and conclusions contained in the software and documentation are 29 * those of the authors and should not be interpreted as representing official 30 * policies, either expressed or implied, of the FreeBSD Project. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include "efx.h" 37 #include "efx_impl.h" 38 #include "mcdi_mon.h" 39 40 #if EFSYS_OPT_SIENA 41 42 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 43 44 static __checkReturn efx_rc_t 45 siena_nic_get_partn_mask( 46 __in efx_nic_t *enp, 47 __out unsigned int *maskp) 48 { 49 efx_mcdi_req_t req; 50 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN, 51 MC_CMD_NVRAM_TYPES_OUT_LEN); 52 efx_rc_t rc; 53 54 req.emr_cmd = MC_CMD_NVRAM_TYPES; 55 req.emr_in_buf = payload; 56 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN; 57 req.emr_out_buf = payload; 58 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN; 59 60 efx_mcdi_execute(enp, &req); 61 62 if (req.emr_rc != 0) { 63 rc = req.emr_rc; 64 goto fail1; 65 } 66 67 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) { 68 rc = EMSGSIZE; 69 goto fail2; 70 } 71 72 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES); 73 74 return (0); 75 76 fail2: 77 EFSYS_PROBE(fail2); 78 fail1: 79 EFSYS_PROBE1(fail1, efx_rc_t, rc); 80 81 return (rc); 82 } 83 84 #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */ 85 86 static __checkReturn efx_rc_t 87 siena_board_cfg( 88 __in efx_nic_t *enp) 89 { 90 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 91 uint8_t mac_addr[6]; 92 efx_dword_t capabilities; 93 uint32_t board_type; 94 uint32_t nevq, nrxq, ntxq; 95 efx_rc_t rc; 96 97 /* Siena has a fixed 8Kbyte VI window size */ 98 EFX_STATIC_ASSERT(1U << EFX_VI_WINDOW_SHIFT_8K == 8192); 99 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 100 101 /* External port identifier using one-based port numbering */ 102 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port; 103 104 /* Board configuration */ 105 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type, 106 &capabilities, mac_addr)) != 0) 107 goto fail1; 108 109 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 110 111 encp->enc_board_type = board_type; 112 113 /* 114 * There is no possibility to determine the number of PFs on Siena 115 * by issuing MCDI request, and it is not an easy task to find the 116 * value based on the board type, so 'enc_hw_pf_count' is set to 1 117 */ 118 encp->enc_hw_pf_count = 1; 119 120 /* Additional capabilities */ 121 encp->enc_clk_mult = 1; 122 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) { 123 enp->en_features |= EFX_FEATURE_TURBO; 124 125 if (EFX_DWORD_FIELD(capabilities, 126 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) { 127 encp->enc_clk_mult = 2; 128 } 129 } 130 131 encp->enc_evq_timer_quantum_ns = 132 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult; 133 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 134 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000; 135 136 /* When hash header insertion is enabled, Siena inserts 16 bytes */ 137 encp->enc_rx_prefix_size = 16; 138 139 /* Alignment for receive packet DMA buffers */ 140 encp->enc_rx_buf_align_start = 1; 141 encp->enc_rx_buf_align_end = 1; 142 143 /* Alignment for WPTR updates */ 144 encp->enc_rx_push_align = 1; 145 146 #if EFSYS_OPT_RX_SCALE 147 /* There is one RSS context per function */ 148 encp->enc_rx_scale_max_exclusive_contexts = 1; 149 150 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR); 151 encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ); 152 153 /* 154 * It is always possible to use port numbers 155 * as the input data for hash computation. 156 */ 157 encp->enc_rx_scale_l4_hash_supported = B_TRUE; 158 159 /* There is no support for additional RSS modes */ 160 encp->enc_rx_scale_additional_modes_supported = B_FALSE; 161 #endif /* EFSYS_OPT_RX_SCALE */ 162 163 encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT); 164 /* Fragments must not span 4k boundaries. */ 165 encp->enc_tx_dma_desc_boundary = 4096; 166 167 /* Resource limits */ 168 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq); 169 if (rc != 0) { 170 if (rc != ENOTSUP) 171 goto fail2; 172 173 nevq = 1024; 174 nrxq = EFX_RXQ_LIMIT_TARGET; 175 ntxq = EFX_TXQ_LIMIT_TARGET; 176 } 177 encp->enc_evq_limit = nevq; 178 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq); 179 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq); 180 181 encp->enc_txq_max_ndescs = 4096; 182 183 encp->enc_buftbl_limit = SIENA_SRAM_ROWS - 184 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) - 185 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE)); 186 187 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 188 encp->enc_fw_assisted_tso_enabled = B_FALSE; 189 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE; 190 encp->enc_fw_assisted_tso_v2_n_contexts = 0; 191 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 192 encp->enc_rx_packed_stream_supported = B_FALSE; 193 encp->enc_rx_var_packed_stream_supported = B_FALSE; 194 encp->enc_rx_es_super_buffer_supported = B_FALSE; 195 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE; 196 197 /* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */ 198 encp->enc_required_pcie_bandwidth_mbps = 2 * 10000; 199 encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2; 200 201 encp->enc_nvram_update_verify_result_supported = B_FALSE; 202 203 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS; 204 205 encp->enc_filter_action_flag_supported = B_FALSE; 206 encp->enc_filter_action_mark_supported = B_FALSE; 207 encp->enc_filter_action_mark_max = 0; 208 209 return (0); 210 211 fail2: 212 EFSYS_PROBE(fail2); 213 fail1: 214 EFSYS_PROBE1(fail1, efx_rc_t, rc); 215 216 return (rc); 217 } 218 219 static __checkReturn efx_rc_t 220 siena_phy_cfg( 221 __in efx_nic_t *enp) 222 { 223 #if EFSYS_OPT_PHY_STATS 224 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 225 #endif /* EFSYS_OPT_PHY_STATS */ 226 efx_rc_t rc; 227 228 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 229 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 230 goto fail1; 231 232 #if EFSYS_OPT_PHY_STATS 233 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */ 234 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask, 235 NULL, &encp->enc_phy_stat_mask, NULL); 236 #endif /* EFSYS_OPT_PHY_STATS */ 237 238 return (0); 239 240 fail1: 241 EFSYS_PROBE1(fail1, efx_rc_t, rc); 242 243 return (rc); 244 } 245 246 #define SIENA_BIU_MAGIC0 0x01234567 247 #define SIENA_BIU_MAGIC1 0xfedcba98 248 249 static __checkReturn efx_rc_t 250 siena_nic_biu_test( 251 __in efx_nic_t *enp) 252 { 253 efx_oword_t oword; 254 efx_rc_t rc; 255 256 /* 257 * Write magic values to scratch registers 0 and 1, then 258 * verify that the values were written correctly. Interleave 259 * the accesses to ensure that the BIU is not just reading 260 * back the cached value that was last written. 261 */ 262 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0); 263 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 264 265 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1); 266 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 267 268 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 269 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) { 270 rc = EIO; 271 goto fail1; 272 } 273 274 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 275 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) { 276 rc = EIO; 277 goto fail2; 278 } 279 280 /* 281 * Perform the same test, with the values swapped. This 282 * ensures that subsequent tests don't start with the correct 283 * values already written into the scratch registers. 284 */ 285 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC1); 286 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 287 288 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, SIENA_BIU_MAGIC0); 289 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 290 291 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE); 292 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC1) { 293 rc = EIO; 294 goto fail3; 295 } 296 297 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE); 298 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != SIENA_BIU_MAGIC0) { 299 rc = EIO; 300 goto fail4; 301 } 302 303 return (0); 304 305 fail4: 306 EFSYS_PROBE(fail4); 307 fail3: 308 EFSYS_PROBE(fail3); 309 fail2: 310 EFSYS_PROBE(fail2); 311 fail1: 312 EFSYS_PROBE1(fail1, efx_rc_t, rc); 313 314 return (rc); 315 } 316 317 __checkReturn efx_rc_t 318 siena_nic_probe( 319 __in efx_nic_t *enp) 320 { 321 efx_port_t *epp = &(enp->en_port); 322 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 323 siena_link_state_t sls; 324 unsigned int mask; 325 efx_oword_t oword; 326 efx_rc_t rc; 327 328 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 329 330 /* Test BIU */ 331 if ((rc = siena_nic_biu_test(enp)) != 0) 332 goto fail1; 333 334 /* Clear the region register */ 335 EFX_POPULATE_OWORD_4(oword, 336 FRF_AZ_ADR_REGION0, 0, 337 FRF_AZ_ADR_REGION1, (1 << 16), 338 FRF_AZ_ADR_REGION2, (2 << 16), 339 FRF_AZ_ADR_REGION3, (3 << 16)); 340 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); 341 342 /* Read clear any assertion state */ 343 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 344 goto fail2; 345 346 /* Exit the assertion handler */ 347 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 348 goto fail3; 349 350 /* Wrestle control from the BMC */ 351 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 352 goto fail4; 353 354 if ((rc = siena_board_cfg(enp)) != 0) 355 goto fail5; 356 357 if ((rc = siena_phy_cfg(enp)) != 0) 358 goto fail6; 359 360 /* Obtain the default PHY advertised capabilities */ 361 if ((rc = siena_nic_reset(enp)) != 0) 362 goto fail7; 363 if ((rc = siena_phy_get_link(enp, &sls)) != 0) 364 goto fail8; 365 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask; 366 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; 367 368 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 369 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0) 370 goto fail9; 371 enp->en_u.siena.enu_partn_mask = mask; 372 #endif 373 374 #if EFSYS_OPT_MAC_STATS 375 /* Wipe the MAC statistics */ 376 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 377 goto fail10; 378 #endif 379 380 #if EFSYS_OPT_LOOPBACK 381 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 382 goto fail11; 383 #endif 384 385 #if EFSYS_OPT_MON_STATS 386 if ((rc = mcdi_mon_cfg_build(enp)) != 0) 387 goto fail12; 388 #endif 389 390 encp->enc_features = enp->en_features; 391 392 return (0); 393 394 #if EFSYS_OPT_MON_STATS 395 fail12: 396 EFSYS_PROBE(fail12); 397 #endif 398 #if EFSYS_OPT_LOOPBACK 399 fail11: 400 EFSYS_PROBE(fail11); 401 #endif 402 #if EFSYS_OPT_MAC_STATS 403 fail10: 404 EFSYS_PROBE(fail10); 405 #endif 406 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 407 fail9: 408 EFSYS_PROBE(fail9); 409 #endif 410 fail8: 411 EFSYS_PROBE(fail8); 412 fail7: 413 EFSYS_PROBE(fail7); 414 fail6: 415 EFSYS_PROBE(fail6); 416 fail5: 417 EFSYS_PROBE(fail5); 418 fail4: 419 EFSYS_PROBE(fail4); 420 fail3: 421 EFSYS_PROBE(fail3); 422 fail2: 423 EFSYS_PROBE(fail2); 424 fail1: 425 EFSYS_PROBE1(fail1, efx_rc_t, rc); 426 427 return (rc); 428 } 429 430 __checkReturn efx_rc_t 431 siena_nic_reset( 432 __in efx_nic_t *enp) 433 { 434 efx_mcdi_req_t req; 435 efx_rc_t rc; 436 437 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 438 439 /* siena_nic_reset() is called to recover from BADASSERT failures. */ 440 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 441 goto fail1; 442 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 443 goto fail2; 444 445 /* 446 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied 447 * for backwards compatibility with PORT_RESET_IN_LEN. 448 */ 449 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0); 450 451 req.emr_cmd = MC_CMD_ENTITY_RESET; 452 req.emr_in_buf = NULL; 453 req.emr_in_length = 0; 454 req.emr_out_buf = NULL; 455 req.emr_out_length = 0; 456 457 efx_mcdi_execute(enp, &req); 458 459 if (req.emr_rc != 0) { 460 rc = req.emr_rc; 461 goto fail3; 462 } 463 464 return (0); 465 466 fail3: 467 EFSYS_PROBE(fail3); 468 fail2: 469 EFSYS_PROBE(fail2); 470 fail1: 471 EFSYS_PROBE1(fail1, efx_rc_t, rc); 472 473 return (0); 474 } 475 476 static void 477 siena_nic_rx_cfg( 478 __in efx_nic_t *enp) 479 { 480 efx_oword_t oword; 481 482 /* 483 * RX_INGR_EN is always enabled on Siena, because we rely on 484 * the RX parser to be resiliant to missing SOP/EOP. 485 */ 486 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); 487 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1); 488 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); 489 490 /* Disable parsing of additional 802.1Q in Q packets */ 491 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 492 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0); 493 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 494 } 495 496 static void 497 siena_nic_usrev_dis( 498 __in efx_nic_t *enp) 499 { 500 efx_oword_t oword; 501 502 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1); 503 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword); 504 } 505 506 __checkReturn efx_rc_t 507 siena_nic_init( 508 __in efx_nic_t *enp) 509 { 510 efx_rc_t rc; 511 512 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 513 514 /* Enable reporting of some events (e.g. link change) */ 515 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 516 goto fail1; 517 518 siena_sram_init(enp); 519 520 /* Configure Siena's RX block */ 521 siena_nic_rx_cfg(enp); 522 523 /* Disable USR_EVents for now */ 524 siena_nic_usrev_dis(enp); 525 526 /* bug17057: Ensure set_link is called */ 527 if ((rc = siena_phy_reconfigure(enp)) != 0) 528 goto fail2; 529 530 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1; 531 532 return (0); 533 534 fail2: 535 EFSYS_PROBE(fail2); 536 fail1: 537 EFSYS_PROBE1(fail1, efx_rc_t, rc); 538 539 return (rc); 540 } 541 542 void 543 siena_nic_fini( 544 __in efx_nic_t *enp) 545 { 546 _NOTE(ARGUNUSED(enp)) 547 } 548 549 void 550 siena_nic_unprobe( 551 __in efx_nic_t *enp) 552 { 553 #if EFSYS_OPT_MON_STATS 554 mcdi_mon_cfg_free(enp); 555 #endif /* EFSYS_OPT_MON_STATS */ 556 (void) efx_mcdi_drv_attach(enp, B_FALSE); 557 } 558 559 #if EFSYS_OPT_DIAG 560 561 static siena_register_set_t __siena_registers[] = { 562 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 }, 563 { FR_CZ_USR_EV_CFG_OFST, 0, 1 }, 564 { FR_AZ_RX_CFG_REG_OFST, 0, 1 }, 565 { FR_AZ_TX_CFG_REG_OFST, 0, 1 }, 566 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 }, 567 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 }, 568 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 }, 569 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 }, 570 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 }, 571 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1}, 572 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1}, 573 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1}, 574 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1} 575 }; 576 577 static const uint32_t __siena_register_masks[] = { 578 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 579 0x000103FF, 0x00000000, 0x00000000, 0x00000000, 580 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000, 581 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF, 582 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF, 583 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000, 584 0x00000003, 0x00000000, 0x00000000, 0x00000000, 585 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 586 0x00000FFF, 0x00000000, 0x00000000, 0x00000000, 587 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 588 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 589 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 590 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000 591 }; 592 593 static siena_register_set_t __siena_tables[] = { 594 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP, 595 FR_AZ_RX_FILTER_TBL0_ROWS }, 596 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP, 597 FR_CZ_RX_MAC_FILTER_TBL0_ROWS }, 598 { FR_AZ_RX_DESC_PTR_TBL_OFST, 599 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS }, 600 { FR_AZ_TX_DESC_PTR_TBL_OFST, 601 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS }, 602 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS }, 603 { FR_CZ_TX_FILTER_TBL0_OFST, 604 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS }, 605 { FR_CZ_TX_MAC_FILTER_TBL0_OFST, 606 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS } 607 }; 608 609 static const uint32_t __siena_table_masks[] = { 610 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF, 611 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000, 612 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000, 613 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000, 614 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000, 615 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF, 616 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000, 617 }; 618 619 __checkReturn efx_rc_t 620 siena_nic_test_registers( 621 __in efx_nic_t *enp, 622 __in siena_register_set_t *rsp, 623 __in size_t count) 624 { 625 unsigned int bit; 626 efx_oword_t original; 627 efx_oword_t reg; 628 efx_oword_t buf; 629 efx_rc_t rc; 630 631 while (count > 0) { 632 /* This function is only suitable for registers */ 633 EFSYS_ASSERT(rsp->rows == 1); 634 635 /* bit sweep on and off */ 636 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original, 637 B_TRUE); 638 for (bit = 0; bit < 128; bit++) { 639 /* Is this bit in the mask? */ 640 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit)) 641 continue; 642 643 /* Test this bit can be set in isolation */ 644 reg = original; 645 EFX_AND_OWORD(reg, rsp->mask); 646 EFX_SET_OWORD_BIT(reg, bit); 647 648 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, 649 B_TRUE); 650 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, 651 B_TRUE); 652 653 EFX_AND_OWORD(buf, rsp->mask); 654 if (memcmp(®, &buf, sizeof (reg))) { 655 rc = EIO; 656 goto fail1; 657 } 658 659 /* Test this bit can be cleared in isolation */ 660 EFX_OR_OWORD(reg, rsp->mask); 661 EFX_CLEAR_OWORD_BIT(reg, bit); 662 663 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, ®, 664 B_TRUE); 665 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf, 666 B_TRUE); 667 668 EFX_AND_OWORD(buf, rsp->mask); 669 if (memcmp(®, &buf, sizeof (reg))) { 670 rc = EIO; 671 goto fail2; 672 } 673 } 674 675 /* Restore the old value */ 676 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, 677 B_TRUE); 678 679 --count; 680 ++rsp; 681 } 682 683 return (0); 684 685 fail2: 686 EFSYS_PROBE(fail2); 687 fail1: 688 EFSYS_PROBE1(fail1, efx_rc_t, rc); 689 690 /* Restore the old value */ 691 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE); 692 693 return (rc); 694 } 695 696 __checkReturn efx_rc_t 697 siena_nic_test_tables( 698 __in efx_nic_t *enp, 699 __in siena_register_set_t *rsp, 700 __in efx_pattern_type_t pattern, 701 __in size_t count) 702 { 703 efx_sram_pattern_fn_t func; 704 unsigned int index; 705 unsigned int address; 706 efx_oword_t reg; 707 efx_oword_t buf; 708 efx_rc_t rc; 709 710 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES); 711 func = __efx_sram_pattern_fns[pattern]; 712 713 while (count > 0) { 714 /* Write */ 715 address = rsp->address; 716 for (index = 0; index < rsp->rows; ++index) { 717 func(2 * index + 0, B_FALSE, ®.eo_qword[0]); 718 func(2 * index + 1, B_FALSE, ®.eo_qword[1]); 719 EFX_AND_OWORD(reg, rsp->mask); 720 EFSYS_BAR_WRITEO(enp->en_esbp, address, ®, B_TRUE); 721 722 address += rsp->step; 723 } 724 725 /* Read */ 726 address = rsp->address; 727 for (index = 0; index < rsp->rows; ++index) { 728 func(2 * index + 0, B_FALSE, ®.eo_qword[0]); 729 func(2 * index + 1, B_FALSE, ®.eo_qword[1]); 730 EFX_AND_OWORD(reg, rsp->mask); 731 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE); 732 if (memcmp(®, &buf, sizeof (reg))) { 733 rc = EIO; 734 goto fail1; 735 } 736 737 address += rsp->step; 738 } 739 740 ++rsp; 741 --count; 742 } 743 744 return (0); 745 746 fail1: 747 EFSYS_PROBE1(fail1, efx_rc_t, rc); 748 749 return (rc); 750 } 751 752 __checkReturn efx_rc_t 753 siena_nic_register_test( 754 __in efx_nic_t *enp) 755 { 756 siena_register_set_t *rsp; 757 const uint32_t *dwordp; 758 unsigned int nitems; 759 unsigned int count; 760 efx_rc_t rc; 761 762 /* Fill out the register mask entries */ 763 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks) 764 == EFX_ARRAY_SIZE(__siena_registers) * 4); 765 766 nitems = EFX_ARRAY_SIZE(__siena_registers); 767 dwordp = __siena_register_masks; 768 for (count = 0; count < nitems; ++count) { 769 rsp = __siena_registers + count; 770 rsp->mask.eo_u32[0] = *dwordp++; 771 rsp->mask.eo_u32[1] = *dwordp++; 772 rsp->mask.eo_u32[2] = *dwordp++; 773 rsp->mask.eo_u32[3] = *dwordp++; 774 } 775 776 /* Fill out the register table entries */ 777 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks) 778 == EFX_ARRAY_SIZE(__siena_tables) * 4); 779 780 nitems = EFX_ARRAY_SIZE(__siena_tables); 781 dwordp = __siena_table_masks; 782 for (count = 0; count < nitems; ++count) { 783 rsp = __siena_tables + count; 784 rsp->mask.eo_u32[0] = *dwordp++; 785 rsp->mask.eo_u32[1] = *dwordp++; 786 rsp->mask.eo_u32[2] = *dwordp++; 787 rsp->mask.eo_u32[3] = *dwordp++; 788 } 789 790 if ((rc = siena_nic_test_registers(enp, __siena_registers, 791 EFX_ARRAY_SIZE(__siena_registers))) != 0) 792 goto fail1; 793 794 if ((rc = siena_nic_test_tables(enp, __siena_tables, 795 EFX_PATTERN_BYTE_ALTERNATE, 796 EFX_ARRAY_SIZE(__siena_tables))) != 0) 797 goto fail2; 798 799 if ((rc = siena_nic_test_tables(enp, __siena_tables, 800 EFX_PATTERN_BYTE_CHANGING, 801 EFX_ARRAY_SIZE(__siena_tables))) != 0) 802 goto fail3; 803 804 if ((rc = siena_nic_test_tables(enp, __siena_tables, 805 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0) 806 goto fail4; 807 808 return (0); 809 810 fail4: 811 EFSYS_PROBE(fail4); 812 fail3: 813 EFSYS_PROBE(fail3); 814 fail2: 815 EFSYS_PROBE(fail2); 816 fail1: 817 EFSYS_PROBE1(fail1, efx_rc_t, rc); 818 819 return (rc); 820 } 821 822 #endif /* EFSYS_OPT_DIAG */ 823 824 #endif /* EFSYS_OPT_SIENA */ 825