1 /*- 2 * Copyright (c) 2012-2016 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 <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include "efx.h" 35 #include "efx_impl.h" 36 #if EFSYS_OPT_MON_MCDI 37 #include "mcdi_mon.h" 38 #endif 39 40 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 41 42 #include "ef10_tlv_layout.h" 43 44 __checkReturn efx_rc_t 45 efx_mcdi_get_port_assignment( 46 __in efx_nic_t *enp, 47 __out uint32_t *portp) 48 { 49 efx_mcdi_req_t req; 50 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN, 51 MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN); 52 efx_rc_t rc; 53 54 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 55 enp->en_family == EFX_FAMILY_MEDFORD || 56 enp->en_family == EFX_FAMILY_MEDFORD2); 57 58 req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT; 59 req.emr_in_buf = payload; 60 req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN; 61 req.emr_out_buf = payload; 62 req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN; 63 64 efx_mcdi_execute(enp, &req); 65 66 if (req.emr_rc != 0) { 67 rc = req.emr_rc; 68 goto fail1; 69 } 70 71 if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) { 72 rc = EMSGSIZE; 73 goto fail2; 74 } 75 76 *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT); 77 78 return (0); 79 80 fail2: 81 EFSYS_PROBE(fail2); 82 fail1: 83 EFSYS_PROBE1(fail1, efx_rc_t, rc); 84 85 return (rc); 86 } 87 88 __checkReturn efx_rc_t 89 efx_mcdi_get_port_modes( 90 __in efx_nic_t *enp, 91 __out uint32_t *modesp, 92 __out_opt uint32_t *current_modep, 93 __out_opt uint32_t *default_modep) 94 { 95 efx_mcdi_req_t req; 96 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_MODES_IN_LEN, 97 MC_CMD_GET_PORT_MODES_OUT_LEN); 98 efx_rc_t rc; 99 100 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 101 enp->en_family == EFX_FAMILY_MEDFORD || 102 enp->en_family == EFX_FAMILY_MEDFORD2); 103 104 req.emr_cmd = MC_CMD_GET_PORT_MODES; 105 req.emr_in_buf = payload; 106 req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN; 107 req.emr_out_buf = payload; 108 req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN; 109 110 efx_mcdi_execute(enp, &req); 111 112 if (req.emr_rc != 0) { 113 rc = req.emr_rc; 114 goto fail1; 115 } 116 117 /* 118 * Require only Modes and DefaultMode fields, unless the current mode 119 * was requested (CurrentMode field was added for Medford). 120 */ 121 if (req.emr_out_length_used < 122 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) { 123 rc = EMSGSIZE; 124 goto fail2; 125 } 126 if ((current_modep != NULL) && (req.emr_out_length_used < 127 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST + 4)) { 128 rc = EMSGSIZE; 129 goto fail3; 130 } 131 132 *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES); 133 134 if (current_modep != NULL) { 135 *current_modep = MCDI_OUT_DWORD(req, 136 GET_PORT_MODES_OUT_CURRENT_MODE); 137 } 138 139 if (default_modep != NULL) { 140 *default_modep = MCDI_OUT_DWORD(req, 141 GET_PORT_MODES_OUT_DEFAULT_MODE); 142 } 143 144 return (0); 145 146 fail3: 147 EFSYS_PROBE(fail3); 148 fail2: 149 EFSYS_PROBE(fail2); 150 fail1: 151 EFSYS_PROBE1(fail1, efx_rc_t, rc); 152 153 return (rc); 154 } 155 156 __checkReturn efx_rc_t 157 ef10_nic_get_port_mode_bandwidth( 158 __in efx_nic_t *enp, 159 __out uint32_t *bandwidth_mbpsp) 160 { 161 uint32_t port_modes; 162 uint32_t current_mode; 163 efx_port_t *epp = &(enp->en_port); 164 165 uint32_t single_lane; 166 uint32_t dual_lane; 167 uint32_t quad_lane; 168 uint32_t bandwidth; 169 efx_rc_t rc; 170 171 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, 172 ¤t_mode, NULL)) != 0) { 173 /* No port mode info available. */ 174 goto fail1; 175 } 176 177 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_25000FDX)) 178 single_lane = 25000; 179 else 180 single_lane = 10000; 181 182 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_50000FDX)) 183 dual_lane = 50000; 184 else 185 dual_lane = 20000; 186 187 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_100000FDX)) 188 quad_lane = 100000; 189 else 190 quad_lane = 40000; 191 192 switch (current_mode) { 193 case TLV_PORT_MODE_1x1_NA: /* mode 0 */ 194 bandwidth = single_lane; 195 break; 196 case TLV_PORT_MODE_1x2_NA: /* mode 10 */ 197 case TLV_PORT_MODE_NA_1x2: /* mode 11 */ 198 bandwidth = dual_lane; 199 break; 200 case TLV_PORT_MODE_1x1_1x1: /* mode 2 */ 201 bandwidth = single_lane + single_lane; 202 break; 203 case TLV_PORT_MODE_4x1_NA: /* mode 4 */ 204 case TLV_PORT_MODE_NA_4x1: /* mode 8 */ 205 bandwidth = 4 * single_lane; 206 break; 207 case TLV_PORT_MODE_2x1_2x1: /* mode 5 */ 208 bandwidth = (2 * single_lane) + (2 * single_lane); 209 break; 210 case TLV_PORT_MODE_1x2_1x2: /* mode 12 */ 211 bandwidth = dual_lane + dual_lane; 212 break; 213 case TLV_PORT_MODE_1x2_2x1: /* mode 17 */ 214 case TLV_PORT_MODE_2x1_1x2: /* mode 18 */ 215 bandwidth = dual_lane + (2 * single_lane); 216 break; 217 /* Legacy Medford-only mode. Do not use (see bug63270) */ 218 case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2: /* mode 9 */ 219 bandwidth = 4 * single_lane; 220 break; 221 case TLV_PORT_MODE_1x4_NA: /* mode 1 */ 222 case TLV_PORT_MODE_NA_1x4: /* mode 22 */ 223 bandwidth = quad_lane; 224 break; 225 case TLV_PORT_MODE_2x2_NA: /* mode 13 */ 226 case TLV_PORT_MODE_NA_2x2: /* mode 14 */ 227 bandwidth = 2 * dual_lane; 228 break; 229 case TLV_PORT_MODE_1x4_2x1: /* mode 6 */ 230 case TLV_PORT_MODE_2x1_1x4: /* mode 7 */ 231 bandwidth = quad_lane + (2 * single_lane); 232 break; 233 case TLV_PORT_MODE_1x4_1x2: /* mode 15 */ 234 case TLV_PORT_MODE_1x2_1x4: /* mode 16 */ 235 bandwidth = quad_lane + dual_lane; 236 break; 237 case TLV_PORT_MODE_1x4_1x4: /* mode 3 */ 238 bandwidth = quad_lane + quad_lane; 239 break; 240 default: 241 rc = EINVAL; 242 goto fail2; 243 } 244 245 *bandwidth_mbpsp = bandwidth; 246 247 return (0); 248 249 fail2: 250 EFSYS_PROBE(fail2); 251 fail1: 252 EFSYS_PROBE1(fail1, efx_rc_t, rc); 253 254 return (rc); 255 } 256 257 static __checkReturn efx_rc_t 258 efx_mcdi_vadaptor_alloc( 259 __in efx_nic_t *enp, 260 __in uint32_t port_id) 261 { 262 efx_mcdi_req_t req; 263 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_ALLOC_IN_LEN, 264 MC_CMD_VADAPTOR_ALLOC_OUT_LEN); 265 efx_rc_t rc; 266 267 EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL); 268 269 req.emr_cmd = MC_CMD_VADAPTOR_ALLOC; 270 req.emr_in_buf = payload; 271 req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN; 272 req.emr_out_buf = payload; 273 req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN; 274 275 MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id); 276 MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS, 277 VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED, 278 enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0); 279 280 efx_mcdi_execute(enp, &req); 281 282 if (req.emr_rc != 0) { 283 rc = req.emr_rc; 284 goto fail1; 285 } 286 287 return (0); 288 289 fail1: 290 EFSYS_PROBE1(fail1, efx_rc_t, rc); 291 292 return (rc); 293 } 294 295 static __checkReturn efx_rc_t 296 efx_mcdi_vadaptor_free( 297 __in efx_nic_t *enp, 298 __in uint32_t port_id) 299 { 300 efx_mcdi_req_t req; 301 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_FREE_IN_LEN, 302 MC_CMD_VADAPTOR_FREE_OUT_LEN); 303 efx_rc_t rc; 304 305 req.emr_cmd = MC_CMD_VADAPTOR_FREE; 306 req.emr_in_buf = payload; 307 req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN; 308 req.emr_out_buf = payload; 309 req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN; 310 311 MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id); 312 313 efx_mcdi_execute(enp, &req); 314 315 if (req.emr_rc != 0) { 316 rc = req.emr_rc; 317 goto fail1; 318 } 319 320 return (0); 321 322 fail1: 323 EFSYS_PROBE1(fail1, efx_rc_t, rc); 324 325 return (rc); 326 } 327 328 __checkReturn efx_rc_t 329 efx_mcdi_get_mac_address_pf( 330 __in efx_nic_t *enp, 331 __out_ecount_opt(6) uint8_t mac_addrp[6]) 332 { 333 efx_mcdi_req_t req; 334 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_MAC_ADDRESSES_IN_LEN, 335 MC_CMD_GET_MAC_ADDRESSES_OUT_LEN); 336 efx_rc_t rc; 337 338 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 339 enp->en_family == EFX_FAMILY_MEDFORD || 340 enp->en_family == EFX_FAMILY_MEDFORD2); 341 342 req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES; 343 req.emr_in_buf = payload; 344 req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN; 345 req.emr_out_buf = payload; 346 req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN; 347 348 efx_mcdi_execute(enp, &req); 349 350 if (req.emr_rc != 0) { 351 rc = req.emr_rc; 352 goto fail1; 353 } 354 355 if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) { 356 rc = EMSGSIZE; 357 goto fail2; 358 } 359 360 if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) { 361 rc = ENOENT; 362 goto fail3; 363 } 364 365 if (mac_addrp != NULL) { 366 uint8_t *addrp; 367 368 addrp = MCDI_OUT2(req, uint8_t, 369 GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE); 370 371 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 372 } 373 374 return (0); 375 376 fail3: 377 EFSYS_PROBE(fail3); 378 fail2: 379 EFSYS_PROBE(fail2); 380 fail1: 381 EFSYS_PROBE1(fail1, efx_rc_t, rc); 382 383 return (rc); 384 } 385 386 __checkReturn efx_rc_t 387 efx_mcdi_get_mac_address_vf( 388 __in efx_nic_t *enp, 389 __out_ecount_opt(6) uint8_t mac_addrp[6]) 390 { 391 efx_mcdi_req_t req; 392 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN, 393 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX); 394 efx_rc_t rc; 395 396 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 397 enp->en_family == EFX_FAMILY_MEDFORD || 398 enp->en_family == EFX_FAMILY_MEDFORD2); 399 400 req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES; 401 req.emr_in_buf = payload; 402 req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN; 403 req.emr_out_buf = payload; 404 req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX; 405 406 MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID, 407 EVB_PORT_ID_ASSIGNED); 408 409 efx_mcdi_execute(enp, &req); 410 411 if (req.emr_rc != 0) { 412 rc = req.emr_rc; 413 goto fail1; 414 } 415 416 if (req.emr_out_length_used < 417 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) { 418 rc = EMSGSIZE; 419 goto fail2; 420 } 421 422 if (MCDI_OUT_DWORD(req, 423 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) { 424 rc = ENOENT; 425 goto fail3; 426 } 427 428 if (mac_addrp != NULL) { 429 uint8_t *addrp; 430 431 addrp = MCDI_OUT2(req, uint8_t, 432 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR); 433 434 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 435 } 436 437 return (0); 438 439 fail3: 440 EFSYS_PROBE(fail3); 441 fail2: 442 EFSYS_PROBE(fail2); 443 fail1: 444 EFSYS_PROBE1(fail1, efx_rc_t, rc); 445 446 return (rc); 447 } 448 449 __checkReturn efx_rc_t 450 efx_mcdi_get_clock( 451 __in efx_nic_t *enp, 452 __out uint32_t *sys_freqp, 453 __out uint32_t *dpcpu_freqp) 454 { 455 efx_mcdi_req_t req; 456 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CLOCK_IN_LEN, 457 MC_CMD_GET_CLOCK_OUT_LEN); 458 efx_rc_t rc; 459 460 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 461 enp->en_family == EFX_FAMILY_MEDFORD || 462 enp->en_family == EFX_FAMILY_MEDFORD2); 463 464 req.emr_cmd = MC_CMD_GET_CLOCK; 465 req.emr_in_buf = payload; 466 req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN; 467 req.emr_out_buf = payload; 468 req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN; 469 470 efx_mcdi_execute(enp, &req); 471 472 if (req.emr_rc != 0) { 473 rc = req.emr_rc; 474 goto fail1; 475 } 476 477 if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) { 478 rc = EMSGSIZE; 479 goto fail2; 480 } 481 482 *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ); 483 if (*sys_freqp == 0) { 484 rc = EINVAL; 485 goto fail3; 486 } 487 *dpcpu_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_DPCPU_FREQ); 488 if (*dpcpu_freqp == 0) { 489 rc = EINVAL; 490 goto fail4; 491 } 492 493 return (0); 494 495 fail4: 496 EFSYS_PROBE(fail4); 497 fail3: 498 EFSYS_PROBE(fail3); 499 fail2: 500 EFSYS_PROBE(fail2); 501 fail1: 502 EFSYS_PROBE1(fail1, efx_rc_t, rc); 503 504 return (rc); 505 } 506 507 __checkReturn efx_rc_t 508 efx_mcdi_get_rxdp_config( 509 __in efx_nic_t *enp, 510 __out uint32_t *end_paddingp) 511 { 512 efx_mcdi_req_t req; 513 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RXDP_CONFIG_IN_LEN, 514 MC_CMD_GET_RXDP_CONFIG_OUT_LEN); 515 uint32_t end_padding; 516 efx_rc_t rc; 517 518 req.emr_cmd = MC_CMD_GET_RXDP_CONFIG; 519 req.emr_in_buf = payload; 520 req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN; 521 req.emr_out_buf = payload; 522 req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN; 523 524 efx_mcdi_execute(enp, &req); 525 if (req.emr_rc != 0) { 526 rc = req.emr_rc; 527 goto fail1; 528 } 529 530 if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA, 531 GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) { 532 /* RX DMA end padding is disabled */ 533 end_padding = 0; 534 } else { 535 switch (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA, 536 GET_RXDP_CONFIG_OUT_PAD_HOST_LEN)) { 537 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64: 538 end_padding = 64; 539 break; 540 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128: 541 end_padding = 128; 542 break; 543 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256: 544 end_padding = 256; 545 break; 546 default: 547 rc = ENOTSUP; 548 goto fail2; 549 } 550 } 551 552 *end_paddingp = end_padding; 553 554 return (0); 555 556 fail2: 557 EFSYS_PROBE(fail2); 558 fail1: 559 EFSYS_PROBE1(fail1, efx_rc_t, rc); 560 561 return (rc); 562 } 563 564 __checkReturn efx_rc_t 565 efx_mcdi_get_vector_cfg( 566 __in efx_nic_t *enp, 567 __out_opt uint32_t *vec_basep, 568 __out_opt uint32_t *pf_nvecp, 569 __out_opt uint32_t *vf_nvecp) 570 { 571 efx_mcdi_req_t req; 572 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_VECTOR_CFG_IN_LEN, 573 MC_CMD_GET_VECTOR_CFG_OUT_LEN); 574 efx_rc_t rc; 575 576 req.emr_cmd = MC_CMD_GET_VECTOR_CFG; 577 req.emr_in_buf = payload; 578 req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN; 579 req.emr_out_buf = payload; 580 req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN; 581 582 efx_mcdi_execute(enp, &req); 583 584 if (req.emr_rc != 0) { 585 rc = req.emr_rc; 586 goto fail1; 587 } 588 589 if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) { 590 rc = EMSGSIZE; 591 goto fail2; 592 } 593 594 if (vec_basep != NULL) 595 *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE); 596 if (pf_nvecp != NULL) 597 *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF); 598 if (vf_nvecp != NULL) 599 *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF); 600 601 return (0); 602 603 fail2: 604 EFSYS_PROBE(fail2); 605 fail1: 606 EFSYS_PROBE1(fail1, efx_rc_t, rc); 607 608 return (rc); 609 } 610 611 static __checkReturn efx_rc_t 612 efx_mcdi_alloc_vis( 613 __in efx_nic_t *enp, 614 __in uint32_t min_vi_count, 615 __in uint32_t max_vi_count, 616 __out uint32_t *vi_basep, 617 __out uint32_t *vi_countp, 618 __out uint32_t *vi_shiftp) 619 { 620 efx_mcdi_req_t req; 621 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN, 622 MC_CMD_ALLOC_VIS_EXT_OUT_LEN); 623 efx_rc_t rc; 624 625 if (vi_countp == NULL) { 626 rc = EINVAL; 627 goto fail1; 628 } 629 630 req.emr_cmd = MC_CMD_ALLOC_VIS; 631 req.emr_in_buf = payload; 632 req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN; 633 req.emr_out_buf = payload; 634 req.emr_out_length = MC_CMD_ALLOC_VIS_EXT_OUT_LEN; 635 636 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count); 637 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count); 638 639 efx_mcdi_execute(enp, &req); 640 641 if (req.emr_rc != 0) { 642 rc = req.emr_rc; 643 goto fail2; 644 } 645 646 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) { 647 rc = EMSGSIZE; 648 goto fail3; 649 } 650 651 *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE); 652 *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT); 653 654 /* Report VI_SHIFT if available (always zero for Huntington) */ 655 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN) 656 *vi_shiftp = 0; 657 else 658 *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT); 659 660 return (0); 661 662 fail3: 663 EFSYS_PROBE(fail3); 664 fail2: 665 EFSYS_PROBE(fail2); 666 fail1: 667 EFSYS_PROBE1(fail1, efx_rc_t, rc); 668 669 return (rc); 670 } 671 672 673 static __checkReturn efx_rc_t 674 efx_mcdi_free_vis( 675 __in efx_nic_t *enp) 676 { 677 efx_mcdi_req_t req; 678 efx_rc_t rc; 679 680 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0); 681 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0); 682 683 req.emr_cmd = MC_CMD_FREE_VIS; 684 req.emr_in_buf = NULL; 685 req.emr_in_length = 0; 686 req.emr_out_buf = NULL; 687 req.emr_out_length = 0; 688 689 efx_mcdi_execute_quiet(enp, &req); 690 691 /* Ignore ELREADY (no allocated VIs, so nothing to free) */ 692 if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) { 693 rc = req.emr_rc; 694 goto fail1; 695 } 696 697 return (0); 698 699 fail1: 700 EFSYS_PROBE1(fail1, efx_rc_t, rc); 701 702 return (rc); 703 } 704 705 706 static __checkReturn efx_rc_t 707 efx_mcdi_alloc_piobuf( 708 __in efx_nic_t *enp, 709 __out efx_piobuf_handle_t *handlep) 710 { 711 efx_mcdi_req_t req; 712 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN, 713 MC_CMD_ALLOC_PIOBUF_OUT_LEN); 714 efx_rc_t rc; 715 716 if (handlep == NULL) { 717 rc = EINVAL; 718 goto fail1; 719 } 720 721 req.emr_cmd = MC_CMD_ALLOC_PIOBUF; 722 req.emr_in_buf = payload; 723 req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN; 724 req.emr_out_buf = payload; 725 req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN; 726 727 efx_mcdi_execute_quiet(enp, &req); 728 729 if (req.emr_rc != 0) { 730 rc = req.emr_rc; 731 goto fail2; 732 } 733 734 if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) { 735 rc = EMSGSIZE; 736 goto fail3; 737 } 738 739 *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE); 740 741 return (0); 742 743 fail3: 744 EFSYS_PROBE(fail3); 745 fail2: 746 EFSYS_PROBE(fail2); 747 fail1: 748 EFSYS_PROBE1(fail1, efx_rc_t, rc); 749 750 return (rc); 751 } 752 753 static __checkReturn efx_rc_t 754 efx_mcdi_free_piobuf( 755 __in efx_nic_t *enp, 756 __in efx_piobuf_handle_t handle) 757 { 758 efx_mcdi_req_t req; 759 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN, 760 MC_CMD_FREE_PIOBUF_OUT_LEN); 761 efx_rc_t rc; 762 763 req.emr_cmd = MC_CMD_FREE_PIOBUF; 764 req.emr_in_buf = payload; 765 req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN; 766 req.emr_out_buf = payload; 767 req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN; 768 769 MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle); 770 771 efx_mcdi_execute_quiet(enp, &req); 772 773 if (req.emr_rc != 0) { 774 rc = req.emr_rc; 775 goto fail1; 776 } 777 778 return (0); 779 780 fail1: 781 EFSYS_PROBE1(fail1, efx_rc_t, rc); 782 783 return (rc); 784 } 785 786 static __checkReturn efx_rc_t 787 efx_mcdi_link_piobuf( 788 __in efx_nic_t *enp, 789 __in uint32_t vi_index, 790 __in efx_piobuf_handle_t handle) 791 { 792 efx_mcdi_req_t req; 793 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN, 794 MC_CMD_LINK_PIOBUF_OUT_LEN); 795 efx_rc_t rc; 796 797 req.emr_cmd = MC_CMD_LINK_PIOBUF; 798 req.emr_in_buf = payload; 799 req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN; 800 req.emr_out_buf = payload; 801 req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN; 802 803 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle); 804 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 805 806 efx_mcdi_execute(enp, &req); 807 808 if (req.emr_rc != 0) { 809 rc = req.emr_rc; 810 goto fail1; 811 } 812 813 return (0); 814 815 fail1: 816 EFSYS_PROBE1(fail1, efx_rc_t, rc); 817 818 return (rc); 819 } 820 821 static __checkReturn efx_rc_t 822 efx_mcdi_unlink_piobuf( 823 __in efx_nic_t *enp, 824 __in uint32_t vi_index) 825 { 826 efx_mcdi_req_t req; 827 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN, 828 MC_CMD_UNLINK_PIOBUF_OUT_LEN); 829 efx_rc_t rc; 830 831 req.emr_cmd = MC_CMD_UNLINK_PIOBUF; 832 req.emr_in_buf = payload; 833 req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN; 834 req.emr_out_buf = payload; 835 req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN; 836 837 MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 838 839 efx_mcdi_execute_quiet(enp, &req); 840 841 if (req.emr_rc != 0) { 842 rc = req.emr_rc; 843 goto fail1; 844 } 845 846 return (0); 847 848 fail1: 849 EFSYS_PROBE1(fail1, efx_rc_t, rc); 850 851 return (rc); 852 } 853 854 static void 855 ef10_nic_alloc_piobufs( 856 __in efx_nic_t *enp, 857 __in uint32_t max_piobuf_count) 858 { 859 efx_piobuf_handle_t *handlep; 860 unsigned int i; 861 862 EFSYS_ASSERT3U(max_piobuf_count, <=, 863 EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle)); 864 865 enp->en_arch.ef10.ena_piobuf_count = 0; 866 867 for (i = 0; i < max_piobuf_count; i++) { 868 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 869 870 if (efx_mcdi_alloc_piobuf(enp, handlep) != 0) 871 goto fail1; 872 873 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0; 874 enp->en_arch.ef10.ena_piobuf_count++; 875 } 876 877 return; 878 879 fail1: 880 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 881 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 882 883 (void) efx_mcdi_free_piobuf(enp, *handlep); 884 *handlep = EFX_PIOBUF_HANDLE_INVALID; 885 } 886 enp->en_arch.ef10.ena_piobuf_count = 0; 887 } 888 889 890 static void 891 ef10_nic_free_piobufs( 892 __in efx_nic_t *enp) 893 { 894 efx_piobuf_handle_t *handlep; 895 unsigned int i; 896 897 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 898 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 899 900 (void) efx_mcdi_free_piobuf(enp, *handlep); 901 *handlep = EFX_PIOBUF_HANDLE_INVALID; 902 } 903 enp->en_arch.ef10.ena_piobuf_count = 0; 904 } 905 906 /* Sub-allocate a block from a piobuf */ 907 __checkReturn efx_rc_t 908 ef10_nic_pio_alloc( 909 __inout efx_nic_t *enp, 910 __out uint32_t *bufnump, 911 __out efx_piobuf_handle_t *handlep, 912 __out uint32_t *blknump, 913 __out uint32_t *offsetp, 914 __out size_t *sizep) 915 { 916 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 917 efx_drv_cfg_t *edcp = &enp->en_drv_cfg; 918 uint32_t blk_per_buf; 919 uint32_t buf, blk; 920 efx_rc_t rc; 921 922 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 923 enp->en_family == EFX_FAMILY_MEDFORD || 924 enp->en_family == EFX_FAMILY_MEDFORD2); 925 EFSYS_ASSERT(bufnump); 926 EFSYS_ASSERT(handlep); 927 EFSYS_ASSERT(blknump); 928 EFSYS_ASSERT(offsetp); 929 EFSYS_ASSERT(sizep); 930 931 if ((edcp->edc_pio_alloc_size == 0) || 932 (enp->en_arch.ef10.ena_piobuf_count == 0)) { 933 rc = ENOMEM; 934 goto fail1; 935 } 936 blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size; 937 938 for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) { 939 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf]; 940 941 if (~(*map) == 0) 942 continue; 943 944 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map))); 945 for (blk = 0; blk < blk_per_buf; blk++) { 946 if ((*map & (1u << blk)) == 0) { 947 *map |= (1u << blk); 948 goto done; 949 } 950 } 951 } 952 rc = ENOMEM; 953 goto fail2; 954 955 done: 956 *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf]; 957 *bufnump = buf; 958 *blknump = blk; 959 *sizep = edcp->edc_pio_alloc_size; 960 *offsetp = blk * (*sizep); 961 962 return (0); 963 964 fail2: 965 EFSYS_PROBE(fail2); 966 fail1: 967 EFSYS_PROBE1(fail1, efx_rc_t, rc); 968 969 return (rc); 970 } 971 972 /* Free a piobuf sub-allocated block */ 973 __checkReturn efx_rc_t 974 ef10_nic_pio_free( 975 __inout efx_nic_t *enp, 976 __in uint32_t bufnum, 977 __in uint32_t blknum) 978 { 979 uint32_t *map; 980 efx_rc_t rc; 981 982 if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) || 983 (blknum >= (8 * sizeof (*map)))) { 984 rc = EINVAL; 985 goto fail1; 986 } 987 988 map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum]; 989 if ((*map & (1u << blknum)) == 0) { 990 rc = ENOENT; 991 goto fail2; 992 } 993 *map &= ~(1u << blknum); 994 995 return (0); 996 997 fail2: 998 EFSYS_PROBE(fail2); 999 fail1: 1000 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1001 1002 return (rc); 1003 } 1004 1005 __checkReturn efx_rc_t 1006 ef10_nic_pio_link( 1007 __inout efx_nic_t *enp, 1008 __in uint32_t vi_index, 1009 __in efx_piobuf_handle_t handle) 1010 { 1011 return (efx_mcdi_link_piobuf(enp, vi_index, handle)); 1012 } 1013 1014 __checkReturn efx_rc_t 1015 ef10_nic_pio_unlink( 1016 __inout efx_nic_t *enp, 1017 __in uint32_t vi_index) 1018 { 1019 return (efx_mcdi_unlink_piobuf(enp, vi_index)); 1020 } 1021 1022 static __checkReturn efx_rc_t 1023 ef10_mcdi_get_pf_count( 1024 __in efx_nic_t *enp, 1025 __out uint32_t *pf_countp) 1026 { 1027 efx_mcdi_req_t req; 1028 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN, 1029 MC_CMD_GET_PF_COUNT_OUT_LEN); 1030 efx_rc_t rc; 1031 1032 req.emr_cmd = MC_CMD_GET_PF_COUNT; 1033 req.emr_in_buf = payload; 1034 req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN; 1035 req.emr_out_buf = payload; 1036 req.emr_out_length = MC_CMD_GET_PF_COUNT_OUT_LEN; 1037 1038 efx_mcdi_execute(enp, &req); 1039 1040 if (req.emr_rc != 0) { 1041 rc = req.emr_rc; 1042 goto fail1; 1043 } 1044 1045 if (req.emr_out_length_used < MC_CMD_GET_PF_COUNT_OUT_LEN) { 1046 rc = EMSGSIZE; 1047 goto fail2; 1048 } 1049 1050 *pf_countp = *MCDI_OUT(req, uint8_t, 1051 MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST); 1052 1053 EFSYS_ASSERT(*pf_countp != 0); 1054 1055 return (0); 1056 1057 fail2: 1058 EFSYS_PROBE(fail2); 1059 fail1: 1060 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1061 1062 return (rc); 1063 } 1064 1065 static __checkReturn efx_rc_t 1066 ef10_get_datapath_caps( 1067 __in efx_nic_t *enp) 1068 { 1069 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1070 efx_mcdi_req_t req; 1071 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN, 1072 MC_CMD_GET_CAPABILITIES_V5_OUT_LEN); 1073 efx_rc_t rc; 1074 1075 if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0) 1076 goto fail1; 1077 1078 1079 req.emr_cmd = MC_CMD_GET_CAPABILITIES; 1080 req.emr_in_buf = payload; 1081 req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; 1082 req.emr_out_buf = payload; 1083 req.emr_out_length = MC_CMD_GET_CAPABILITIES_V5_OUT_LEN; 1084 1085 efx_mcdi_execute_quiet(enp, &req); 1086 1087 if (req.emr_rc != 0) { 1088 rc = req.emr_rc; 1089 goto fail2; 1090 } 1091 1092 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) { 1093 rc = EMSGSIZE; 1094 goto fail3; 1095 } 1096 1097 #define CAP_FLAGS1(_req, _flag) \ 1098 (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_OUT_FLAGS1) & \ 1099 (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN))) 1100 1101 #define CAP_FLAGS2(_req, _flag) \ 1102 (((_req).emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) && \ 1103 (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_V2_OUT_FLAGS2) & \ 1104 (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN)))) 1105 1106 /* 1107 * Huntington RXDP firmware inserts a 0 or 14 byte prefix. 1108 * We only support the 14 byte prefix here. 1109 */ 1110 if (CAP_FLAGS1(req, RX_PREFIX_LEN_14) == 0) { 1111 rc = ENOTSUP; 1112 goto fail4; 1113 } 1114 encp->enc_rx_prefix_size = 14; 1115 1116 #if EFSYS_OPT_RX_SCALE 1117 /* Check if the firmware supports additional RSS modes */ 1118 if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES)) 1119 encp->enc_rx_scale_additional_modes_supported = B_TRUE; 1120 else 1121 encp->enc_rx_scale_additional_modes_supported = B_FALSE; 1122 #endif /* EFSYS_OPT_RX_SCALE */ 1123 1124 /* Check if the firmware supports TSO */ 1125 if (CAP_FLAGS1(req, TX_TSO)) 1126 encp->enc_fw_assisted_tso_enabled = B_TRUE; 1127 else 1128 encp->enc_fw_assisted_tso_enabled = B_FALSE; 1129 1130 /* Check if the firmware supports FATSOv2 */ 1131 if (CAP_FLAGS2(req, TX_TSO_V2)) { 1132 encp->enc_fw_assisted_tso_v2_enabled = B_TRUE; 1133 encp->enc_fw_assisted_tso_v2_n_contexts = MCDI_OUT_WORD(req, 1134 GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS); 1135 } else { 1136 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE; 1137 encp->enc_fw_assisted_tso_v2_n_contexts = 0; 1138 } 1139 1140 /* Check if the firmware supports FATSOv2 encap */ 1141 if (CAP_FLAGS2(req, TX_TSO_V2_ENCAP)) 1142 encp->enc_fw_assisted_tso_v2_encap_enabled = B_TRUE; 1143 else 1144 encp->enc_fw_assisted_tso_v2_encap_enabled = B_FALSE; 1145 1146 /* Check if the firmware has vadapter/vport/vswitch support */ 1147 if (CAP_FLAGS1(req, EVB)) 1148 encp->enc_datapath_cap_evb = B_TRUE; 1149 else 1150 encp->enc_datapath_cap_evb = B_FALSE; 1151 1152 /* Check if the firmware supports VLAN insertion */ 1153 if (CAP_FLAGS1(req, TX_VLAN_INSERTION)) 1154 encp->enc_hw_tx_insert_vlan_enabled = B_TRUE; 1155 else 1156 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 1157 1158 /* Check if the firmware supports RX event batching */ 1159 if (CAP_FLAGS1(req, RX_BATCHING)) 1160 encp->enc_rx_batching_enabled = B_TRUE; 1161 else 1162 encp->enc_rx_batching_enabled = B_FALSE; 1163 1164 /* 1165 * Even if batching isn't reported as supported, we may still get 1166 * batched events. 1167 */ 1168 encp->enc_rx_batch_max = 16; 1169 1170 /* Check if the firmware supports disabling scatter on RXQs */ 1171 if (CAP_FLAGS1(req, RX_DISABLE_SCATTER)) 1172 encp->enc_rx_disable_scatter_supported = B_TRUE; 1173 else 1174 encp->enc_rx_disable_scatter_supported = B_FALSE; 1175 1176 /* Check if the firmware supports packed stream mode */ 1177 if (CAP_FLAGS1(req, RX_PACKED_STREAM)) 1178 encp->enc_rx_packed_stream_supported = B_TRUE; 1179 else 1180 encp->enc_rx_packed_stream_supported = B_FALSE; 1181 1182 /* 1183 * Check if the firmware supports configurable buffer sizes 1184 * for packed stream mode (otherwise buffer size is 1Mbyte) 1185 */ 1186 if (CAP_FLAGS1(req, RX_PACKED_STREAM_VAR_BUFFERS)) 1187 encp->enc_rx_var_packed_stream_supported = B_TRUE; 1188 else 1189 encp->enc_rx_var_packed_stream_supported = B_FALSE; 1190 1191 /* Check if the firmware supports equal stride super-buffer mode */ 1192 if (CAP_FLAGS2(req, EQUAL_STRIDE_SUPER_BUFFER)) 1193 encp->enc_rx_es_super_buffer_supported = B_TRUE; 1194 else 1195 encp->enc_rx_es_super_buffer_supported = B_FALSE; 1196 1197 /* Check if the firmware supports FW subvariant w/o Tx checksumming */ 1198 if (CAP_FLAGS2(req, FW_SUBVARIANT_NO_TX_CSUM)) 1199 encp->enc_fw_subvariant_no_tx_csum_supported = B_TRUE; 1200 else 1201 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE; 1202 1203 /* Check if the firmware supports set mac with running filters */ 1204 if (CAP_FLAGS1(req, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED)) 1205 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 1206 else 1207 encp->enc_allow_set_mac_with_installed_filters = B_FALSE; 1208 1209 /* 1210 * Check if firmware supports the extended MC_CMD_SET_MAC, which allows 1211 * specifying which parameters to configure. 1212 */ 1213 if (CAP_FLAGS1(req, SET_MAC_ENHANCED)) 1214 encp->enc_enhanced_set_mac_supported = B_TRUE; 1215 else 1216 encp->enc_enhanced_set_mac_supported = B_FALSE; 1217 1218 /* 1219 * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows 1220 * us to let the firmware choose the settings to use on an EVQ. 1221 */ 1222 if (CAP_FLAGS2(req, INIT_EVQ_V2)) 1223 encp->enc_init_evq_v2_supported = B_TRUE; 1224 else 1225 encp->enc_init_evq_v2_supported = B_FALSE; 1226 1227 /* 1228 * Check if firmware-verified NVRAM updates must be used. 1229 * 1230 * The firmware trusted installer requires all NVRAM updates to use 1231 * version 2 of MC_CMD_NVRAM_UPDATE_START (to enable verified update) 1232 * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated 1233 * partition and report the result). 1234 */ 1235 if (CAP_FLAGS2(req, NVRAM_UPDATE_REPORT_VERIFY_RESULT)) 1236 encp->enc_nvram_update_verify_result_supported = B_TRUE; 1237 else 1238 encp->enc_nvram_update_verify_result_supported = B_FALSE; 1239 1240 /* 1241 * Check if firmware provides packet memory and Rx datapath 1242 * counters. 1243 */ 1244 if (CAP_FLAGS1(req, PM_AND_RXDP_COUNTERS)) 1245 encp->enc_pm_and_rxdp_counters = B_TRUE; 1246 else 1247 encp->enc_pm_and_rxdp_counters = B_FALSE; 1248 1249 /* 1250 * Check if the 40G MAC hardware is capable of reporting 1251 * statistics for Tx size bins. 1252 */ 1253 if (CAP_FLAGS2(req, MAC_STATS_40G_TX_SIZE_BINS)) 1254 encp->enc_mac_stats_40g_tx_size_bins = B_TRUE; 1255 else 1256 encp->enc_mac_stats_40g_tx_size_bins = B_FALSE; 1257 1258 /* 1259 * Check if firmware supports VXLAN and NVGRE tunnels. 1260 * The capability indicates Geneve protocol support as well. 1261 */ 1262 if (CAP_FLAGS1(req, VXLAN_NVGRE)) { 1263 encp->enc_tunnel_encapsulations_supported = 1264 (1u << EFX_TUNNEL_PROTOCOL_VXLAN) | 1265 (1u << EFX_TUNNEL_PROTOCOL_GENEVE) | 1266 (1u << EFX_TUNNEL_PROTOCOL_NVGRE); 1267 1268 EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES == 1269 MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM); 1270 encp->enc_tunnel_config_udp_entries_max = 1271 EFX_TUNNEL_MAXNENTRIES; 1272 } else { 1273 encp->enc_tunnel_config_udp_entries_max = 0; 1274 } 1275 1276 /* 1277 * Check if firmware reports the VI window mode. 1278 * Medford2 has a variable VI window size (8K, 16K or 64K). 1279 * Medford and Huntington have a fixed 8K VI window size. 1280 */ 1281 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) { 1282 uint8_t mode = 1283 MCDI_OUT_BYTE(req, GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); 1284 1285 switch (mode) { 1286 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K: 1287 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 1288 break; 1289 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K: 1290 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_16K; 1291 break; 1292 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K: 1293 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_64K; 1294 break; 1295 default: 1296 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID; 1297 break; 1298 } 1299 } else if ((enp->en_family == EFX_FAMILY_HUNTINGTON) || 1300 (enp->en_family == EFX_FAMILY_MEDFORD)) { 1301 /* Huntington and Medford have fixed 8K window size */ 1302 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 1303 } else { 1304 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID; 1305 } 1306 1307 /* Check if firmware supports extended MAC stats. */ 1308 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) { 1309 /* Extended stats buffer supported */ 1310 encp->enc_mac_stats_nstats = MCDI_OUT_WORD(req, 1311 GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS); 1312 } else { 1313 /* Use Siena-compatible legacy MAC stats */ 1314 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS; 1315 } 1316 1317 if (encp->enc_mac_stats_nstats >= MC_CMD_MAC_NSTATS_V2) 1318 encp->enc_fec_counters = B_TRUE; 1319 else 1320 encp->enc_fec_counters = B_FALSE; 1321 1322 /* Check if the firmware provides head-of-line blocking counters */ 1323 if (CAP_FLAGS2(req, RXDP_HLB_IDLE)) 1324 encp->enc_hlb_counters = B_TRUE; 1325 else 1326 encp->enc_hlb_counters = B_FALSE; 1327 1328 #if EFSYS_OPT_RX_SCALE 1329 if (CAP_FLAGS1(req, RX_RSS_LIMITED)) { 1330 /* Only one exclusive RSS context is available per port. */ 1331 encp->enc_rx_scale_max_exclusive_contexts = 1; 1332 1333 switch (enp->en_family) { 1334 case EFX_FAMILY_MEDFORD2: 1335 encp->enc_rx_scale_hash_alg_mask = 1336 (1U << EFX_RX_HASHALG_TOEPLITZ); 1337 break; 1338 1339 case EFX_FAMILY_MEDFORD: 1340 case EFX_FAMILY_HUNTINGTON: 1341 /* 1342 * Packed stream firmware variant maintains a 1343 * non-standard algorithm for hash computation. 1344 * It implies explicit XORing together 1345 * source + destination IP addresses (or last 1346 * four bytes in the case of IPv6) and using the 1347 * resulting value as the input to a Toeplitz hash. 1348 */ 1349 encp->enc_rx_scale_hash_alg_mask = 1350 (1U << EFX_RX_HASHALG_PACKED_STREAM); 1351 break; 1352 1353 default: 1354 rc = EINVAL; 1355 goto fail5; 1356 } 1357 1358 /* Port numbers cannot contribute to the hash value */ 1359 encp->enc_rx_scale_l4_hash_supported = B_FALSE; 1360 } else { 1361 /* 1362 * Maximum number of exclusive RSS contexts. 1363 * EF10 hardware supports 64 in total, but 6 are reserved 1364 * for shared contexts. They are a global resource so 1365 * not all may be available. 1366 */ 1367 encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; 1368 1369 encp->enc_rx_scale_hash_alg_mask = 1370 (1U << EFX_RX_HASHALG_TOEPLITZ); 1371 1372 /* 1373 * It is possible to use port numbers as 1374 * the input data for hash computation. 1375 */ 1376 encp->enc_rx_scale_l4_hash_supported = B_TRUE; 1377 } 1378 #endif /* EFSYS_OPT_RX_SCALE */ 1379 1380 /* Check if the firmware supports "FLAG" and "MARK" filter actions */ 1381 if (CAP_FLAGS2(req, FILTER_ACTION_FLAG)) 1382 encp->enc_filter_action_flag_supported = B_TRUE; 1383 else 1384 encp->enc_filter_action_flag_supported = B_FALSE; 1385 1386 if (CAP_FLAGS2(req, FILTER_ACTION_MARK)) 1387 encp->enc_filter_action_mark_supported = B_TRUE; 1388 else 1389 encp->enc_filter_action_mark_supported = B_FALSE; 1390 1391 /* Get maximum supported value for "MARK" filter action */ 1392 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V5_OUT_LEN) 1393 encp->enc_filter_action_mark_max = MCDI_OUT_DWORD(req, 1394 GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX); 1395 else 1396 encp->enc_filter_action_mark_max = 0; 1397 1398 #undef CAP_FLAGS1 1399 #undef CAP_FLAGS2 1400 1401 return (0); 1402 1403 #if EFSYS_OPT_RX_SCALE 1404 fail5: 1405 EFSYS_PROBE(fail5); 1406 #endif /* EFSYS_OPT_RX_SCALE */ 1407 fail4: 1408 EFSYS_PROBE(fail4); 1409 fail3: 1410 EFSYS_PROBE(fail3); 1411 fail2: 1412 EFSYS_PROBE(fail2); 1413 fail1: 1414 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1415 1416 return (rc); 1417 } 1418 1419 1420 #define EF10_LEGACY_PF_PRIVILEGE_MASK \ 1421 (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \ 1422 MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK | \ 1423 MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD | \ 1424 MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP | \ 1425 MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS | \ 1426 MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING | \ 1427 MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST | \ 1428 MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST | \ 1429 MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST | \ 1430 MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \ 1431 MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS) 1432 1433 #define EF10_LEGACY_VF_PRIVILEGE_MASK 0 1434 1435 1436 __checkReturn efx_rc_t 1437 ef10_get_privilege_mask( 1438 __in efx_nic_t *enp, 1439 __out uint32_t *maskp) 1440 { 1441 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1442 uint32_t mask; 1443 efx_rc_t rc; 1444 1445 if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf, 1446 &mask)) != 0) { 1447 if (rc != ENOTSUP) 1448 goto fail1; 1449 1450 /* Fallback for old firmware without privilege mask support */ 1451 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1452 /* Assume PF has admin privilege */ 1453 mask = EF10_LEGACY_PF_PRIVILEGE_MASK; 1454 } else { 1455 /* VF is always unprivileged by default */ 1456 mask = EF10_LEGACY_VF_PRIVILEGE_MASK; 1457 } 1458 } 1459 1460 *maskp = mask; 1461 1462 return (0); 1463 1464 fail1: 1465 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1466 1467 return (rc); 1468 } 1469 1470 1471 /* 1472 * Table of mapping schemes from port number to external number. 1473 * 1474 * Each port number ultimately corresponds to a connector: either as part of 1475 * a cable assembly attached to a module inserted in an SFP+/QSFP+ cage on 1476 * the board, or fixed to the board (e.g. 10GBASE-T magjack on SFN5121T 1477 * "Salina"). In general: 1478 * 1479 * Port number (0-based) 1480 * | 1481 * port mapping (n:1) 1482 * | 1483 * v 1484 * External port number (normally 1-based) 1485 * | 1486 * fixed (1:1) or cable assembly (1:m) 1487 * | 1488 * v 1489 * Connector 1490 * 1491 * The external numbering refers to the cages or magjacks on the board, 1492 * as visibly annotated on the board or back panel. This table describes 1493 * how to determine which external cage/magjack corresponds to the port 1494 * numbers used by the driver. 1495 * 1496 * The count of adjacent port numbers that map to each external number, 1497 * and the offset in the numbering, is determined by the chip family and 1498 * current port mode. 1499 * 1500 * For the Huntington family, the current port mode cannot be discovered, 1501 * but a single mapping is used by all modes for a given chip variant, 1502 * so the mapping used is instead the last match in the table to the full 1503 * set of port modes to which the NIC can be configured. Therefore the 1504 * ordering of entries in the mapping table is significant. 1505 */ 1506 static struct ef10_external_port_map_s { 1507 efx_family_t family; 1508 uint32_t modes_mask; 1509 int32_t count; 1510 int32_t offset; 1511 } __ef10_external_port_mappings[] = { 1512 /* 1513 * Modes used by Huntington family controllers where each port 1514 * number maps to a separate cage. 1515 * SFN7x22F (Torino): 1516 * port 0 -> cage 1 1517 * port 1 -> cage 2 1518 * SFN7xx4F (Pavia): 1519 * port 0 -> cage 1 1520 * port 1 -> cage 2 1521 * port 2 -> cage 3 1522 * port 3 -> cage 4 1523 */ 1524 { 1525 EFX_FAMILY_HUNTINGTON, 1526 (1U << TLV_PORT_MODE_10G) | /* mode 0 */ 1527 (1U << TLV_PORT_MODE_10G_10G) | /* mode 2 */ 1528 (1U << TLV_PORT_MODE_10G_10G_10G_10G), /* mode 4 */ 1529 1, /* ports per cage */ 1530 1 /* first cage */ 1531 }, 1532 /* 1533 * Modes which for Huntington identify a chip variant where 2 1534 * adjacent port numbers map to each cage. 1535 * SFN7x42Q (Monza): 1536 * port 0 -> cage 1 1537 * port 1 -> cage 1 1538 * port 2 -> cage 2 1539 * port 3 -> cage 2 1540 */ 1541 { 1542 EFX_FAMILY_HUNTINGTON, 1543 (1U << TLV_PORT_MODE_40G) | /* mode 1 */ 1544 (1U << TLV_PORT_MODE_40G_40G) | /* mode 3 */ 1545 (1U << TLV_PORT_MODE_40G_10G_10G) | /* mode 6 */ 1546 (1U << TLV_PORT_MODE_10G_10G_40G), /* mode 7 */ 1547 2, /* ports per cage */ 1548 1 /* first cage */ 1549 }, 1550 /* 1551 * Modes that on Medford allocate each port number to a separate 1552 * cage. 1553 * port 0 -> cage 1 1554 * port 1 -> cage 2 1555 * port 2 -> cage 3 1556 * port 3 -> cage 4 1557 */ 1558 { 1559 EFX_FAMILY_MEDFORD, 1560 (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ 1561 (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */ 1562 1, /* ports per cage */ 1563 1 /* first cage */ 1564 }, 1565 /* 1566 * Modes that on Medford allocate 2 adjacent port numbers to each 1567 * cage. 1568 * port 0 -> cage 1 1569 * port 1 -> cage 1 1570 * port 2 -> cage 2 1571 * port 3 -> cage 2 1572 */ 1573 { 1574 EFX_FAMILY_MEDFORD, 1575 (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ 1576 (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */ 1577 (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */ 1578 (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ 1579 /* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */ 1580 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), /* mode 9 */ 1581 2, /* ports per cage */ 1582 1 /* first cage */ 1583 }, 1584 /* 1585 * Modes that on Medford allocate 4 adjacent port numbers to each 1586 * connector, starting on cage 1. 1587 * port 0 -> cage 1 1588 * port 1 -> cage 1 1589 * port 2 -> cage 1 1590 * port 3 -> cage 1 1591 */ 1592 { 1593 EFX_FAMILY_MEDFORD, 1594 (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 5 */ 1595 /* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */ 1596 (1U << TLV_PORT_MODE_4x1_NA), /* mode 4 */ 1597 4, /* ports per cage */ 1598 1 /* first cage */ 1599 }, 1600 /* 1601 * Modes that on Medford allocate 4 adjacent port numbers to each 1602 * connector, starting on cage 2. 1603 * port 0 -> cage 2 1604 * port 1 -> cage 2 1605 * port 2 -> cage 2 1606 * port 3 -> cage 2 1607 */ 1608 { 1609 EFX_FAMILY_MEDFORD, 1610 (1U << TLV_PORT_MODE_NA_4x1), /* mode 8 */ 1611 4, /* ports per cage */ 1612 2 /* first cage */ 1613 }, 1614 /* 1615 * Modes that on Medford2 allocate each port number to a separate 1616 * cage. 1617 * port 0 -> cage 1 1618 * port 1 -> cage 2 1619 * port 2 -> cage 3 1620 * port 3 -> cage 4 1621 */ 1622 { 1623 EFX_FAMILY_MEDFORD2, 1624 (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ 1625 (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ 1626 (1U << TLV_PORT_MODE_1x1_1x1) | /* mode 2 */ 1627 (1U << TLV_PORT_MODE_1x2_NA) | /* mode 10 */ 1628 (1U << TLV_PORT_MODE_1x2_1x2) | /* mode 12 */ 1629 (1U << TLV_PORT_MODE_1x4_1x2) | /* mode 15 */ 1630 (1U << TLV_PORT_MODE_1x2_1x4), /* mode 16 */ 1631 1, /* ports per cage */ 1632 1 /* first cage */ 1633 }, 1634 /* 1635 * FIXME: Some port modes are not representable in this mapping: 1636 * - TLV_PORT_MODE_1x2_2x1 (mode 17): 1637 * port 0 -> cage 1 1638 * port 1 -> cage 2 1639 * port 2 -> cage 2 1640 */ 1641 /* 1642 * Modes that on Medford2 allocate 2 adjacent port numbers to each 1643 * cage, starting on cage 1. 1644 * port 0 -> cage 1 1645 * port 1 -> cage 1 1646 * port 2 -> cage 2 1647 * port 3 -> cage 2 1648 */ 1649 { 1650 EFX_FAMILY_MEDFORD2, 1651 (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */ 1652 (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 4 */ 1653 (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */ 1654 (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ 1655 (1U << TLV_PORT_MODE_2x2_NA) | /* mode 13 */ 1656 (1U << TLV_PORT_MODE_2x1_1x2), /* mode 18 */ 1657 2, /* ports per cage */ 1658 1 /* first cage */ 1659 }, 1660 /* 1661 * Modes that on Medford2 allocate 2 adjacent port numbers to each 1662 * cage, starting on cage 2. 1663 * port 0 -> cage 2 1664 * port 1 -> cage 2 1665 */ 1666 { 1667 EFX_FAMILY_MEDFORD2, 1668 (1U << TLV_PORT_MODE_NA_2x2), /* mode 14 */ 1669 2, /* ports per cage */ 1670 2 /* first cage */ 1671 }, 1672 /* 1673 * Modes that on Medford2 allocate 4 adjacent port numbers to each 1674 * connector, starting on cage 1. 1675 * port 0 -> cage 1 1676 * port 1 -> cage 1 1677 * port 2 -> cage 1 1678 * port 3 -> cage 1 1679 */ 1680 { 1681 EFX_FAMILY_MEDFORD2, 1682 (1U << TLV_PORT_MODE_4x1_NA), /* mode 5 */ 1683 4, /* ports per cage */ 1684 1 /* first cage */ 1685 }, 1686 /* 1687 * Modes that on Medford2 allocate 4 adjacent port numbers to each 1688 * connector, starting on cage 2. 1689 * port 0 -> cage 2 1690 * port 1 -> cage 2 1691 * port 2 -> cage 2 1692 * port 3 -> cage 2 1693 */ 1694 { 1695 EFX_FAMILY_MEDFORD2, 1696 (1U << TLV_PORT_MODE_NA_4x1) | /* mode 8 */ 1697 (1U << TLV_PORT_MODE_NA_1x2), /* mode 11 */ 1698 4, /* ports per cage */ 1699 2 /* first cage */ 1700 }, 1701 }; 1702 1703 static __checkReturn efx_rc_t 1704 ef10_external_port_mapping( 1705 __in efx_nic_t *enp, 1706 __in uint32_t port, 1707 __out uint8_t *external_portp) 1708 { 1709 efx_rc_t rc; 1710 int i; 1711 uint32_t port_modes; 1712 uint32_t matches; 1713 uint32_t current; 1714 int32_t count = 1; /* Default 1-1 mapping */ 1715 int32_t offset = 1; /* Default starting external port number */ 1716 1717 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t, 1718 NULL)) != 0) { 1719 /* 1720 * No current port mode information (i.e. Huntington) 1721 * - infer mapping from available modes 1722 */ 1723 if ((rc = efx_mcdi_get_port_modes(enp, 1724 &port_modes, NULL, NULL)) != 0) { 1725 /* 1726 * No port mode information available 1727 * - use default mapping 1728 */ 1729 goto out; 1730 } 1731 } else { 1732 /* Only need to scan the current mode */ 1733 port_modes = 1 << current; 1734 } 1735 1736 /* 1737 * Infer the internal port -> external number mapping from 1738 * the possible port modes for this NIC. 1739 */ 1740 for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) { 1741 struct ef10_external_port_map_s *eepmp = 1742 &__ef10_external_port_mappings[i]; 1743 if (eepmp->family != enp->en_family) 1744 continue; 1745 matches = (eepmp->modes_mask & port_modes); 1746 if (matches != 0) { 1747 /* 1748 * Some modes match. For some Huntington boards 1749 * there will be multiple matches. The mapping on the 1750 * last match is used. 1751 */ 1752 count = eepmp->count; 1753 offset = eepmp->offset; 1754 port_modes &= ~matches; 1755 } 1756 } 1757 1758 if (port_modes != 0) { 1759 /* Some advertised modes are not supported */ 1760 rc = ENOTSUP; 1761 goto fail1; 1762 } 1763 1764 out: 1765 /* 1766 * Scale as required by last matched mode and then convert to 1767 * correctly offset numbering 1768 */ 1769 *external_portp = (uint8_t)((port / count) + offset); 1770 return (0); 1771 1772 fail1: 1773 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1774 1775 return (rc); 1776 } 1777 1778 static __checkReturn efx_rc_t 1779 ef10_nic_board_cfg( 1780 __in efx_nic_t *enp) 1781 { 1782 const efx_nic_ops_t *enop = enp->en_enop; 1783 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 1784 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1785 ef10_link_state_t els; 1786 efx_port_t *epp = &(enp->en_port); 1787 uint32_t board_type = 0; 1788 uint32_t base, nvec; 1789 uint32_t port; 1790 uint32_t mask; 1791 uint32_t pf; 1792 uint32_t vf; 1793 uint8_t mac_addr[6] = { 0 }; 1794 efx_rc_t rc; 1795 1796 /* Get the (zero-based) MCDI port number */ 1797 if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) 1798 goto fail1; 1799 1800 /* EFX MCDI interface uses one-based port numbers */ 1801 emip->emi_port = port + 1; 1802 1803 if ((rc = ef10_external_port_mapping(enp, port, 1804 &encp->enc_external_port)) != 0) 1805 goto fail2; 1806 1807 /* 1808 * Get PCIe function number from firmware (used for 1809 * per-function privilege and dynamic config info). 1810 * - PCIe PF: pf = PF number, vf = 0xffff. 1811 * - PCIe VF: pf = parent PF, vf = VF number. 1812 */ 1813 if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0) 1814 goto fail3; 1815 1816 encp->enc_pf = pf; 1817 encp->enc_vf = vf; 1818 1819 /* MAC address for this function */ 1820 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1821 rc = efx_mcdi_get_mac_address_pf(enp, mac_addr); 1822 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 1823 /* 1824 * Disable static config checking, ONLY for manufacturing test 1825 * and setup at the factory, to allow the static config to be 1826 * installed. 1827 */ 1828 #else /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */ 1829 if ((rc == 0) && (mac_addr[0] & 0x02)) { 1830 /* 1831 * If the static config does not include a global MAC 1832 * address pool then the board may return a locally 1833 * administered MAC address (this should only happen on 1834 * incorrectly programmed boards). 1835 */ 1836 rc = EINVAL; 1837 } 1838 #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */ 1839 } else { 1840 rc = efx_mcdi_get_mac_address_vf(enp, mac_addr); 1841 } 1842 if (rc != 0) 1843 goto fail4; 1844 1845 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 1846 1847 /* Board configuration (legacy) */ 1848 rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL); 1849 if (rc != 0) { 1850 /* Unprivileged functions may not be able to read board cfg */ 1851 if (rc == EACCES) 1852 board_type = 0; 1853 else 1854 goto fail5; 1855 } 1856 1857 encp->enc_board_type = board_type; 1858 encp->enc_clk_mult = 1; /* not used for EF10 */ 1859 1860 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 1861 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 1862 goto fail6; 1863 1864 /* 1865 * Firmware with support for *_FEC capability bits does not 1866 * report that the corresponding *_FEC_REQUESTED bits are supported. 1867 * Add them here so that drivers understand that they are supported. 1868 */ 1869 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_BASER_FEC)) 1870 epp->ep_phy_cap_mask |= 1871 (1u << EFX_PHY_CAP_BASER_FEC_REQUESTED); 1872 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_RS_FEC)) 1873 epp->ep_phy_cap_mask |= 1874 (1u << EFX_PHY_CAP_RS_FEC_REQUESTED); 1875 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_25G_BASER_FEC)) 1876 epp->ep_phy_cap_mask |= 1877 (1u << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED); 1878 1879 /* Obtain the default PHY advertised capabilities */ 1880 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 1881 goto fail7; 1882 epp->ep_default_adv_cap_mask = els.epls.epls_adv_cap_mask; 1883 epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask; 1884 1885 /* Check capabilities of running datapath firmware */ 1886 if ((rc = ef10_get_datapath_caps(enp)) != 0) 1887 goto fail8; 1888 1889 /* Alignment for WPTR updates */ 1890 encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; 1891 1892 encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); 1893 /* No boundary crossing limits */ 1894 encp->enc_tx_dma_desc_boundary = 0; 1895 1896 /* 1897 * Maximum number of bytes into the frame the TCP header can start for 1898 * firmware assisted TSO to work. 1899 */ 1900 encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT; 1901 1902 /* 1903 * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use 1904 * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available 1905 * resources (allocated to this PCIe function), which is zero until 1906 * after we have allocated VIs. 1907 */ 1908 encp->enc_evq_limit = 1024; 1909 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET; 1910 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET; 1911 1912 encp->enc_buftbl_limit = 0xFFFFFFFF; 1913 1914 /* Get interrupt vector limits */ 1915 if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) { 1916 if (EFX_PCI_FUNCTION_IS_PF(encp)) 1917 goto fail9; 1918 1919 /* Ignore error (cannot query vector limits from a VF). */ 1920 base = 0; 1921 nvec = 1024; 1922 } 1923 encp->enc_intr_vec_base = base; 1924 encp->enc_intr_limit = nvec; 1925 1926 /* 1927 * Get the current privilege mask. Note that this may be modified 1928 * dynamically, so this value is informational only. DO NOT use 1929 * the privilege mask to check for sufficient privileges, as that 1930 * can result in time-of-check/time-of-use bugs. 1931 */ 1932 if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0) 1933 goto fail10; 1934 encp->enc_privilege_mask = mask; 1935 1936 /* Get remaining controller-specific board config */ 1937 if ((rc = enop->eno_board_cfg(enp)) != 0) 1938 if (rc != EACCES) 1939 goto fail11; 1940 1941 return (0); 1942 1943 fail11: 1944 EFSYS_PROBE(fail11); 1945 fail10: 1946 EFSYS_PROBE(fail10); 1947 fail9: 1948 EFSYS_PROBE(fail9); 1949 fail8: 1950 EFSYS_PROBE(fail8); 1951 fail7: 1952 EFSYS_PROBE(fail7); 1953 fail6: 1954 EFSYS_PROBE(fail6); 1955 fail5: 1956 EFSYS_PROBE(fail5); 1957 fail4: 1958 EFSYS_PROBE(fail4); 1959 fail3: 1960 EFSYS_PROBE(fail3); 1961 fail2: 1962 EFSYS_PROBE(fail2); 1963 fail1: 1964 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1965 1966 return (rc); 1967 } 1968 1969 __checkReturn efx_rc_t 1970 ef10_nic_probe( 1971 __in efx_nic_t *enp) 1972 { 1973 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1974 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1975 efx_rc_t rc; 1976 1977 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1978 enp->en_family == EFX_FAMILY_MEDFORD || 1979 enp->en_family == EFX_FAMILY_MEDFORD2); 1980 1981 /* Read and clear any assertion state */ 1982 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1983 goto fail1; 1984 1985 /* Exit the assertion handler */ 1986 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1987 if (rc != EACCES) 1988 goto fail2; 1989 1990 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 1991 goto fail3; 1992 1993 if ((rc = ef10_nic_board_cfg(enp)) != 0) 1994 goto fail4; 1995 1996 /* 1997 * Set default driver config limits (based on board config). 1998 * 1999 * FIXME: For now allocate a fixed number of VIs which is likely to be 2000 * sufficient and small enough to allow multiple functions on the same 2001 * port. 2002 */ 2003 edcp->edc_min_vi_count = edcp->edc_max_vi_count = 2004 MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit)); 2005 2006 /* The client driver must configure and enable PIO buffer support */ 2007 edcp->edc_max_piobuf_count = 0; 2008 edcp->edc_pio_alloc_size = 0; 2009 2010 #if EFSYS_OPT_MAC_STATS 2011 /* Wipe the MAC statistics */ 2012 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 2013 goto fail5; 2014 #endif 2015 2016 #if EFSYS_OPT_LOOPBACK 2017 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 2018 goto fail6; 2019 #endif 2020 2021 #if EFSYS_OPT_MON_STATS 2022 if ((rc = mcdi_mon_cfg_build(enp)) != 0) { 2023 /* Unprivileged functions do not have access to sensors */ 2024 if (rc != EACCES) 2025 goto fail7; 2026 } 2027 #endif 2028 2029 encp->enc_features = enp->en_features; 2030 2031 return (0); 2032 2033 #if EFSYS_OPT_MON_STATS 2034 fail7: 2035 EFSYS_PROBE(fail7); 2036 #endif 2037 #if EFSYS_OPT_LOOPBACK 2038 fail6: 2039 EFSYS_PROBE(fail6); 2040 #endif 2041 #if EFSYS_OPT_MAC_STATS 2042 fail5: 2043 EFSYS_PROBE(fail5); 2044 #endif 2045 fail4: 2046 EFSYS_PROBE(fail4); 2047 fail3: 2048 EFSYS_PROBE(fail3); 2049 fail2: 2050 EFSYS_PROBE(fail2); 2051 fail1: 2052 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2053 2054 return (rc); 2055 } 2056 2057 __checkReturn efx_rc_t 2058 ef10_nic_set_drv_limits( 2059 __inout efx_nic_t *enp, 2060 __in efx_drv_limits_t *edlp) 2061 { 2062 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 2063 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 2064 uint32_t min_evq_count, max_evq_count; 2065 uint32_t min_rxq_count, max_rxq_count; 2066 uint32_t min_txq_count, max_txq_count; 2067 efx_rc_t rc; 2068 2069 if (edlp == NULL) { 2070 rc = EINVAL; 2071 goto fail1; 2072 } 2073 2074 /* Get minimum required and maximum usable VI limits */ 2075 min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit); 2076 min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit); 2077 min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit); 2078 2079 edcp->edc_min_vi_count = 2080 MAX(min_evq_count, MAX(min_rxq_count, min_txq_count)); 2081 2082 max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit); 2083 max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit); 2084 max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit); 2085 2086 edcp->edc_max_vi_count = 2087 MAX(max_evq_count, MAX(max_rxq_count, max_txq_count)); 2088 2089 /* 2090 * Check limits for sub-allocated piobuf blocks. 2091 * PIO is optional, so don't fail if the limits are incorrect. 2092 */ 2093 if ((encp->enc_piobuf_size == 0) || 2094 (encp->enc_piobuf_limit == 0) || 2095 (edlp->edl_min_pio_alloc_size == 0) || 2096 (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) { 2097 /* Disable PIO */ 2098 edcp->edc_max_piobuf_count = 0; 2099 edcp->edc_pio_alloc_size = 0; 2100 } else { 2101 uint32_t blk_size, blk_count, blks_per_piobuf; 2102 2103 blk_size = 2104 MAX(edlp->edl_min_pio_alloc_size, 2105 encp->enc_piobuf_min_alloc_size); 2106 2107 blks_per_piobuf = encp->enc_piobuf_size / blk_size; 2108 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32); 2109 2110 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf); 2111 2112 /* A zero max pio alloc count means unlimited */ 2113 if ((edlp->edl_max_pio_alloc_count > 0) && 2114 (edlp->edl_max_pio_alloc_count < blk_count)) { 2115 blk_count = edlp->edl_max_pio_alloc_count; 2116 } 2117 2118 edcp->edc_pio_alloc_size = blk_size; 2119 edcp->edc_max_piobuf_count = 2120 (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf; 2121 } 2122 2123 return (0); 2124 2125 fail1: 2126 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2127 2128 return (rc); 2129 } 2130 2131 2132 __checkReturn efx_rc_t 2133 ef10_nic_reset( 2134 __in efx_nic_t *enp) 2135 { 2136 efx_mcdi_req_t req; 2137 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN, 2138 MC_CMD_ENTITY_RESET_OUT_LEN); 2139 efx_rc_t rc; 2140 2141 /* ef10_nic_reset() is called to recover from BADASSERT failures. */ 2142 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 2143 goto fail1; 2144 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 2145 goto fail2; 2146 2147 req.emr_cmd = MC_CMD_ENTITY_RESET; 2148 req.emr_in_buf = payload; 2149 req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; 2150 req.emr_out_buf = payload; 2151 req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; 2152 2153 MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, 2154 ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); 2155 2156 efx_mcdi_execute(enp, &req); 2157 2158 if (req.emr_rc != 0) { 2159 rc = req.emr_rc; 2160 goto fail3; 2161 } 2162 2163 /* Clear RX/TX DMA queue errors */ 2164 enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR); 2165 2166 return (0); 2167 2168 fail3: 2169 EFSYS_PROBE(fail3); 2170 fail2: 2171 EFSYS_PROBE(fail2); 2172 fail1: 2173 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2174 2175 return (rc); 2176 } 2177 2178 __checkReturn efx_rc_t 2179 ef10_nic_init( 2180 __in efx_nic_t *enp) 2181 { 2182 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 2183 uint32_t min_vi_count, max_vi_count; 2184 uint32_t vi_count, vi_base, vi_shift; 2185 uint32_t i; 2186 uint32_t retry; 2187 uint32_t delay_us; 2188 uint32_t vi_window_size; 2189 efx_rc_t rc; 2190 2191 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2192 enp->en_family == EFX_FAMILY_MEDFORD || 2193 enp->en_family == EFX_FAMILY_MEDFORD2); 2194 2195 /* Enable reporting of some events (e.g. link change) */ 2196 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 2197 goto fail1; 2198 2199 /* Allocate (optional) on-chip PIO buffers */ 2200 ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count); 2201 2202 /* 2203 * For best performance, PIO writes should use a write-combined 2204 * (WC) memory mapping. Using a separate WC mapping for the PIO 2205 * aperture of each VI would be a burden to drivers (and not 2206 * possible if the host page size is >4Kbyte). 2207 * 2208 * To avoid this we use a single uncached (UC) mapping for VI 2209 * register access, and a single WC mapping for extra VIs used 2210 * for PIO writes. 2211 * 2212 * Each piobuf must be linked to a VI in the WC mapping, and to 2213 * each VI that is using a sub-allocated block from the piobuf. 2214 */ 2215 min_vi_count = edcp->edc_min_vi_count; 2216 max_vi_count = 2217 edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count; 2218 2219 /* Ensure that the previously attached driver's VIs are freed */ 2220 if ((rc = efx_mcdi_free_vis(enp)) != 0) 2221 goto fail2; 2222 2223 /* 2224 * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this 2225 * fails then retrying the request for fewer VI resources may succeed. 2226 */ 2227 vi_count = 0; 2228 if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count, 2229 &vi_base, &vi_count, &vi_shift)) != 0) 2230 goto fail3; 2231 2232 EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count); 2233 2234 if (vi_count < min_vi_count) { 2235 rc = ENOMEM; 2236 goto fail4; 2237 } 2238 2239 enp->en_arch.ef10.ena_vi_base = vi_base; 2240 enp->en_arch.ef10.ena_vi_count = vi_count; 2241 enp->en_arch.ef10.ena_vi_shift = vi_shift; 2242 2243 if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) { 2244 /* Not enough extra VIs to map piobufs */ 2245 ef10_nic_free_piobufs(enp); 2246 } 2247 2248 enp->en_arch.ef10.ena_pio_write_vi_base = 2249 vi_count - enp->en_arch.ef10.ena_piobuf_count; 2250 2251 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=, 2252 EFX_VI_WINDOW_SHIFT_INVALID); 2253 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=, 2254 EFX_VI_WINDOW_SHIFT_64K); 2255 vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift; 2256 2257 /* Save UC memory mapping details */ 2258 enp->en_arch.ef10.ena_uc_mem_map_offset = 0; 2259 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2260 enp->en_arch.ef10.ena_uc_mem_map_size = 2261 (vi_window_size * 2262 enp->en_arch.ef10.ena_pio_write_vi_base); 2263 } else { 2264 enp->en_arch.ef10.ena_uc_mem_map_size = 2265 (vi_window_size * 2266 enp->en_arch.ef10.ena_vi_count); 2267 } 2268 2269 /* Save WC memory mapping details */ 2270 enp->en_arch.ef10.ena_wc_mem_map_offset = 2271 enp->en_arch.ef10.ena_uc_mem_map_offset + 2272 enp->en_arch.ef10.ena_uc_mem_map_size; 2273 2274 enp->en_arch.ef10.ena_wc_mem_map_size = 2275 (vi_window_size * 2276 enp->en_arch.ef10.ena_piobuf_count); 2277 2278 /* Link piobufs to extra VIs in WC mapping */ 2279 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2280 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 2281 rc = efx_mcdi_link_piobuf(enp, 2282 enp->en_arch.ef10.ena_pio_write_vi_base + i, 2283 enp->en_arch.ef10.ena_piobuf_handle[i]); 2284 if (rc != 0) 2285 break; 2286 } 2287 } 2288 2289 /* 2290 * Allocate a vAdaptor attached to our upstream vPort/pPort. 2291 * 2292 * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF 2293 * driver has yet to bring up the EVB port. See bug 56147. In this case, 2294 * retry the request several times after waiting a while. The wait time 2295 * between retries starts small (10ms) and exponentially increases. 2296 * Total wait time is a little over two seconds. Retry logic in the 2297 * client driver may mean this whole loop is repeated if it continues to 2298 * fail. 2299 */ 2300 retry = 0; 2301 delay_us = 10000; 2302 while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { 2303 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || 2304 (rc != ENOENT)) { 2305 /* 2306 * Do not retry alloc for PF, or for other errors on 2307 * a VF. 2308 */ 2309 goto fail5; 2310 } 2311 2312 /* VF startup before PF is ready. Retry allocation. */ 2313 if (retry > 5) { 2314 /* Too many attempts */ 2315 rc = EINVAL; 2316 goto fail6; 2317 } 2318 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); 2319 EFSYS_SLEEP(delay_us); 2320 retry++; 2321 if (delay_us < 500000) 2322 delay_us <<= 2; 2323 } 2324 2325 enp->en_vport_id = EVB_PORT_ID_ASSIGNED; 2326 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2; 2327 2328 return (0); 2329 2330 fail6: 2331 EFSYS_PROBE(fail6); 2332 fail5: 2333 EFSYS_PROBE(fail5); 2334 fail4: 2335 EFSYS_PROBE(fail4); 2336 fail3: 2337 EFSYS_PROBE(fail3); 2338 fail2: 2339 EFSYS_PROBE(fail2); 2340 2341 ef10_nic_free_piobufs(enp); 2342 2343 fail1: 2344 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2345 2346 return (rc); 2347 } 2348 2349 __checkReturn efx_rc_t 2350 ef10_nic_get_vi_pool( 2351 __in efx_nic_t *enp, 2352 __out uint32_t *vi_countp) 2353 { 2354 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2355 enp->en_family == EFX_FAMILY_MEDFORD || 2356 enp->en_family == EFX_FAMILY_MEDFORD2); 2357 2358 /* 2359 * Report VIs that the client driver can use. 2360 * Do not include VIs used for PIO buffer writes. 2361 */ 2362 *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base; 2363 2364 return (0); 2365 } 2366 2367 __checkReturn efx_rc_t 2368 ef10_nic_get_bar_region( 2369 __in efx_nic_t *enp, 2370 __in efx_nic_region_t region, 2371 __out uint32_t *offsetp, 2372 __out size_t *sizep) 2373 { 2374 efx_rc_t rc; 2375 2376 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2377 enp->en_family == EFX_FAMILY_MEDFORD || 2378 enp->en_family == EFX_FAMILY_MEDFORD2); 2379 2380 /* 2381 * TODO: Specify host memory mapping alignment and granularity 2382 * in efx_drv_limits_t so that they can be taken into account 2383 * when allocating extra VIs for PIO writes. 2384 */ 2385 switch (region) { 2386 case EFX_REGION_VI: 2387 /* UC mapped memory BAR region for VI registers */ 2388 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset; 2389 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size; 2390 break; 2391 2392 case EFX_REGION_PIO_WRITE_VI: 2393 /* WC mapped memory BAR region for piobuf writes */ 2394 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset; 2395 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size; 2396 break; 2397 2398 default: 2399 rc = EINVAL; 2400 goto fail1; 2401 } 2402 2403 return (0); 2404 2405 fail1: 2406 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2407 2408 return (rc); 2409 } 2410 2411 __checkReturn boolean_t 2412 ef10_nic_hw_unavailable( 2413 __in efx_nic_t *enp) 2414 { 2415 efx_dword_t dword; 2416 2417 if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL) 2418 return (B_TRUE); 2419 2420 EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE); 2421 if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff) 2422 goto unavail; 2423 2424 return (B_FALSE); 2425 2426 unavail: 2427 ef10_nic_set_hw_unavailable(enp); 2428 2429 return (B_TRUE); 2430 } 2431 2432 void 2433 ef10_nic_set_hw_unavailable( 2434 __in efx_nic_t *enp) 2435 { 2436 EFSYS_PROBE(hw_unavail); 2437 enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL; 2438 } 2439 2440 2441 void 2442 ef10_nic_fini( 2443 __in efx_nic_t *enp) 2444 { 2445 uint32_t i; 2446 efx_rc_t rc; 2447 2448 (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id); 2449 enp->en_vport_id = 0; 2450 2451 /* Unlink piobufs from extra VIs in WC mapping */ 2452 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2453 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 2454 rc = efx_mcdi_unlink_piobuf(enp, 2455 enp->en_arch.ef10.ena_pio_write_vi_base + i); 2456 if (rc != 0) 2457 break; 2458 } 2459 } 2460 2461 ef10_nic_free_piobufs(enp); 2462 2463 (void) efx_mcdi_free_vis(enp); 2464 enp->en_arch.ef10.ena_vi_count = 0; 2465 } 2466 2467 void 2468 ef10_nic_unprobe( 2469 __in efx_nic_t *enp) 2470 { 2471 #if EFSYS_OPT_MON_STATS 2472 mcdi_mon_cfg_free(enp); 2473 #endif /* EFSYS_OPT_MON_STATS */ 2474 (void) efx_mcdi_drv_attach(enp, B_FALSE); 2475 } 2476 2477 #if EFSYS_OPT_DIAG 2478 2479 __checkReturn efx_rc_t 2480 ef10_nic_register_test( 2481 __in efx_nic_t *enp) 2482 { 2483 efx_rc_t rc; 2484 2485 /* FIXME */ 2486 _NOTE(ARGUNUSED(enp)) 2487 _NOTE(CONSTANTCONDITION) 2488 if (B_FALSE) { 2489 rc = ENOTSUP; 2490 goto fail1; 2491 } 2492 /* FIXME */ 2493 2494 return (0); 2495 2496 fail1: 2497 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2498 2499 return (rc); 2500 } 2501 2502 #endif /* EFSYS_OPT_DIAG */ 2503 2504 #if EFSYS_OPT_FW_SUBVARIANT_AWARE 2505 2506 __checkReturn efx_rc_t 2507 efx_mcdi_get_nic_global( 2508 __in efx_nic_t *enp, 2509 __in uint32_t key, 2510 __out uint32_t *valuep) 2511 { 2512 efx_mcdi_req_t req; 2513 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN, 2514 MC_CMD_GET_NIC_GLOBAL_OUT_LEN); 2515 efx_rc_t rc; 2516 2517 req.emr_cmd = MC_CMD_GET_NIC_GLOBAL; 2518 req.emr_in_buf = payload; 2519 req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN; 2520 req.emr_out_buf = payload; 2521 req.emr_out_length = MC_CMD_GET_NIC_GLOBAL_OUT_LEN; 2522 2523 MCDI_IN_SET_DWORD(req, GET_NIC_GLOBAL_IN_KEY, key); 2524 2525 efx_mcdi_execute(enp, &req); 2526 2527 if (req.emr_rc != 0) { 2528 rc = req.emr_rc; 2529 goto fail1; 2530 } 2531 2532 if (req.emr_out_length_used != MC_CMD_GET_NIC_GLOBAL_OUT_LEN) { 2533 rc = EMSGSIZE; 2534 goto fail2; 2535 } 2536 2537 *valuep = MCDI_OUT_DWORD(req, GET_NIC_GLOBAL_OUT_VALUE); 2538 2539 return (0); 2540 2541 fail2: 2542 EFSYS_PROBE(fail2); 2543 fail1: 2544 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2545 2546 return (rc); 2547 } 2548 2549 __checkReturn efx_rc_t 2550 efx_mcdi_set_nic_global( 2551 __in efx_nic_t *enp, 2552 __in uint32_t key, 2553 __in uint32_t value) 2554 { 2555 efx_mcdi_req_t req; 2556 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0); 2557 efx_rc_t rc; 2558 2559 req.emr_cmd = MC_CMD_SET_NIC_GLOBAL; 2560 req.emr_in_buf = payload; 2561 req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN; 2562 req.emr_out_buf = NULL; 2563 req.emr_out_length = 0; 2564 2565 MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_KEY, key); 2566 MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_VALUE, value); 2567 2568 efx_mcdi_execute(enp, &req); 2569 2570 if (req.emr_rc != 0) { 2571 rc = req.emr_rc; 2572 goto fail1; 2573 } 2574 2575 return (0); 2576 2577 fail1: 2578 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2579 2580 return (rc); 2581 } 2582 2583 #endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */ 2584 2585 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ 2586