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