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