1 /*- 2 * Copyright (c) 2012-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #include <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 41 42 #include "ef10_tlv_layout.h" 43 44 static __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 static __checkReturn efx_rc_t 89 efx_mcdi_get_port_modes( 90 __in efx_nic_t *enp, 91 __out uint32_t *modesp) 92 { 93 efx_mcdi_req_t req; 94 uint8_t payload[MAX(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 (void) memset(payload, 0, sizeof (payload)); 102 req.emr_cmd = MC_CMD_GET_PORT_MODES; 103 req.emr_in_buf = payload; 104 req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN; 105 req.emr_out_buf = payload; 106 req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN; 107 108 efx_mcdi_execute(enp, &req); 109 110 if (req.emr_rc != 0) { 111 rc = req.emr_rc; 112 goto fail1; 113 } 114 115 /* Accept pre-Medford size (8 bytes - no CurrentMode field) */ 116 if (req.emr_out_length_used < 117 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) { 118 rc = EMSGSIZE; 119 goto fail2; 120 } 121 122 *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES); 123 124 return (0); 125 126 fail2: 127 EFSYS_PROBE(fail2); 128 fail1: 129 EFSYS_PROBE1(fail1, efx_rc_t, rc); 130 131 return (rc); 132 } 133 134 135 static __checkReturn efx_rc_t 136 efx_mcdi_vadaptor_alloc( 137 __in efx_nic_t *enp, 138 __in uint32_t port_id) 139 { 140 efx_mcdi_req_t req; 141 uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN, 142 MC_CMD_VADAPTOR_ALLOC_OUT_LEN)]; 143 efx_rc_t rc; 144 145 EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL); 146 147 (void) memset(payload, 0, sizeof (payload)); 148 req.emr_cmd = MC_CMD_VADAPTOR_ALLOC; 149 req.emr_in_buf = payload; 150 req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN; 151 req.emr_out_buf = payload; 152 req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN; 153 154 MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id); 155 MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS, 156 VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED, 157 enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0); 158 159 efx_mcdi_execute(enp, &req); 160 161 if (req.emr_rc != 0) { 162 rc = req.emr_rc; 163 goto fail1; 164 } 165 166 return (0); 167 168 fail1: 169 EFSYS_PROBE1(fail1, efx_rc_t, rc); 170 171 return (rc); 172 } 173 174 static __checkReturn efx_rc_t 175 efx_mcdi_vadaptor_free( 176 __in efx_nic_t *enp, 177 __in uint32_t port_id) 178 { 179 efx_mcdi_req_t req; 180 uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN, 181 MC_CMD_VADAPTOR_FREE_OUT_LEN)]; 182 efx_rc_t rc; 183 184 (void) memset(payload, 0, sizeof (payload)); 185 req.emr_cmd = MC_CMD_VADAPTOR_FREE; 186 req.emr_in_buf = payload; 187 req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN; 188 req.emr_out_buf = payload; 189 req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN; 190 191 MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id); 192 193 efx_mcdi_execute(enp, &req); 194 195 if (req.emr_rc != 0) { 196 rc = req.emr_rc; 197 goto fail1; 198 } 199 200 return (0); 201 202 fail1: 203 EFSYS_PROBE1(fail1, efx_rc_t, rc); 204 205 return (rc); 206 } 207 208 static __checkReturn efx_rc_t 209 efx_mcdi_get_mac_address_pf( 210 __in efx_nic_t *enp, 211 __out_ecount_opt(6) uint8_t mac_addrp[6]) 212 { 213 efx_mcdi_req_t req; 214 uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN, 215 MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)]; 216 efx_rc_t rc; 217 218 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 219 enp->en_family == EFX_FAMILY_MEDFORD); 220 221 (void) memset(payload, 0, sizeof (payload)); 222 req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES; 223 req.emr_in_buf = payload; 224 req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN; 225 req.emr_out_buf = payload; 226 req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN; 227 228 efx_mcdi_execute(enp, &req); 229 230 if (req.emr_rc != 0) { 231 rc = req.emr_rc; 232 goto fail1; 233 } 234 235 if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) { 236 rc = EMSGSIZE; 237 goto fail2; 238 } 239 240 if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) { 241 rc = ENOENT; 242 goto fail3; 243 } 244 245 if (mac_addrp != NULL) { 246 uint8_t *addrp; 247 248 addrp = MCDI_OUT2(req, uint8_t, 249 GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE); 250 251 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 252 } 253 254 return (0); 255 256 fail3: 257 EFSYS_PROBE(fail3); 258 fail2: 259 EFSYS_PROBE(fail2); 260 fail1: 261 EFSYS_PROBE1(fail1, efx_rc_t, rc); 262 263 return (rc); 264 } 265 266 static __checkReturn efx_rc_t 267 efx_mcdi_get_mac_address_vf( 268 __in efx_nic_t *enp, 269 __out_ecount_opt(6) uint8_t mac_addrp[6]) 270 { 271 efx_mcdi_req_t req; 272 uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN, 273 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)]; 274 efx_rc_t rc; 275 276 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 277 enp->en_family == EFX_FAMILY_MEDFORD); 278 279 (void) memset(payload, 0, sizeof (payload)); 280 req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES; 281 req.emr_in_buf = payload; 282 req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN; 283 req.emr_out_buf = payload; 284 req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX; 285 286 MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID, 287 EVB_PORT_ID_ASSIGNED); 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 < 297 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) { 298 rc = EMSGSIZE; 299 goto fail2; 300 } 301 302 if (MCDI_OUT_DWORD(req, 303 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) { 304 rc = ENOENT; 305 goto fail3; 306 } 307 308 if (mac_addrp != NULL) { 309 uint8_t *addrp; 310 311 addrp = MCDI_OUT2(req, uint8_t, 312 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR); 313 314 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 315 } 316 317 return (0); 318 319 fail3: 320 EFSYS_PROBE(fail3); 321 fail2: 322 EFSYS_PROBE(fail2); 323 fail1: 324 EFSYS_PROBE1(fail1, efx_rc_t, rc); 325 326 return (rc); 327 } 328 329 static __checkReturn efx_rc_t 330 efx_mcdi_get_clock( 331 __in efx_nic_t *enp, 332 __out uint32_t *sys_freqp) 333 { 334 efx_mcdi_req_t req; 335 uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN, 336 MC_CMD_GET_CLOCK_OUT_LEN)]; 337 efx_rc_t rc; 338 339 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 340 enp->en_family == EFX_FAMILY_MEDFORD); 341 342 (void) memset(payload, 0, sizeof (payload)); 343 req.emr_cmd = MC_CMD_GET_CLOCK; 344 req.emr_in_buf = payload; 345 req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN; 346 req.emr_out_buf = payload; 347 req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN; 348 349 efx_mcdi_execute(enp, &req); 350 351 if (req.emr_rc != 0) { 352 rc = req.emr_rc; 353 goto fail1; 354 } 355 356 if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) { 357 rc = EMSGSIZE; 358 goto fail2; 359 } 360 361 *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ); 362 if (*sys_freqp == 0) { 363 rc = EINVAL; 364 goto fail3; 365 } 366 367 return (0); 368 369 fail3: 370 EFSYS_PROBE(fail3); 371 fail2: 372 EFSYS_PROBE(fail2); 373 fail1: 374 EFSYS_PROBE1(fail1, efx_rc_t, rc); 375 376 return (rc); 377 } 378 379 static __checkReturn efx_rc_t 380 efx_mcdi_get_vector_cfg( 381 __in efx_nic_t *enp, 382 __out_opt uint32_t *vec_basep, 383 __out_opt uint32_t *pf_nvecp, 384 __out_opt uint32_t *vf_nvecp) 385 { 386 efx_mcdi_req_t req; 387 uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN, 388 MC_CMD_GET_VECTOR_CFG_OUT_LEN)]; 389 efx_rc_t rc; 390 391 (void) memset(payload, 0, sizeof (payload)); 392 req.emr_cmd = MC_CMD_GET_VECTOR_CFG; 393 req.emr_in_buf = payload; 394 req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN; 395 req.emr_out_buf = payload; 396 req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN; 397 398 efx_mcdi_execute(enp, &req); 399 400 if (req.emr_rc != 0) { 401 rc = req.emr_rc; 402 goto fail1; 403 } 404 405 if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) { 406 rc = EMSGSIZE; 407 goto fail2; 408 } 409 410 if (vec_basep != NULL) 411 *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE); 412 if (pf_nvecp != NULL) 413 *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF); 414 if (vf_nvecp != NULL) 415 *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF); 416 417 return (0); 418 419 fail2: 420 EFSYS_PROBE(fail2); 421 fail1: 422 EFSYS_PROBE1(fail1, efx_rc_t, rc); 423 424 return (rc); 425 } 426 427 static __checkReturn efx_rc_t 428 efx_mcdi_get_capabilities( 429 __in efx_nic_t *enp, 430 __out efx_dword_t *flagsp, 431 __out efx_dword_t *flags2p) 432 { 433 efx_mcdi_req_t req; 434 uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN, 435 MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)]; 436 efx_rc_t rc; 437 438 (void) memset(payload, 0, sizeof (payload)); 439 req.emr_cmd = MC_CMD_GET_CAPABILITIES; 440 req.emr_in_buf = payload; 441 req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; 442 req.emr_out_buf = payload; 443 req.emr_out_length = MC_CMD_GET_CAPABILITIES_V2_OUT_LEN; 444 445 efx_mcdi_execute(enp, &req); 446 447 if (req.emr_rc != 0) { 448 rc = req.emr_rc; 449 goto fail1; 450 } 451 452 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) { 453 rc = EMSGSIZE; 454 goto fail2; 455 } 456 457 *flagsp = *MCDI_OUT2(req, efx_dword_t, GET_CAPABILITIES_OUT_FLAGS1); 458 459 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) 460 EFX_ZERO_DWORD(*flags2p); 461 else 462 *flags2p = *MCDI_OUT2(req, efx_dword_t, 463 GET_CAPABILITIES_V2_OUT_FLAGS2); 464 465 return (0); 466 467 fail2: 468 EFSYS_PROBE(fail2); 469 fail1: 470 EFSYS_PROBE1(fail1, efx_rc_t, rc); 471 472 return (rc); 473 } 474 475 476 static __checkReturn efx_rc_t 477 efx_mcdi_alloc_vis( 478 __in efx_nic_t *enp, 479 __in uint32_t min_vi_count, 480 __in uint32_t max_vi_count, 481 __out uint32_t *vi_basep, 482 __out uint32_t *vi_countp, 483 __out uint32_t *vi_shiftp) 484 { 485 efx_mcdi_req_t req; 486 uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN, 487 MC_CMD_ALLOC_VIS_OUT_LEN)]; 488 efx_rc_t rc; 489 490 if (vi_countp == NULL) { 491 rc = EINVAL; 492 goto fail1; 493 } 494 495 (void) memset(payload, 0, sizeof (payload)); 496 req.emr_cmd = MC_CMD_ALLOC_VIS; 497 req.emr_in_buf = payload; 498 req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN; 499 req.emr_out_buf = payload; 500 req.emr_out_length = MC_CMD_ALLOC_VIS_OUT_LEN; 501 502 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count); 503 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count); 504 505 efx_mcdi_execute(enp, &req); 506 507 if (req.emr_rc != 0) { 508 rc = req.emr_rc; 509 goto fail2; 510 } 511 512 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) { 513 rc = EMSGSIZE; 514 goto fail3; 515 } 516 517 *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE); 518 *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT); 519 520 /* Report VI_SHIFT if available (always zero for Huntington) */ 521 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN) 522 *vi_shiftp = 0; 523 else 524 *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT); 525 526 return (0); 527 528 fail3: 529 EFSYS_PROBE(fail3); 530 fail2: 531 EFSYS_PROBE(fail2); 532 fail1: 533 EFSYS_PROBE1(fail1, efx_rc_t, rc); 534 535 return (rc); 536 } 537 538 539 static __checkReturn efx_rc_t 540 efx_mcdi_free_vis( 541 __in efx_nic_t *enp) 542 { 543 efx_mcdi_req_t req; 544 efx_rc_t rc; 545 546 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0); 547 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0); 548 549 req.emr_cmd = MC_CMD_FREE_VIS; 550 req.emr_in_buf = NULL; 551 req.emr_in_length = 0; 552 req.emr_out_buf = NULL; 553 req.emr_out_length = 0; 554 555 efx_mcdi_execute_quiet(enp, &req); 556 557 /* Ignore ELREADY (no allocated VIs, so nothing to free) */ 558 if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) { 559 rc = req.emr_rc; 560 goto fail1; 561 } 562 563 return (0); 564 565 fail1: 566 EFSYS_PROBE1(fail1, efx_rc_t, rc); 567 568 return (rc); 569 } 570 571 572 static __checkReturn efx_rc_t 573 efx_mcdi_alloc_piobuf( 574 __in efx_nic_t *enp, 575 __out efx_piobuf_handle_t *handlep) 576 { 577 efx_mcdi_req_t req; 578 uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN, 579 MC_CMD_ALLOC_PIOBUF_OUT_LEN)]; 580 efx_rc_t rc; 581 582 if (handlep == NULL) { 583 rc = EINVAL; 584 goto fail1; 585 } 586 587 (void) memset(payload, 0, sizeof (payload)); 588 req.emr_cmd = MC_CMD_ALLOC_PIOBUF; 589 req.emr_in_buf = payload; 590 req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN; 591 req.emr_out_buf = payload; 592 req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN; 593 594 efx_mcdi_execute_quiet(enp, &req); 595 596 if (req.emr_rc != 0) { 597 rc = req.emr_rc; 598 goto fail2; 599 } 600 601 if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) { 602 rc = EMSGSIZE; 603 goto fail3; 604 } 605 606 *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE); 607 608 return (0); 609 610 fail3: 611 EFSYS_PROBE(fail3); 612 fail2: 613 EFSYS_PROBE(fail2); 614 fail1: 615 EFSYS_PROBE1(fail1, efx_rc_t, rc); 616 617 return (rc); 618 } 619 620 static __checkReturn efx_rc_t 621 efx_mcdi_free_piobuf( 622 __in efx_nic_t *enp, 623 __in efx_piobuf_handle_t handle) 624 { 625 efx_mcdi_req_t req; 626 uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN, 627 MC_CMD_FREE_PIOBUF_OUT_LEN)]; 628 efx_rc_t rc; 629 630 (void) memset(payload, 0, sizeof (payload)); 631 req.emr_cmd = MC_CMD_FREE_PIOBUF; 632 req.emr_in_buf = payload; 633 req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN; 634 req.emr_out_buf = payload; 635 req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN; 636 637 MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle); 638 639 efx_mcdi_execute_quiet(enp, &req); 640 641 if (req.emr_rc != 0) { 642 rc = req.emr_rc; 643 goto fail1; 644 } 645 646 return (0); 647 648 fail1: 649 EFSYS_PROBE1(fail1, efx_rc_t, rc); 650 651 return (rc); 652 } 653 654 static __checkReturn efx_rc_t 655 efx_mcdi_link_piobuf( 656 __in efx_nic_t *enp, 657 __in uint32_t vi_index, 658 __in efx_piobuf_handle_t handle) 659 { 660 efx_mcdi_req_t req; 661 uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN, 662 MC_CMD_LINK_PIOBUF_OUT_LEN)]; 663 efx_rc_t rc; 664 665 (void) memset(payload, 0, sizeof (payload)); 666 req.emr_cmd = MC_CMD_LINK_PIOBUF; 667 req.emr_in_buf = payload; 668 req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN; 669 req.emr_out_buf = payload; 670 req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN; 671 672 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle); 673 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 674 675 efx_mcdi_execute(enp, &req); 676 677 if (req.emr_rc != 0) { 678 rc = req.emr_rc; 679 goto fail1; 680 } 681 682 return (0); 683 684 fail1: 685 EFSYS_PROBE1(fail1, efx_rc_t, rc); 686 687 return (rc); 688 } 689 690 static __checkReturn efx_rc_t 691 efx_mcdi_unlink_piobuf( 692 __in efx_nic_t *enp, 693 __in uint32_t vi_index) 694 { 695 efx_mcdi_req_t req; 696 uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN, 697 MC_CMD_UNLINK_PIOBUF_OUT_LEN)]; 698 efx_rc_t rc; 699 700 (void) memset(payload, 0, sizeof (payload)); 701 req.emr_cmd = MC_CMD_UNLINK_PIOBUF; 702 req.emr_in_buf = payload; 703 req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN; 704 req.emr_out_buf = payload; 705 req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN; 706 707 MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 708 709 efx_mcdi_execute(enp, &req); 710 711 if (req.emr_rc != 0) { 712 rc = req.emr_rc; 713 goto fail1; 714 } 715 716 return (0); 717 718 fail1: 719 EFSYS_PROBE1(fail1, efx_rc_t, rc); 720 721 return (rc); 722 } 723 724 static void 725 ef10_nic_alloc_piobufs( 726 __in efx_nic_t *enp, 727 __in uint32_t max_piobuf_count) 728 { 729 efx_piobuf_handle_t *handlep; 730 unsigned int i; 731 efx_rc_t rc; 732 733 EFSYS_ASSERT3U(max_piobuf_count, <=, 734 EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle)); 735 736 enp->en_arch.ef10.ena_piobuf_count = 0; 737 738 for (i = 0; i < max_piobuf_count; i++) { 739 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 740 741 if ((rc = efx_mcdi_alloc_piobuf(enp, handlep)) != 0) 742 goto fail1; 743 744 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0; 745 enp->en_arch.ef10.ena_piobuf_count++; 746 } 747 748 return; 749 750 fail1: 751 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 752 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 753 754 efx_mcdi_free_piobuf(enp, *handlep); 755 *handlep = EFX_PIOBUF_HANDLE_INVALID; 756 } 757 enp->en_arch.ef10.ena_piobuf_count = 0; 758 } 759 760 761 static void 762 ef10_nic_free_piobufs( 763 __in efx_nic_t *enp) 764 { 765 efx_piobuf_handle_t *handlep; 766 unsigned int i; 767 768 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 769 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 770 771 efx_mcdi_free_piobuf(enp, *handlep); 772 *handlep = EFX_PIOBUF_HANDLE_INVALID; 773 } 774 enp->en_arch.ef10.ena_piobuf_count = 0; 775 } 776 777 /* Sub-allocate a block from a piobuf */ 778 __checkReturn efx_rc_t 779 ef10_nic_pio_alloc( 780 __inout efx_nic_t *enp, 781 __out uint32_t *bufnump, 782 __out efx_piobuf_handle_t *handlep, 783 __out uint32_t *blknump, 784 __out uint32_t *offsetp, 785 __out size_t *sizep) 786 { 787 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 788 efx_drv_cfg_t *edcp = &enp->en_drv_cfg; 789 uint32_t blk_per_buf; 790 uint32_t buf, blk; 791 efx_rc_t rc; 792 793 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 794 enp->en_family == EFX_FAMILY_MEDFORD); 795 EFSYS_ASSERT(bufnump); 796 EFSYS_ASSERT(handlep); 797 EFSYS_ASSERT(blknump); 798 EFSYS_ASSERT(offsetp); 799 EFSYS_ASSERT(sizep); 800 801 if ((edcp->edc_pio_alloc_size == 0) || 802 (enp->en_arch.ef10.ena_piobuf_count == 0)) { 803 rc = ENOMEM; 804 goto fail1; 805 } 806 blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size; 807 808 for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) { 809 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf]; 810 811 if (~(*map) == 0) 812 continue; 813 814 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map))); 815 for (blk = 0; blk < blk_per_buf; blk++) { 816 if ((*map & (1u << blk)) == 0) { 817 *map |= (1u << blk); 818 goto done; 819 } 820 } 821 } 822 rc = ENOMEM; 823 goto fail2; 824 825 done: 826 *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf]; 827 *bufnump = buf; 828 *blknump = blk; 829 *sizep = edcp->edc_pio_alloc_size; 830 *offsetp = blk * (*sizep); 831 832 return (0); 833 834 fail2: 835 EFSYS_PROBE(fail2); 836 fail1: 837 EFSYS_PROBE1(fail1, efx_rc_t, rc); 838 839 return (rc); 840 } 841 842 /* Free a piobuf sub-allocated block */ 843 __checkReturn efx_rc_t 844 ef10_nic_pio_free( 845 __inout efx_nic_t *enp, 846 __in uint32_t bufnum, 847 __in uint32_t blknum) 848 { 849 uint32_t *map; 850 efx_rc_t rc; 851 852 if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) || 853 (blknum >= (8 * sizeof (*map)))) { 854 rc = EINVAL; 855 goto fail1; 856 } 857 858 map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum]; 859 if ((*map & (1u << blknum)) == 0) { 860 rc = ENOENT; 861 goto fail2; 862 } 863 *map &= ~(1u << blknum); 864 865 return (0); 866 867 fail2: 868 EFSYS_PROBE(fail2); 869 fail1: 870 EFSYS_PROBE1(fail1, efx_rc_t, rc); 871 872 return (rc); 873 } 874 875 __checkReturn efx_rc_t 876 ef10_nic_pio_link( 877 __inout efx_nic_t *enp, 878 __in uint32_t vi_index, 879 __in efx_piobuf_handle_t handle) 880 { 881 return (efx_mcdi_link_piobuf(enp, vi_index, handle)); 882 } 883 884 __checkReturn efx_rc_t 885 ef10_nic_pio_unlink( 886 __inout efx_nic_t *enp, 887 __in uint32_t vi_index) 888 { 889 return (efx_mcdi_unlink_piobuf(enp, vi_index)); 890 } 891 892 static __checkReturn efx_rc_t 893 ef10_get_datapath_caps( 894 __in efx_nic_t *enp) 895 { 896 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 897 efx_dword_t datapath_capabilities; 898 efx_dword_t datapath_capabilities_v2; 899 efx_rc_t rc; 900 901 if ((rc = efx_mcdi_get_capabilities(enp, &datapath_capabilities, 902 &datapath_capabilities_v2)) != 0) 903 goto fail1; 904 905 /* 906 * Huntington RXDP firmware inserts a 0 or 14 byte prefix. 907 * We only support the 14 byte prefix here. 908 */ 909 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 910 GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14) != 1) { 911 rc = ENOTSUP; 912 goto fail2; 913 } 914 encp->enc_rx_prefix_size = 14; 915 916 /* Check if the firmware supports TSO */ 917 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 918 GET_CAPABILITIES_OUT_TX_TSO) == 1) 919 encp->enc_fw_assisted_tso_enabled = B_TRUE; 920 else 921 encp->enc_fw_assisted_tso_enabled = B_FALSE; 922 923 /* Check if the firmware has vadapter/vport/vswitch support */ 924 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 925 GET_CAPABILITIES_OUT_EVB) == 1) 926 encp->enc_datapath_cap_evb = B_TRUE; 927 else 928 encp->enc_datapath_cap_evb = B_FALSE; 929 930 /* Check if the firmware supports VLAN insertion */ 931 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 932 GET_CAPABILITIES_OUT_TX_VLAN_INSERTION) == 1) 933 encp->enc_hw_tx_insert_vlan_enabled = B_TRUE; 934 else 935 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 936 937 /* Check if the firmware supports RX event batching */ 938 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 939 GET_CAPABILITIES_OUT_RX_BATCHING) == 1) { 940 encp->enc_rx_batching_enabled = B_TRUE; 941 encp->enc_rx_batch_max = 16; 942 } else { 943 encp->enc_rx_batching_enabled = B_FALSE; 944 } 945 946 /* Check if the firmware supports disabling scatter on RXQs */ 947 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 948 GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER) == 1) { 949 encp->enc_rx_disable_scatter_supported = B_TRUE; 950 } else { 951 encp->enc_rx_disable_scatter_supported = B_FALSE; 952 } 953 954 /* Check if the firmware supports set mac with running filters */ 955 if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities, 956 GET_CAPABILITIES_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED) 957 == 1) { 958 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 959 } else { 960 encp->enc_allow_set_mac_with_installed_filters = B_FALSE; 961 } 962 963 return (0); 964 965 fail2: 966 EFSYS_PROBE(fail2); 967 fail1: 968 EFSYS_PROBE1(fail1, efx_rc_t, rc); 969 970 return (rc); 971 } 972 973 /* 974 * The external port mapping is a one-based numbering of the external 975 * connectors on the board. It does not distinguish off-board separated 976 * outputs such as multi-headed cables. 977 * The number of ports that map to each external port connector 978 * on the board is determined by the chip family and the port modes to 979 * which the NIC can be configured. The mapping table lists modes with 980 * port numbering requirements in increasing order. 981 */ 982 static struct { 983 efx_family_t family; 984 uint32_t modes_mask; 985 uint32_t stride; 986 } __ef10_external_port_mappings[] = { 987 /* Supported modes requiring 1 output per port */ 988 { 989 EFX_FAMILY_HUNTINGTON, 990 (1 << TLV_PORT_MODE_10G) | 991 (1 << TLV_PORT_MODE_10G_10G) | 992 (1 << TLV_PORT_MODE_10G_10G_10G_10G), 993 1 994 }, 995 /* Supported modes requiring 2 outputs per port */ 996 { 997 EFX_FAMILY_HUNTINGTON, 998 (1 << TLV_PORT_MODE_40G) | 999 (1 << TLV_PORT_MODE_40G_40G) | 1000 (1 << TLV_PORT_MODE_40G_10G_10G) | 1001 (1 << TLV_PORT_MODE_10G_10G_40G), 1002 2 1003 } 1004 /* 1005 * NOTE: Medford modes will require 4 outputs per port: 1006 * TLV_PORT_MODE_10G_10G_10G_10G_Q 1007 * TLV_PORT_MODE_10G_10G_10G_10G_Q2 1008 * The Q2 mode routes outputs to external port 2. Support for this 1009 * will require a new field specifying the number to add after 1010 * scaling by stride. This is fixed at 1 currently. 1011 */ 1012 }; 1013 1014 static __checkReturn efx_rc_t 1015 ef10_external_port_mapping( 1016 __in efx_nic_t *enp, 1017 __in uint32_t port, 1018 __out uint8_t *external_portp) 1019 { 1020 efx_rc_t rc; 1021 int i; 1022 uint32_t port_modes; 1023 uint32_t matches; 1024 uint32_t stride = 1; /* default 1-1 mapping */ 1025 1026 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes)) != 0) { 1027 /* No port mode information available - use default mapping */ 1028 goto out; 1029 } 1030 1031 /* 1032 * Infer the internal port -> external port mapping from 1033 * the possible port modes for this NIC. 1034 */ 1035 for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) { 1036 if (__ef10_external_port_mappings[i].family != 1037 enp->en_family) 1038 continue; 1039 matches = (__ef10_external_port_mappings[i].modes_mask & 1040 port_modes); 1041 if (matches != 0) { 1042 stride = __ef10_external_port_mappings[i].stride; 1043 port_modes &= ~matches; 1044 } 1045 } 1046 1047 if (port_modes != 0) { 1048 /* Some advertised modes are not supported */ 1049 rc = ENOTSUP; 1050 goto fail1; 1051 } 1052 1053 out: 1054 /* 1055 * Scale as required by last matched mode and then convert to 1056 * one-based numbering 1057 */ 1058 *external_portp = (uint8_t)(port / stride) + 1; 1059 return (0); 1060 1061 fail1: 1062 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1063 1064 return (rc); 1065 } 1066 1067 static __checkReturn efx_rc_t 1068 hunt_board_cfg( 1069 __in efx_nic_t *enp) 1070 { 1071 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 1072 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1073 uint8_t mac_addr[6]; 1074 uint32_t board_type = 0; 1075 hunt_link_state_t hls; 1076 efx_port_t *epp = &(enp->en_port); 1077 uint32_t port; 1078 uint32_t pf; 1079 uint32_t vf; 1080 uint32_t mask; 1081 uint32_t flags; 1082 uint32_t sysclk; 1083 uint32_t base, nvec; 1084 efx_rc_t rc; 1085 1086 if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) 1087 goto fail1; 1088 1089 /* 1090 * NOTE: The MCDI protocol numbers ports from zero. 1091 * The common code MCDI interface numbers ports from one. 1092 */ 1093 emip->emi_port = port + 1; 1094 1095 if ((rc = ef10_external_port_mapping(enp, port, 1096 &encp->enc_external_port)) != 0) 1097 goto fail2; 1098 1099 /* 1100 * Get PCIe function number from firmware (used for 1101 * per-function privilege and dynamic config info). 1102 * - PCIe PF: pf = PF number, vf = 0xffff. 1103 * - PCIe VF: pf = parent PF, vf = VF number. 1104 */ 1105 if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0) 1106 goto fail3; 1107 1108 encp->enc_pf = pf; 1109 encp->enc_vf = vf; 1110 1111 /* MAC address for this function */ 1112 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1113 rc = efx_mcdi_get_mac_address_pf(enp, mac_addr); 1114 if ((rc == 0) && (mac_addr[0] & 0x02)) { 1115 /* 1116 * If the static config does not include a global MAC 1117 * address pool then the board may return a locally 1118 * administered MAC address (this should only happen on 1119 * incorrectly programmed boards). 1120 */ 1121 rc = EINVAL; 1122 } 1123 } else { 1124 rc = efx_mcdi_get_mac_address_vf(enp, mac_addr); 1125 } 1126 if (rc != 0) 1127 goto fail4; 1128 1129 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 1130 1131 /* Board configuration */ 1132 rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL); 1133 if (rc != 0) { 1134 /* Unprivileged functions may not be able to read board cfg */ 1135 if (rc == EACCES) 1136 board_type = 0; 1137 else 1138 goto fail5; 1139 } 1140 1141 encp->enc_board_type = board_type; 1142 encp->enc_clk_mult = 1; /* not used for Huntington */ 1143 1144 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 1145 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 1146 goto fail6; 1147 1148 /* Obtain the default PHY advertised capabilities */ 1149 if ((rc = hunt_phy_get_link(enp, &hls)) != 0) 1150 goto fail7; 1151 epp->ep_default_adv_cap_mask = hls.hls_adv_cap_mask; 1152 epp->ep_adv_cap_mask = hls.hls_adv_cap_mask; 1153 1154 /* 1155 * Enable firmware workarounds for hardware errata. 1156 * Expected responses are: 1157 * - 0 (zero): 1158 * Success: workaround enabled or disabled as requested. 1159 * - MC_CMD_ERR_ENOSYS (reported as ENOTSUP): 1160 * Firmware does not support the MC_CMD_WORKAROUND request. 1161 * (assume that the workaround is not supported). 1162 * - MC_CMD_ERR_ENOENT (reported as ENOENT): 1163 * Firmware does not support the requested workaround. 1164 * - MC_CMD_ERR_EPERM (reported as EACCES): 1165 * Unprivileged function cannot enable/disable workarounds. 1166 * 1167 * See efx_mcdi_request_errcode() for MCDI error translations. 1168 */ 1169 1170 /* 1171 * If the bug35388 workaround is enabled, then use an indirect access 1172 * method to avoid unsafe EVQ writes. 1173 */ 1174 rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG35388, B_TRUE, 1175 NULL); 1176 if ((rc == 0) || (rc == EACCES)) 1177 encp->enc_bug35388_workaround = B_TRUE; 1178 else if ((rc == ENOTSUP) || (rc == ENOENT)) 1179 encp->enc_bug35388_workaround = B_FALSE; 1180 else 1181 goto fail8; 1182 1183 /* 1184 * If the bug41750 workaround is enabled, then do not test interrupts, 1185 * as the test will fail (seen with Greenport controllers). 1186 */ 1187 rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG41750, B_TRUE, 1188 NULL); 1189 if (rc == 0) { 1190 encp->enc_bug41750_workaround = B_TRUE; 1191 } else if (rc == EACCES) { 1192 /* Assume a controller with 40G ports needs the workaround. */ 1193 if (epp->ep_default_adv_cap_mask & EFX_PHY_CAP_40000FDX) 1194 encp->enc_bug41750_workaround = B_TRUE; 1195 else 1196 encp->enc_bug41750_workaround = B_FALSE; 1197 } else if ((rc == ENOTSUP) || (rc == ENOENT)) { 1198 encp->enc_bug41750_workaround = B_FALSE; 1199 } else { 1200 goto fail9; 1201 } 1202 if (EFX_PCI_FUNCTION_IS_VF(encp)) { 1203 /* Interrupt testing does not work for VFs. See bug50084. */ 1204 encp->enc_bug41750_workaround = B_TRUE; 1205 } 1206 1207 /* 1208 * If the bug26807 workaround is enabled, then firmware has enabled 1209 * support for chained multicast filters. Firmware will reset (FLR) 1210 * functions which have filters in the hardware filter table when the 1211 * workaround is enabled/disabled. 1212 * 1213 * We must recheck if the workaround is enabled after inserting the 1214 * first hardware filter, in case it has been changed since this check. 1215 */ 1216 rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807, 1217 B_TRUE, &flags); 1218 if (rc == 0) { 1219 encp->enc_bug26807_workaround = B_TRUE; 1220 if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) { 1221 /* 1222 * Other functions had installed filters before the 1223 * workaround was enabled, and they have been reset 1224 * by firmware. 1225 */ 1226 EFSYS_PROBE(bug26807_workaround_flr_done); 1227 /* FIXME: bump MC warm boot count ? */ 1228 } 1229 } else if (rc == EACCES) { 1230 /* 1231 * Unprivileged functions cannot enable the workaround in older 1232 * firmware. 1233 */ 1234 encp->enc_bug26807_workaround = B_FALSE; 1235 } else if ((rc == ENOTSUP) || (rc == ENOENT)) { 1236 encp->enc_bug26807_workaround = B_FALSE; 1237 } else { 1238 goto fail10; 1239 } 1240 1241 /* Get sysclk frequency (in MHz). */ 1242 if ((rc = efx_mcdi_get_clock(enp, &sysclk)) != 0) 1243 goto fail11; 1244 1245 /* 1246 * The timer quantum is 1536 sysclk cycles, documented for the 1247 * EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units. 1248 */ 1249 encp->enc_evq_timer_quantum_ns = 1536000UL / sysclk; /* 1536 cycles */ 1250 if (encp->enc_bug35388_workaround) { 1251 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 1252 ERF_DD_EVQ_IND_TIMER_VAL_WIDTH) / 1000; 1253 } else { 1254 encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns << 1255 FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000; 1256 } 1257 1258 /* Check capabilities of running datapath firmware */ 1259 if ((rc = ef10_get_datapath_caps(enp)) != 0) 1260 goto fail12; 1261 1262 /* Alignment for receive packet DMA buffers */ 1263 encp->enc_rx_buf_align_start = 1; 1264 encp->enc_rx_buf_align_end = 64; /* RX DMA end padding */ 1265 1266 /* Alignment for WPTR updates */ 1267 encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; 1268 1269 /* 1270 * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use 1271 * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available 1272 * resources (allocated to this PCIe function), which is zero until 1273 * after we have allocated VIs. 1274 */ 1275 encp->enc_evq_limit = 1024; 1276 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET; 1277 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET; 1278 1279 encp->enc_buftbl_limit = 0xFFFFFFFF; 1280 1281 encp->enc_piobuf_limit = HUNT_PIOBUF_NBUFS; 1282 encp->enc_piobuf_size = HUNT_PIOBUF_SIZE; 1283 encp->enc_piobuf_min_alloc_size = HUNT_MIN_PIO_ALLOC_SIZE; 1284 1285 /* 1286 * Get the current privilege mask. Note that this may be modified 1287 * dynamically, so this value is informational only. DO NOT use 1288 * the privilege mask to check for sufficient privileges, as that 1289 * can result in time-of-check/time-of-use bugs. 1290 */ 1291 if ((rc = efx_mcdi_privilege_mask(enp, pf, vf, &mask)) != 0) { 1292 if (rc != ENOTSUP) 1293 goto fail13; 1294 1295 /* Fallback for old firmware without privilege mask support */ 1296 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1297 /* Assume PF has admin privilege */ 1298 mask = HUNT_LEGACY_PF_PRIVILEGE_MASK; 1299 } else { 1300 /* VF is always unprivileged by default */ 1301 mask = HUNT_LEGACY_VF_PRIVILEGE_MASK; 1302 } 1303 } 1304 1305 encp->enc_privilege_mask = mask; 1306 1307 /* Get interrupt vector limits */ 1308 if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) { 1309 if (EFX_PCI_FUNCTION_IS_PF(encp)) 1310 goto fail14; 1311 1312 /* Ignore error (cannot query vector limits from a VF). */ 1313 base = 0; 1314 nvec = 1024; 1315 } 1316 encp->enc_intr_vec_base = base; 1317 encp->enc_intr_limit = nvec; 1318 1319 /* 1320 * Maximum number of bytes into the frame the TCP header can start for 1321 * firmware assisted TSO to work. 1322 */ 1323 encp->enc_tx_tso_tcp_header_offset_limit = 208; 1324 1325 return (0); 1326 1327 fail14: 1328 EFSYS_PROBE(fail14); 1329 fail13: 1330 EFSYS_PROBE(fail13); 1331 fail12: 1332 EFSYS_PROBE(fail12); 1333 fail11: 1334 EFSYS_PROBE(fail11); 1335 fail10: 1336 EFSYS_PROBE(fail10); 1337 fail9: 1338 EFSYS_PROBE(fail9); 1339 fail8: 1340 EFSYS_PROBE(fail8); 1341 fail7: 1342 EFSYS_PROBE(fail7); 1343 fail6: 1344 EFSYS_PROBE(fail6); 1345 fail5: 1346 EFSYS_PROBE(fail5); 1347 fail4: 1348 EFSYS_PROBE(fail4); 1349 fail3: 1350 EFSYS_PROBE(fail3); 1351 fail2: 1352 EFSYS_PROBE(fail2); 1353 fail1: 1354 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1355 1356 return (rc); 1357 } 1358 1359 1360 __checkReturn efx_rc_t 1361 ef10_nic_probe( 1362 __in efx_nic_t *enp) 1363 { 1364 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1365 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1366 efx_rc_t rc; 1367 1368 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1369 enp->en_family == EFX_FAMILY_MEDFORD); 1370 1371 /* Read and clear any assertion state */ 1372 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1373 goto fail1; 1374 1375 /* Exit the assertion handler */ 1376 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1377 if (rc != EACCES) 1378 goto fail2; 1379 1380 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 1381 goto fail3; 1382 1383 if ((rc = hunt_board_cfg(enp)) != 0) 1384 if (rc != EACCES) 1385 goto fail4; 1386 1387 /* 1388 * Set default driver config limits (based on board config). 1389 * 1390 * FIXME: For now allocate a fixed number of VIs which is likely to be 1391 * sufficient and small enough to allow multiple functions on the same 1392 * port. 1393 */ 1394 edcp->edc_min_vi_count = edcp->edc_max_vi_count = 1395 MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit)); 1396 1397 /* The client driver must configure and enable PIO buffer support */ 1398 edcp->edc_max_piobuf_count = 0; 1399 edcp->edc_pio_alloc_size = 0; 1400 1401 #if EFSYS_OPT_MAC_STATS 1402 /* Wipe the MAC statistics */ 1403 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 1404 goto fail5; 1405 #endif 1406 1407 #if EFSYS_OPT_LOOPBACK 1408 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 1409 goto fail6; 1410 #endif 1411 1412 #if EFSYS_OPT_MON_STATS 1413 if ((rc = mcdi_mon_cfg_build(enp)) != 0) { 1414 /* Unprivileged functions do not have access to sensors */ 1415 if (rc != EACCES) 1416 goto fail7; 1417 } 1418 #endif 1419 1420 encp->enc_features = enp->en_features; 1421 1422 return (0); 1423 1424 #if EFSYS_OPT_MON_STATS 1425 fail7: 1426 EFSYS_PROBE(fail7); 1427 #endif 1428 #if EFSYS_OPT_LOOPBACK 1429 fail6: 1430 EFSYS_PROBE(fail6); 1431 #endif 1432 #if EFSYS_OPT_MAC_STATS 1433 fail5: 1434 EFSYS_PROBE(fail5); 1435 #endif 1436 fail4: 1437 EFSYS_PROBE(fail4); 1438 fail3: 1439 EFSYS_PROBE(fail3); 1440 fail2: 1441 EFSYS_PROBE(fail2); 1442 fail1: 1443 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1444 1445 return (rc); 1446 } 1447 1448 __checkReturn efx_rc_t 1449 ef10_nic_set_drv_limits( 1450 __inout efx_nic_t *enp, 1451 __in efx_drv_limits_t *edlp) 1452 { 1453 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1454 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1455 uint32_t min_evq_count, max_evq_count; 1456 uint32_t min_rxq_count, max_rxq_count; 1457 uint32_t min_txq_count, max_txq_count; 1458 efx_rc_t rc; 1459 1460 if (edlp == NULL) { 1461 rc = EINVAL; 1462 goto fail1; 1463 } 1464 1465 /* Get minimum required and maximum usable VI limits */ 1466 min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit); 1467 min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit); 1468 min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit); 1469 1470 edcp->edc_min_vi_count = 1471 MAX(min_evq_count, MAX(min_rxq_count, min_txq_count)); 1472 1473 max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit); 1474 max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit); 1475 max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit); 1476 1477 edcp->edc_max_vi_count = 1478 MAX(max_evq_count, MAX(max_rxq_count, max_txq_count)); 1479 1480 /* 1481 * Check limits for sub-allocated piobuf blocks. 1482 * PIO is optional, so don't fail if the limits are incorrect. 1483 */ 1484 if ((encp->enc_piobuf_size == 0) || 1485 (encp->enc_piobuf_limit == 0) || 1486 (edlp->edl_min_pio_alloc_size == 0) || 1487 (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) { 1488 /* Disable PIO */ 1489 edcp->edc_max_piobuf_count = 0; 1490 edcp->edc_pio_alloc_size = 0; 1491 } else { 1492 uint32_t blk_size, blk_count, blks_per_piobuf; 1493 1494 blk_size = 1495 MAX(edlp->edl_min_pio_alloc_size, 1496 encp->enc_piobuf_min_alloc_size); 1497 1498 blks_per_piobuf = encp->enc_piobuf_size / blk_size; 1499 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32); 1500 1501 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf); 1502 1503 /* A zero max pio alloc count means unlimited */ 1504 if ((edlp->edl_max_pio_alloc_count > 0) && 1505 (edlp->edl_max_pio_alloc_count < blk_count)) { 1506 blk_count = edlp->edl_max_pio_alloc_count; 1507 } 1508 1509 edcp->edc_pio_alloc_size = blk_size; 1510 edcp->edc_max_piobuf_count = 1511 (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf; 1512 } 1513 1514 return (0); 1515 1516 fail1: 1517 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1518 1519 return (rc); 1520 } 1521 1522 1523 __checkReturn efx_rc_t 1524 ef10_nic_reset( 1525 __in efx_nic_t *enp) 1526 { 1527 efx_mcdi_req_t req; 1528 uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN, 1529 MC_CMD_ENTITY_RESET_OUT_LEN)]; 1530 efx_rc_t rc; 1531 1532 /* ef10_nic_reset() is called to recover from BADASSERT failures. */ 1533 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1534 goto fail1; 1535 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1536 goto fail2; 1537 1538 (void) memset(payload, 0, sizeof (payload)); 1539 req.emr_cmd = MC_CMD_ENTITY_RESET; 1540 req.emr_in_buf = payload; 1541 req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; 1542 req.emr_out_buf = payload; 1543 req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; 1544 1545 MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, 1546 ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); 1547 1548 efx_mcdi_execute(enp, &req); 1549 1550 if (req.emr_rc != 0) { 1551 rc = req.emr_rc; 1552 goto fail3; 1553 } 1554 1555 /* Clear RX/TX DMA queue errors */ 1556 enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR); 1557 1558 return (0); 1559 1560 fail3: 1561 EFSYS_PROBE(fail3); 1562 fail2: 1563 EFSYS_PROBE(fail2); 1564 fail1: 1565 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1566 1567 return (rc); 1568 } 1569 1570 __checkReturn efx_rc_t 1571 ef10_nic_init( 1572 __in efx_nic_t *enp) 1573 { 1574 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1575 uint32_t min_vi_count, max_vi_count; 1576 uint32_t vi_count, vi_base, vi_shift; 1577 uint32_t i; 1578 uint32_t retry; 1579 uint32_t delay_us; 1580 efx_rc_t rc; 1581 1582 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1583 enp->en_family == EFX_FAMILY_MEDFORD); 1584 1585 /* Enable reporting of some events (e.g. link change) */ 1586 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 1587 goto fail1; 1588 1589 /* Allocate (optional) on-chip PIO buffers */ 1590 ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count); 1591 1592 /* 1593 * For best performance, PIO writes should use a write-combined 1594 * (WC) memory mapping. Using a separate WC mapping for the PIO 1595 * aperture of each VI would be a burden to drivers (and not 1596 * possible if the host page size is >4Kbyte). 1597 * 1598 * To avoid this we use a single uncached (UC) mapping for VI 1599 * register access, and a single WC mapping for extra VIs used 1600 * for PIO writes. 1601 * 1602 * Each piobuf must be linked to a VI in the WC mapping, and to 1603 * each VI that is using a sub-allocated block from the piobuf. 1604 */ 1605 min_vi_count = edcp->edc_min_vi_count; 1606 max_vi_count = 1607 edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count; 1608 1609 /* Ensure that the previously attached driver's VIs are freed */ 1610 if ((rc = efx_mcdi_free_vis(enp)) != 0) 1611 goto fail2; 1612 1613 /* 1614 * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this 1615 * fails then retrying the request for fewer VI resources may succeed. 1616 */ 1617 vi_count = 0; 1618 if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count, 1619 &vi_base, &vi_count, &vi_shift)) != 0) 1620 goto fail3; 1621 1622 EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count); 1623 1624 if (vi_count < min_vi_count) { 1625 rc = ENOMEM; 1626 goto fail4; 1627 } 1628 1629 enp->en_arch.ef10.ena_vi_base = vi_base; 1630 enp->en_arch.ef10.ena_vi_count = vi_count; 1631 enp->en_arch.ef10.ena_vi_shift = vi_shift; 1632 1633 if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) { 1634 /* Not enough extra VIs to map piobufs */ 1635 ef10_nic_free_piobufs(enp); 1636 } 1637 1638 enp->en_arch.ef10.ena_pio_write_vi_base = 1639 vi_count - enp->en_arch.ef10.ena_piobuf_count; 1640 1641 /* Save UC memory mapping details */ 1642 enp->en_arch.ef10.ena_uc_mem_map_offset = 0; 1643 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 1644 enp->en_arch.ef10.ena_uc_mem_map_size = 1645 (ER_DZ_TX_PIOBUF_STEP * 1646 enp->en_arch.ef10.ena_pio_write_vi_base); 1647 } else { 1648 enp->en_arch.ef10.ena_uc_mem_map_size = 1649 (ER_DZ_TX_PIOBUF_STEP * 1650 enp->en_arch.ef10.ena_vi_count); 1651 } 1652 1653 /* Save WC memory mapping details */ 1654 enp->en_arch.ef10.ena_wc_mem_map_offset = 1655 enp->en_arch.ef10.ena_uc_mem_map_offset + 1656 enp->en_arch.ef10.ena_uc_mem_map_size; 1657 1658 enp->en_arch.ef10.ena_wc_mem_map_size = 1659 (ER_DZ_TX_PIOBUF_STEP * 1660 enp->en_arch.ef10.ena_piobuf_count); 1661 1662 /* Link piobufs to extra VIs in WC mapping */ 1663 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 1664 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 1665 rc = efx_mcdi_link_piobuf(enp, 1666 enp->en_arch.ef10.ena_pio_write_vi_base + i, 1667 enp->en_arch.ef10.ena_piobuf_handle[i]); 1668 if (rc != 0) 1669 break; 1670 } 1671 } 1672 1673 /* 1674 * Allocate a vAdaptor attached to our upstream vPort/pPort. 1675 * 1676 * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF 1677 * driver has yet to bring up the EVB port. See bug 56147. In this case, 1678 * retry the request several times after waiting a while. The wait time 1679 * between retries starts small (10ms) and exponentially increases. 1680 * Total wait time is a little over two seconds. Retry logic in the 1681 * client driver may mean this whole loop is repeated if it continues to 1682 * fail. 1683 */ 1684 retry = 0; 1685 delay_us = 10000; 1686 while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { 1687 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || 1688 (rc != ENOENT)) { 1689 /* 1690 * Do not retry alloc for PF, or for other errors on 1691 * a VF. 1692 */ 1693 goto fail5; 1694 } 1695 1696 /* VF startup before PF is ready. Retry allocation. */ 1697 if (retry > 5) { 1698 /* Too many attempts */ 1699 rc = EINVAL; 1700 goto fail6; 1701 } 1702 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); 1703 EFSYS_SLEEP(delay_us); 1704 retry++; 1705 if (delay_us < 500000) 1706 delay_us <<= 2; 1707 } 1708 1709 enp->en_vport_id = EVB_PORT_ID_ASSIGNED; 1710 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2; 1711 1712 return (0); 1713 1714 fail6: 1715 EFSYS_PROBE(fail6); 1716 fail5: 1717 EFSYS_PROBE(fail5); 1718 fail4: 1719 EFSYS_PROBE(fail4); 1720 fail3: 1721 EFSYS_PROBE(fail3); 1722 fail2: 1723 EFSYS_PROBE(fail2); 1724 1725 ef10_nic_free_piobufs(enp); 1726 1727 fail1: 1728 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1729 1730 return (rc); 1731 } 1732 1733 __checkReturn efx_rc_t 1734 ef10_nic_get_vi_pool( 1735 __in efx_nic_t *enp, 1736 __out uint32_t *vi_countp) 1737 { 1738 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1739 enp->en_family == EFX_FAMILY_MEDFORD); 1740 1741 /* 1742 * Report VIs that the client driver can use. 1743 * Do not include VIs used for PIO buffer writes. 1744 */ 1745 *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base; 1746 1747 return (0); 1748 } 1749 1750 __checkReturn efx_rc_t 1751 ef10_nic_get_bar_region( 1752 __in efx_nic_t *enp, 1753 __in efx_nic_region_t region, 1754 __out uint32_t *offsetp, 1755 __out size_t *sizep) 1756 { 1757 efx_rc_t rc; 1758 1759 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1760 enp->en_family == EFX_FAMILY_MEDFORD); 1761 1762 /* 1763 * TODO: Specify host memory mapping alignment and granularity 1764 * in efx_drv_limits_t so that they can be taken into account 1765 * when allocating extra VIs for PIO writes. 1766 */ 1767 switch (region) { 1768 case EFX_REGION_VI: 1769 /* UC mapped memory BAR region for VI registers */ 1770 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset; 1771 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size; 1772 break; 1773 1774 case EFX_REGION_PIO_WRITE_VI: 1775 /* WC mapped memory BAR region for piobuf writes */ 1776 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset; 1777 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size; 1778 break; 1779 1780 default: 1781 rc = EINVAL; 1782 goto fail1; 1783 } 1784 1785 return (0); 1786 1787 fail1: 1788 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1789 1790 return (rc); 1791 } 1792 1793 void 1794 ef10_nic_fini( 1795 __in efx_nic_t *enp) 1796 { 1797 uint32_t i; 1798 efx_rc_t rc; 1799 1800 (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id); 1801 enp->en_vport_id = 0; 1802 1803 /* Unlink piobufs from extra VIs in WC mapping */ 1804 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 1805 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 1806 rc = efx_mcdi_unlink_piobuf(enp, 1807 enp->en_arch.ef10.ena_pio_write_vi_base + i); 1808 if (rc != 0) 1809 break; 1810 } 1811 } 1812 1813 ef10_nic_free_piobufs(enp); 1814 1815 (void) efx_mcdi_free_vis(enp); 1816 enp->en_arch.ef10.ena_vi_count = 0; 1817 } 1818 1819 void 1820 ef10_nic_unprobe( 1821 __in efx_nic_t *enp) 1822 { 1823 #if EFSYS_OPT_MON_STATS 1824 mcdi_mon_cfg_free(enp); 1825 #endif /* EFSYS_OPT_MON_STATS */ 1826 (void) efx_mcdi_drv_attach(enp, B_FALSE); 1827 } 1828 1829 #if EFSYS_OPT_DIAG 1830 1831 __checkReturn efx_rc_t 1832 ef10_nic_register_test( 1833 __in efx_nic_t *enp) 1834 { 1835 efx_rc_t rc; 1836 1837 /* FIXME */ 1838 _NOTE(ARGUNUSED(enp)) 1839 if (B_FALSE) { 1840 rc = ENOTSUP; 1841 goto fail1; 1842 } 1843 /* FIXME */ 1844 1845 return (0); 1846 1847 fail1: 1848 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1849 1850 return (rc); 1851 } 1852 1853 #endif /* EFSYS_OPT_DIAG */ 1854 1855 1856 1857 #endif /* EFSYS_OPT_HUNTINGTON */ 1858