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