1 /*- 2 * Copyright (c) 2012-2016 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include "efx.h" 35 #include "efx_impl.h" 36 #if EFSYS_OPT_MON_MCDI 37 #include "mcdi_mon.h" 38 #endif 39 40 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 41 42 #include "ef10_tlv_layout.h" 43 44 __checkReturn efx_rc_t 45 efx_mcdi_get_port_assignment( 46 __in efx_nic_t *enp, 47 __out uint32_t *portp) 48 { 49 efx_mcdi_req_t req; 50 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN, 51 MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN); 52 efx_rc_t rc; 53 54 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 55 enp->en_family == EFX_FAMILY_MEDFORD || 56 enp->en_family == EFX_FAMILY_MEDFORD2); 57 58 req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT; 59 req.emr_in_buf = payload; 60 req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN; 61 req.emr_out_buf = payload; 62 req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN; 63 64 efx_mcdi_execute(enp, &req); 65 66 if (req.emr_rc != 0) { 67 rc = req.emr_rc; 68 goto fail1; 69 } 70 71 if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) { 72 rc = EMSGSIZE; 73 goto fail2; 74 } 75 76 *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT); 77 78 return (0); 79 80 fail2: 81 EFSYS_PROBE(fail2); 82 fail1: 83 EFSYS_PROBE1(fail1, efx_rc_t, rc); 84 85 return (rc); 86 } 87 88 __checkReturn efx_rc_t 89 efx_mcdi_get_port_modes( 90 __in efx_nic_t *enp, 91 __out uint32_t *modesp, 92 __out_opt uint32_t *current_modep, 93 __out_opt uint32_t *default_modep) 94 { 95 efx_mcdi_req_t req; 96 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_MODES_IN_LEN, 97 MC_CMD_GET_PORT_MODES_OUT_LEN); 98 efx_rc_t rc; 99 100 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 101 enp->en_family == EFX_FAMILY_MEDFORD || 102 enp->en_family == EFX_FAMILY_MEDFORD2); 103 104 req.emr_cmd = MC_CMD_GET_PORT_MODES; 105 req.emr_in_buf = payload; 106 req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN; 107 req.emr_out_buf = payload; 108 req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN; 109 110 efx_mcdi_execute(enp, &req); 111 112 if (req.emr_rc != 0) { 113 rc = req.emr_rc; 114 goto fail1; 115 } 116 117 /* 118 * Require only Modes and DefaultMode fields, unless the current mode 119 * was requested (CurrentMode field was added for Medford). 120 */ 121 if (req.emr_out_length_used < 122 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) { 123 rc = EMSGSIZE; 124 goto fail2; 125 } 126 if ((current_modep != NULL) && (req.emr_out_length_used < 127 MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST + 4)) { 128 rc = EMSGSIZE; 129 goto fail3; 130 } 131 132 *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES); 133 134 if (current_modep != NULL) { 135 *current_modep = MCDI_OUT_DWORD(req, 136 GET_PORT_MODES_OUT_CURRENT_MODE); 137 } 138 139 if (default_modep != NULL) { 140 *default_modep = MCDI_OUT_DWORD(req, 141 GET_PORT_MODES_OUT_DEFAULT_MODE); 142 } 143 144 return (0); 145 146 fail3: 147 EFSYS_PROBE(fail3); 148 fail2: 149 EFSYS_PROBE(fail2); 150 fail1: 151 EFSYS_PROBE1(fail1, efx_rc_t, rc); 152 153 return (rc); 154 } 155 156 __checkReturn efx_rc_t 157 ef10_nic_get_port_mode_bandwidth( 158 __in efx_nic_t *enp, 159 __out uint32_t *bandwidth_mbpsp) 160 { 161 uint32_t port_modes; 162 uint32_t current_mode; 163 efx_port_t *epp = &(enp->en_port); 164 165 uint32_t single_lane; 166 uint32_t dual_lane; 167 uint32_t quad_lane; 168 uint32_t bandwidth; 169 efx_rc_t rc; 170 171 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, 172 ¤t_mode, NULL)) != 0) { 173 /* No port mode info available. */ 174 goto fail1; 175 } 176 177 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_25000FDX)) 178 single_lane = 25000; 179 else 180 single_lane = 10000; 181 182 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_50000FDX)) 183 dual_lane = 50000; 184 else 185 dual_lane = 20000; 186 187 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_100000FDX)) 188 quad_lane = 100000; 189 else 190 quad_lane = 40000; 191 192 switch (current_mode) { 193 case TLV_PORT_MODE_1x1_NA: /* mode 0 */ 194 bandwidth = single_lane; 195 break; 196 case TLV_PORT_MODE_1x2_NA: /* mode 10 */ 197 case TLV_PORT_MODE_NA_1x2: /* mode 11 */ 198 bandwidth = dual_lane; 199 break; 200 case TLV_PORT_MODE_1x1_1x1: /* mode 2 */ 201 bandwidth = single_lane + single_lane; 202 break; 203 case TLV_PORT_MODE_4x1_NA: /* mode 4 */ 204 case TLV_PORT_MODE_NA_4x1: /* mode 8 */ 205 bandwidth = 4 * single_lane; 206 break; 207 case TLV_PORT_MODE_2x1_2x1: /* mode 5 */ 208 bandwidth = (2 * single_lane) + (2 * single_lane); 209 break; 210 case TLV_PORT_MODE_1x2_1x2: /* mode 12 */ 211 bandwidth = dual_lane + dual_lane; 212 break; 213 case TLV_PORT_MODE_1x2_2x1: /* mode 17 */ 214 case TLV_PORT_MODE_2x1_1x2: /* mode 18 */ 215 bandwidth = dual_lane + (2 * single_lane); 216 break; 217 /* Legacy Medford-only mode. Do not use (see bug63270) */ 218 case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2: /* mode 9 */ 219 bandwidth = 4 * single_lane; 220 break; 221 case TLV_PORT_MODE_1x4_NA: /* mode 1 */ 222 case TLV_PORT_MODE_NA_1x4: /* mode 22 */ 223 bandwidth = quad_lane; 224 break; 225 case TLV_PORT_MODE_2x2_NA: /* mode 13 */ 226 case TLV_PORT_MODE_NA_2x2: /* mode 14 */ 227 bandwidth = 2 * dual_lane; 228 break; 229 case TLV_PORT_MODE_1x4_2x1: /* mode 6 */ 230 case TLV_PORT_MODE_2x1_1x4: /* mode 7 */ 231 bandwidth = quad_lane + (2 * single_lane); 232 break; 233 case TLV_PORT_MODE_1x4_1x2: /* mode 15 */ 234 case TLV_PORT_MODE_1x2_1x4: /* mode 16 */ 235 bandwidth = quad_lane + dual_lane; 236 break; 237 case TLV_PORT_MODE_1x4_1x4: /* mode 3 */ 238 bandwidth = quad_lane + quad_lane; 239 break; 240 default: 241 rc = EINVAL; 242 goto fail2; 243 } 244 245 *bandwidth_mbpsp = bandwidth; 246 247 return (0); 248 249 fail2: 250 EFSYS_PROBE(fail2); 251 fail1: 252 EFSYS_PROBE1(fail1, efx_rc_t, rc); 253 254 return (rc); 255 } 256 257 static __checkReturn efx_rc_t 258 efx_mcdi_vadaptor_alloc( 259 __in efx_nic_t *enp, 260 __in uint32_t port_id) 261 { 262 efx_mcdi_req_t req; 263 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_ALLOC_IN_LEN, 264 MC_CMD_VADAPTOR_ALLOC_OUT_LEN); 265 efx_rc_t rc; 266 267 EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL); 268 269 req.emr_cmd = MC_CMD_VADAPTOR_ALLOC; 270 req.emr_in_buf = payload; 271 req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN; 272 req.emr_out_buf = payload; 273 req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN; 274 275 MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id); 276 MCDI_IN_POPULATE_DWORD_1(req, VADAPTOR_ALLOC_IN_FLAGS, 277 VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED, 278 enp->en_nic_cfg.enc_allow_set_mac_with_installed_filters ? 1 : 0); 279 280 efx_mcdi_execute(enp, &req); 281 282 if (req.emr_rc != 0) { 283 rc = req.emr_rc; 284 goto fail1; 285 } 286 287 return (0); 288 289 fail1: 290 EFSYS_PROBE1(fail1, efx_rc_t, rc); 291 292 return (rc); 293 } 294 295 static __checkReturn efx_rc_t 296 efx_mcdi_vadaptor_free( 297 __in efx_nic_t *enp, 298 __in uint32_t port_id) 299 { 300 efx_mcdi_req_t req; 301 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_FREE_IN_LEN, 302 MC_CMD_VADAPTOR_FREE_OUT_LEN); 303 efx_rc_t rc; 304 305 req.emr_cmd = MC_CMD_VADAPTOR_FREE; 306 req.emr_in_buf = payload; 307 req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN; 308 req.emr_out_buf = payload; 309 req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN; 310 311 MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id); 312 313 efx_mcdi_execute(enp, &req); 314 315 if (req.emr_rc != 0) { 316 rc = req.emr_rc; 317 goto fail1; 318 } 319 320 return (0); 321 322 fail1: 323 EFSYS_PROBE1(fail1, efx_rc_t, rc); 324 325 return (rc); 326 } 327 328 __checkReturn efx_rc_t 329 efx_mcdi_get_mac_address_pf( 330 __in efx_nic_t *enp, 331 __out_ecount_opt(6) uint8_t mac_addrp[6]) 332 { 333 efx_mcdi_req_t req; 334 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_MAC_ADDRESSES_IN_LEN, 335 MC_CMD_GET_MAC_ADDRESSES_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 enp->en_family == EFX_FAMILY_MEDFORD2); 341 342 req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES; 343 req.emr_in_buf = payload; 344 req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN; 345 req.emr_out_buf = payload; 346 req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_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_MAC_ADDRESSES_OUT_LEN) { 356 rc = EMSGSIZE; 357 goto fail2; 358 } 359 360 if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) { 361 rc = ENOENT; 362 goto fail3; 363 } 364 365 if (mac_addrp != NULL) { 366 uint8_t *addrp; 367 368 addrp = MCDI_OUT2(req, uint8_t, 369 GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE); 370 371 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 372 } 373 374 return (0); 375 376 fail3: 377 EFSYS_PROBE(fail3); 378 fail2: 379 EFSYS_PROBE(fail2); 380 fail1: 381 EFSYS_PROBE1(fail1, efx_rc_t, rc); 382 383 return (rc); 384 } 385 386 __checkReturn efx_rc_t 387 efx_mcdi_get_mac_address_vf( 388 __in efx_nic_t *enp, 389 __out_ecount_opt(6) uint8_t mac_addrp[6]) 390 { 391 efx_mcdi_req_t req; 392 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN, 393 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX); 394 efx_rc_t rc; 395 396 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 397 enp->en_family == EFX_FAMILY_MEDFORD || 398 enp->en_family == EFX_FAMILY_MEDFORD2); 399 400 req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES; 401 req.emr_in_buf = payload; 402 req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN; 403 req.emr_out_buf = payload; 404 req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX; 405 406 MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID, 407 EVB_PORT_ID_ASSIGNED); 408 409 efx_mcdi_execute(enp, &req); 410 411 if (req.emr_rc != 0) { 412 rc = req.emr_rc; 413 goto fail1; 414 } 415 416 if (req.emr_out_length_used < 417 MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) { 418 rc = EMSGSIZE; 419 goto fail2; 420 } 421 422 if (MCDI_OUT_DWORD(req, 423 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) { 424 rc = ENOENT; 425 goto fail3; 426 } 427 428 if (mac_addrp != NULL) { 429 uint8_t *addrp; 430 431 addrp = MCDI_OUT2(req, uint8_t, 432 VPORT_GET_MAC_ADDRESSES_OUT_MACADDR); 433 434 EFX_MAC_ADDR_COPY(mac_addrp, addrp); 435 } 436 437 return (0); 438 439 fail3: 440 EFSYS_PROBE(fail3); 441 fail2: 442 EFSYS_PROBE(fail2); 443 fail1: 444 EFSYS_PROBE1(fail1, efx_rc_t, rc); 445 446 return (rc); 447 } 448 449 __checkReturn efx_rc_t 450 efx_mcdi_get_clock( 451 __in efx_nic_t *enp, 452 __out uint32_t *sys_freqp, 453 __out uint32_t *dpcpu_freqp) 454 { 455 efx_mcdi_req_t req; 456 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CLOCK_IN_LEN, 457 MC_CMD_GET_CLOCK_OUT_LEN); 458 efx_rc_t rc; 459 460 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 461 enp->en_family == EFX_FAMILY_MEDFORD || 462 enp->en_family == EFX_FAMILY_MEDFORD2); 463 464 req.emr_cmd = MC_CMD_GET_CLOCK; 465 req.emr_in_buf = payload; 466 req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN; 467 req.emr_out_buf = payload; 468 req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN; 469 470 efx_mcdi_execute(enp, &req); 471 472 if (req.emr_rc != 0) { 473 rc = req.emr_rc; 474 goto fail1; 475 } 476 477 if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) { 478 rc = EMSGSIZE; 479 goto fail2; 480 } 481 482 *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ); 483 if (*sys_freqp == 0) { 484 rc = EINVAL; 485 goto fail3; 486 } 487 *dpcpu_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_DPCPU_FREQ); 488 if (*dpcpu_freqp == 0) { 489 rc = EINVAL; 490 goto fail4; 491 } 492 493 return (0); 494 495 fail4: 496 EFSYS_PROBE(fail4); 497 fail3: 498 EFSYS_PROBE(fail3); 499 fail2: 500 EFSYS_PROBE(fail2); 501 fail1: 502 EFSYS_PROBE1(fail1, efx_rc_t, rc); 503 504 return (rc); 505 } 506 507 __checkReturn efx_rc_t 508 efx_mcdi_get_rxdp_config( 509 __in efx_nic_t *enp, 510 __out uint32_t *end_paddingp) 511 { 512 efx_mcdi_req_t req; 513 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RXDP_CONFIG_IN_LEN, 514 MC_CMD_GET_RXDP_CONFIG_OUT_LEN); 515 uint32_t end_padding; 516 efx_rc_t rc; 517 518 req.emr_cmd = MC_CMD_GET_RXDP_CONFIG; 519 req.emr_in_buf = payload; 520 req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN; 521 req.emr_out_buf = payload; 522 req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN; 523 524 efx_mcdi_execute(enp, &req); 525 if (req.emr_rc != 0) { 526 rc = req.emr_rc; 527 goto fail1; 528 } 529 530 if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA, 531 GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) { 532 /* RX DMA end padding is disabled */ 533 end_padding = 0; 534 } else { 535 switch (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA, 536 GET_RXDP_CONFIG_OUT_PAD_HOST_LEN)) { 537 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64: 538 end_padding = 64; 539 break; 540 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128: 541 end_padding = 128; 542 break; 543 case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256: 544 end_padding = 256; 545 break; 546 default: 547 rc = ENOTSUP; 548 goto fail2; 549 } 550 } 551 552 *end_paddingp = end_padding; 553 554 return (0); 555 556 fail2: 557 EFSYS_PROBE(fail2); 558 fail1: 559 EFSYS_PROBE1(fail1, efx_rc_t, rc); 560 561 return (rc); 562 } 563 564 __checkReturn efx_rc_t 565 efx_mcdi_get_vector_cfg( 566 __in efx_nic_t *enp, 567 __out_opt uint32_t *vec_basep, 568 __out_opt uint32_t *pf_nvecp, 569 __out_opt uint32_t *vf_nvecp) 570 { 571 efx_mcdi_req_t req; 572 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_VECTOR_CFG_IN_LEN, 573 MC_CMD_GET_VECTOR_CFG_OUT_LEN); 574 efx_rc_t rc; 575 576 req.emr_cmd = MC_CMD_GET_VECTOR_CFG; 577 req.emr_in_buf = payload; 578 req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN; 579 req.emr_out_buf = payload; 580 req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN; 581 582 efx_mcdi_execute(enp, &req); 583 584 if (req.emr_rc != 0) { 585 rc = req.emr_rc; 586 goto fail1; 587 } 588 589 if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) { 590 rc = EMSGSIZE; 591 goto fail2; 592 } 593 594 if (vec_basep != NULL) 595 *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE); 596 if (pf_nvecp != NULL) 597 *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF); 598 if (vf_nvecp != NULL) 599 *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF); 600 601 return (0); 602 603 fail2: 604 EFSYS_PROBE(fail2); 605 fail1: 606 EFSYS_PROBE1(fail1, efx_rc_t, rc); 607 608 return (rc); 609 } 610 611 static __checkReturn efx_rc_t 612 efx_mcdi_alloc_vis( 613 __in efx_nic_t *enp, 614 __in uint32_t min_vi_count, 615 __in uint32_t max_vi_count, 616 __out uint32_t *vi_basep, 617 __out uint32_t *vi_countp, 618 __out uint32_t *vi_shiftp) 619 { 620 efx_mcdi_req_t req; 621 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN, 622 MC_CMD_ALLOC_VIS_EXT_OUT_LEN); 623 efx_rc_t rc; 624 625 if (vi_countp == NULL) { 626 rc = EINVAL; 627 goto fail1; 628 } 629 630 req.emr_cmd = MC_CMD_ALLOC_VIS; 631 req.emr_in_buf = payload; 632 req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN; 633 req.emr_out_buf = payload; 634 req.emr_out_length = MC_CMD_ALLOC_VIS_EXT_OUT_LEN; 635 636 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count); 637 MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count); 638 639 efx_mcdi_execute(enp, &req); 640 641 if (req.emr_rc != 0) { 642 rc = req.emr_rc; 643 goto fail2; 644 } 645 646 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) { 647 rc = EMSGSIZE; 648 goto fail3; 649 } 650 651 *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE); 652 *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT); 653 654 /* Report VI_SHIFT if available (always zero for Huntington) */ 655 if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_EXT_OUT_LEN) 656 *vi_shiftp = 0; 657 else 658 *vi_shiftp = MCDI_OUT_DWORD(req, ALLOC_VIS_EXT_OUT_VI_SHIFT); 659 660 return (0); 661 662 fail3: 663 EFSYS_PROBE(fail3); 664 fail2: 665 EFSYS_PROBE(fail2); 666 fail1: 667 EFSYS_PROBE1(fail1, efx_rc_t, rc); 668 669 return (rc); 670 } 671 672 static __checkReturn efx_rc_t 673 efx_mcdi_free_vis( 674 __in efx_nic_t *enp) 675 { 676 efx_mcdi_req_t req; 677 efx_rc_t rc; 678 679 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0); 680 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0); 681 682 req.emr_cmd = MC_CMD_FREE_VIS; 683 req.emr_in_buf = NULL; 684 req.emr_in_length = 0; 685 req.emr_out_buf = NULL; 686 req.emr_out_length = 0; 687 688 efx_mcdi_execute_quiet(enp, &req); 689 690 /* Ignore ELREADY (no allocated VIs, so nothing to free) */ 691 if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) { 692 rc = req.emr_rc; 693 goto fail1; 694 } 695 696 return (0); 697 698 fail1: 699 EFSYS_PROBE1(fail1, efx_rc_t, rc); 700 701 return (rc); 702 } 703 704 static __checkReturn efx_rc_t 705 efx_mcdi_alloc_piobuf( 706 __in efx_nic_t *enp, 707 __out efx_piobuf_handle_t *handlep) 708 { 709 efx_mcdi_req_t req; 710 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN, 711 MC_CMD_ALLOC_PIOBUF_OUT_LEN); 712 efx_rc_t rc; 713 714 if (handlep == NULL) { 715 rc = EINVAL; 716 goto fail1; 717 } 718 719 req.emr_cmd = MC_CMD_ALLOC_PIOBUF; 720 req.emr_in_buf = payload; 721 req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN; 722 req.emr_out_buf = payload; 723 req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN; 724 725 efx_mcdi_execute_quiet(enp, &req); 726 727 if (req.emr_rc != 0) { 728 rc = req.emr_rc; 729 goto fail2; 730 } 731 732 if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) { 733 rc = EMSGSIZE; 734 goto fail3; 735 } 736 737 *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE); 738 739 return (0); 740 741 fail3: 742 EFSYS_PROBE(fail3); 743 fail2: 744 EFSYS_PROBE(fail2); 745 fail1: 746 EFSYS_PROBE1(fail1, efx_rc_t, rc); 747 748 return (rc); 749 } 750 751 static __checkReturn efx_rc_t 752 efx_mcdi_free_piobuf( 753 __in efx_nic_t *enp, 754 __in efx_piobuf_handle_t handle) 755 { 756 efx_mcdi_req_t req; 757 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN, 758 MC_CMD_FREE_PIOBUF_OUT_LEN); 759 efx_rc_t rc; 760 761 req.emr_cmd = MC_CMD_FREE_PIOBUF; 762 req.emr_in_buf = payload; 763 req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN; 764 req.emr_out_buf = payload; 765 req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN; 766 767 MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle); 768 769 efx_mcdi_execute_quiet(enp, &req); 770 771 if (req.emr_rc != 0) { 772 rc = req.emr_rc; 773 goto fail1; 774 } 775 776 return (0); 777 778 fail1: 779 EFSYS_PROBE1(fail1, efx_rc_t, rc); 780 781 return (rc); 782 } 783 784 static __checkReturn efx_rc_t 785 efx_mcdi_link_piobuf( 786 __in efx_nic_t *enp, 787 __in uint32_t vi_index, 788 __in efx_piobuf_handle_t handle) 789 { 790 efx_mcdi_req_t req; 791 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN, 792 MC_CMD_LINK_PIOBUF_OUT_LEN); 793 efx_rc_t rc; 794 795 req.emr_cmd = MC_CMD_LINK_PIOBUF; 796 req.emr_in_buf = payload; 797 req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN; 798 req.emr_out_buf = payload; 799 req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN; 800 801 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle); 802 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 803 804 efx_mcdi_execute(enp, &req); 805 806 if (req.emr_rc != 0) { 807 rc = req.emr_rc; 808 goto fail1; 809 } 810 811 return (0); 812 813 fail1: 814 EFSYS_PROBE1(fail1, efx_rc_t, rc); 815 816 return (rc); 817 } 818 819 static __checkReturn efx_rc_t 820 efx_mcdi_unlink_piobuf( 821 __in efx_nic_t *enp, 822 __in uint32_t vi_index) 823 { 824 efx_mcdi_req_t req; 825 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN, 826 MC_CMD_UNLINK_PIOBUF_OUT_LEN); 827 efx_rc_t rc; 828 829 req.emr_cmd = MC_CMD_UNLINK_PIOBUF; 830 req.emr_in_buf = payload; 831 req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN; 832 req.emr_out_buf = payload; 833 req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN; 834 835 MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 836 837 efx_mcdi_execute_quiet(enp, &req); 838 839 if (req.emr_rc != 0) { 840 rc = req.emr_rc; 841 goto fail1; 842 } 843 844 return (0); 845 846 fail1: 847 EFSYS_PROBE1(fail1, efx_rc_t, rc); 848 849 return (rc); 850 } 851 852 static void 853 ef10_nic_alloc_piobufs( 854 __in efx_nic_t *enp, 855 __in uint32_t max_piobuf_count) 856 { 857 efx_piobuf_handle_t *handlep; 858 unsigned int i; 859 860 EFSYS_ASSERT3U(max_piobuf_count, <=, 861 EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle)); 862 863 enp->en_arch.ef10.ena_piobuf_count = 0; 864 865 for (i = 0; i < max_piobuf_count; i++) { 866 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 867 868 if (efx_mcdi_alloc_piobuf(enp, handlep) != 0) 869 goto fail1; 870 871 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0; 872 enp->en_arch.ef10.ena_piobuf_count++; 873 } 874 875 return; 876 877 fail1: 878 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 879 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 880 881 (void) efx_mcdi_free_piobuf(enp, *handlep); 882 *handlep = EFX_PIOBUF_HANDLE_INVALID; 883 } 884 enp->en_arch.ef10.ena_piobuf_count = 0; 885 } 886 887 static void 888 ef10_nic_free_piobufs( 889 __in efx_nic_t *enp) 890 { 891 efx_piobuf_handle_t *handlep; 892 unsigned int i; 893 894 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 895 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 896 897 (void) efx_mcdi_free_piobuf(enp, *handlep); 898 *handlep = EFX_PIOBUF_HANDLE_INVALID; 899 } 900 enp->en_arch.ef10.ena_piobuf_count = 0; 901 } 902 903 /* Sub-allocate a block from a piobuf */ 904 __checkReturn efx_rc_t 905 ef10_nic_pio_alloc( 906 __inout efx_nic_t *enp, 907 __out uint32_t *bufnump, 908 __out efx_piobuf_handle_t *handlep, 909 __out uint32_t *blknump, 910 __out uint32_t *offsetp, 911 __out size_t *sizep) 912 { 913 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 914 efx_drv_cfg_t *edcp = &enp->en_drv_cfg; 915 uint32_t blk_per_buf; 916 uint32_t buf, blk; 917 efx_rc_t rc; 918 919 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 920 enp->en_family == EFX_FAMILY_MEDFORD || 921 enp->en_family == EFX_FAMILY_MEDFORD2); 922 EFSYS_ASSERT(bufnump); 923 EFSYS_ASSERT(handlep); 924 EFSYS_ASSERT(blknump); 925 EFSYS_ASSERT(offsetp); 926 EFSYS_ASSERT(sizep); 927 928 if ((edcp->edc_pio_alloc_size == 0) || 929 (enp->en_arch.ef10.ena_piobuf_count == 0)) { 930 rc = ENOMEM; 931 goto fail1; 932 } 933 blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size; 934 935 for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) { 936 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf]; 937 938 if (~(*map) == 0) 939 continue; 940 941 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map))); 942 for (blk = 0; blk < blk_per_buf; blk++) { 943 if ((*map & (1u << blk)) == 0) { 944 *map |= (1u << blk); 945 goto done; 946 } 947 } 948 } 949 rc = ENOMEM; 950 goto fail2; 951 952 done: 953 *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf]; 954 *bufnump = buf; 955 *blknump = blk; 956 *sizep = edcp->edc_pio_alloc_size; 957 *offsetp = blk * (*sizep); 958 959 return (0); 960 961 fail2: 962 EFSYS_PROBE(fail2); 963 fail1: 964 EFSYS_PROBE1(fail1, efx_rc_t, rc); 965 966 return (rc); 967 } 968 969 /* Free a piobuf sub-allocated block */ 970 __checkReturn efx_rc_t 971 ef10_nic_pio_free( 972 __inout efx_nic_t *enp, 973 __in uint32_t bufnum, 974 __in uint32_t blknum) 975 { 976 uint32_t *map; 977 efx_rc_t rc; 978 979 if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) || 980 (blknum >= (8 * sizeof (*map)))) { 981 rc = EINVAL; 982 goto fail1; 983 } 984 985 map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum]; 986 if ((*map & (1u << blknum)) == 0) { 987 rc = ENOENT; 988 goto fail2; 989 } 990 *map &= ~(1u << blknum); 991 992 return (0); 993 994 fail2: 995 EFSYS_PROBE(fail2); 996 fail1: 997 EFSYS_PROBE1(fail1, efx_rc_t, rc); 998 999 return (rc); 1000 } 1001 1002 __checkReturn efx_rc_t 1003 ef10_nic_pio_link( 1004 __inout efx_nic_t *enp, 1005 __in uint32_t vi_index, 1006 __in efx_piobuf_handle_t handle) 1007 { 1008 return (efx_mcdi_link_piobuf(enp, vi_index, handle)); 1009 } 1010 1011 __checkReturn efx_rc_t 1012 ef10_nic_pio_unlink( 1013 __inout efx_nic_t *enp, 1014 __in uint32_t vi_index) 1015 { 1016 return (efx_mcdi_unlink_piobuf(enp, vi_index)); 1017 } 1018 1019 static __checkReturn efx_rc_t 1020 ef10_mcdi_get_pf_count( 1021 __in efx_nic_t *enp, 1022 __out uint32_t *pf_countp) 1023 { 1024 efx_mcdi_req_t req; 1025 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN, 1026 MC_CMD_GET_PF_COUNT_OUT_LEN); 1027 efx_rc_t rc; 1028 1029 req.emr_cmd = MC_CMD_GET_PF_COUNT; 1030 req.emr_in_buf = payload; 1031 req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN; 1032 req.emr_out_buf = payload; 1033 req.emr_out_length = MC_CMD_GET_PF_COUNT_OUT_LEN; 1034 1035 efx_mcdi_execute(enp, &req); 1036 1037 if (req.emr_rc != 0) { 1038 rc = req.emr_rc; 1039 goto fail1; 1040 } 1041 1042 if (req.emr_out_length_used < MC_CMD_GET_PF_COUNT_OUT_LEN) { 1043 rc = EMSGSIZE; 1044 goto fail2; 1045 } 1046 1047 *pf_countp = *MCDI_OUT(req, uint8_t, 1048 MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST); 1049 1050 EFSYS_ASSERT(*pf_countp != 0); 1051 1052 return (0); 1053 1054 fail2: 1055 EFSYS_PROBE(fail2); 1056 fail1: 1057 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1058 1059 return (rc); 1060 } 1061 1062 static __checkReturn efx_rc_t 1063 ef10_get_datapath_caps( 1064 __in efx_nic_t *enp) 1065 { 1066 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1067 efx_mcdi_req_t req; 1068 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN, 1069 MC_CMD_GET_CAPABILITIES_V5_OUT_LEN); 1070 efx_rc_t rc; 1071 1072 if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0) 1073 goto fail1; 1074 1075 req.emr_cmd = MC_CMD_GET_CAPABILITIES; 1076 req.emr_in_buf = payload; 1077 req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; 1078 req.emr_out_buf = payload; 1079 req.emr_out_length = MC_CMD_GET_CAPABILITIES_V5_OUT_LEN; 1080 1081 efx_mcdi_execute_quiet(enp, &req); 1082 1083 if (req.emr_rc != 0) { 1084 rc = req.emr_rc; 1085 goto fail2; 1086 } 1087 1088 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) { 1089 rc = EMSGSIZE; 1090 goto fail3; 1091 } 1092 1093 #define CAP_FLAGS1(_req, _flag) \ 1094 (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_OUT_FLAGS1) & \ 1095 (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN))) 1096 1097 #define CAP_FLAGS2(_req, _flag) \ 1098 (((_req).emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) && \ 1099 (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_V2_OUT_FLAGS2) & \ 1100 (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN)))) 1101 1102 /* 1103 * Huntington RXDP firmware inserts a 0 or 14 byte prefix. 1104 * We only support the 14 byte prefix here. 1105 */ 1106 if (CAP_FLAGS1(req, RX_PREFIX_LEN_14) == 0) { 1107 rc = ENOTSUP; 1108 goto fail4; 1109 } 1110 encp->enc_rx_prefix_size = 14; 1111 1112 #if EFSYS_OPT_RX_SCALE 1113 /* Check if the firmware supports additional RSS modes */ 1114 if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES)) 1115 encp->enc_rx_scale_additional_modes_supported = B_TRUE; 1116 else 1117 encp->enc_rx_scale_additional_modes_supported = B_FALSE; 1118 #endif /* EFSYS_OPT_RX_SCALE */ 1119 1120 /* Check if the firmware supports TSO */ 1121 if (CAP_FLAGS1(req, TX_TSO)) 1122 encp->enc_fw_assisted_tso_enabled = B_TRUE; 1123 else 1124 encp->enc_fw_assisted_tso_enabled = B_FALSE; 1125 1126 /* Check if the firmware supports FATSOv2 */ 1127 if (CAP_FLAGS2(req, TX_TSO_V2)) { 1128 encp->enc_fw_assisted_tso_v2_enabled = B_TRUE; 1129 encp->enc_fw_assisted_tso_v2_n_contexts = MCDI_OUT_WORD(req, 1130 GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS); 1131 } else { 1132 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE; 1133 encp->enc_fw_assisted_tso_v2_n_contexts = 0; 1134 } 1135 1136 /* Check if the firmware supports FATSOv2 encap */ 1137 if (CAP_FLAGS2(req, TX_TSO_V2_ENCAP)) 1138 encp->enc_fw_assisted_tso_v2_encap_enabled = B_TRUE; 1139 else 1140 encp->enc_fw_assisted_tso_v2_encap_enabled = B_FALSE; 1141 1142 /* Check if the firmware has vadapter/vport/vswitch support */ 1143 if (CAP_FLAGS1(req, EVB)) 1144 encp->enc_datapath_cap_evb = B_TRUE; 1145 else 1146 encp->enc_datapath_cap_evb = B_FALSE; 1147 1148 /* Check if the firmware supports VLAN insertion */ 1149 if (CAP_FLAGS1(req, TX_VLAN_INSERTION)) 1150 encp->enc_hw_tx_insert_vlan_enabled = B_TRUE; 1151 else 1152 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 1153 1154 /* Check if the firmware supports RX event batching */ 1155 if (CAP_FLAGS1(req, RX_BATCHING)) 1156 encp->enc_rx_batching_enabled = B_TRUE; 1157 else 1158 encp->enc_rx_batching_enabled = B_FALSE; 1159 1160 /* 1161 * Even if batching isn't reported as supported, we may still get 1162 * batched events. 1163 */ 1164 encp->enc_rx_batch_max = 16; 1165 1166 /* Check if the firmware supports disabling scatter on RXQs */ 1167 if (CAP_FLAGS1(req, RX_DISABLE_SCATTER)) 1168 encp->enc_rx_disable_scatter_supported = B_TRUE; 1169 else 1170 encp->enc_rx_disable_scatter_supported = B_FALSE; 1171 1172 /* Check if the firmware supports packed stream mode */ 1173 if (CAP_FLAGS1(req, RX_PACKED_STREAM)) 1174 encp->enc_rx_packed_stream_supported = B_TRUE; 1175 else 1176 encp->enc_rx_packed_stream_supported = B_FALSE; 1177 1178 /* 1179 * Check if the firmware supports configurable buffer sizes 1180 * for packed stream mode (otherwise buffer size is 1Mbyte) 1181 */ 1182 if (CAP_FLAGS1(req, RX_PACKED_STREAM_VAR_BUFFERS)) 1183 encp->enc_rx_var_packed_stream_supported = B_TRUE; 1184 else 1185 encp->enc_rx_var_packed_stream_supported = B_FALSE; 1186 1187 /* Check if the firmware supports equal stride super-buffer mode */ 1188 if (CAP_FLAGS2(req, EQUAL_STRIDE_SUPER_BUFFER)) 1189 encp->enc_rx_es_super_buffer_supported = B_TRUE; 1190 else 1191 encp->enc_rx_es_super_buffer_supported = B_FALSE; 1192 1193 /* Check if the firmware supports FW subvariant w/o Tx checksumming */ 1194 if (CAP_FLAGS2(req, FW_SUBVARIANT_NO_TX_CSUM)) 1195 encp->enc_fw_subvariant_no_tx_csum_supported = B_TRUE; 1196 else 1197 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE; 1198 1199 /* Check if the firmware supports set mac with running filters */ 1200 if (CAP_FLAGS1(req, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED)) 1201 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 1202 else 1203 encp->enc_allow_set_mac_with_installed_filters = B_FALSE; 1204 1205 /* 1206 * Check if firmware supports the extended MC_CMD_SET_MAC, which allows 1207 * specifying which parameters to configure. 1208 */ 1209 if (CAP_FLAGS1(req, SET_MAC_ENHANCED)) 1210 encp->enc_enhanced_set_mac_supported = B_TRUE; 1211 else 1212 encp->enc_enhanced_set_mac_supported = B_FALSE; 1213 1214 /* 1215 * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows 1216 * us to let the firmware choose the settings to use on an EVQ. 1217 */ 1218 if (CAP_FLAGS2(req, INIT_EVQ_V2)) 1219 encp->enc_init_evq_v2_supported = B_TRUE; 1220 else 1221 encp->enc_init_evq_v2_supported = B_FALSE; 1222 1223 /* 1224 * Check if firmware-verified NVRAM updates must be used. 1225 * 1226 * The firmware trusted installer requires all NVRAM updates to use 1227 * version 2 of MC_CMD_NVRAM_UPDATE_START (to enable verified update) 1228 * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated 1229 * partition and report the result). 1230 */ 1231 if (CAP_FLAGS2(req, NVRAM_UPDATE_REPORT_VERIFY_RESULT)) 1232 encp->enc_nvram_update_verify_result_supported = B_TRUE; 1233 else 1234 encp->enc_nvram_update_verify_result_supported = B_FALSE; 1235 1236 /* 1237 * Check if firmware provides packet memory and Rx datapath 1238 * counters. 1239 */ 1240 if (CAP_FLAGS1(req, PM_AND_RXDP_COUNTERS)) 1241 encp->enc_pm_and_rxdp_counters = B_TRUE; 1242 else 1243 encp->enc_pm_and_rxdp_counters = B_FALSE; 1244 1245 /* 1246 * Check if the 40G MAC hardware is capable of reporting 1247 * statistics for Tx size bins. 1248 */ 1249 if (CAP_FLAGS2(req, MAC_STATS_40G_TX_SIZE_BINS)) 1250 encp->enc_mac_stats_40g_tx_size_bins = B_TRUE; 1251 else 1252 encp->enc_mac_stats_40g_tx_size_bins = B_FALSE; 1253 1254 /* 1255 * Check if firmware supports VXLAN and NVGRE tunnels. 1256 * The capability indicates Geneve protocol support as well. 1257 */ 1258 if (CAP_FLAGS1(req, VXLAN_NVGRE)) { 1259 encp->enc_tunnel_encapsulations_supported = 1260 (1u << EFX_TUNNEL_PROTOCOL_VXLAN) | 1261 (1u << EFX_TUNNEL_PROTOCOL_GENEVE) | 1262 (1u << EFX_TUNNEL_PROTOCOL_NVGRE); 1263 1264 EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES == 1265 MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM); 1266 encp->enc_tunnel_config_udp_entries_max = 1267 EFX_TUNNEL_MAXNENTRIES; 1268 } else { 1269 encp->enc_tunnel_config_udp_entries_max = 0; 1270 } 1271 1272 /* 1273 * Check if firmware reports the VI window mode. 1274 * Medford2 has a variable VI window size (8K, 16K or 64K). 1275 * Medford and Huntington have a fixed 8K VI window size. 1276 */ 1277 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) { 1278 uint8_t mode = 1279 MCDI_OUT_BYTE(req, GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); 1280 1281 switch (mode) { 1282 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K: 1283 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 1284 break; 1285 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K: 1286 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_16K; 1287 break; 1288 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K: 1289 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_64K; 1290 break; 1291 default: 1292 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID; 1293 break; 1294 } 1295 } else if ((enp->en_family == EFX_FAMILY_HUNTINGTON) || 1296 (enp->en_family == EFX_FAMILY_MEDFORD)) { 1297 /* Huntington and Medford have fixed 8K window size */ 1298 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 1299 } else { 1300 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID; 1301 } 1302 1303 /* Check if firmware supports extended MAC stats. */ 1304 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) { 1305 /* Extended stats buffer supported */ 1306 encp->enc_mac_stats_nstats = MCDI_OUT_WORD(req, 1307 GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS); 1308 } else { 1309 /* Use Siena-compatible legacy MAC stats */ 1310 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS; 1311 } 1312 1313 if (encp->enc_mac_stats_nstats >= MC_CMD_MAC_NSTATS_V2) 1314 encp->enc_fec_counters = B_TRUE; 1315 else 1316 encp->enc_fec_counters = B_FALSE; 1317 1318 /* Check if the firmware provides head-of-line blocking counters */ 1319 if (CAP_FLAGS2(req, RXDP_HLB_IDLE)) 1320 encp->enc_hlb_counters = B_TRUE; 1321 else 1322 encp->enc_hlb_counters = B_FALSE; 1323 1324 #if EFSYS_OPT_RX_SCALE 1325 if (CAP_FLAGS1(req, RX_RSS_LIMITED)) { 1326 /* Only one exclusive RSS context is available per port. */ 1327 encp->enc_rx_scale_max_exclusive_contexts = 1; 1328 1329 switch (enp->en_family) { 1330 case EFX_FAMILY_MEDFORD2: 1331 encp->enc_rx_scale_hash_alg_mask = 1332 (1U << EFX_RX_HASHALG_TOEPLITZ); 1333 break; 1334 1335 case EFX_FAMILY_MEDFORD: 1336 case EFX_FAMILY_HUNTINGTON: 1337 /* 1338 * Packed stream firmware variant maintains a 1339 * non-standard algorithm for hash computation. 1340 * It implies explicit XORing together 1341 * source + destination IP addresses (or last 1342 * four bytes in the case of IPv6) and using the 1343 * resulting value as the input to a Toeplitz hash. 1344 */ 1345 encp->enc_rx_scale_hash_alg_mask = 1346 (1U << EFX_RX_HASHALG_PACKED_STREAM); 1347 break; 1348 1349 default: 1350 rc = EINVAL; 1351 goto fail5; 1352 } 1353 1354 /* Port numbers cannot contribute to the hash value */ 1355 encp->enc_rx_scale_l4_hash_supported = B_FALSE; 1356 } else { 1357 /* 1358 * Maximum number of exclusive RSS contexts. 1359 * EF10 hardware supports 64 in total, but 6 are reserved 1360 * for shared contexts. They are a global resource so 1361 * not all may be available. 1362 */ 1363 encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; 1364 1365 encp->enc_rx_scale_hash_alg_mask = 1366 (1U << EFX_RX_HASHALG_TOEPLITZ); 1367 1368 /* 1369 * It is possible to use port numbers as 1370 * the input data for hash computation. 1371 */ 1372 encp->enc_rx_scale_l4_hash_supported = B_TRUE; 1373 } 1374 #endif /* EFSYS_OPT_RX_SCALE */ 1375 1376 /* Check if the firmware supports "FLAG" and "MARK" filter actions */ 1377 if (CAP_FLAGS2(req, FILTER_ACTION_FLAG)) 1378 encp->enc_filter_action_flag_supported = B_TRUE; 1379 else 1380 encp->enc_filter_action_flag_supported = B_FALSE; 1381 1382 if (CAP_FLAGS2(req, FILTER_ACTION_MARK)) 1383 encp->enc_filter_action_mark_supported = B_TRUE; 1384 else 1385 encp->enc_filter_action_mark_supported = B_FALSE; 1386 1387 /* Get maximum supported value for "MARK" filter action */ 1388 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V5_OUT_LEN) 1389 encp->enc_filter_action_mark_max = MCDI_OUT_DWORD(req, 1390 GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX); 1391 else 1392 encp->enc_filter_action_mark_max = 0; 1393 1394 #undef CAP_FLAGS1 1395 #undef CAP_FLAGS2 1396 1397 return (0); 1398 1399 #if EFSYS_OPT_RX_SCALE 1400 fail5: 1401 EFSYS_PROBE(fail5); 1402 #endif /* EFSYS_OPT_RX_SCALE */ 1403 fail4: 1404 EFSYS_PROBE(fail4); 1405 fail3: 1406 EFSYS_PROBE(fail3); 1407 fail2: 1408 EFSYS_PROBE(fail2); 1409 fail1: 1410 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1411 1412 return (rc); 1413 } 1414 1415 #define EF10_LEGACY_PF_PRIVILEGE_MASK \ 1416 (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \ 1417 MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK | \ 1418 MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD | \ 1419 MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP | \ 1420 MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS | \ 1421 MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING | \ 1422 MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST | \ 1423 MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST | \ 1424 MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST | \ 1425 MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \ 1426 MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS) 1427 1428 #define EF10_LEGACY_VF_PRIVILEGE_MASK 0 1429 1430 __checkReturn efx_rc_t 1431 ef10_get_privilege_mask( 1432 __in efx_nic_t *enp, 1433 __out uint32_t *maskp) 1434 { 1435 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1436 uint32_t mask; 1437 efx_rc_t rc; 1438 1439 if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf, 1440 &mask)) != 0) { 1441 if (rc != ENOTSUP) 1442 goto fail1; 1443 1444 /* Fallback for old firmware without privilege mask support */ 1445 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1446 /* Assume PF has admin privilege */ 1447 mask = EF10_LEGACY_PF_PRIVILEGE_MASK; 1448 } else { 1449 /* VF is always unprivileged by default */ 1450 mask = EF10_LEGACY_VF_PRIVILEGE_MASK; 1451 } 1452 } 1453 1454 *maskp = mask; 1455 1456 return (0); 1457 1458 fail1: 1459 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1460 1461 return (rc); 1462 } 1463 1464 #define EFX_EXT_PORT_MAX 4 1465 #define EFX_EXT_PORT_NA 0xFF 1466 1467 /* 1468 * Table of mapping schemes from port number to external number. 1469 * 1470 * Each port number ultimately corresponds to a connector: either as part of 1471 * a cable assembly attached to a module inserted in an SFP+/QSFP+ cage on 1472 * the board, or fixed to the board (e.g. 10GBASE-T magjack on SFN5121T 1473 * "Salina"). In general: 1474 * 1475 * Port number (0-based) 1476 * | 1477 * port mapping (n:1) 1478 * | 1479 * v 1480 * External port number (1-based) 1481 * | 1482 * fixed (1:1) or cable assembly (1:m) 1483 * | 1484 * v 1485 * Connector 1486 * 1487 * The external numbering refers to the cages or magjacks on the board, 1488 * as visibly annotated on the board or back panel. This table describes 1489 * how to determine which external cage/magjack corresponds to the port 1490 * numbers used by the driver. 1491 * 1492 * The count of consecutive port numbers that map to each external number, 1493 * is determined by the chip family and the current port mode. 1494 * 1495 * For the Huntington family, the current port mode cannot be discovered, 1496 * but a single mapping is used by all modes for a given chip variant, 1497 * so the mapping used is instead the last match in the table to the full 1498 * set of port modes to which the NIC can be configured. Therefore the 1499 * ordering of entries in the mapping table is significant. 1500 */ 1501 static struct ef10_external_port_map_s { 1502 efx_family_t family; 1503 uint32_t modes_mask; 1504 uint8_t base_port[EFX_EXT_PORT_MAX]; 1505 } __ef10_external_port_mappings[] = { 1506 /* 1507 * Modes used by Huntington family controllers where each port 1508 * number maps to a separate cage. 1509 * SFN7x22F (Torino): 1510 * port 0 -> cage 1 1511 * port 1 -> cage 2 1512 * SFN7xx4F (Pavia): 1513 * port 0 -> cage 1 1514 * port 1 -> cage 2 1515 * port 2 -> cage 3 1516 * port 3 -> cage 4 1517 */ 1518 { 1519 EFX_FAMILY_HUNTINGTON, 1520 (1U << TLV_PORT_MODE_10G) | /* mode 0 */ 1521 (1U << TLV_PORT_MODE_10G_10G) | /* mode 2 */ 1522 (1U << TLV_PORT_MODE_10G_10G_10G_10G), /* mode 4 */ 1523 { 0, 1, 2, 3 } 1524 }, 1525 /* 1526 * Modes which for Huntington identify a chip variant where 2 1527 * adjacent port numbers map to each cage. 1528 * SFN7x42Q (Monza): 1529 * port 0 -> cage 1 1530 * port 1 -> cage 1 1531 * port 2 -> cage 2 1532 * port 3 -> cage 2 1533 */ 1534 { 1535 EFX_FAMILY_HUNTINGTON, 1536 (1U << TLV_PORT_MODE_40G) | /* mode 1 */ 1537 (1U << TLV_PORT_MODE_40G_40G) | /* mode 3 */ 1538 (1U << TLV_PORT_MODE_40G_10G_10G) | /* mode 6 */ 1539 (1U << TLV_PORT_MODE_10G_10G_40G), /* mode 7 */ 1540 { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1541 }, 1542 /* 1543 * Modes that on Medford allocate each port number to a separate 1544 * cage. 1545 * port 0 -> cage 1 1546 * port 1 -> cage 2 1547 * port 2 -> cage 3 1548 * port 3 -> cage 4 1549 */ 1550 { 1551 EFX_FAMILY_MEDFORD, 1552 (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ 1553 (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */ 1554 { 0, 1, 2, 3 } 1555 }, 1556 /* 1557 * Modes that on Medford allocate 2 adjacent port numbers to each 1558 * cage. 1559 * port 0 -> cage 1 1560 * port 1 -> cage 1 1561 * port 2 -> cage 2 1562 * port 3 -> cage 2 1563 */ 1564 { 1565 EFX_FAMILY_MEDFORD, 1566 (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ 1567 (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */ 1568 (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */ 1569 (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ 1570 /* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */ 1571 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), /* mode 9 */ 1572 { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1573 }, 1574 /* 1575 * Modes that on Medford allocate 4 adjacent port numbers to each 1576 * connector, starting on cage 1. 1577 * port 0 -> cage 1 1578 * port 1 -> cage 1 1579 * port 2 -> cage 1 1580 * port 3 -> cage 1 1581 */ 1582 { 1583 EFX_FAMILY_MEDFORD, 1584 (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 5 */ 1585 /* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */ 1586 (1U << TLV_PORT_MODE_4x1_NA), /* mode 4 */ 1587 { 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1588 }, 1589 /* 1590 * Modes that on Medford allocate 4 adjacent port numbers to each 1591 * connector, starting on cage 2. 1592 * port 0 -> cage 2 1593 * port 1 -> cage 2 1594 * port 2 -> cage 2 1595 * port 3 -> cage 2 1596 */ 1597 { 1598 EFX_FAMILY_MEDFORD, 1599 (1U << TLV_PORT_MODE_NA_4x1), /* mode 8 */ 1600 { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1601 }, 1602 /* 1603 * Modes that on Medford2 allocate each port number to a separate 1604 * cage. 1605 * port 0 -> cage 1 1606 * port 1 -> cage 2 1607 * port 2 -> cage 3 1608 * port 3 -> cage 4 1609 */ 1610 { 1611 EFX_FAMILY_MEDFORD2, 1612 (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ 1613 (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ 1614 (1U << TLV_PORT_MODE_1x1_1x1) | /* mode 2 */ 1615 (1U << TLV_PORT_MODE_1x2_NA) | /* mode 10 */ 1616 (1U << TLV_PORT_MODE_1x2_1x2) | /* mode 12 */ 1617 (1U << TLV_PORT_MODE_1x4_1x2) | /* mode 15 */ 1618 (1U << TLV_PORT_MODE_1x2_1x4), /* mode 16 */ 1619 { 0, 1, 2, 3 } 1620 }, 1621 /* 1622 * Modes that on Medford2 allocate 1 port to cage 1 and the rest 1623 * to cage 2. 1624 * port 0 -> cage 1 1625 * port 1 -> cage 2 1626 * port 2 -> cage 2 1627 */ 1628 { 1629 EFX_FAMILY_MEDFORD2, 1630 (1U << TLV_PORT_MODE_1x2_2x1) | /* mode 17 */ 1631 (1U << TLV_PORT_MODE_1x4_2x1), /* mode 6 */ 1632 { 0, 1, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1633 }, 1634 /* 1635 * Modes that on Medford2 allocate 2 adjacent port numbers to each 1636 * cage, starting on cage 1. 1637 * port 0 -> cage 1 1638 * port 1 -> cage 1 1639 * port 2 -> cage 2 1640 * port 3 -> cage 2 1641 */ 1642 { 1643 EFX_FAMILY_MEDFORD2, 1644 (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */ 1645 (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 4 */ 1646 (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */ 1647 (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ 1648 (1U << TLV_PORT_MODE_2x2_NA) | /* mode 13 */ 1649 (1U << TLV_PORT_MODE_2x1_1x2), /* mode 18 */ 1650 { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1651 }, 1652 /* 1653 * Modes that on Medford2 allocate 2 adjacent port numbers to each 1654 * cage, starting on cage 2. 1655 * port 0 -> cage 2 1656 * port 1 -> cage 2 1657 */ 1658 { 1659 EFX_FAMILY_MEDFORD2, 1660 (1U << TLV_PORT_MODE_NA_2x2), /* mode 14 */ 1661 { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1662 }, 1663 /* 1664 * Modes that on Medford2 allocate 4 adjacent port numbers to each 1665 * connector, starting on cage 1. 1666 * port 0 -> cage 1 1667 * port 1 -> cage 1 1668 * port 2 -> cage 1 1669 * port 3 -> cage 1 1670 */ 1671 { 1672 EFX_FAMILY_MEDFORD2, 1673 (1U << TLV_PORT_MODE_4x1_NA), /* mode 5 */ 1674 { 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1675 }, 1676 /* 1677 * Modes that on Medford2 allocate 4 adjacent port numbers to each 1678 * connector, starting on cage 2. 1679 * port 0 -> cage 2 1680 * port 1 -> cage 2 1681 * port 2 -> cage 2 1682 * port 3 -> cage 2 1683 */ 1684 { 1685 EFX_FAMILY_MEDFORD2, 1686 (1U << TLV_PORT_MODE_NA_4x1) | /* mode 8 */ 1687 (1U << TLV_PORT_MODE_NA_1x2), /* mode 11 */ 1688 { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1689 }, 1690 }; 1691 1692 static __checkReturn efx_rc_t 1693 ef10_external_port_mapping( 1694 __in efx_nic_t *enp, 1695 __in uint32_t port, 1696 __out uint8_t *external_portp) 1697 { 1698 efx_rc_t rc; 1699 int i; 1700 uint32_t port_modes; 1701 uint32_t matches; 1702 uint32_t current; 1703 struct ef10_external_port_map_s *mapp = NULL; 1704 int ext_index = port; /* Default 1-1 mapping */ 1705 1706 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t, 1707 NULL)) != 0) { 1708 /* 1709 * No current port mode information (i.e. Huntington) 1710 * - infer mapping from available modes 1711 */ 1712 if ((rc = efx_mcdi_get_port_modes(enp, 1713 &port_modes, NULL, NULL)) != 0) { 1714 /* 1715 * No port mode information available 1716 * - use default mapping 1717 */ 1718 goto out; 1719 } 1720 } else { 1721 /* Only need to scan the current mode */ 1722 port_modes = 1 << current; 1723 } 1724 1725 /* 1726 * Infer the internal port -> external number mapping from 1727 * the possible port modes for this NIC. 1728 */ 1729 for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) { 1730 struct ef10_external_port_map_s *eepmp = 1731 &__ef10_external_port_mappings[i]; 1732 if (eepmp->family != enp->en_family) 1733 continue; 1734 matches = (eepmp->modes_mask & port_modes); 1735 if (matches != 0) { 1736 /* 1737 * Some modes match. For some Huntington boards 1738 * there will be multiple matches. The mapping on the 1739 * last match is used. 1740 */ 1741 mapp = eepmp; 1742 port_modes &= ~matches; 1743 } 1744 } 1745 1746 if (port_modes != 0) { 1747 /* Some advertised modes are not supported */ 1748 rc = ENOTSUP; 1749 goto fail1; 1750 } 1751 1752 out: 1753 if (mapp != NULL) { 1754 /* 1755 * External ports are assigned a sequence of consecutive 1756 * port numbers, so find the one with the closest base_port. 1757 */ 1758 uint32_t delta = EFX_EXT_PORT_NA; 1759 1760 for (i = 0; i < EFX_EXT_PORT_MAX; i++) { 1761 uint32_t base = mapp->base_port[i]; 1762 if ((base != EFX_EXT_PORT_NA) && (base <= port)) { 1763 if ((port - base) < delta) { 1764 delta = (port - base); 1765 ext_index = i; 1766 } 1767 } 1768 } 1769 } 1770 *external_portp = (uint8_t)(ext_index + 1); 1771 1772 return (0); 1773 1774 fail1: 1775 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1776 1777 return (rc); 1778 } 1779 1780 static __checkReturn efx_rc_t 1781 ef10_nic_board_cfg( 1782 __in efx_nic_t *enp) 1783 { 1784 const efx_nic_ops_t *enop = enp->en_enop; 1785 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 1786 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1787 ef10_link_state_t els; 1788 efx_port_t *epp = &(enp->en_port); 1789 uint32_t board_type = 0; 1790 uint32_t base, nvec; 1791 uint32_t port; 1792 uint32_t mask; 1793 uint32_t pf; 1794 uint32_t vf; 1795 uint8_t mac_addr[6] = { 0 }; 1796 efx_rc_t rc; 1797 1798 /* Get the (zero-based) MCDI port number */ 1799 if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) 1800 goto fail1; 1801 1802 /* EFX MCDI interface uses one-based port numbers */ 1803 emip->emi_port = port + 1; 1804 1805 if ((rc = ef10_external_port_mapping(enp, port, 1806 &encp->enc_external_port)) != 0) 1807 goto fail2; 1808 1809 /* 1810 * Get PCIe function number from firmware (used for 1811 * per-function privilege and dynamic config info). 1812 * - PCIe PF: pf = PF number, vf = 0xffff. 1813 * - PCIe VF: pf = parent PF, vf = VF number. 1814 */ 1815 if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0) 1816 goto fail3; 1817 1818 encp->enc_pf = pf; 1819 encp->enc_vf = vf; 1820 1821 /* MAC address for this function */ 1822 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1823 rc = efx_mcdi_get_mac_address_pf(enp, mac_addr); 1824 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 1825 /* 1826 * Disable static config checking, ONLY for manufacturing test 1827 * and setup at the factory, to allow the static config to be 1828 * installed. 1829 */ 1830 #else /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */ 1831 if ((rc == 0) && (mac_addr[0] & 0x02)) { 1832 /* 1833 * If the static config does not include a global MAC 1834 * address pool then the board may return a locally 1835 * administered MAC address (this should only happen on 1836 * incorrectly programmed boards). 1837 */ 1838 rc = EINVAL; 1839 } 1840 #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */ 1841 } else { 1842 rc = efx_mcdi_get_mac_address_vf(enp, mac_addr); 1843 } 1844 if (rc != 0) 1845 goto fail4; 1846 1847 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 1848 1849 /* Board configuration (legacy) */ 1850 rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL); 1851 if (rc != 0) { 1852 /* Unprivileged functions may not be able to read board cfg */ 1853 if (rc == EACCES) 1854 board_type = 0; 1855 else 1856 goto fail5; 1857 } 1858 1859 encp->enc_board_type = board_type; 1860 encp->enc_clk_mult = 1; /* not used for EF10 */ 1861 1862 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 1863 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 1864 goto fail6; 1865 1866 /* 1867 * Firmware with support for *_FEC capability bits does not 1868 * report that the corresponding *_FEC_REQUESTED bits are supported. 1869 * Add them here so that drivers understand that they are supported. 1870 */ 1871 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_BASER_FEC)) 1872 epp->ep_phy_cap_mask |= 1873 (1u << EFX_PHY_CAP_BASER_FEC_REQUESTED); 1874 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_RS_FEC)) 1875 epp->ep_phy_cap_mask |= 1876 (1u << EFX_PHY_CAP_RS_FEC_REQUESTED); 1877 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_25G_BASER_FEC)) 1878 epp->ep_phy_cap_mask |= 1879 (1u << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED); 1880 1881 /* Obtain the default PHY advertised capabilities */ 1882 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 1883 goto fail7; 1884 epp->ep_default_adv_cap_mask = els.epls.epls_adv_cap_mask; 1885 epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask; 1886 1887 /* Check capabilities of running datapath firmware */ 1888 if ((rc = ef10_get_datapath_caps(enp)) != 0) 1889 goto fail8; 1890 1891 /* Alignment for WPTR updates */ 1892 encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; 1893 1894 encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); 1895 /* No boundary crossing limits */ 1896 encp->enc_tx_dma_desc_boundary = 0; 1897 1898 /* 1899 * Maximum number of bytes into the frame the TCP header can start for 1900 * firmware assisted TSO to work. 1901 */ 1902 encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT; 1903 1904 /* 1905 * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use 1906 * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available 1907 * resources (allocated to this PCIe function), which is zero until 1908 * after we have allocated VIs. 1909 */ 1910 encp->enc_evq_limit = 1024; 1911 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET; 1912 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET; 1913 1914 encp->enc_buftbl_limit = 0xFFFFFFFF; 1915 1916 /* Get interrupt vector limits */ 1917 if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) { 1918 if (EFX_PCI_FUNCTION_IS_PF(encp)) 1919 goto fail9; 1920 1921 /* Ignore error (cannot query vector limits from a VF). */ 1922 base = 0; 1923 nvec = 1024; 1924 } 1925 encp->enc_intr_vec_base = base; 1926 encp->enc_intr_limit = nvec; 1927 1928 /* 1929 * Get the current privilege mask. Note that this may be modified 1930 * dynamically, so this value is informational only. DO NOT use 1931 * the privilege mask to check for sufficient privileges, as that 1932 * can result in time-of-check/time-of-use bugs. 1933 */ 1934 if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0) 1935 goto fail10; 1936 encp->enc_privilege_mask = mask; 1937 1938 /* Get remaining controller-specific board config */ 1939 if ((rc = enop->eno_board_cfg(enp)) != 0) 1940 if (rc != EACCES) 1941 goto fail11; 1942 1943 return (0); 1944 1945 fail11: 1946 EFSYS_PROBE(fail11); 1947 fail10: 1948 EFSYS_PROBE(fail10); 1949 fail9: 1950 EFSYS_PROBE(fail9); 1951 fail8: 1952 EFSYS_PROBE(fail8); 1953 fail7: 1954 EFSYS_PROBE(fail7); 1955 fail6: 1956 EFSYS_PROBE(fail6); 1957 fail5: 1958 EFSYS_PROBE(fail5); 1959 fail4: 1960 EFSYS_PROBE(fail4); 1961 fail3: 1962 EFSYS_PROBE(fail3); 1963 fail2: 1964 EFSYS_PROBE(fail2); 1965 fail1: 1966 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1967 1968 return (rc); 1969 } 1970 1971 __checkReturn efx_rc_t 1972 ef10_nic_probe( 1973 __in efx_nic_t *enp) 1974 { 1975 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1976 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1977 efx_rc_t rc; 1978 1979 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1980 enp->en_family == EFX_FAMILY_MEDFORD || 1981 enp->en_family == EFX_FAMILY_MEDFORD2); 1982 1983 /* Read and clear any assertion state */ 1984 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1985 goto fail1; 1986 1987 /* Exit the assertion handler */ 1988 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1989 if (rc != EACCES) 1990 goto fail2; 1991 1992 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 1993 goto fail3; 1994 1995 if ((rc = ef10_nic_board_cfg(enp)) != 0) 1996 goto fail4; 1997 1998 /* 1999 * Set default driver config limits (based on board config). 2000 * 2001 * FIXME: For now allocate a fixed number of VIs which is likely to be 2002 * sufficient and small enough to allow multiple functions on the same 2003 * port. 2004 */ 2005 edcp->edc_min_vi_count = edcp->edc_max_vi_count = 2006 MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit)); 2007 2008 /* The client driver must configure and enable PIO buffer support */ 2009 edcp->edc_max_piobuf_count = 0; 2010 edcp->edc_pio_alloc_size = 0; 2011 2012 #if EFSYS_OPT_MAC_STATS 2013 /* Wipe the MAC statistics */ 2014 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 2015 goto fail5; 2016 #endif 2017 2018 #if EFSYS_OPT_LOOPBACK 2019 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 2020 goto fail6; 2021 #endif 2022 2023 #if EFSYS_OPT_MON_STATS 2024 if ((rc = mcdi_mon_cfg_build(enp)) != 0) { 2025 /* Unprivileged functions do not have access to sensors */ 2026 if (rc != EACCES) 2027 goto fail7; 2028 } 2029 #endif 2030 2031 encp->enc_features = enp->en_features; 2032 2033 return (0); 2034 2035 #if EFSYS_OPT_MON_STATS 2036 fail7: 2037 EFSYS_PROBE(fail7); 2038 #endif 2039 #if EFSYS_OPT_LOOPBACK 2040 fail6: 2041 EFSYS_PROBE(fail6); 2042 #endif 2043 #if EFSYS_OPT_MAC_STATS 2044 fail5: 2045 EFSYS_PROBE(fail5); 2046 #endif 2047 fail4: 2048 EFSYS_PROBE(fail4); 2049 fail3: 2050 EFSYS_PROBE(fail3); 2051 fail2: 2052 EFSYS_PROBE(fail2); 2053 fail1: 2054 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2055 2056 return (rc); 2057 } 2058 2059 __checkReturn efx_rc_t 2060 ef10_nic_set_drv_limits( 2061 __inout efx_nic_t *enp, 2062 __in efx_drv_limits_t *edlp) 2063 { 2064 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 2065 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 2066 uint32_t min_evq_count, max_evq_count; 2067 uint32_t min_rxq_count, max_rxq_count; 2068 uint32_t min_txq_count, max_txq_count; 2069 efx_rc_t rc; 2070 2071 if (edlp == NULL) { 2072 rc = EINVAL; 2073 goto fail1; 2074 } 2075 2076 /* Get minimum required and maximum usable VI limits */ 2077 min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit); 2078 min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit); 2079 min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit); 2080 2081 edcp->edc_min_vi_count = 2082 MAX(min_evq_count, MAX(min_rxq_count, min_txq_count)); 2083 2084 max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit); 2085 max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit); 2086 max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit); 2087 2088 edcp->edc_max_vi_count = 2089 MAX(max_evq_count, MAX(max_rxq_count, max_txq_count)); 2090 2091 /* 2092 * Check limits for sub-allocated piobuf blocks. 2093 * PIO is optional, so don't fail if the limits are incorrect. 2094 */ 2095 if ((encp->enc_piobuf_size == 0) || 2096 (encp->enc_piobuf_limit == 0) || 2097 (edlp->edl_min_pio_alloc_size == 0) || 2098 (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) { 2099 /* Disable PIO */ 2100 edcp->edc_max_piobuf_count = 0; 2101 edcp->edc_pio_alloc_size = 0; 2102 } else { 2103 uint32_t blk_size, blk_count, blks_per_piobuf; 2104 2105 blk_size = 2106 MAX(edlp->edl_min_pio_alloc_size, 2107 encp->enc_piobuf_min_alloc_size); 2108 2109 blks_per_piobuf = encp->enc_piobuf_size / blk_size; 2110 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32); 2111 2112 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf); 2113 2114 /* A zero max pio alloc count means unlimited */ 2115 if ((edlp->edl_max_pio_alloc_count > 0) && 2116 (edlp->edl_max_pio_alloc_count < blk_count)) { 2117 blk_count = edlp->edl_max_pio_alloc_count; 2118 } 2119 2120 edcp->edc_pio_alloc_size = blk_size; 2121 edcp->edc_max_piobuf_count = 2122 (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf; 2123 } 2124 2125 return (0); 2126 2127 fail1: 2128 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2129 2130 return (rc); 2131 } 2132 2133 __checkReturn efx_rc_t 2134 ef10_nic_reset( 2135 __in efx_nic_t *enp) 2136 { 2137 efx_mcdi_req_t req; 2138 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN, 2139 MC_CMD_ENTITY_RESET_OUT_LEN); 2140 efx_rc_t rc; 2141 2142 /* ef10_nic_reset() is called to recover from BADASSERT failures. */ 2143 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 2144 goto fail1; 2145 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 2146 goto fail2; 2147 2148 req.emr_cmd = MC_CMD_ENTITY_RESET; 2149 req.emr_in_buf = payload; 2150 req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; 2151 req.emr_out_buf = payload; 2152 req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; 2153 2154 MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, 2155 ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); 2156 2157 efx_mcdi_execute(enp, &req); 2158 2159 if (req.emr_rc != 0) { 2160 rc = req.emr_rc; 2161 goto fail3; 2162 } 2163 2164 /* Clear RX/TX DMA queue errors */ 2165 enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR); 2166 2167 return (0); 2168 2169 fail3: 2170 EFSYS_PROBE(fail3); 2171 fail2: 2172 EFSYS_PROBE(fail2); 2173 fail1: 2174 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2175 2176 return (rc); 2177 } 2178 2179 __checkReturn efx_rc_t 2180 ef10_nic_init( 2181 __in efx_nic_t *enp) 2182 { 2183 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 2184 uint32_t min_vi_count, max_vi_count; 2185 uint32_t vi_count, vi_base, vi_shift; 2186 uint32_t i; 2187 uint32_t retry; 2188 uint32_t delay_us; 2189 uint32_t vi_window_size; 2190 efx_rc_t rc; 2191 2192 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2193 enp->en_family == EFX_FAMILY_MEDFORD || 2194 enp->en_family == EFX_FAMILY_MEDFORD2); 2195 2196 /* Enable reporting of some events (e.g. link change) */ 2197 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 2198 goto fail1; 2199 2200 /* Allocate (optional) on-chip PIO buffers */ 2201 ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count); 2202 2203 /* 2204 * For best performance, PIO writes should use a write-combined 2205 * (WC) memory mapping. Using a separate WC mapping for the PIO 2206 * aperture of each VI would be a burden to drivers (and not 2207 * possible if the host page size is >4Kbyte). 2208 * 2209 * To avoid this we use a single uncached (UC) mapping for VI 2210 * register access, and a single WC mapping for extra VIs used 2211 * for PIO writes. 2212 * 2213 * Each piobuf must be linked to a VI in the WC mapping, and to 2214 * each VI that is using a sub-allocated block from the piobuf. 2215 */ 2216 min_vi_count = edcp->edc_min_vi_count; 2217 max_vi_count = 2218 edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count; 2219 2220 /* Ensure that the previously attached driver's VIs are freed */ 2221 if ((rc = efx_mcdi_free_vis(enp)) != 0) 2222 goto fail2; 2223 2224 /* 2225 * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this 2226 * fails then retrying the request for fewer VI resources may succeed. 2227 */ 2228 vi_count = 0; 2229 if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count, 2230 &vi_base, &vi_count, &vi_shift)) != 0) 2231 goto fail3; 2232 2233 EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count); 2234 2235 if (vi_count < min_vi_count) { 2236 rc = ENOMEM; 2237 goto fail4; 2238 } 2239 2240 enp->en_arch.ef10.ena_vi_base = vi_base; 2241 enp->en_arch.ef10.ena_vi_count = vi_count; 2242 enp->en_arch.ef10.ena_vi_shift = vi_shift; 2243 2244 if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) { 2245 /* Not enough extra VIs to map piobufs */ 2246 ef10_nic_free_piobufs(enp); 2247 } 2248 2249 enp->en_arch.ef10.ena_pio_write_vi_base = 2250 vi_count - enp->en_arch.ef10.ena_piobuf_count; 2251 2252 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=, 2253 EFX_VI_WINDOW_SHIFT_INVALID); 2254 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=, 2255 EFX_VI_WINDOW_SHIFT_64K); 2256 vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift; 2257 2258 /* Save UC memory mapping details */ 2259 enp->en_arch.ef10.ena_uc_mem_map_offset = 0; 2260 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2261 enp->en_arch.ef10.ena_uc_mem_map_size = 2262 (vi_window_size * 2263 enp->en_arch.ef10.ena_pio_write_vi_base); 2264 } else { 2265 enp->en_arch.ef10.ena_uc_mem_map_size = 2266 (vi_window_size * 2267 enp->en_arch.ef10.ena_vi_count); 2268 } 2269 2270 /* Save WC memory mapping details */ 2271 enp->en_arch.ef10.ena_wc_mem_map_offset = 2272 enp->en_arch.ef10.ena_uc_mem_map_offset + 2273 enp->en_arch.ef10.ena_uc_mem_map_size; 2274 2275 enp->en_arch.ef10.ena_wc_mem_map_size = 2276 (vi_window_size * 2277 enp->en_arch.ef10.ena_piobuf_count); 2278 2279 /* Link piobufs to extra VIs in WC mapping */ 2280 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2281 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 2282 rc = efx_mcdi_link_piobuf(enp, 2283 enp->en_arch.ef10.ena_pio_write_vi_base + i, 2284 enp->en_arch.ef10.ena_piobuf_handle[i]); 2285 if (rc != 0) 2286 break; 2287 } 2288 } 2289 2290 /* 2291 * Allocate a vAdaptor attached to our upstream vPort/pPort. 2292 * 2293 * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF 2294 * driver has yet to bring up the EVB port. See bug 56147. In this case, 2295 * retry the request several times after waiting a while. The wait time 2296 * between retries starts small (10ms) and exponentially increases. 2297 * Total wait time is a little over two seconds. Retry logic in the 2298 * client driver may mean this whole loop is repeated if it continues to 2299 * fail. 2300 */ 2301 retry = 0; 2302 delay_us = 10000; 2303 while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { 2304 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || 2305 (rc != ENOENT)) { 2306 /* 2307 * Do not retry alloc for PF, or for other errors on 2308 * a VF. 2309 */ 2310 goto fail5; 2311 } 2312 2313 /* VF startup before PF is ready. Retry allocation. */ 2314 if (retry > 5) { 2315 /* Too many attempts */ 2316 rc = EINVAL; 2317 goto fail6; 2318 } 2319 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); 2320 EFSYS_SLEEP(delay_us); 2321 retry++; 2322 if (delay_us < 500000) 2323 delay_us <<= 2; 2324 } 2325 2326 enp->en_vport_id = EVB_PORT_ID_ASSIGNED; 2327 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2; 2328 2329 return (0); 2330 2331 fail6: 2332 EFSYS_PROBE(fail6); 2333 fail5: 2334 EFSYS_PROBE(fail5); 2335 fail4: 2336 EFSYS_PROBE(fail4); 2337 fail3: 2338 EFSYS_PROBE(fail3); 2339 fail2: 2340 EFSYS_PROBE(fail2); 2341 2342 ef10_nic_free_piobufs(enp); 2343 2344 fail1: 2345 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2346 2347 return (rc); 2348 } 2349 2350 __checkReturn efx_rc_t 2351 ef10_nic_get_vi_pool( 2352 __in efx_nic_t *enp, 2353 __out uint32_t *vi_countp) 2354 { 2355 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2356 enp->en_family == EFX_FAMILY_MEDFORD || 2357 enp->en_family == EFX_FAMILY_MEDFORD2); 2358 2359 /* 2360 * Report VIs that the client driver can use. 2361 * Do not include VIs used for PIO buffer writes. 2362 */ 2363 *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base; 2364 2365 return (0); 2366 } 2367 2368 __checkReturn efx_rc_t 2369 ef10_nic_get_bar_region( 2370 __in efx_nic_t *enp, 2371 __in efx_nic_region_t region, 2372 __out uint32_t *offsetp, 2373 __out size_t *sizep) 2374 { 2375 efx_rc_t rc; 2376 2377 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2378 enp->en_family == EFX_FAMILY_MEDFORD || 2379 enp->en_family == EFX_FAMILY_MEDFORD2); 2380 2381 /* 2382 * TODO: Specify host memory mapping alignment and granularity 2383 * in efx_drv_limits_t so that they can be taken into account 2384 * when allocating extra VIs for PIO writes. 2385 */ 2386 switch (region) { 2387 case EFX_REGION_VI: 2388 /* UC mapped memory BAR region for VI registers */ 2389 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset; 2390 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size; 2391 break; 2392 2393 case EFX_REGION_PIO_WRITE_VI: 2394 /* WC mapped memory BAR region for piobuf writes */ 2395 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset; 2396 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size; 2397 break; 2398 2399 default: 2400 rc = EINVAL; 2401 goto fail1; 2402 } 2403 2404 return (0); 2405 2406 fail1: 2407 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2408 2409 return (rc); 2410 } 2411 2412 __checkReturn boolean_t 2413 ef10_nic_hw_unavailable( 2414 __in efx_nic_t *enp) 2415 { 2416 efx_dword_t dword; 2417 2418 if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL) 2419 return (B_TRUE); 2420 2421 EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE); 2422 if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff) 2423 goto unavail; 2424 2425 return (B_FALSE); 2426 2427 unavail: 2428 ef10_nic_set_hw_unavailable(enp); 2429 2430 return (B_TRUE); 2431 } 2432 2433 void 2434 ef10_nic_set_hw_unavailable( 2435 __in efx_nic_t *enp) 2436 { 2437 EFSYS_PROBE(hw_unavail); 2438 enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL; 2439 } 2440 2441 void 2442 ef10_nic_fini( 2443 __in efx_nic_t *enp) 2444 { 2445 uint32_t i; 2446 efx_rc_t rc; 2447 2448 (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id); 2449 enp->en_vport_id = 0; 2450 2451 /* Unlink piobufs from extra VIs in WC mapping */ 2452 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2453 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 2454 rc = efx_mcdi_unlink_piobuf(enp, 2455 enp->en_arch.ef10.ena_pio_write_vi_base + i); 2456 if (rc != 0) 2457 break; 2458 } 2459 } 2460 2461 ef10_nic_free_piobufs(enp); 2462 2463 (void) efx_mcdi_free_vis(enp); 2464 enp->en_arch.ef10.ena_vi_count = 0; 2465 } 2466 2467 void 2468 ef10_nic_unprobe( 2469 __in efx_nic_t *enp) 2470 { 2471 #if EFSYS_OPT_MON_STATS 2472 mcdi_mon_cfg_free(enp); 2473 #endif /* EFSYS_OPT_MON_STATS */ 2474 (void) efx_mcdi_drv_attach(enp, B_FALSE); 2475 } 2476 2477 #if EFSYS_OPT_DIAG 2478 2479 __checkReturn efx_rc_t 2480 ef10_nic_register_test( 2481 __in efx_nic_t *enp) 2482 { 2483 efx_rc_t rc; 2484 2485 /* FIXME */ 2486 _NOTE(ARGUNUSED(enp)) 2487 _NOTE(CONSTANTCONDITION) 2488 if (B_FALSE) { 2489 rc = ENOTSUP; 2490 goto fail1; 2491 } 2492 /* FIXME */ 2493 2494 return (0); 2495 2496 fail1: 2497 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2498 2499 return (rc); 2500 } 2501 2502 #endif /* EFSYS_OPT_DIAG */ 2503 2504 #if EFSYS_OPT_FW_SUBVARIANT_AWARE 2505 2506 __checkReturn efx_rc_t 2507 efx_mcdi_get_nic_global( 2508 __in efx_nic_t *enp, 2509 __in uint32_t key, 2510 __out uint32_t *valuep) 2511 { 2512 efx_mcdi_req_t req; 2513 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN, 2514 MC_CMD_GET_NIC_GLOBAL_OUT_LEN); 2515 efx_rc_t rc; 2516 2517 req.emr_cmd = MC_CMD_GET_NIC_GLOBAL; 2518 req.emr_in_buf = payload; 2519 req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN; 2520 req.emr_out_buf = payload; 2521 req.emr_out_length = MC_CMD_GET_NIC_GLOBAL_OUT_LEN; 2522 2523 MCDI_IN_SET_DWORD(req, GET_NIC_GLOBAL_IN_KEY, key); 2524 2525 efx_mcdi_execute(enp, &req); 2526 2527 if (req.emr_rc != 0) { 2528 rc = req.emr_rc; 2529 goto fail1; 2530 } 2531 2532 if (req.emr_out_length_used != MC_CMD_GET_NIC_GLOBAL_OUT_LEN) { 2533 rc = EMSGSIZE; 2534 goto fail2; 2535 } 2536 2537 *valuep = MCDI_OUT_DWORD(req, GET_NIC_GLOBAL_OUT_VALUE); 2538 2539 return (0); 2540 2541 fail2: 2542 EFSYS_PROBE(fail2); 2543 fail1: 2544 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2545 2546 return (rc); 2547 } 2548 2549 __checkReturn efx_rc_t 2550 efx_mcdi_set_nic_global( 2551 __in efx_nic_t *enp, 2552 __in uint32_t key, 2553 __in uint32_t value) 2554 { 2555 efx_mcdi_req_t req; 2556 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0); 2557 efx_rc_t rc; 2558 2559 req.emr_cmd = MC_CMD_SET_NIC_GLOBAL; 2560 req.emr_in_buf = payload; 2561 req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN; 2562 req.emr_out_buf = NULL; 2563 req.emr_out_length = 0; 2564 2565 MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_KEY, key); 2566 MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_VALUE, value); 2567 2568 efx_mcdi_execute(enp, &req); 2569 2570 if (req.emr_rc != 0) { 2571 rc = req.emr_rc; 2572 goto fail1; 2573 } 2574 2575 return (0); 2576 2577 fail1: 2578 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2579 2580 return (rc); 2581 } 2582 2583 #endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */ 2584 2585 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ 2586