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