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