1 /* 2 * Copyright (c) 2009-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #include "efx.h" 32 #include "efx_impl.h" 33 #include "mcdi_mon.h" 34 35 #if EFSYS_OPT_SIENA 36 37 static __checkReturn efx_rc_t 38 siena_nic_get_partn_mask( 39 __in efx_nic_t *enp, 40 __out unsigned int *maskp) 41 { 42 efx_mcdi_req_t req; 43 uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN, 44 MC_CMD_NVRAM_TYPES_OUT_LEN)]; 45 efx_rc_t rc; 46 47 (void) memset(payload, 0, sizeof (payload)); 48 req.emr_cmd = MC_CMD_NVRAM_TYPES; 49 req.emr_in_buf = payload; 50 req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN; 51 req.emr_out_buf = payload; 52 req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN; 53 54 efx_mcdi_execute(enp, &req); 55 56 if (req.emr_rc != 0) { 57 rc = req.emr_rc; 58 goto fail1; 59 } 60 61 if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) { 62 rc = EMSGSIZE; 63 goto fail2; 64 } 65 66 *maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES); 67 68 return (0); 69 70 fail2: 71 EFSYS_PROBE(fail2); 72 fail1: 73 EFSYS_PROBE1(fail1, efx_rc_t, rc); 74 75 return (rc); 76 } 77 78 static __checkReturn efx_rc_t 79 siena_board_cfg( 80 __in efx_nic_t *enp) 81 { 82 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 83 uint8_t mac_addr[6]; 84 efx_dword_t capabilities; 85 uint32_t board_type; 86 uint32_t nevq, nrxq, ntxq; 87 efx_rc_t rc; 88 89 /* External port identifier using one-based port numbering */ 90 encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port; 91 92 /* Board configuration */ 93 if ((rc = efx_mcdi_get_board_cfg(enp, &board_type, 94 &capabilities, mac_addr)) != 0) 95 goto fail1; 96 97 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 98 99 encp->enc_board_type = board_type; 100 101 /* Additional capabilities */ 102 encp->enc_clk_mult = 1; 103 if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) { 104 enp->en_features |= EFX_FEATURE_TURBO; 105 106 if (EFX_DWORD_FIELD(capabilities, 107 MC_CMD_CAPABILITIES_TURBO_ACTIVE)) { 108 encp->enc_clk_mult = 2; 109 } 110 } 111 112 encp->enc_evq_timer_quantum_ns = 113 EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult; 114 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 115 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000; 116 117 /* When hash header insertion is enabled, Siena inserts 16 bytes */ 118 encp->enc_rx_prefix_size = 16; 119 120 /* Alignment for receive packet DMA buffers */ 121 encp->enc_rx_buf_align_start = 1; 122 encp->enc_rx_buf_align_end = 1; 123 124 /* Alignment for WPTR updates */ 125 encp->enc_rx_push_align = 1; 126 127 /* Resource limits */ 128 rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq); 129 if (rc != 0) { 130 if (rc != ENOTSUP) 131 goto fail2; 132 133 nevq = 1024; 134 nrxq = EFX_RXQ_LIMIT_TARGET; 135 ntxq = EFX_TXQ_LIMIT_TARGET; 136 } 137 encp->enc_evq_limit = nevq; 138 encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq); 139 encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq); 140 141 encp->enc_buftbl_limit = SIENA_SRAM_ROWS - 142 (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) - 143 (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE)); 144 145 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 146 encp->enc_fw_assisted_tso_enabled = B_FALSE; 147 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE; 148 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 149 150 return (0); 151 152 fail2: 153 EFSYS_PROBE(fail2); 154 fail1: 155 EFSYS_PROBE1(fail1, efx_rc_t, rc); 156 157 return (rc); 158 } 159 160 static __checkReturn efx_rc_t 161 siena_phy_cfg( 162 __in efx_nic_t *enp) 163 { 164 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 165 efx_rc_t rc; 166 167 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 168 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 169 goto fail1; 170 171 #if EFSYS_OPT_PHY_STATS 172 /* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */ 173 siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask, 174 NULL, &encp->enc_phy_stat_mask, NULL); 175 #endif /* EFSYS_OPT_PHY_STATS */ 176 177 return (0); 178 179 fail1: 180 EFSYS_PROBE1(fail1, efx_rc_t, rc); 181 182 return (rc); 183 } 184 185 __checkReturn efx_rc_t 186 siena_nic_probe( 187 __in efx_nic_t *enp) 188 { 189 efx_port_t *epp = &(enp->en_port); 190 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 191 siena_link_state_t sls; 192 unsigned int mask; 193 efx_oword_t oword; 194 efx_rc_t rc; 195 196 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 197 198 /* Test BIU */ 199 if ((rc = efx_nic_biu_test(enp)) != 0) 200 goto fail1; 201 202 /* Clear the region register */ 203 EFX_POPULATE_OWORD_4(oword, 204 FRF_AZ_ADR_REGION0, 0, 205 FRF_AZ_ADR_REGION1, (1 << 16), 206 FRF_AZ_ADR_REGION2, (2 << 16), 207 FRF_AZ_ADR_REGION3, (3 << 16)); 208 EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword); 209 210 /* Read clear any assertion state */ 211 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 212 goto fail2; 213 214 /* Exit the assertion handler */ 215 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 216 goto fail3; 217 218 /* Wrestle control from the BMC */ 219 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 220 goto fail4; 221 222 if ((rc = siena_board_cfg(enp)) != 0) 223 goto fail5; 224 225 if ((rc = siena_phy_cfg(enp)) != 0) 226 goto fail6; 227 228 /* Obtain the default PHY advertised capabilities */ 229 if ((rc = siena_nic_reset(enp)) != 0) 230 goto fail7; 231 if ((rc = siena_phy_get_link(enp, &sls)) != 0) 232 goto fail8; 233 epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask; 234 epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; 235 236 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 237 if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0) 238 goto fail9; 239 enp->en_u.siena.enu_partn_mask = mask; 240 #endif 241 242 #if EFSYS_OPT_MAC_STATS 243 /* Wipe the MAC statistics */ 244 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 245 goto fail10; 246 #endif 247 248 #if EFSYS_OPT_LOOPBACK 249 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 250 goto fail11; 251 #endif 252 253 #if EFSYS_OPT_MON_STATS 254 if ((rc = mcdi_mon_cfg_build(enp)) != 0) 255 goto fail12; 256 #endif 257 258 encp->enc_features = enp->en_features; 259 260 return (0); 261 262 #if EFSYS_OPT_MON_STATS 263 fail12: 264 EFSYS_PROBE(fail12); 265 #endif 266 #if EFSYS_OPT_LOOPBACK 267 fail11: 268 EFSYS_PROBE(fail11); 269 #endif 270 #if EFSYS_OPT_MAC_STATS 271 fail10: 272 EFSYS_PROBE(fail10); 273 #endif 274 #if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM 275 fail9: 276 EFSYS_PROBE(fail9); 277 #endif 278 fail8: 279 EFSYS_PROBE(fail8); 280 fail7: 281 EFSYS_PROBE(fail7); 282 fail6: 283 EFSYS_PROBE(fail6); 284 fail5: 285 EFSYS_PROBE(fail5); 286 fail4: 287 EFSYS_PROBE(fail4); 288 fail3: 289 EFSYS_PROBE(fail3); 290 fail2: 291 EFSYS_PROBE(fail2); 292 fail1: 293 EFSYS_PROBE1(fail1, efx_rc_t, rc); 294 295 return (rc); 296 } 297 298 __checkReturn efx_rc_t 299 siena_nic_reset( 300 __in efx_nic_t *enp) 301 { 302 efx_mcdi_req_t req; 303 efx_rc_t rc; 304 305 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 306 307 /* siena_nic_reset() is called to recover from BADASSERT failures. */ 308 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 309 goto fail1; 310 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 311 goto fail2; 312 313 /* 314 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied 315 * for backwards compatibility with PORT_RESET_IN_LEN. 316 */ 317 EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0); 318 319 req.emr_cmd = MC_CMD_ENTITY_RESET; 320 req.emr_in_buf = NULL; 321 req.emr_in_length = 0; 322 req.emr_out_buf = NULL; 323 req.emr_out_length = 0; 324 325 efx_mcdi_execute(enp, &req); 326 327 if (req.emr_rc != 0) { 328 rc = req.emr_rc; 329 goto fail3; 330 } 331 332 return (0); 333 334 fail3: 335 EFSYS_PROBE(fail3); 336 fail2: 337 EFSYS_PROBE(fail2); 338 fail1: 339 EFSYS_PROBE1(fail1, efx_rc_t, rc); 340 341 return (0); 342 } 343 344 static void 345 siena_nic_rx_cfg( 346 __in efx_nic_t *enp) 347 { 348 efx_oword_t oword; 349 350 /* 351 * RX_INGR_EN is always enabled on Siena, because we rely on 352 * the RX parser to be resiliant to missing SOP/EOP. 353 */ 354 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword); 355 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1); 356 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword); 357 358 /* Disable parsing of additional 802.1Q in Q packets */ 359 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 360 EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0); 361 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword); 362 } 363 364 static void 365 siena_nic_usrev_dis( 366 __in efx_nic_t *enp) 367 { 368 efx_oword_t oword; 369 370 EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1); 371 EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword); 372 } 373 374 __checkReturn efx_rc_t 375 siena_nic_init( 376 __in efx_nic_t *enp) 377 { 378 efx_rc_t rc; 379 380 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 381 382 /* Enable reporting of some events (e.g. link change) */ 383 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 384 goto fail1; 385 386 siena_sram_init(enp); 387 388 /* Configure Siena's RX block */ 389 siena_nic_rx_cfg(enp); 390 391 /* Disable USR_EVents for now */ 392 siena_nic_usrev_dis(enp); 393 394 /* bug17057: Ensure set_link is called */ 395 if ((rc = siena_phy_reconfigure(enp)) != 0) 396 goto fail2; 397 398 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1; 399 400 return (0); 401 402 fail2: 403 EFSYS_PROBE(fail2); 404 fail1: 405 EFSYS_PROBE1(fail1, efx_rc_t, rc); 406 407 return (rc); 408 } 409 410 void 411 siena_nic_fini( 412 __in efx_nic_t *enp) 413 { 414 _NOTE(ARGUNUSED(enp)) 415 } 416 417 void 418 siena_nic_unprobe( 419 __in efx_nic_t *enp) 420 { 421 #if EFSYS_OPT_MON_STATS 422 mcdi_mon_cfg_free(enp); 423 #endif /* EFSYS_OPT_MON_STATS */ 424 (void) efx_mcdi_drv_attach(enp, B_FALSE); 425 } 426 427 #if EFSYS_OPT_DIAG 428 429 static efx_register_set_t __siena_registers[] = { 430 { FR_AZ_ADR_REGION_REG_OFST, 0, 1 }, 431 { FR_CZ_USR_EV_CFG_OFST, 0, 1 }, 432 { FR_AZ_RX_CFG_REG_OFST, 0, 1 }, 433 { FR_AZ_TX_CFG_REG_OFST, 0, 1 }, 434 { FR_AZ_TX_RESERVED_REG_OFST, 0, 1 }, 435 { FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 }, 436 { FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 }, 437 { FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 }, 438 { FR_AZ_DP_CTRL_REG_OFST, 0, 1 }, 439 { FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1}, 440 { FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1}, 441 { FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1}, 442 { FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1} 443 }; 444 445 static const uint32_t __siena_register_masks[] = { 446 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 447 0x000103FF, 0x00000000, 0x00000000, 0x00000000, 448 0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000, 449 0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF, 450 0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF, 451 0x001FFFFF, 0x00000000, 0x00000000, 0x00000000, 452 0x00000003, 0x00000000, 0x00000000, 0x00000000, 453 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 454 0x00000FFF, 0x00000000, 0x00000000, 0x00000000, 455 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 456 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 457 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 458 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000 459 }; 460 461 static efx_register_set_t __siena_tables[] = { 462 { FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP, 463 FR_AZ_RX_FILTER_TBL0_ROWS }, 464 { FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP, 465 FR_CZ_RX_MAC_FILTER_TBL0_ROWS }, 466 { FR_AZ_RX_DESC_PTR_TBL_OFST, 467 FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS }, 468 { FR_AZ_TX_DESC_PTR_TBL_OFST, 469 FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS }, 470 { FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS }, 471 { FR_CZ_TX_FILTER_TBL0_OFST, 472 FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS }, 473 { FR_CZ_TX_MAC_FILTER_TBL0_OFST, 474 FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS } 475 }; 476 477 static const uint32_t __siena_table_masks[] = { 478 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF, 479 0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000, 480 0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000, 481 0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000, 482 0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000, 483 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF, 484 0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000, 485 }; 486 487 __checkReturn efx_rc_t 488 siena_nic_register_test( 489 __in efx_nic_t *enp) 490 { 491 efx_register_set_t *rsp; 492 const uint32_t *dwordp; 493 unsigned int nitems; 494 unsigned int count; 495 efx_rc_t rc; 496 497 /* Fill out the register mask entries */ 498 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks) 499 == EFX_ARRAY_SIZE(__siena_registers) * 4); 500 501 nitems = EFX_ARRAY_SIZE(__siena_registers); 502 dwordp = __siena_register_masks; 503 for (count = 0; count < nitems; ++count) { 504 rsp = __siena_registers + count; 505 rsp->mask.eo_u32[0] = *dwordp++; 506 rsp->mask.eo_u32[1] = *dwordp++; 507 rsp->mask.eo_u32[2] = *dwordp++; 508 rsp->mask.eo_u32[3] = *dwordp++; 509 } 510 511 /* Fill out the register table entries */ 512 EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks) 513 == EFX_ARRAY_SIZE(__siena_tables) * 4); 514 515 nitems = EFX_ARRAY_SIZE(__siena_tables); 516 dwordp = __siena_table_masks; 517 for (count = 0; count < nitems; ++count) { 518 rsp = __siena_tables + count; 519 rsp->mask.eo_u32[0] = *dwordp++; 520 rsp->mask.eo_u32[1] = *dwordp++; 521 rsp->mask.eo_u32[2] = *dwordp++; 522 rsp->mask.eo_u32[3] = *dwordp++; 523 } 524 525 if ((rc = efx_nic_test_registers(enp, __siena_registers, 526 EFX_ARRAY_SIZE(__siena_registers))) != 0) 527 goto fail1; 528 529 if ((rc = efx_nic_test_tables(enp, __siena_tables, 530 EFX_PATTERN_BYTE_ALTERNATE, 531 EFX_ARRAY_SIZE(__siena_tables))) != 0) 532 goto fail2; 533 534 if ((rc = efx_nic_test_tables(enp, __siena_tables, 535 EFX_PATTERN_BYTE_CHANGING, 536 EFX_ARRAY_SIZE(__siena_tables))) != 0) 537 goto fail3; 538 539 if ((rc = efx_nic_test_tables(enp, __siena_tables, 540 EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0) 541 goto fail4; 542 543 return (0); 544 545 fail4: 546 EFSYS_PROBE(fail4); 547 fail3: 548 EFSYS_PROBE(fail3); 549 fail2: 550 EFSYS_PROBE(fail2); 551 fail1: 552 EFSYS_PROBE1(fail1, efx_rc_t, rc); 553 554 return (rc); 555 } 556 557 #endif /* EFSYS_OPT_DIAG */ 558 559 #endif /* EFSYS_OPT_SIENA */