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: stable/10/sys/dev/sfxge/common/ef10_nic.c 342516 2018-12-26 10:25:01Z arybchik $"); 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 41 42#include "ef10_tlv_layout.h" 43 44 __checkReturn efx_rc_t 45efx_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 57 req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT; 58 req.emr_in_buf = payload; 59 req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN; 60 req.emr_out_buf = payload; 61 req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN; 62 63 efx_mcdi_execute(enp, &req); 64 65 if (req.emr_rc != 0) { 66 rc = req.emr_rc; 67 goto fail1; 68 } 69 70 if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) { 71 rc = EMSGSIZE; 72 goto fail2; 73 } 74 75 *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT); 76 77 return (0); 78 79fail2: 80 EFSYS_PROBE(fail2); 81fail1: 82 EFSYS_PROBE1(fail1, efx_rc_t, rc); 83 84 return (rc); 85} 86 87 __checkReturn efx_rc_t 88efx_mcdi_get_port_modes( 89 __in efx_nic_t *enp, 90 __out uint32_t *modesp, 91 __out_opt uint32_t *current_modep) 92{ 93 efx_mcdi_req_t req; 94 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_MODES_IN_LEN, 95 MC_CMD_GET_PORT_MODES_OUT_LEN); 96 efx_rc_t rc; 97 98 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 99 enp->en_family == EFX_FAMILY_MEDFORD); 100 101 req.emr_cmd = MC_CMD_GET_PORT_MODES; 102 req.emr_in_buf = payload; 103 req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN; 104 req.emr_out_buf = payload; 105 req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN; 106 107 efx_mcdi_execute(enp, &req); 108 109 if (req.emr_rc != 0) { 110 rc = req.emr_rc; 111 goto fail1; 112 } 113 114 /* 115 * Require only Modes and DefaultMode fields, unless the current mode 116 * was requested (CurrentMode field was added for Medford). 117 */ 118 if (req.emr_out_length_used < 119 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) { 120 rc = EMSGSIZE; 121 goto fail2; 122 } 123 if ((current_modep != NULL) && (req.emr_out_length_used < 124 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST + 4)) { 125 rc = EMSGSIZE; 126 goto fail3; 127 } 128 129 *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES); 130 131 if (current_modep != NULL) { 132 *current_modep = MCDI_OUT_DWORD(req, 133 GET_PORT_MODES_OUT_CURRENT_MODE); 134 } 135 136 return (0); 137 138fail3: 139 EFSYS_PROBE(fail3); 140fail2: 141 EFSYS_PROBE(fail2); 142fail1: 143 EFSYS_PROBE1(fail1, efx_rc_t, rc); 144 145 return (rc); 146} 147 148 __checkReturn efx_rc_t 149ef10_nic_get_port_mode_bandwidth( 150 __in uint32_t port_mode, 151 __out uint32_t *bandwidth_mbpsp) 152{ 153 uint32_t bandwidth; 154 efx_rc_t rc; 155 156 switch (port_mode) { 157 case TLV_PORT_MODE_10G: 158 bandwidth = 10000; 159 break; 160 case TLV_PORT_MODE_10G_10G: 161 bandwidth = 10000 * 2; 162 break; 163 case TLV_PORT_MODE_10G_10G_10G_10G: 164 case TLV_PORT_MODE_10G_10G_10G_10G_Q: 165 case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2: 166 case TLV_PORT_MODE_10G_10G_10G_10G_Q2: 167 bandwidth = 10000 * 4; 168 break; 169 case TLV_PORT_MODE_40G: 170 bandwidth = 40000; 171 break; 172 case TLV_PORT_MODE_40G_40G: 173 bandwidth = 40000 * 2; 174 break; 175 case TLV_PORT_MODE_40G_10G_10G: 176 case TLV_PORT_MODE_10G_10G_40G: 177 bandwidth = 40000 + (10000 * 2); 178 break; 179 default: 180 rc = EINVAL; 181 goto fail1; 182 } 183 184 *bandwidth_mbpsp = bandwidth; 185 186 return (0); 187 188fail1: 189 EFSYS_PROBE1(fail1, efx_rc_t, rc); 190 191 return (rc); 192} 193 194static __checkReturn efx_rc_t 195efx_mcdi_vadaptor_alloc( 196 __in efx_nic_t *enp, 197 __in uint32_t port_id) 198{ 199 efx_mcdi_req_t req; 200 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_ALLOC_IN_LEN, 201 MC_CMD_VADAPTOR_ALLOC_OUT_LEN); 202 efx_rc_t rc; 203 204 EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL); 205 206 req.emr_cmd = MC_CMD_VADAPTOR_ALLOC; 207 req.emr_in_buf = payload; 208 req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN; 209 req.emr_out_buf = payload; 210 req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN; 211 212 MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id); 213 MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS, 214 VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED, 215 enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0); 216 217 efx_mcdi_execute(enp, &req); 218 219 if (req.emr_rc != 0) { 220 rc = req.emr_rc; 221 goto fail1; 222 } 223 224 return (0); 225 226fail1: 227 EFSYS_PROBE1(fail1, efx_rc_t, rc); 228 229 return (rc); 230} 231 232static __checkReturn efx_rc_t 233efx_mcdi_vadaptor_free( 234 __in efx_nic_t *enp, 235 __in uint32_t port_id) 236{ 237 efx_mcdi_req_t req; 238 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_FREE_IN_LEN, 239 MC_CMD_VADAPTOR_FREE_OUT_LEN); 240 efx_rc_t rc; 241 242 req.emr_cmd = MC_CMD_VADAPTOR_FREE; 243 req.emr_in_buf = payload; 244 req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN; 245 req.emr_out_buf = payload; 246 req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN; 247 248 MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id); 249 250 efx_mcdi_execute(enp, &req); 251 252 if (req.emr_rc != 0) { 253 rc = req.emr_rc; 254 goto fail1; 255 } 256 257 return (0); 258 259fail1: 260 EFSYS_PROBE1(fail1, efx_rc_t, rc); 261 262 return (rc); 263} 264 265 __checkReturn efx_rc_t 266efx_mcdi_get_mac_address_pf( 267 __in efx_nic_t *enp, 268 __out_ecount_opt(6) uint8_t mac_addrp[6]) 269{ 270 efx_mcdi_req_t req; 271 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_MAC_ADDRESSES_IN_LEN, 272 MC_CMD_GET_MAC_ADDRESSES_OUT_LEN); 273 efx_rc_t rc; 274 275 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 276 enp->en_family == EFX_FAMILY_MEDFORD); 277 278 req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES; 279 req.emr_in_buf = payload; 280 req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN; 281 req.emr_out_buf = payload; 282 req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN; 283 284 efx_mcdi_execute(enp, &req); 285 286 if (req.emr_rc != 0) { 287 rc = req.emr_rc; 288 goto fail1; 289 } 290 291 if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) { 292 rc = EMSGSIZE; 293 goto fail2; 294 } 295 296 if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) { 297 rc = ENOENT; 298 goto fail3; 299 } 300 301 if (mac_addrp != NULL) { 302 uint8_t *addrp; 303 304 addrp = MCDI_OUT2(req, uint8_t, 305 GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE); 306 307 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 308 } 309 310 return (0); 311 312fail3: 313 EFSYS_PROBE(fail3); 314fail2: 315 EFSYS_PROBE(fail2); 316fail1: 317 EFSYS_PROBE1(fail1, efx_rc_t, rc); 318 319 return (rc); 320} 321 322 __checkReturn efx_rc_t 323efx_mcdi_get_mac_address_vf( 324 __in efx_nic_t *enp, 325 __out_ecount_opt(6) uint8_t mac_addrp[6]) 326{ 327 efx_mcdi_req_t req; 328 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN, 329 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX); 330 efx_rc_t rc; 331 332 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 333 enp->en_family == EFX_FAMILY_MEDFORD); 334 335 req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES; 336 req.emr_in_buf = payload; 337 req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN; 338 req.emr_out_buf = payload; 339 req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX; 340 341 MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID, 342 EVB_PORT_ID_ASSIGNED); 343 344 efx_mcdi_execute(enp, &req); 345 346 if (req.emr_rc != 0) { 347 rc = req.emr_rc; 348 goto fail1; 349 } 350 351 if (req.emr_out_length_used < 352 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) { 353 rc = EMSGSIZE; 354 goto fail2; 355 } 356 357 if (MCDI_OUT_DWORD(req, 358 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) { 359 rc = ENOENT; 360 goto fail3; 361 } 362 363 if (mac_addrp != NULL) { 364 uint8_t *addrp; 365 366 addrp = MCDI_OUT2(req, uint8_t, 367 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR); 368 369 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 370 } 371 372 return (0); 373 374fail3: 375 EFSYS_PROBE(fail3); 376fail2: 377 EFSYS_PROBE(fail2); 378fail1: 379 EFSYS_PROBE1(fail1, efx_rc_t, rc); 380 381 return (rc); 382} 383 384 __checkReturn efx_rc_t 385efx_mcdi_get_clock( 386 __in efx_nic_t *enp, 387 __out uint32_t *sys_freqp, 388 __out uint32_t *dpcpu_freqp) 389{ 390 efx_mcdi_req_t req; 391 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CLOCK_IN_LEN, 392 MC_CMD_GET_CLOCK_OUT_LEN); 393 efx_rc_t rc; 394 395 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 396 enp->en_family == EFX_FAMILY_MEDFORD); 397 398 req.emr_cmd = MC_CMD_GET_CLOCK; 399 req.emr_in_buf = payload; 400 req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN; 401 req.emr_out_buf = payload; 402 req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN; 403 404 efx_mcdi_execute(enp, &req); 405 406 if (req.emr_rc != 0) { 407 rc = req.emr_rc; 408 goto fail1; 409 } 410 411 if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) { 412 rc = EMSGSIZE; 413 goto fail2; 414 } 415 416 *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ); 417 if (*sys_freqp == 0) { 418 rc = EINVAL; 419 goto fail3; 420 } 421 *dpcpu_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_DPCPU_FREQ); 422 if (*dpcpu_freqp == 0) { 423 rc = EINVAL; 424 goto fail4; 425 } 426 427 return (0); 428 429fail4: 430 EFSYS_PROBE(fail4); 431fail3: 432 EFSYS_PROBE(fail3); 433fail2: 434 EFSYS_PROBE(fail2); 435fail1: 436 EFSYS_PROBE1(fail1, efx_rc_t, rc); 437 438 return (rc); 439} 440 441 __checkReturn efx_rc_t 442efx_mcdi_get_vector_cfg( 443 __in efx_nic_t *enp, 444 __out_opt uint32_t *vec_basep, 445 __out_opt uint32_t *pf_nvecp, 446 __out_opt uint32_t *vf_nvecp) 447{ 448 efx_mcdi_req_t req; 449 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_VECTOR_CFG_IN_LEN, 450 MC_CMD_GET_VECTOR_CFG_OUT_LEN); 451 efx_rc_t rc; 452 453 req.emr_cmd = MC_CMD_GET_VECTOR_CFG; 454 req.emr_in_buf = payload; 455 req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN; 456 req.emr_out_buf = payload; 457 req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN; 458 459 efx_mcdi_execute(enp, &req); 460 461 if (req.emr_rc != 0) { 462 rc = req.emr_rc; 463 goto fail1; 464 } 465 466 if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) { 467 rc = EMSGSIZE; 468 goto fail2; 469 } 470 471 if (vec_basep != NULL) 472 *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE); 473 if (pf_nvecp != NULL) 474 *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF); 475 if (vf_nvecp != NULL) 476 *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF); 477 478 return (0); 479 480fail2: 481 EFSYS_PROBE(fail2); 482fail1: 483 EFSYS_PROBE1(fail1, efx_rc_t, rc); 484 485 return (rc); 486} 487 488static __checkReturn efx_rc_t 489efx_mcdi_get_capabilities( 490 __in efx_nic_t *enp, 491 __out uint32_t *flagsp, 492 __out uint32_t *flags2p, 493 __out uint32_t *tso2ncp) 494{ 495 efx_mcdi_req_t req; 496 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN, 497 MC_CMD_GET_CAPABILITIES_V2_OUT_LEN); 498 efx_rc_t rc; 499 500 req.emr_cmd = MC_CMD_GET_CAPABILITIES; 501 req.emr_in_buf = payload; 502 req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; 503 req.emr_out_buf = payload; 504 req.emr_out_length = MC_CMD_GET_CAPABILITIES_V2_OUT_LEN; 505 506 efx_mcdi_execute(enp, &req); 507 508 if (req.emr_rc != 0) { 509 rc = req.emr_rc; 510 goto fail1; 511 } 512 513 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) { 514 rc = EMSGSIZE; 515 goto fail2; 516 } 517 518 *flagsp = MCDI_OUT_DWORD(req, GET_CAPABILITIES_OUT_FLAGS1); 519 520 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) { 521 *flags2p = 0; 522 *tso2ncp = 0; 523 } else { 524 *flags2p = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V2_OUT_FLAGS2); 525 *tso2ncp = MCDI_OUT_WORD(req, 526 GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS); 527 } 528 529 return (0); 530 531fail2: 532 EFSYS_PROBE(fail2); 533fail1: 534 EFSYS_PROBE1(fail1, efx_rc_t, rc); 535 536 return (rc); 537} 538 539 540static __checkReturn efx_rc_t 541efx_mcdi_alloc_vis( 542 __in efx_nic_t *enp, 543 __in uint32_t min_vi_count, 544 __in uint32_t max_vi_count, 545 __out uint32_t *vi_basep, 546 __out uint32_t *vi_countp, 547 __out uint32_t *vi_shiftp) 548{ 549 efx_mcdi_req_t req; 550 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN, 551 MC_CMD_ALLOC_VIS_EXT_OUT_LEN); 552 efx_rc_t rc; 553 554 if (vi_countp == NULL) { 555 rc = EINVAL; 556 goto fail1; 557 } 558 559 req.emr_cmd = MC_CMD_ALLOC_VIS; 560 req.emr_in_buf = payload; 561 req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN; 562 req.emr_out_buf = payload; 563 req.emr_out_length = MC_CMD_ALLOC_VIS_EXT_OUT_LEN; 564 565 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count); 566 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count); 567 568 efx_mcdi_execute(enp, &req); 569 570 if (req.emr_rc != 0) { 571 rc = req.emr_rc; 572 goto fail2; 573 } 574 575 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) { 576 rc = EMSGSIZE; 577 goto fail3; 578 } 579 580 *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE); 581 *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT); 582 583 /* Report VI_SHIFT if available (always zero for Huntington) */ 584 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN) 585 *vi_shiftp = 0; 586 else 587 *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT); 588 589 return (0); 590 591fail3: 592 EFSYS_PROBE(fail3); 593fail2: 594 EFSYS_PROBE(fail2); 595fail1: 596 EFSYS_PROBE1(fail1, efx_rc_t, rc); 597 598 return (rc); 599} 600 601 602static __checkReturn efx_rc_t 603efx_mcdi_free_vis( 604 __in efx_nic_t *enp) 605{ 606 efx_mcdi_req_t req; 607 efx_rc_t rc; 608 609 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0); 610 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0); 611 612 req.emr_cmd = MC_CMD_FREE_VIS; 613 req.emr_in_buf = NULL; 614 req.emr_in_length = 0; 615 req.emr_out_buf = NULL; 616 req.emr_out_length = 0; 617 618 efx_mcdi_execute_quiet(enp, &req); 619 620 /* Ignore ELREADY (no allocated VIs, so nothing to free) */ 621 if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) { 622 rc = req.emr_rc; 623 goto fail1; 624 } 625 626 return (0); 627 628fail1: 629 EFSYS_PROBE1(fail1, efx_rc_t, rc); 630 631 return (rc); 632} 633 634 635static __checkReturn efx_rc_t 636efx_mcdi_alloc_piobuf( 637 __in efx_nic_t *enp, 638 __out efx_piobuf_handle_t *handlep) 639{ 640 efx_mcdi_req_t req; 641 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN, 642 MC_CMD_ALLOC_PIOBUF_OUT_LEN); 643 efx_rc_t rc; 644 645 if (handlep == NULL) { 646 rc = EINVAL; 647 goto fail1; 648 } 649 650 req.emr_cmd = MC_CMD_ALLOC_PIOBUF; 651 req.emr_in_buf = payload; 652 req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN; 653 req.emr_out_buf = payload; 654 req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN; 655 656 efx_mcdi_execute_quiet(enp, &req); 657 658 if (req.emr_rc != 0) { 659 rc = req.emr_rc; 660 goto fail2; 661 } 662 663 if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) { 664 rc = EMSGSIZE; 665 goto fail3; 666 } 667 668 *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE); 669 670 return (0); 671 672fail3: 673 EFSYS_PROBE(fail3); 674fail2: 675 EFSYS_PROBE(fail2); 676fail1: 677 EFSYS_PROBE1(fail1, efx_rc_t, rc); 678 679 return (rc); 680} 681 682static __checkReturn efx_rc_t 683efx_mcdi_free_piobuf( 684 __in efx_nic_t *enp, 685 __in efx_piobuf_handle_t handle) 686{ 687 efx_mcdi_req_t req; 688 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN, 689 MC_CMD_FREE_PIOBUF_OUT_LEN); 690 efx_rc_t rc; 691 692 req.emr_cmd = MC_CMD_FREE_PIOBUF; 693 req.emr_in_buf = payload; 694 req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN; 695 req.emr_out_buf = payload; 696 req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN; 697 698 MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle); 699 700 efx_mcdi_execute_quiet(enp, &req); 701 702 if (req.emr_rc != 0) { 703 rc = req.emr_rc; 704 goto fail1; 705 } 706 707 return (0); 708 709fail1: 710 EFSYS_PROBE1(fail1, efx_rc_t, rc); 711 712 return (rc); 713} 714 715static __checkReturn efx_rc_t 716efx_mcdi_link_piobuf( 717 __in efx_nic_t *enp, 718 __in uint32_t vi_index, 719 __in efx_piobuf_handle_t handle) 720{ 721 efx_mcdi_req_t req; 722 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN, 723 MC_CMD_LINK_PIOBUF_OUT_LEN); 724 efx_rc_t rc; 725 726 req.emr_cmd = MC_CMD_LINK_PIOBUF; 727 req.emr_in_buf = payload; 728 req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN; 729 req.emr_out_buf = payload; 730 req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN; 731 732 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle); 733 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 734 735 efx_mcdi_execute(enp, &req); 736 737 if (req.emr_rc != 0) { 738 rc = req.emr_rc; 739 goto fail1; 740 } 741 742 return (0); 743 744fail1: 745 EFSYS_PROBE1(fail1, efx_rc_t, rc); 746 747 return (rc); 748} 749 750static __checkReturn efx_rc_t 751efx_mcdi_unlink_piobuf( 752 __in efx_nic_t *enp, 753 __in uint32_t vi_index) 754{ 755 efx_mcdi_req_t req; 756 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN, 757 MC_CMD_UNLINK_PIOBUF_OUT_LEN); 758 efx_rc_t rc; 759 760 req.emr_cmd = MC_CMD_UNLINK_PIOBUF; 761 req.emr_in_buf = payload; 762 req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN; 763 req.emr_out_buf = payload; 764 req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN; 765 766 MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 767 768 efx_mcdi_execute_quiet(enp, &req); 769 770 if (req.emr_rc != 0) { 771 rc = req.emr_rc; 772 goto fail1; 773 } 774 775 return (0); 776 777fail1: 778 EFSYS_PROBE1(fail1, efx_rc_t, rc); 779 780 return (rc); 781} 782 783static void 784ef10_nic_alloc_piobufs( 785 __in efx_nic_t *enp, 786 __in uint32_t max_piobuf_count) 787{ 788 efx_piobuf_handle_t *handlep; 789 unsigned int i; 790 791 EFSYS_ASSERT3U(max_piobuf_count, <=, 792 EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle)); 793 794 enp->en_arch.ef10.ena_piobuf_count = 0; 795 796 for (i = 0; i < max_piobuf_count; i++) { 797 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 798 799 if (efx_mcdi_alloc_piobuf(enp, handlep) != 0) 800 goto fail1; 801 802 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0; 803 enp->en_arch.ef10.ena_piobuf_count++; 804 } 805 806 return; 807 808fail1: 809 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 810 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 811 812 (void) efx_mcdi_free_piobuf(enp, *handlep); 813 *handlep = EFX_PIOBUF_HANDLE_INVALID; 814 } 815 enp->en_arch.ef10.ena_piobuf_count = 0; 816} 817 818 819static void 820ef10_nic_free_piobufs( 821 __in efx_nic_t *enp) 822{ 823 efx_piobuf_handle_t *handlep; 824 unsigned int i; 825 826 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 827 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 828 829 (void) efx_mcdi_free_piobuf(enp, *handlep); 830 *handlep = EFX_PIOBUF_HANDLE_INVALID; 831 } 832 enp->en_arch.ef10.ena_piobuf_count = 0; 833} 834 835/* Sub-allocate a block from a piobuf */ 836 __checkReturn efx_rc_t 837ef10_nic_pio_alloc( 838 __inout efx_nic_t *enp, 839 __out uint32_t *bufnump, 840 __out efx_piobuf_handle_t *handlep, 841 __out uint32_t *blknump, 842 __out uint32_t *offsetp, 843 __out size_t *sizep) 844{ 845 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 846 efx_drv_cfg_t *edcp = &enp->en_drv_cfg; 847 uint32_t blk_per_buf; 848 uint32_t buf, blk; 849 efx_rc_t rc; 850 851 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 852 enp->en_family == EFX_FAMILY_MEDFORD); 853 EFSYS_ASSERT(bufnump); 854 EFSYS_ASSERT(handlep); 855 EFSYS_ASSERT(blknump); 856 EFSYS_ASSERT(offsetp); 857 EFSYS_ASSERT(sizep); 858 859 if ((edcp->edc_pio_alloc_size == 0) || 860 (enp->en_arch.ef10.ena_piobuf_count == 0)) { 861 rc = ENOMEM; 862 goto fail1; 863 } 864 blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size; 865 866 for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) { 867 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf]; 868 869 if (~(*map) == 0) 870 continue; 871 872 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map))); 873 for (blk = 0; blk < blk_per_buf; blk++) { 874 if ((*map & (1u << blk)) == 0) { 875 *map |= (1u << blk); 876 goto done; 877 } 878 } 879 } 880 rc = ENOMEM; 881 goto fail2; 882 883done: 884 *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf]; 885 *bufnump = buf; 886 *blknump = blk; 887 *sizep = edcp->edc_pio_alloc_size; 888 *offsetp = blk * (*sizep); 889 890 return (0); 891 892fail2: 893 EFSYS_PROBE(fail2); 894fail1: 895 EFSYS_PROBE1(fail1, efx_rc_t, rc); 896 897 return (rc); 898} 899 900/* Free a piobuf sub-allocated block */ 901 __checkReturn efx_rc_t 902ef10_nic_pio_free( 903 __inout efx_nic_t *enp, 904 __in uint32_t bufnum, 905 __in uint32_t blknum) 906{ 907 uint32_t *map; 908 efx_rc_t rc; 909 910 if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) || 911 (blknum >= (8 * sizeof (*map)))) { 912 rc = EINVAL; 913 goto fail1; 914 } 915 916 map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum]; 917 if ((*map & (1u << blknum)) == 0) { 918 rc = ENOENT; 919 goto fail2; 920 } 921 *map &= ~(1u << blknum); 922 923 return (0); 924 925fail2: 926 EFSYS_PROBE(fail2); 927fail1: 928 EFSYS_PROBE1(fail1, efx_rc_t, rc); 929 930 return (rc); 931} 932 933 __checkReturn efx_rc_t 934ef10_nic_pio_link( 935 __inout efx_nic_t *enp, 936 __in uint32_t vi_index, 937 __in efx_piobuf_handle_t handle) 938{ 939 return (efx_mcdi_link_piobuf(enp, vi_index, handle)); 940} 941 942 __checkReturn efx_rc_t 943ef10_nic_pio_unlink( 944 __inout efx_nic_t *enp, 945 __in uint32_t vi_index) 946{ 947 return (efx_mcdi_unlink_piobuf(enp, vi_index)); 948} 949 950static __checkReturn efx_rc_t 951ef10_mcdi_get_pf_count( 952 __in efx_nic_t *enp, 953 __out uint32_t *pf_countp) 954{ 955 efx_mcdi_req_t req; 956 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN, 957 MC_CMD_GET_PF_COUNT_OUT_LEN); 958 efx_rc_t rc; 959 960 req.emr_cmd = MC_CMD_GET_PF_COUNT; 961 req.emr_in_buf = payload; 962 req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN; 963 req.emr_out_buf = payload; 964 req.emr_out_length = MC_CMD_GET_PF_COUNT_OUT_LEN; 965 966 efx_mcdi_execute(enp, &req); 967 968 if (req.emr_rc != 0) { 969 rc = req.emr_rc; 970 goto fail1; 971 } 972 973 if (req.emr_out_length_used < MC_CMD_GET_PF_COUNT_OUT_LEN) { 974 rc = EMSGSIZE; 975 goto fail2; 976 } 977 978 *pf_countp = *MCDI_OUT(req, uint8_t, 979 MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST); 980 981 EFSYS_ASSERT(*pf_countp != 0); 982 983 return (0); 984 985fail2: 986 EFSYS_PROBE(fail2); 987fail1: 988 EFSYS_PROBE1(fail1, efx_rc_t, rc); 989 990 return (rc); 991} 992 993 __checkReturn efx_rc_t 994ef10_get_datapath_caps( 995 __in efx_nic_t *enp) 996{ 997 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 998 uint32_t flags; 999 uint32_t flags2; 1000 uint32_t tso2nc; 1001 efx_rc_t rc; 1002 1003 if ((rc = efx_mcdi_get_capabilities(enp, &flags, &flags2, 1004 &tso2nc)) != 0) 1005 goto fail1; 1006 1007 if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0) 1008 goto fail1; 1009 1010#define CAP_FLAG(flags1, field) \ 1011 ((flags1) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN))) 1012 1013#define CAP_FLAG2(flags2, field) \ 1014 ((flags2) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN))) 1015 1016 /* 1017 * Huntington RXDP firmware inserts a 0 or 14 byte prefix. 1018 * We only support the 14 byte prefix here. 1019 */ 1020 if (CAP_FLAG(flags, RX_PREFIX_LEN_14) == 0) { 1021 rc = ENOTSUP; 1022 goto fail2; 1023 } 1024 encp->enc_rx_prefix_size = 14; 1025 1026 /* Check if the firmware supports TSO */ 1027 encp->enc_fw_assisted_tso_enabled = 1028 CAP_FLAG(flags, TX_TSO) ? B_TRUE : B_FALSE; 1029 1030 /* Check if the firmware supports FATSOv2 */ 1031 encp->enc_fw_assisted_tso_v2_enabled = 1032 CAP_FLAG2(flags2, TX_TSO_V2) ? B_TRUE : B_FALSE; 1033 1034 /* Get the number of TSO contexts (FATSOv2) */ 1035 encp->enc_fw_assisted_tso_v2_n_contexts = 1036 CAP_FLAG2(flags2, TX_TSO_V2) ? tso2nc : 0; 1037 1038 /* Check if the firmware has vadapter/vport/vswitch support */ 1039 encp->enc_datapath_cap_evb = 1040 CAP_FLAG(flags, EVB) ? B_TRUE : B_FALSE; 1041 1042 /* Check if the firmware supports VLAN insertion */ 1043 encp->enc_hw_tx_insert_vlan_enabled = 1044 CAP_FLAG(flags, TX_VLAN_INSERTION) ? B_TRUE : B_FALSE; 1045 1046 /* Check if the firmware supports RX event batching */ 1047 encp->enc_rx_batching_enabled = 1048 CAP_FLAG(flags, RX_BATCHING) ? B_TRUE : B_FALSE; 1049 1050 /* 1051 * Even if batching isn't reported as supported, we may still get 1052 * batched events. 1053 */ 1054 encp->enc_rx_batch_max = 16; 1055 1056 /* Check if the firmware supports disabling scatter on RXQs */ 1057 encp->enc_rx_disable_scatter_supported = 1058 CAP_FLAG(flags, RX_DISABLE_SCATTER) ? B_TRUE : B_FALSE; 1059 1060 /* Check if the firmware supports set mac with running filters */ 1061 encp->enc_allow_set_mac_with_installed_filters = 1062 CAP_FLAG(flags, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED) ? 1063 B_TRUE : B_FALSE; 1064 1065 /* 1066 * Check if firmware supports the extended MC_CMD_SET_MAC, which allows 1067 * specifying which parameters to configure. 1068 */ 1069 encp->enc_enhanced_set_mac_supported = 1070 CAP_FLAG(flags, SET_MAC_ENHANCED) ? B_TRUE : B_FALSE; 1071 1072 /* 1073 * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows 1074 * us to let the firmware choose the settings to use on an EVQ. 1075 */ 1076 encp->enc_init_evq_v2_supported = 1077 CAP_FLAG2(flags2, INIT_EVQ_V2) ? B_TRUE : B_FALSE; 1078 1079 /* 1080 * Check if firmware-verified NVRAM updates must be used. 1081 * 1082 * The firmware trusted installer requires all NVRAM updates to use 1083 * version 2 of MC_CMD_NVRAM_UPDATE_START (to enable verified update) 1084 * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated 1085 * partition and report the result). 1086 */ 1087 encp->enc_fw_verified_nvram_update_required = 1088 CAP_FLAG2(flags2, NVRAM_UPDATE_REPORT_VERIFY_RESULT) ? 1089 B_TRUE : B_FALSE; 1090 1091 /* 1092 * Check if firmware provides packet memory and Rx datapath 1093 * counters. 1094 */ 1095 encp->enc_pm_and_rxdp_counters = 1096 CAP_FLAG(flags, PM_AND_RXDP_COUNTERS) ? B_TRUE : B_FALSE; 1097 1098 /* 1099 * Check if the 40G MAC hardware is capable of reporting 1100 * statistics for Tx size bins. 1101 */ 1102 encp->enc_mac_stats_40g_tx_size_bins = 1103 CAP_FLAG2(flags2, MAC_STATS_40G_TX_SIZE_BINS) ? B_TRUE : B_FALSE; 1104 1105 /* 1106 * Check if firmware supports VXLAN and NVGRE tunnels. 1107 * The capability indicates Geneve protocol support as well. 1108 */ 1109 if (CAP_FLAG(flags, VXLAN_NVGRE)) 1110 encp->enc_tunnel_encapsulations_supported = 1111 (1u << EFX_TUNNEL_PROTOCOL_VXLAN) | 1112 (1u << EFX_TUNNEL_PROTOCOL_GENEVE) | 1113 (1u << EFX_TUNNEL_PROTOCOL_NVGRE); 1114 1115#undef CAP_FLAG 1116#undef CAP_FLAG2 1117 1118 return (0); 1119 1120fail2: 1121 EFSYS_PROBE(fail2); 1122fail1: 1123 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1124 1125 return (rc); 1126} 1127 1128 1129#define EF10_LEGACY_PF_PRIVILEGE_MASK \ 1130 (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \ 1131 MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK | \ 1132 MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD | \ 1133 MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP | \ 1134 MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS | \ 1135 MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING | \ 1136 MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST | \ 1137 MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST | \ 1138 MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST | \ 1139 MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \ 1140 MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS) 1141 1142#define EF10_LEGACY_VF_PRIVILEGE_MASK 0 1143 1144 1145 __checkReturn efx_rc_t 1146ef10_get_privilege_mask( 1147 __in efx_nic_t *enp, 1148 __out uint32_t *maskp) 1149{ 1150 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1151 uint32_t mask; 1152 efx_rc_t rc; 1153 1154 if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf, 1155 &mask)) != 0) { 1156 if (rc != ENOTSUP) 1157 goto fail1; 1158 1159 /* Fallback for old firmware without privilege mask support */ 1160 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1161 /* Assume PF has admin privilege */ 1162 mask = EF10_LEGACY_PF_PRIVILEGE_MASK; 1163 } else { 1164 /* VF is always unprivileged by default */ 1165 mask = EF10_LEGACY_VF_PRIVILEGE_MASK; 1166 } 1167 } 1168 1169 *maskp = mask; 1170 1171 return (0); 1172 1173fail1: 1174 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1175 1176 return (rc); 1177} 1178 1179 1180/* 1181 * Table of mapping schemes from port number to the number of the external 1182 * connector on the board. The external numbering does not distinguish 1183 * off-board separated outputs such as from multi-headed cables. 1184 * 1185 * The count of adjacent port numbers that map to each external port 1186 * and the offset in the numbering, is determined by the chip family and 1187 * current port mode. 1188 * 1189 * For the Huntington family, the current port mode cannot be discovered, 1190 * so the mapping used is instead the last match in the table to the full 1191 * set of port modes to which the NIC can be configured. Therefore the 1192 * ordering of entries in the the mapping table is significant. 1193 */ 1194static struct { 1195 efx_family_t family; 1196 uint32_t modes_mask; 1197 int32_t count; 1198 int32_t offset; 1199} __ef10_external_port_mappings[] = { 1200 /* Supported modes with 1 output per external port */ 1201 { 1202 EFX_FAMILY_HUNTINGTON, 1203 (1 << TLV_PORT_MODE_10G) | 1204 (1 << TLV_PORT_MODE_10G_10G) | 1205 (1 << TLV_PORT_MODE_10G_10G_10G_10G), 1206 1, 1207 1 1208 }, 1209 { 1210 EFX_FAMILY_MEDFORD, 1211 (1 << TLV_PORT_MODE_10G) | 1212 (1 << TLV_PORT_MODE_10G_10G), 1213 1, 1214 1 1215 }, 1216 /* Supported modes with 2 outputs per external port */ 1217 { 1218 EFX_FAMILY_HUNTINGTON, 1219 (1 << TLV_PORT_MODE_40G) | 1220 (1 << TLV_PORT_MODE_40G_40G) | 1221 (1 << TLV_PORT_MODE_40G_10G_10G) | 1222 (1 << TLV_PORT_MODE_10G_10G_40G), 1223 2, 1224 1 1225 }, 1226 { 1227 EFX_FAMILY_MEDFORD, 1228 (1 << TLV_PORT_MODE_40G) | 1229 (1 << TLV_PORT_MODE_40G_40G) | 1230 (1 << TLV_PORT_MODE_40G_10G_10G) | 1231 (1 << TLV_PORT_MODE_10G_10G_40G) | 1232 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), 1233 2, 1234 1 1235 }, 1236 /* Supported modes with 4 outputs per external port */ 1237 { 1238 EFX_FAMILY_MEDFORD, 1239 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) | 1240 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1), 1241 4, 1242 1, 1243 }, 1244 { 1245 EFX_FAMILY_MEDFORD, 1246 (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2), 1247 4, 1248 2 1249 }, 1250}; 1251 1252 __checkReturn efx_rc_t 1253ef10_external_port_mapping( 1254 __in efx_nic_t *enp, 1255 __in uint32_t port, 1256 __out uint8_t *external_portp) 1257{ 1258 efx_rc_t rc; 1259 int i; 1260 uint32_t port_modes; 1261 uint32_t matches; 1262 uint32_t current; 1263 int32_t count = 1; /* Default 1-1 mapping */ 1264 int32_t offset = 1; /* Default starting external port number */ 1265 1266 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t)) != 0) { 1267 /* 1268 * No current port mode information 1269 * - infer mapping from available modes 1270 */ 1271 if ((rc = efx_mcdi_get_port_modes(enp, 1272 &port_modes, NULL)) != 0) { 1273 /* 1274 * No port mode information available 1275 * - use default mapping 1276 */ 1277 goto out; 1278 } 1279 } else { 1280 /* Only need to scan the current mode */ 1281 port_modes = 1 << current; 1282 } 1283 1284 /* 1285 * Infer the internal port -> external port mapping from 1286 * the possible port modes for this NIC. 1287 */ 1288 for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) { 1289 if (__ef10_external_port_mappings[i].family != 1290 enp->en_family) 1291 continue; 1292 matches = (__ef10_external_port_mappings[i].modes_mask & 1293 port_modes); 1294 if (matches != 0) { 1295 count = __ef10_external_port_mappings[i].count; 1296 offset = __ef10_external_port_mappings[i].offset; 1297 port_modes &= ~matches; 1298 } 1299 } 1300 1301 if (port_modes != 0) { 1302 /* Some advertised modes are not supported */ 1303 rc = ENOTSUP; 1304 goto fail1; 1305 } 1306 1307out: 1308 /* 1309 * Scale as required by last matched mode and then convert to 1310 * correctly offset numbering 1311 */ 1312 *external_portp = (uint8_t)((port / count) + offset); 1313 return (0); 1314 1315fail1: 1316 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1317 1318 return (rc); 1319} 1320 1321 1322 __checkReturn efx_rc_t 1323ef10_nic_probe( 1324 __in efx_nic_t *enp) 1325{ 1326 const efx_nic_ops_t *enop = enp->en_enop; 1327 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1328 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1329 efx_rc_t rc; 1330 1331 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1332 enp->en_family == EFX_FAMILY_MEDFORD); 1333 1334 /* Read and clear any assertion state */ 1335 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1336 goto fail1; 1337 1338 /* Exit the assertion handler */ 1339 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1340 if (rc != EACCES) 1341 goto fail2; 1342 1343 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 1344 goto fail3; 1345 1346 if ((rc = enop->eno_board_cfg(enp)) != 0) 1347 if (rc != EACCES) 1348 goto fail4; 1349 1350 /* 1351 * Set default driver config limits (based on board config). 1352 * 1353 * FIXME: For now allocate a fixed number of VIs which is likely to be 1354 * sufficient and small enough to allow multiple functions on the same 1355 * port. 1356 */ 1357 edcp->edc_min_vi_count = edcp->edc_max_vi_count = 1358 MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit)); 1359 1360 /* The client driver must configure and enable PIO buffer support */ 1361 edcp->edc_max_piobuf_count = 0; 1362 edcp->edc_pio_alloc_size = 0; 1363 1364#if EFSYS_OPT_MAC_STATS 1365 /* Wipe the MAC statistics */ 1366 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 1367 goto fail5; 1368#endif 1369 1370#if EFSYS_OPT_LOOPBACK 1371 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 1372 goto fail6; 1373#endif 1374 1375#if EFSYS_OPT_MON_STATS 1376 if ((rc = mcdi_mon_cfg_build(enp)) != 0) { 1377 /* Unprivileged functions do not have access to sensors */ 1378 if (rc != EACCES) 1379 goto fail7; 1380 } 1381#endif 1382 1383 encp->enc_features = enp->en_features; 1384 1385 return (0); 1386 1387#if EFSYS_OPT_MON_STATS 1388fail7: 1389 EFSYS_PROBE(fail7); 1390#endif 1391#if EFSYS_OPT_LOOPBACK 1392fail6: 1393 EFSYS_PROBE(fail6); 1394#endif 1395#if EFSYS_OPT_MAC_STATS 1396fail5: 1397 EFSYS_PROBE(fail5); 1398#endif 1399fail4: 1400 EFSYS_PROBE(fail4); 1401fail3: 1402 EFSYS_PROBE(fail3); 1403fail2: 1404 EFSYS_PROBE(fail2); 1405fail1: 1406 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1407 1408 return (rc); 1409} 1410 1411 __checkReturn efx_rc_t 1412ef10_nic_set_drv_limits( 1413 __inout efx_nic_t *enp, 1414 __in efx_drv_limits_t *edlp) 1415{ 1416 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1417 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1418 uint32_t min_evq_count, max_evq_count; 1419 uint32_t min_rxq_count, max_rxq_count; 1420 uint32_t min_txq_count, max_txq_count; 1421 efx_rc_t rc; 1422 1423 if (edlp == NULL) { 1424 rc = EINVAL; 1425 goto fail1; 1426 } 1427 1428 /* Get minimum required and maximum usable VI limits */ 1429 min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit); 1430 min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit); 1431 min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit); 1432 1433 edcp->edc_min_vi_count = 1434 MAX(min_evq_count, MAX(min_rxq_count, min_txq_count)); 1435 1436 max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit); 1437 max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit); 1438 max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit); 1439 1440 edcp->edc_max_vi_count = 1441 MAX(max_evq_count, MAX(max_rxq_count, max_txq_count)); 1442 1443 /* 1444 * Check limits for sub-allocated piobuf blocks. 1445 * PIO is optional, so don't fail if the limits are incorrect. 1446 */ 1447 if ((encp->enc_piobuf_size == 0) || 1448 (encp->enc_piobuf_limit == 0) || 1449 (edlp->edl_min_pio_alloc_size == 0) || 1450 (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) { 1451 /* Disable PIO */ 1452 edcp->edc_max_piobuf_count = 0; 1453 edcp->edc_pio_alloc_size = 0; 1454 } else { 1455 uint32_t blk_size, blk_count, blks_per_piobuf; 1456 1457 blk_size = 1458 MAX(edlp->edl_min_pio_alloc_size, 1459 encp->enc_piobuf_min_alloc_size); 1460 1461 blks_per_piobuf = encp->enc_piobuf_size / blk_size; 1462 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32); 1463 1464 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf); 1465 1466 /* A zero max pio alloc count means unlimited */ 1467 if ((edlp->edl_max_pio_alloc_count > 0) && 1468 (edlp->edl_max_pio_alloc_count < blk_count)) { 1469 blk_count = edlp->edl_max_pio_alloc_count; 1470 } 1471 1472 edcp->edc_pio_alloc_size = blk_size; 1473 edcp->edc_max_piobuf_count = 1474 (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf; 1475 } 1476 1477 return (0); 1478 1479fail1: 1480 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1481 1482 return (rc); 1483} 1484 1485 1486 __checkReturn efx_rc_t 1487ef10_nic_reset( 1488 __in efx_nic_t *enp) 1489{ 1490 efx_mcdi_req_t req; 1491 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN, 1492 MC_CMD_ENTITY_RESET_OUT_LEN); 1493 efx_rc_t rc; 1494 1495 /* ef10_nic_reset() is called to recover from BADASSERT failures. */ 1496 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1497 goto fail1; 1498 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1499 goto fail2; 1500 1501 req.emr_cmd = MC_CMD_ENTITY_RESET; 1502 req.emr_in_buf = payload; 1503 req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; 1504 req.emr_out_buf = payload; 1505 req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; 1506 1507 MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, 1508 ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); 1509 1510 efx_mcdi_execute(enp, &req); 1511 1512 if (req.emr_rc != 0) { 1513 rc = req.emr_rc; 1514 goto fail3; 1515 } 1516 1517 /* Clear RX/TX DMA queue errors */ 1518 enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR); 1519 1520 return (0); 1521 1522fail3: 1523 EFSYS_PROBE(fail3); 1524fail2: 1525 EFSYS_PROBE(fail2); 1526fail1: 1527 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1528 1529 return (rc); 1530} 1531 1532 __checkReturn efx_rc_t 1533ef10_nic_init( 1534 __in efx_nic_t *enp) 1535{ 1536 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1537 uint32_t min_vi_count, max_vi_count; 1538 uint32_t vi_count, vi_base, vi_shift; 1539 uint32_t i; 1540 uint32_t retry; 1541 uint32_t delay_us; 1542 efx_rc_t rc; 1543 1544 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1545 enp->en_family == EFX_FAMILY_MEDFORD); 1546 1547 /* Enable reporting of some events (e.g. link change) */ 1548 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 1549 goto fail1; 1550 1551 /* Allocate (optional) on-chip PIO buffers */ 1552 ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count); 1553 1554 /* 1555 * For best performance, PIO writes should use a write-combined 1556 * (WC) memory mapping. Using a separate WC mapping for the PIO 1557 * aperture of each VI would be a burden to drivers (and not 1558 * possible if the host page size is >4Kbyte). 1559 * 1560 * To avoid this we use a single uncached (UC) mapping for VI 1561 * register access, and a single WC mapping for extra VIs used 1562 * for PIO writes. 1563 * 1564 * Each piobuf must be linked to a VI in the WC mapping, and to 1565 * each VI that is using a sub-allocated block from the piobuf. 1566 */ 1567 min_vi_count = edcp->edc_min_vi_count; 1568 max_vi_count = 1569 edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count; 1570 1571 /* Ensure that the previously attached driver's VIs are freed */ 1572 if ((rc = efx_mcdi_free_vis(enp)) != 0) 1573 goto fail2; 1574 1575 /* 1576 * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this 1577 * fails then retrying the request for fewer VI resources may succeed. 1578 */ 1579 vi_count = 0; 1580 if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count, 1581 &vi_base, &vi_count, &vi_shift)) != 0) 1582 goto fail3; 1583 1584 EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count); 1585 1586 if (vi_count < min_vi_count) { 1587 rc = ENOMEM; 1588 goto fail4; 1589 } 1590 1591 enp->en_arch.ef10.ena_vi_base = vi_base; 1592 enp->en_arch.ef10.ena_vi_count = vi_count; 1593 enp->en_arch.ef10.ena_vi_shift = vi_shift; 1594 1595 if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) { 1596 /* Not enough extra VIs to map piobufs */ 1597 ef10_nic_free_piobufs(enp); 1598 } 1599 1600 enp->en_arch.ef10.ena_pio_write_vi_base = 1601 vi_count - enp->en_arch.ef10.ena_piobuf_count; 1602 1603 /* Save UC memory mapping details */ 1604 enp->en_arch.ef10.ena_uc_mem_map_offset = 0; 1605 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 1606 enp->en_arch.ef10.ena_uc_mem_map_size = 1607 (ER_DZ_TX_PIOBUF_STEP * 1608 enp->en_arch.ef10.ena_pio_write_vi_base); 1609 } else { 1610 enp->en_arch.ef10.ena_uc_mem_map_size = 1611 (ER_DZ_TX_PIOBUF_STEP * 1612 enp->en_arch.ef10.ena_vi_count); 1613 } 1614 1615 /* Save WC memory mapping details */ 1616 enp->en_arch.ef10.ena_wc_mem_map_offset = 1617 enp->en_arch.ef10.ena_uc_mem_map_offset + 1618 enp->en_arch.ef10.ena_uc_mem_map_size; 1619 1620 enp->en_arch.ef10.ena_wc_mem_map_size = 1621 (ER_DZ_TX_PIOBUF_STEP * 1622 enp->en_arch.ef10.ena_piobuf_count); 1623 1624 /* Link piobufs to extra VIs in WC mapping */ 1625 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 1626 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 1627 rc = efx_mcdi_link_piobuf(enp, 1628 enp->en_arch.ef10.ena_pio_write_vi_base + i, 1629 enp->en_arch.ef10.ena_piobuf_handle[i]); 1630 if (rc != 0) 1631 break; 1632 } 1633 } 1634 1635 /* 1636 * Allocate a vAdaptor attached to our upstream vPort/pPort. 1637 * 1638 * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF 1639 * driver has yet to bring up the EVB port. See bug 56147. In this case, 1640 * retry the request several times after waiting a while. The wait time 1641 * between retries starts small (10ms) and exponentially increases. 1642 * Total wait time is a little over two seconds. Retry logic in the 1643 * client driver may mean this whole loop is repeated if it continues to 1644 * fail. 1645 */ 1646 retry = 0; 1647 delay_us = 10000; 1648 while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { 1649 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || 1650 (rc != ENOENT)) { 1651 /* 1652 * Do not retry alloc for PF, or for other errors on 1653 * a VF. 1654 */ 1655 goto fail5; 1656 } 1657 1658 /* VF startup before PF is ready. Retry allocation. */ 1659 if (retry > 5) { 1660 /* Too many attempts */ 1661 rc = EINVAL; 1662 goto fail6; 1663 } 1664 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); 1665 EFSYS_SLEEP(delay_us); 1666 retry++; 1667 if (delay_us < 500000) 1668 delay_us <<= 2; 1669 } 1670 1671 enp->en_vport_id = EVB_PORT_ID_ASSIGNED; 1672 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2; 1673 1674 return (0); 1675 1676fail6: 1677 EFSYS_PROBE(fail6); 1678fail5: 1679 EFSYS_PROBE(fail5); 1680fail4: 1681 EFSYS_PROBE(fail4); 1682fail3: 1683 EFSYS_PROBE(fail3); 1684fail2: 1685 EFSYS_PROBE(fail2); 1686 1687 ef10_nic_free_piobufs(enp); 1688 1689fail1: 1690 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1691 1692 return (rc); 1693} 1694 1695 __checkReturn efx_rc_t 1696ef10_nic_get_vi_pool( 1697 __in efx_nic_t *enp, 1698 __out uint32_t *vi_countp) 1699{ 1700 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1701 enp->en_family == EFX_FAMILY_MEDFORD); 1702 1703 /* 1704 * Report VIs that the client driver can use. 1705 * Do not include VIs used for PIO buffer writes. 1706 */ 1707 *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base; 1708 1709 return (0); 1710} 1711 1712 __checkReturn efx_rc_t 1713ef10_nic_get_bar_region( 1714 __in efx_nic_t *enp, 1715 __in efx_nic_region_t region, 1716 __out uint32_t *offsetp, 1717 __out size_t *sizep) 1718{ 1719 efx_rc_t rc; 1720 1721 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1722 enp->en_family == EFX_FAMILY_MEDFORD); 1723 1724 /* 1725 * TODO: Specify host memory mapping alignment and granularity 1726 * in efx_drv_limits_t so that they can be taken into account 1727 * when allocating extra VIs for PIO writes. 1728 */ 1729 switch (region) { 1730 case EFX_REGION_VI: 1731 /* UC mapped memory BAR region for VI registers */ 1732 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset; 1733 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size; 1734 break; 1735 1736 case EFX_REGION_PIO_WRITE_VI: 1737 /* WC mapped memory BAR region for piobuf writes */ 1738 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset; 1739 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size; 1740 break; 1741 1742 default: 1743 rc = EINVAL; 1744 goto fail1; 1745 } 1746 1747 return (0); 1748 1749fail1: 1750 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1751 1752 return (rc); 1753} 1754 1755 void 1756ef10_nic_fini( 1757 __in efx_nic_t *enp) 1758{ 1759 uint32_t i; 1760 efx_rc_t rc; 1761 1762 (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id); 1763 enp->en_vport_id = 0; 1764 1765 /* Unlink piobufs from extra VIs in WC mapping */ 1766 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 1767 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 1768 rc = efx_mcdi_unlink_piobuf(enp, 1769 enp->en_arch.ef10.ena_pio_write_vi_base + i); 1770 if (rc != 0) 1771 break; 1772 } 1773 } 1774 1775 ef10_nic_free_piobufs(enp); 1776 1777 (void) efx_mcdi_free_vis(enp); 1778 enp->en_arch.ef10.ena_vi_count = 0; 1779} 1780 1781 void 1782ef10_nic_unprobe( 1783 __in efx_nic_t *enp) 1784{ 1785#if EFSYS_OPT_MON_STATS 1786 mcdi_mon_cfg_free(enp); 1787#endif /* EFSYS_OPT_MON_STATS */ 1788 (void) efx_mcdi_drv_attach(enp, B_FALSE); 1789} 1790 1791#if EFSYS_OPT_DIAG 1792 1793 __checkReturn efx_rc_t 1794ef10_nic_register_test( 1795 __in efx_nic_t *enp) 1796{ 1797 efx_rc_t rc; 1798 1799 /* FIXME */ 1800 _NOTE(ARGUNUSED(enp)) 1801 _NOTE(CONSTANTCONDITION) 1802 if (B_FALSE) { 1803 rc = ENOTSUP; 1804 goto fail1; 1805 } 1806 /* FIXME */ 1807 1808 return (0); 1809 1810fail1: 1811 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1812 1813 return (rc); 1814} 1815 1816#endif /* EFSYS_OPT_DIAG */ 1817 1818#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 1819