173 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 174 175 return (0); 176 177fail2: 178 EFSYS_PROBE(fail2); 179fail1: 180 EFSYS_PROBE1(fail1, efx_rc_t, rc); 181 182 return (rc); 183} 184 185static __checkReturn efx_rc_t 186siena_phy_cfg( 187 __in efx_nic_t *enp) 188{ 189 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 190 efx_rc_t rc; 191 192 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 193 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 194 goto fail1; 195 196#if EFSYS_OPT_PHY_STATS 197 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */ 198 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask, 199 NULL, &encp->enc_phy_stat_mask, NULL); 200#endif /* EFSYS_OPT_PHY_STATS */ 201 202 return (0); 203 204fail1: 205 EFSYS_PROBE1(fail1, efx_rc_t, rc); 206 207 return (rc); 208} 209 210 __checkReturn efx_rc_t 211siena_nic_probe( 212 __in efx_nic_t *enp) 213{ 214 efx_port_t *epp = &(enp->en_port); 215 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 216 siena_link_state_t sls; 217 unsigned int mask; 218 efx_oword_t oword; 219 efx_rc_t rc; 220 221 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 222 223 /* Test BIU */ 224 if ((rc = efx_nic_biu_test(enp)) != 0) 225 goto fail1; 226 227 /* Clear the region register */ 228 EFX_POPULATE_OWORD_4(oword, 229 FRF_AZ_ADR_REGION0, 0, 230 FRF_AZ_ADR_REGION1, (1 << 16), 231 FRF_AZ_ADR_REGION2, (2 << 16), 232 FRF_AZ_ADR_REGION3, (3 << 16)); 233 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); 234 235 /* Read clear any assertion state */ 236 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 237 goto fail2; 238 239 /* Exit the assertion handler */ 240 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 241 goto fail3; 242 243 /* Wrestle control from the BMC */ 244 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 245 goto fail4; 246 247 if ((rc = siena_board_cfg(enp)) != 0) 248 goto fail5; 249 250 if ((rc = siena_phy_cfg(enp)) != 0) 251 goto fail6; 252 253 /* Obtain the default PHY advertised capabilities */ 254 if ((rc = siena_nic_reset(enp)) != 0) 255 goto fail7; 256 if ((rc = siena_phy_get_link(enp, &sls)) != 0) 257 goto fail8; 258 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask; 259 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; 260 261#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 262 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0) 263 goto fail9; 264 enp->en_u.siena.enu_partn_mask = mask; 265#endif 266 267#if EFSYS_OPT_MAC_STATS 268 /* Wipe the MAC statistics */ 269 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 270 goto fail10; 271#endif 272 273#if EFSYS_OPT_LOOPBACK 274 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 275 goto fail11; 276#endif 277 278#if EFSYS_OPT_MON_STATS 279 if ((rc = mcdi_mon_cfg_build(enp)) != 0) 280 goto fail12; 281#endif 282 283 encp->enc_features = enp->en_features; 284 285 return (0); 286 287#if EFSYS_OPT_MON_STATS 288fail12: 289 EFSYS_PROBE(fail12); 290#endif 291#if EFSYS_OPT_LOOPBACK 292fail11: 293 EFSYS_PROBE(fail11); 294#endif 295#if EFSYS_OPT_MAC_STATS 296fail10: 297 EFSYS_PROBE(fail10); 298#endif 299#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 300fail9: 301 EFSYS_PROBE(fail9); 302#endif 303fail8: 304 EFSYS_PROBE(fail8); 305fail7: 306 EFSYS_PROBE(fail7); 307fail6: 308 EFSYS_PROBE(fail6); 309fail5: 310 EFSYS_PROBE(fail5); 311fail4: 312 EFSYS_PROBE(fail4); 313fail3: 314 EFSYS_PROBE(fail3); 315fail2: 316 EFSYS_PROBE(fail2); 317fail1: 318 EFSYS_PROBE1(fail1, efx_rc_t, rc); 319 320 return (rc); 321} 322 323 __checkReturn efx_rc_t 324siena_nic_reset( 325 __in efx_nic_t *enp) 326{ 327 efx_mcdi_req_t req; 328 efx_rc_t rc; 329 330 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 331 332 /* siena_nic_reset() is called to recover from BADASSERT failures. */ 333 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 334 goto fail1; 335 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 336 goto fail2; 337 338 /* 339 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied 340 * for backwards compatibility with PORT_RESET_IN_LEN. 341 */ 342 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0); 343 344 req.emr_cmd = MC_CMD_ENTITY_RESET; 345 req.emr_in_buf = NULL; 346 req.emr_in_length = 0; 347 req.emr_out_buf = NULL; 348 req.emr_out_length = 0; 349 350 efx_mcdi_execute(enp, &req); 351 352 if (req.emr_rc != 0) { 353 rc = req.emr_rc; 354 goto fail3; 355 } 356 357 return (0); 358 359fail3: 360 EFSYS_PROBE(fail3); 361fail2: 362 EFSYS_PROBE(fail2); 363fail1: 364 EFSYS_PROBE1(fail1, efx_rc_t, rc); 365 366 return (0); 367} 368 369static void 370siena_nic_rx_cfg( 371 __in efx_nic_t *enp) 372{ 373 efx_oword_t oword; 374 375 /* 376 * RX_INGR_EN is always enabled on Siena, because we rely on 377 * the RX parser to be resiliant to missing SOP/EOP. 378 */ 379 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); 380 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1); 381 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); 382 383 /* Disable parsing of additional 802.1Q in Q packets */ 384 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 385 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0); 386 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 387} 388 389static void 390siena_nic_usrev_dis( 391 __in efx_nic_t *enp) 392{ 393 efx_oword_t oword; 394 395 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1); 396 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword); 397} 398 399 __checkReturn efx_rc_t 400siena_nic_init( 401 __in efx_nic_t *enp) 402{ 403 efx_rc_t rc; 404 405 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 406 407 /* Enable reporting of some events (e.g. link change) */ 408 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 409 goto fail1; 410 411 siena_sram_init(enp); 412 413 /* Configure Siena's RX block */ 414 siena_nic_rx_cfg(enp); 415 416 /* Disable USR_EVents for now */ 417 siena_nic_usrev_dis(enp); 418 419 /* bug17057: Ensure set_link is called */ 420 if ((rc = siena_phy_reconfigure(enp)) != 0) 421 goto fail2; 422 423 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1; 424 425 return (0); 426 427fail2: 428 EFSYS_PROBE(fail2); 429fail1: 430 EFSYS_PROBE1(fail1, efx_rc_t, rc); 431 432 return (rc); 433} 434 435 void 436siena_nic_fini( 437 __in efx_nic_t *enp) 438{ 439 _NOTE(ARGUNUSED(enp)) 440} 441 442 void 443siena_nic_unprobe( 444 __in efx_nic_t *enp) 445{ 446#if EFSYS_OPT_MON_STATS 447 mcdi_mon_cfg_free(enp); 448#endif /* EFSYS_OPT_MON_STATS */ 449 (void) efx_mcdi_drv_attach(enp, B_FALSE); 450} 451 452#if EFSYS_OPT_DIAG 453 454static efx_register_set_t __siena_registers[] = { 455 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 }, 456 { FR_CZ_USR_EV_CFG_OFST, 0, 1 }, 457 { FR_AZ_RX_CFG_REG_OFST, 0, 1 }, 458 { FR_AZ_TX_CFG_REG_OFST, 0, 1 }, 459 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 }, 460 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 }, 461 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 }, 462 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 }, 463 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 }, 464 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1}, 465 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1}, 466 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1}, 467 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1} 468}; 469 470static const uint32_t __siena_register_masks[] = { 471 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 472 0x000103FF, 0x00000000, 0x00000000, 0x00000000, 473 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000, 474 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF, 475 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF, 476 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000, 477 0x00000003, 0x00000000, 0x00000000, 0x00000000, 478 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 479 0x00000FFF, 0x00000000, 0x00000000, 0x00000000, 480 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 481 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 482 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 483 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000 484}; 485 486static efx_register_set_t __siena_tables[] = { 487 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP, 488 FR_AZ_RX_FILTER_TBL0_ROWS }, 489 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP, 490 FR_CZ_RX_MAC_FILTER_TBL0_ROWS }, 491 { FR_AZ_RX_DESC_PTR_TBL_OFST, 492 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS }, 493 { FR_AZ_TX_DESC_PTR_TBL_OFST, 494 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS }, 495 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS }, 496 { FR_CZ_TX_FILTER_TBL0_OFST, 497 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS }, 498 { FR_CZ_TX_MAC_FILTER_TBL0_OFST, 499 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS } 500}; 501 502static const uint32_t __siena_table_masks[] = { 503 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF, 504 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000, 505 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000, 506 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000, 507 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000, 508 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF, 509 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000, 510}; 511 512 __checkReturn efx_rc_t 513siena_nic_register_test( 514 __in efx_nic_t *enp) 515{ 516 efx_register_set_t *rsp; 517 const uint32_t *dwordp; 518 unsigned int nitems; 519 unsigned int count; 520 efx_rc_t rc; 521 522 /* Fill out the register mask entries */ 523 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks) 524 == EFX_ARRAY_SIZE(__siena_registers) * 4); 525 526 nitems = EFX_ARRAY_SIZE(__siena_registers); 527 dwordp = __siena_register_masks; 528 for (count = 0; count < nitems; ++count) { 529 rsp = __siena_registers + count; 530 rsp->mask.eo_u32[0] = *dwordp++; 531 rsp->mask.eo_u32[1] = *dwordp++; 532 rsp->mask.eo_u32[2] = *dwordp++; 533 rsp->mask.eo_u32[3] = *dwordp++; 534 } 535 536 /* Fill out the register table entries */ 537 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks) 538 == EFX_ARRAY_SIZE(__siena_tables) * 4); 539 540 nitems = EFX_ARRAY_SIZE(__siena_tables); 541 dwordp = __siena_table_masks; 542 for (count = 0; count < nitems; ++count) { 543 rsp = __siena_tables + count; 544 rsp->mask.eo_u32[0] = *dwordp++; 545 rsp->mask.eo_u32[1] = *dwordp++; 546 rsp->mask.eo_u32[2] = *dwordp++; 547 rsp->mask.eo_u32[3] = *dwordp++; 548 } 549 550 if ((rc = efx_nic_test_registers(enp, __siena_registers, 551 EFX_ARRAY_SIZE(__siena_registers))) != 0) 552 goto fail1; 553 554 if ((rc = efx_nic_test_tables(enp, __siena_tables, 555 EFX_PATTERN_BYTE_ALTERNATE, 556 EFX_ARRAY_SIZE(__siena_tables))) != 0) 557 goto fail2; 558 559 if ((rc = efx_nic_test_tables(enp, __siena_tables, 560 EFX_PATTERN_BYTE_CHANGING, 561 EFX_ARRAY_SIZE(__siena_tables))) != 0) 562 goto fail3; 563 564 if ((rc = efx_nic_test_tables(enp, __siena_tables, 565 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0) 566 goto fail4; 567 568 return (0); 569 570fail4: 571 EFSYS_PROBE(fail4); 572fail3: 573 EFSYS_PROBE(fail3); 574fail2: 575 EFSYS_PROBE(fail2); 576fail1: 577 EFSYS_PROBE1(fail1, efx_rc_t, rc); 578 579 return (rc); 580} 581 582#endif /* EFSYS_OPT_DIAG */ 583 584#endif /* EFSYS_OPT_SIENA */
|