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