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