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 673 static __checkReturn efx_rc_t 674 efx_mcdi_free_vis( 675 __in efx_nic_t *enp) 676 { 677 efx_mcdi_req_t req; 678 efx_rc_t rc; 679 680 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0); 681 EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0); 682 683 req.emr_cmd = MC_CMD_FREE_VIS; 684 req.emr_in_buf = NULL; 685 req.emr_in_length = 0; 686 req.emr_out_buf = NULL; 687 req.emr_out_length = 0; 688 689 efx_mcdi_execute_quiet(enp, &req); 690 691 /* Ignore ELREADY (no allocated VIs, so nothing to free) */ 692 if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) { 693 rc = req.emr_rc; 694 goto fail1; 695 } 696 697 return (0); 698 699 fail1: 700 EFSYS_PROBE1(fail1, efx_rc_t, rc); 701 702 return (rc); 703 } 704 705 706 static __checkReturn efx_rc_t 707 efx_mcdi_alloc_piobuf( 708 __in efx_nic_t *enp, 709 __out efx_piobuf_handle_t *handlep) 710 { 711 efx_mcdi_req_t req; 712 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN, 713 MC_CMD_ALLOC_PIOBUF_OUT_LEN); 714 efx_rc_t rc; 715 716 if (handlep == NULL) { 717 rc = EINVAL; 718 goto fail1; 719 } 720 721 req.emr_cmd = MC_CMD_ALLOC_PIOBUF; 722 req.emr_in_buf = payload; 723 req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN; 724 req.emr_out_buf = payload; 725 req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN; 726 727 efx_mcdi_execute_quiet(enp, &req); 728 729 if (req.emr_rc != 0) { 730 rc = req.emr_rc; 731 goto fail2; 732 } 733 734 if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) { 735 rc = EMSGSIZE; 736 goto fail3; 737 } 738 739 *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE); 740 741 return (0); 742 743 fail3: 744 EFSYS_PROBE(fail3); 745 fail2: 746 EFSYS_PROBE(fail2); 747 fail1: 748 EFSYS_PROBE1(fail1, efx_rc_t, rc); 749 750 return (rc); 751 } 752 753 static __checkReturn efx_rc_t 754 efx_mcdi_free_piobuf( 755 __in efx_nic_t *enp, 756 __in efx_piobuf_handle_t handle) 757 { 758 efx_mcdi_req_t req; 759 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN, 760 MC_CMD_FREE_PIOBUF_OUT_LEN); 761 efx_rc_t rc; 762 763 req.emr_cmd = MC_CMD_FREE_PIOBUF; 764 req.emr_in_buf = payload; 765 req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN; 766 req.emr_out_buf = payload; 767 req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN; 768 769 MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle); 770 771 efx_mcdi_execute_quiet(enp, &req); 772 773 if (req.emr_rc != 0) { 774 rc = req.emr_rc; 775 goto fail1; 776 } 777 778 return (0); 779 780 fail1: 781 EFSYS_PROBE1(fail1, efx_rc_t, rc); 782 783 return (rc); 784 } 785 786 static __checkReturn efx_rc_t 787 efx_mcdi_link_piobuf( 788 __in efx_nic_t *enp, 789 __in uint32_t vi_index, 790 __in efx_piobuf_handle_t handle) 791 { 792 efx_mcdi_req_t req; 793 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN, 794 MC_CMD_LINK_PIOBUF_OUT_LEN); 795 efx_rc_t rc; 796 797 req.emr_cmd = MC_CMD_LINK_PIOBUF; 798 req.emr_in_buf = payload; 799 req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN; 800 req.emr_out_buf = payload; 801 req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN; 802 803 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle); 804 MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 805 806 efx_mcdi_execute(enp, &req); 807 808 if (req.emr_rc != 0) { 809 rc = req.emr_rc; 810 goto fail1; 811 } 812 813 return (0); 814 815 fail1: 816 EFSYS_PROBE1(fail1, efx_rc_t, rc); 817 818 return (rc); 819 } 820 821 static __checkReturn efx_rc_t 822 efx_mcdi_unlink_piobuf( 823 __in efx_nic_t *enp, 824 __in uint32_t vi_index) 825 { 826 efx_mcdi_req_t req; 827 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN, 828 MC_CMD_UNLINK_PIOBUF_OUT_LEN); 829 efx_rc_t rc; 830 831 req.emr_cmd = MC_CMD_UNLINK_PIOBUF; 832 req.emr_in_buf = payload; 833 req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN; 834 req.emr_out_buf = payload; 835 req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN; 836 837 MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index); 838 839 efx_mcdi_execute_quiet(enp, &req); 840 841 if (req.emr_rc != 0) { 842 rc = req.emr_rc; 843 goto fail1; 844 } 845 846 return (0); 847 848 fail1: 849 EFSYS_PROBE1(fail1, efx_rc_t, rc); 850 851 return (rc); 852 } 853 854 static void 855 ef10_nic_alloc_piobufs( 856 __in efx_nic_t *enp, 857 __in uint32_t max_piobuf_count) 858 { 859 efx_piobuf_handle_t *handlep; 860 unsigned int i; 861 862 EFSYS_ASSERT3U(max_piobuf_count, <=, 863 EFX_ARRAY_SIZE(enp->en_arch.ef10.ena_piobuf_handle)); 864 865 enp->en_arch.ef10.ena_piobuf_count = 0; 866 867 for (i = 0; i < max_piobuf_count; i++) { 868 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 869 870 if (efx_mcdi_alloc_piobuf(enp, handlep) != 0) 871 goto fail1; 872 873 enp->en_arch.ef10.ena_pio_alloc_map[i] = 0; 874 enp->en_arch.ef10.ena_piobuf_count++; 875 } 876 877 return; 878 879 fail1: 880 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 881 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 882 883 (void) efx_mcdi_free_piobuf(enp, *handlep); 884 *handlep = EFX_PIOBUF_HANDLE_INVALID; 885 } 886 enp->en_arch.ef10.ena_piobuf_count = 0; 887 } 888 889 890 static void 891 ef10_nic_free_piobufs( 892 __in efx_nic_t *enp) 893 { 894 efx_piobuf_handle_t *handlep; 895 unsigned int i; 896 897 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 898 handlep = &enp->en_arch.ef10.ena_piobuf_handle[i]; 899 900 (void) efx_mcdi_free_piobuf(enp, *handlep); 901 *handlep = EFX_PIOBUF_HANDLE_INVALID; 902 } 903 enp->en_arch.ef10.ena_piobuf_count = 0; 904 } 905 906 /* Sub-allocate a block from a piobuf */ 907 __checkReturn efx_rc_t 908 ef10_nic_pio_alloc( 909 __inout efx_nic_t *enp, 910 __out uint32_t *bufnump, 911 __out efx_piobuf_handle_t *handlep, 912 __out uint32_t *blknump, 913 __out uint32_t *offsetp, 914 __out size_t *sizep) 915 { 916 efx_nic_cfg_t *encp = &enp->en_nic_cfg; 917 efx_drv_cfg_t *edcp = &enp->en_drv_cfg; 918 uint32_t blk_per_buf; 919 uint32_t buf, blk; 920 efx_rc_t rc; 921 922 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 923 enp->en_family == EFX_FAMILY_MEDFORD || 924 enp->en_family == EFX_FAMILY_MEDFORD2); 925 EFSYS_ASSERT(bufnump); 926 EFSYS_ASSERT(handlep); 927 EFSYS_ASSERT(blknump); 928 EFSYS_ASSERT(offsetp); 929 EFSYS_ASSERT(sizep); 930 931 if ((edcp->edc_pio_alloc_size == 0) || 932 (enp->en_arch.ef10.ena_piobuf_count == 0)) { 933 rc = ENOMEM; 934 goto fail1; 935 } 936 blk_per_buf = encp->enc_piobuf_size / edcp->edc_pio_alloc_size; 937 938 for (buf = 0; buf < enp->en_arch.ef10.ena_piobuf_count; buf++) { 939 uint32_t *map = &enp->en_arch.ef10.ena_pio_alloc_map[buf]; 940 941 if (~(*map) == 0) 942 continue; 943 944 EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map))); 945 for (blk = 0; blk < blk_per_buf; blk++) { 946 if ((*map & (1u << blk)) == 0) { 947 *map |= (1u << blk); 948 goto done; 949 } 950 } 951 } 952 rc = ENOMEM; 953 goto fail2; 954 955 done: 956 *handlep = enp->en_arch.ef10.ena_piobuf_handle[buf]; 957 *bufnump = buf; 958 *blknump = blk; 959 *sizep = edcp->edc_pio_alloc_size; 960 *offsetp = blk * (*sizep); 961 962 return (0); 963 964 fail2: 965 EFSYS_PROBE(fail2); 966 fail1: 967 EFSYS_PROBE1(fail1, efx_rc_t, rc); 968 969 return (rc); 970 } 971 972 /* Free a piobuf sub-allocated block */ 973 __checkReturn efx_rc_t 974 ef10_nic_pio_free( 975 __inout efx_nic_t *enp, 976 __in uint32_t bufnum, 977 __in uint32_t blknum) 978 { 979 uint32_t *map; 980 efx_rc_t rc; 981 982 if ((bufnum >= enp->en_arch.ef10.ena_piobuf_count) || 983 (blknum >= (8 * sizeof (*map)))) { 984 rc = EINVAL; 985 goto fail1; 986 } 987 988 map = &enp->en_arch.ef10.ena_pio_alloc_map[bufnum]; 989 if ((*map & (1u << blknum)) == 0) { 990 rc = ENOENT; 991 goto fail2; 992 } 993 *map &= ~(1u << blknum); 994 995 return (0); 996 997 fail2: 998 EFSYS_PROBE(fail2); 999 fail1: 1000 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1001 1002 return (rc); 1003 } 1004 1005 __checkReturn efx_rc_t 1006 ef10_nic_pio_link( 1007 __inout efx_nic_t *enp, 1008 __in uint32_t vi_index, 1009 __in efx_piobuf_handle_t handle) 1010 { 1011 return (efx_mcdi_link_piobuf(enp, vi_index, handle)); 1012 } 1013 1014 __checkReturn efx_rc_t 1015 ef10_nic_pio_unlink( 1016 __inout efx_nic_t *enp, 1017 __in uint32_t vi_index) 1018 { 1019 return (efx_mcdi_unlink_piobuf(enp, vi_index)); 1020 } 1021 1022 static __checkReturn efx_rc_t 1023 ef10_mcdi_get_pf_count( 1024 __in efx_nic_t *enp, 1025 __out uint32_t *pf_countp) 1026 { 1027 efx_mcdi_req_t req; 1028 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN, 1029 MC_CMD_GET_PF_COUNT_OUT_LEN); 1030 efx_rc_t rc; 1031 1032 req.emr_cmd = MC_CMD_GET_PF_COUNT; 1033 req.emr_in_buf = payload; 1034 req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN; 1035 req.emr_out_buf = payload; 1036 req.emr_out_length = MC_CMD_GET_PF_COUNT_OUT_LEN; 1037 1038 efx_mcdi_execute(enp, &req); 1039 1040 if (req.emr_rc != 0) { 1041 rc = req.emr_rc; 1042 goto fail1; 1043 } 1044 1045 if (req.emr_out_length_used < MC_CMD_GET_PF_COUNT_OUT_LEN) { 1046 rc = EMSGSIZE; 1047 goto fail2; 1048 } 1049 1050 *pf_countp = *MCDI_OUT(req, uint8_t, 1051 MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST); 1052 1053 EFSYS_ASSERT(*pf_countp != 0); 1054 1055 return (0); 1056 1057 fail2: 1058 EFSYS_PROBE(fail2); 1059 fail1: 1060 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1061 1062 return (rc); 1063 } 1064 1065 static __checkReturn efx_rc_t 1066 ef10_get_datapath_caps( 1067 __in efx_nic_t *enp) 1068 { 1069 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1070 efx_mcdi_req_t req; 1071 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN, 1072 MC_CMD_GET_CAPABILITIES_V5_OUT_LEN); 1073 efx_rc_t rc; 1074 1075 if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0) 1076 goto fail1; 1077 1078 1079 req.emr_cmd = MC_CMD_GET_CAPABILITIES; 1080 req.emr_in_buf = payload; 1081 req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; 1082 req.emr_out_buf = payload; 1083 req.emr_out_length = MC_CMD_GET_CAPABILITIES_V5_OUT_LEN; 1084 1085 efx_mcdi_execute_quiet(enp, &req); 1086 1087 if (req.emr_rc != 0) { 1088 rc = req.emr_rc; 1089 goto fail2; 1090 } 1091 1092 if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) { 1093 rc = EMSGSIZE; 1094 goto fail3; 1095 } 1096 1097 #define CAP_FLAGS1(_req, _flag) \ 1098 (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_OUT_FLAGS1) & \ 1099 (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN))) 1100 1101 #define CAP_FLAGS2(_req, _flag) \ 1102 (((_req).emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V2_OUT_LEN) && \ 1103 (MCDI_OUT_DWORD((_req), GET_CAPABILITIES_V2_OUT_FLAGS2) & \ 1104 (1u << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## _flag ## _LBN)))) 1105 1106 /* 1107 * Huntington RXDP firmware inserts a 0 or 14 byte prefix. 1108 * We only support the 14 byte prefix here. 1109 */ 1110 if (CAP_FLAGS1(req, RX_PREFIX_LEN_14) == 0) { 1111 rc = ENOTSUP; 1112 goto fail4; 1113 } 1114 encp->enc_rx_prefix_size = 14; 1115 1116 #if EFSYS_OPT_RX_SCALE 1117 /* Check if the firmware supports additional RSS modes */ 1118 if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES)) 1119 encp->enc_rx_scale_additional_modes_supported = B_TRUE; 1120 else 1121 encp->enc_rx_scale_additional_modes_supported = B_FALSE; 1122 #endif /* EFSYS_OPT_RX_SCALE */ 1123 1124 /* Check if the firmware supports TSO */ 1125 if (CAP_FLAGS1(req, TX_TSO)) 1126 encp->enc_fw_assisted_tso_enabled = B_TRUE; 1127 else 1128 encp->enc_fw_assisted_tso_enabled = B_FALSE; 1129 1130 /* Check if the firmware supports FATSOv2 */ 1131 if (CAP_FLAGS2(req, TX_TSO_V2)) { 1132 encp->enc_fw_assisted_tso_v2_enabled = B_TRUE; 1133 encp->enc_fw_assisted_tso_v2_n_contexts = MCDI_OUT_WORD(req, 1134 GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS); 1135 } else { 1136 encp->enc_fw_assisted_tso_v2_enabled = B_FALSE; 1137 encp->enc_fw_assisted_tso_v2_n_contexts = 0; 1138 } 1139 1140 /* Check if the firmware supports FATSOv2 encap */ 1141 if (CAP_FLAGS2(req, TX_TSO_V2_ENCAP)) 1142 encp->enc_fw_assisted_tso_v2_encap_enabled = B_TRUE; 1143 else 1144 encp->enc_fw_assisted_tso_v2_encap_enabled = B_FALSE; 1145 1146 /* Check if the firmware has vadapter/vport/vswitch support */ 1147 if (CAP_FLAGS1(req, EVB)) 1148 encp->enc_datapath_cap_evb = B_TRUE; 1149 else 1150 encp->enc_datapath_cap_evb = B_FALSE; 1151 1152 /* Check if the firmware supports VLAN insertion */ 1153 if (CAP_FLAGS1(req, TX_VLAN_INSERTION)) 1154 encp->enc_hw_tx_insert_vlan_enabled = B_TRUE; 1155 else 1156 encp->enc_hw_tx_insert_vlan_enabled = B_FALSE; 1157 1158 /* Check if the firmware supports RX event batching */ 1159 if (CAP_FLAGS1(req, RX_BATCHING)) 1160 encp->enc_rx_batching_enabled = B_TRUE; 1161 else 1162 encp->enc_rx_batching_enabled = B_FALSE; 1163 1164 /* 1165 * Even if batching isn't reported as supported, we may still get 1166 * batched events. 1167 */ 1168 encp->enc_rx_batch_max = 16; 1169 1170 /* Check if the firmware supports disabling scatter on RXQs */ 1171 if (CAP_FLAGS1(req, RX_DISABLE_SCATTER)) 1172 encp->enc_rx_disable_scatter_supported = B_TRUE; 1173 else 1174 encp->enc_rx_disable_scatter_supported = B_FALSE; 1175 1176 /* Check if the firmware supports packed stream mode */ 1177 if (CAP_FLAGS1(req, RX_PACKED_STREAM)) 1178 encp->enc_rx_packed_stream_supported = B_TRUE; 1179 else 1180 encp->enc_rx_packed_stream_supported = B_FALSE; 1181 1182 /* 1183 * Check if the firmware supports configurable buffer sizes 1184 * for packed stream mode (otherwise buffer size is 1Mbyte) 1185 */ 1186 if (CAP_FLAGS1(req, RX_PACKED_STREAM_VAR_BUFFERS)) 1187 encp->enc_rx_var_packed_stream_supported = B_TRUE; 1188 else 1189 encp->enc_rx_var_packed_stream_supported = B_FALSE; 1190 1191 /* Check if the firmware supports equal stride super-buffer mode */ 1192 if (CAP_FLAGS2(req, EQUAL_STRIDE_SUPER_BUFFER)) 1193 encp->enc_rx_es_super_buffer_supported = B_TRUE; 1194 else 1195 encp->enc_rx_es_super_buffer_supported = B_FALSE; 1196 1197 /* Check if the firmware supports FW subvariant w/o Tx checksumming */ 1198 if (CAP_FLAGS2(req, FW_SUBVARIANT_NO_TX_CSUM)) 1199 encp->enc_fw_subvariant_no_tx_csum_supported = B_TRUE; 1200 else 1201 encp->enc_fw_subvariant_no_tx_csum_supported = B_FALSE; 1202 1203 /* Check if the firmware supports set mac with running filters */ 1204 if (CAP_FLAGS1(req, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED)) 1205 encp->enc_allow_set_mac_with_installed_filters = B_TRUE; 1206 else 1207 encp->enc_allow_set_mac_with_installed_filters = B_FALSE; 1208 1209 /* 1210 * Check if firmware supports the extended MC_CMD_SET_MAC, which allows 1211 * specifying which parameters to configure. 1212 */ 1213 if (CAP_FLAGS1(req, SET_MAC_ENHANCED)) 1214 encp->enc_enhanced_set_mac_supported = B_TRUE; 1215 else 1216 encp->enc_enhanced_set_mac_supported = B_FALSE; 1217 1218 /* 1219 * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows 1220 * us to let the firmware choose the settings to use on an EVQ. 1221 */ 1222 if (CAP_FLAGS2(req, INIT_EVQ_V2)) 1223 encp->enc_init_evq_v2_supported = B_TRUE; 1224 else 1225 encp->enc_init_evq_v2_supported = B_FALSE; 1226 1227 /* 1228 * Check if firmware-verified NVRAM updates must be used. 1229 * 1230 * The firmware trusted installer requires all NVRAM updates to use 1231 * version 2 of MC_CMD_NVRAM_UPDATE_START (to enable verified update) 1232 * and version 2 of MC_CMD_NVRAM_UPDATE_FINISH (to verify the updated 1233 * partition and report the result). 1234 */ 1235 if (CAP_FLAGS2(req, NVRAM_UPDATE_REPORT_VERIFY_RESULT)) 1236 encp->enc_nvram_update_verify_result_supported = B_TRUE; 1237 else 1238 encp->enc_nvram_update_verify_result_supported = B_FALSE; 1239 1240 /* 1241 * Check if firmware provides packet memory and Rx datapath 1242 * counters. 1243 */ 1244 if (CAP_FLAGS1(req, PM_AND_RXDP_COUNTERS)) 1245 encp->enc_pm_and_rxdp_counters = B_TRUE; 1246 else 1247 encp->enc_pm_and_rxdp_counters = B_FALSE; 1248 1249 /* 1250 * Check if the 40G MAC hardware is capable of reporting 1251 * statistics for Tx size bins. 1252 */ 1253 if (CAP_FLAGS2(req, MAC_STATS_40G_TX_SIZE_BINS)) 1254 encp->enc_mac_stats_40g_tx_size_bins = B_TRUE; 1255 else 1256 encp->enc_mac_stats_40g_tx_size_bins = B_FALSE; 1257 1258 /* 1259 * Check if firmware supports VXLAN and NVGRE tunnels. 1260 * The capability indicates Geneve protocol support as well. 1261 */ 1262 if (CAP_FLAGS1(req, VXLAN_NVGRE)) { 1263 encp->enc_tunnel_encapsulations_supported = 1264 (1u << EFX_TUNNEL_PROTOCOL_VXLAN) | 1265 (1u << EFX_TUNNEL_PROTOCOL_GENEVE) | 1266 (1u << EFX_TUNNEL_PROTOCOL_NVGRE); 1267 1268 EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES == 1269 MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM); 1270 encp->enc_tunnel_config_udp_entries_max = 1271 EFX_TUNNEL_MAXNENTRIES; 1272 } else { 1273 encp->enc_tunnel_config_udp_entries_max = 0; 1274 } 1275 1276 /* 1277 * Check if firmware reports the VI window mode. 1278 * Medford2 has a variable VI window size (8K, 16K or 64K). 1279 * Medford and Huntington have a fixed 8K VI window size. 1280 */ 1281 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) { 1282 uint8_t mode = 1283 MCDI_OUT_BYTE(req, GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); 1284 1285 switch (mode) { 1286 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K: 1287 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 1288 break; 1289 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K: 1290 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_16K; 1291 break; 1292 case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K: 1293 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_64K; 1294 break; 1295 default: 1296 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID; 1297 break; 1298 } 1299 } else if ((enp->en_family == EFX_FAMILY_HUNTINGTON) || 1300 (enp->en_family == EFX_FAMILY_MEDFORD)) { 1301 /* Huntington and Medford have fixed 8K window size */ 1302 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_8K; 1303 } else { 1304 encp->enc_vi_window_shift = EFX_VI_WINDOW_SHIFT_INVALID; 1305 } 1306 1307 /* Check if firmware supports extended MAC stats. */ 1308 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) { 1309 /* Extended stats buffer supported */ 1310 encp->enc_mac_stats_nstats = MCDI_OUT_WORD(req, 1311 GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS); 1312 } else { 1313 /* Use Siena-compatible legacy MAC stats */ 1314 encp->enc_mac_stats_nstats = MC_CMD_MAC_NSTATS; 1315 } 1316 1317 if (encp->enc_mac_stats_nstats >= MC_CMD_MAC_NSTATS_V2) 1318 encp->enc_fec_counters = B_TRUE; 1319 else 1320 encp->enc_fec_counters = B_FALSE; 1321 1322 /* Check if the firmware provides head-of-line blocking counters */ 1323 if (CAP_FLAGS2(req, RXDP_HLB_IDLE)) 1324 encp->enc_hlb_counters = B_TRUE; 1325 else 1326 encp->enc_hlb_counters = B_FALSE; 1327 1328 #if EFSYS_OPT_RX_SCALE 1329 if (CAP_FLAGS1(req, RX_RSS_LIMITED)) { 1330 /* Only one exclusive RSS context is available per port. */ 1331 encp->enc_rx_scale_max_exclusive_contexts = 1; 1332 1333 switch (enp->en_family) { 1334 case EFX_FAMILY_MEDFORD2: 1335 encp->enc_rx_scale_hash_alg_mask = 1336 (1U << EFX_RX_HASHALG_TOEPLITZ); 1337 break; 1338 1339 case EFX_FAMILY_MEDFORD: 1340 case EFX_FAMILY_HUNTINGTON: 1341 /* 1342 * Packed stream firmware variant maintains a 1343 * non-standard algorithm for hash computation. 1344 * It implies explicit XORing together 1345 * source + destination IP addresses (or last 1346 * four bytes in the case of IPv6) and using the 1347 * resulting value as the input to a Toeplitz hash. 1348 */ 1349 encp->enc_rx_scale_hash_alg_mask = 1350 (1U << EFX_RX_HASHALG_PACKED_STREAM); 1351 break; 1352 1353 default: 1354 rc = EINVAL; 1355 goto fail5; 1356 } 1357 1358 /* Port numbers cannot contribute to the hash value */ 1359 encp->enc_rx_scale_l4_hash_supported = B_FALSE; 1360 } else { 1361 /* 1362 * Maximum number of exclusive RSS contexts. 1363 * EF10 hardware supports 64 in total, but 6 are reserved 1364 * for shared contexts. They are a global resource so 1365 * not all may be available. 1366 */ 1367 encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; 1368 1369 encp->enc_rx_scale_hash_alg_mask = 1370 (1U << EFX_RX_HASHALG_TOEPLITZ); 1371 1372 /* 1373 * It is possible to use port numbers as 1374 * the input data for hash computation. 1375 */ 1376 encp->enc_rx_scale_l4_hash_supported = B_TRUE; 1377 } 1378 #endif /* EFSYS_OPT_RX_SCALE */ 1379 1380 /* Check if the firmware supports "FLAG" and "MARK" filter actions */ 1381 if (CAP_FLAGS2(req, FILTER_ACTION_FLAG)) 1382 encp->enc_filter_action_flag_supported = B_TRUE; 1383 else 1384 encp->enc_filter_action_flag_supported = B_FALSE; 1385 1386 if (CAP_FLAGS2(req, FILTER_ACTION_MARK)) 1387 encp->enc_filter_action_mark_supported = B_TRUE; 1388 else 1389 encp->enc_filter_action_mark_supported = B_FALSE; 1390 1391 /* Get maximum supported value for "MARK" filter action */ 1392 if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V5_OUT_LEN) 1393 encp->enc_filter_action_mark_max = MCDI_OUT_DWORD(req, 1394 GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX); 1395 else 1396 encp->enc_filter_action_mark_max = 0; 1397 1398 #undef CAP_FLAGS1 1399 #undef CAP_FLAGS2 1400 1401 return (0); 1402 1403 #if EFSYS_OPT_RX_SCALE 1404 fail5: 1405 EFSYS_PROBE(fail5); 1406 #endif /* EFSYS_OPT_RX_SCALE */ 1407 fail4: 1408 EFSYS_PROBE(fail4); 1409 fail3: 1410 EFSYS_PROBE(fail3); 1411 fail2: 1412 EFSYS_PROBE(fail2); 1413 fail1: 1414 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1415 1416 return (rc); 1417 } 1418 1419 1420 #define EF10_LEGACY_PF_PRIVILEGE_MASK \ 1421 (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \ 1422 MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK | \ 1423 MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD | \ 1424 MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP | \ 1425 MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS | \ 1426 MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING | \ 1427 MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST | \ 1428 MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST | \ 1429 MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST | \ 1430 MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \ 1431 MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS) 1432 1433 #define EF10_LEGACY_VF_PRIVILEGE_MASK 0 1434 1435 1436 __checkReturn efx_rc_t 1437 ef10_get_privilege_mask( 1438 __in efx_nic_t *enp, 1439 __out uint32_t *maskp) 1440 { 1441 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1442 uint32_t mask; 1443 efx_rc_t rc; 1444 1445 if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf, 1446 &mask)) != 0) { 1447 if (rc != ENOTSUP) 1448 goto fail1; 1449 1450 /* Fallback for old firmware without privilege mask support */ 1451 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1452 /* Assume PF has admin privilege */ 1453 mask = EF10_LEGACY_PF_PRIVILEGE_MASK; 1454 } else { 1455 /* VF is always unprivileged by default */ 1456 mask = EF10_LEGACY_VF_PRIVILEGE_MASK; 1457 } 1458 } 1459 1460 *maskp = mask; 1461 1462 return (0); 1463 1464 fail1: 1465 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1466 1467 return (rc); 1468 } 1469 1470 1471 #define EFX_EXT_PORT_MAX 4 1472 #define EFX_EXT_PORT_NA 0xFF 1473 1474 /* 1475 * Table of mapping schemes from port number to external number. 1476 * 1477 * Each port number ultimately corresponds to a connector: either as part of 1478 * a cable assembly attached to a module inserted in an SFP+/QSFP+ cage on 1479 * the board, or fixed to the board (e.g. 10GBASE-T magjack on SFN5121T 1480 * "Salina"). In general: 1481 * 1482 * Port number (0-based) 1483 * | 1484 * port mapping (n:1) 1485 * | 1486 * v 1487 * External port number (1-based) 1488 * | 1489 * fixed (1:1) or cable assembly (1:m) 1490 * | 1491 * v 1492 * Connector 1493 * 1494 * The external numbering refers to the cages or magjacks on the board, 1495 * as visibly annotated on the board or back panel. This table describes 1496 * how to determine which external cage/magjack corresponds to the port 1497 * numbers used by the driver. 1498 * 1499 * The count of consecutive port numbers that map to each external number, 1500 * is determined by the chip family and the current port mode. 1501 * 1502 * For the Huntington family, the current port mode cannot be discovered, 1503 * but a single mapping is used by all modes for a given chip variant, 1504 * so the mapping used is instead the last match in the table to the full 1505 * set of port modes to which the NIC can be configured. Therefore the 1506 * ordering of entries in the mapping table is significant. 1507 */ 1508 static struct ef10_external_port_map_s { 1509 efx_family_t family; 1510 uint32_t modes_mask; 1511 uint8_t base_port[EFX_EXT_PORT_MAX]; 1512 } __ef10_external_port_mappings[] = { 1513 /* 1514 * Modes used by Huntington family controllers where each port 1515 * number maps to a separate cage. 1516 * SFN7x22F (Torino): 1517 * port 0 -> cage 1 1518 * port 1 -> cage 2 1519 * SFN7xx4F (Pavia): 1520 * port 0 -> cage 1 1521 * port 1 -> cage 2 1522 * port 2 -> cage 3 1523 * port 3 -> cage 4 1524 */ 1525 { 1526 EFX_FAMILY_HUNTINGTON, 1527 (1U << TLV_PORT_MODE_10G) | /* mode 0 */ 1528 (1U << TLV_PORT_MODE_10G_10G) | /* mode 2 */ 1529 (1U << TLV_PORT_MODE_10G_10G_10G_10G), /* mode 4 */ 1530 { 0, 1, 2, 3 } 1531 }, 1532 /* 1533 * Modes which for Huntington identify a chip variant where 2 1534 * adjacent port numbers map to each cage. 1535 * SFN7x42Q (Monza): 1536 * port 0 -> cage 1 1537 * port 1 -> cage 1 1538 * port 2 -> cage 2 1539 * port 3 -> cage 2 1540 */ 1541 { 1542 EFX_FAMILY_HUNTINGTON, 1543 (1U << TLV_PORT_MODE_40G) | /* mode 1 */ 1544 (1U << TLV_PORT_MODE_40G_40G) | /* mode 3 */ 1545 (1U << TLV_PORT_MODE_40G_10G_10G) | /* mode 6 */ 1546 (1U << TLV_PORT_MODE_10G_10G_40G), /* mode 7 */ 1547 { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1548 }, 1549 /* 1550 * Modes that on Medford allocate each port number to a separate 1551 * cage. 1552 * port 0 -> cage 1 1553 * port 1 -> cage 2 1554 * port 2 -> cage 3 1555 * port 3 -> cage 4 1556 */ 1557 { 1558 EFX_FAMILY_MEDFORD, 1559 (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ 1560 (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */ 1561 { 0, 1, 2, 3 } 1562 }, 1563 /* 1564 * Modes that on Medford allocate 2 adjacent port numbers to each 1565 * cage. 1566 * port 0 -> cage 1 1567 * port 1 -> cage 1 1568 * port 2 -> cage 2 1569 * port 3 -> cage 2 1570 */ 1571 { 1572 EFX_FAMILY_MEDFORD, 1573 (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ 1574 (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */ 1575 (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */ 1576 (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ 1577 /* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */ 1578 (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), /* mode 9 */ 1579 { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1580 }, 1581 /* 1582 * Modes that on Medford allocate 4 adjacent port numbers to each 1583 * connector, starting on cage 1. 1584 * port 0 -> cage 1 1585 * port 1 -> cage 1 1586 * port 2 -> cage 1 1587 * port 3 -> cage 1 1588 */ 1589 { 1590 EFX_FAMILY_MEDFORD, 1591 (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 5 */ 1592 /* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */ 1593 (1U << TLV_PORT_MODE_4x1_NA), /* mode 4 */ 1594 { 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1595 }, 1596 /* 1597 * Modes that on Medford allocate 4 adjacent port numbers to each 1598 * connector, starting on cage 2. 1599 * port 0 -> cage 2 1600 * port 1 -> cage 2 1601 * port 2 -> cage 2 1602 * port 3 -> cage 2 1603 */ 1604 { 1605 EFX_FAMILY_MEDFORD, 1606 (1U << TLV_PORT_MODE_NA_4x1), /* mode 8 */ 1607 { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1608 }, 1609 /* 1610 * Modes that on Medford2 allocate each port number to a separate 1611 * cage. 1612 * port 0 -> cage 1 1613 * port 1 -> cage 2 1614 * port 2 -> cage 3 1615 * port 3 -> cage 4 1616 */ 1617 { 1618 EFX_FAMILY_MEDFORD2, 1619 (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ 1620 (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */ 1621 (1U << TLV_PORT_MODE_1x1_1x1) | /* mode 2 */ 1622 (1U << TLV_PORT_MODE_1x2_NA) | /* mode 10 */ 1623 (1U << TLV_PORT_MODE_1x2_1x2) | /* mode 12 */ 1624 (1U << TLV_PORT_MODE_1x4_1x2) | /* mode 15 */ 1625 (1U << TLV_PORT_MODE_1x2_1x4), /* mode 16 */ 1626 { 0, 1, 2, 3 } 1627 }, 1628 /* 1629 * Modes that on Medford2 allocate 1 port to cage 1 and the rest 1630 * to cage 2. 1631 * port 0 -> cage 1 1632 * port 1 -> cage 2 1633 * port 2 -> cage 2 1634 */ 1635 { 1636 EFX_FAMILY_MEDFORD2, 1637 (1U << TLV_PORT_MODE_1x2_2x1) | /* mode 17 */ 1638 (1U << TLV_PORT_MODE_1x4_2x1), /* mode 6 */ 1639 { 0, 1, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1640 }, 1641 /* 1642 * Modes that on Medford2 allocate 2 adjacent port numbers to each 1643 * cage, starting on cage 1. 1644 * port 0 -> cage 1 1645 * port 1 -> cage 1 1646 * port 2 -> cage 2 1647 * port 3 -> cage 2 1648 */ 1649 { 1650 EFX_FAMILY_MEDFORD2, 1651 (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */ 1652 (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 4 */ 1653 (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */ 1654 (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ 1655 (1U << TLV_PORT_MODE_2x2_NA) | /* mode 13 */ 1656 (1U << TLV_PORT_MODE_2x1_1x2), /* mode 18 */ 1657 { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1658 }, 1659 /* 1660 * Modes that on Medford2 allocate 2 adjacent port numbers to each 1661 * cage, starting on cage 2. 1662 * port 0 -> cage 2 1663 * port 1 -> cage 2 1664 */ 1665 { 1666 EFX_FAMILY_MEDFORD2, 1667 (1U << TLV_PORT_MODE_NA_2x2), /* mode 14 */ 1668 { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1669 }, 1670 /* 1671 * Modes that on Medford2 allocate 4 adjacent port numbers to each 1672 * connector, starting on cage 1. 1673 * port 0 -> cage 1 1674 * port 1 -> cage 1 1675 * port 2 -> cage 1 1676 * port 3 -> cage 1 1677 */ 1678 { 1679 EFX_FAMILY_MEDFORD2, 1680 (1U << TLV_PORT_MODE_4x1_NA), /* mode 5 */ 1681 { 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1682 }, 1683 /* 1684 * Modes that on Medford2 allocate 4 adjacent port numbers to each 1685 * connector, starting on cage 2. 1686 * port 0 -> cage 2 1687 * port 1 -> cage 2 1688 * port 2 -> cage 2 1689 * port 3 -> cage 2 1690 */ 1691 { 1692 EFX_FAMILY_MEDFORD2, 1693 (1U << TLV_PORT_MODE_NA_4x1) | /* mode 8 */ 1694 (1U << TLV_PORT_MODE_NA_1x2), /* mode 11 */ 1695 { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } 1696 }, 1697 }; 1698 1699 static __checkReturn efx_rc_t 1700 ef10_external_port_mapping( 1701 __in efx_nic_t *enp, 1702 __in uint32_t port, 1703 __out uint8_t *external_portp) 1704 { 1705 efx_rc_t rc; 1706 int i; 1707 uint32_t port_modes; 1708 uint32_t matches; 1709 uint32_t current; 1710 struct ef10_external_port_map_s *mapp = NULL; 1711 int ext_index = port; /* Default 1-1 mapping */ 1712 1713 if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t, 1714 NULL)) != 0) { 1715 /* 1716 * No current port mode information (i.e. Huntington) 1717 * - infer mapping from available modes 1718 */ 1719 if ((rc = efx_mcdi_get_port_modes(enp, 1720 &port_modes, NULL, NULL)) != 0) { 1721 /* 1722 * No port mode information available 1723 * - use default mapping 1724 */ 1725 goto out; 1726 } 1727 } else { 1728 /* Only need to scan the current mode */ 1729 port_modes = 1 << current; 1730 } 1731 1732 /* 1733 * Infer the internal port -> external number mapping from 1734 * the possible port modes for this NIC. 1735 */ 1736 for (i = 0; i < EFX_ARRAY_SIZE(__ef10_external_port_mappings); ++i) { 1737 struct ef10_external_port_map_s *eepmp = 1738 &__ef10_external_port_mappings[i]; 1739 if (eepmp->family != enp->en_family) 1740 continue; 1741 matches = (eepmp->modes_mask & port_modes); 1742 if (matches != 0) { 1743 /* 1744 * Some modes match. For some Huntington boards 1745 * there will be multiple matches. The mapping on the 1746 * last match is used. 1747 */ 1748 mapp = eepmp; 1749 port_modes &= ~matches; 1750 } 1751 } 1752 1753 if (port_modes != 0) { 1754 /* Some advertised modes are not supported */ 1755 rc = ENOTSUP; 1756 goto fail1; 1757 } 1758 1759 out: 1760 if (mapp != NULL) { 1761 /* 1762 * External ports are assigned a sequence of consecutive 1763 * port numbers, so find the one with the closest base_port. 1764 */ 1765 uint32_t delta = EFX_EXT_PORT_NA; 1766 1767 for (i = 0; i < EFX_EXT_PORT_MAX; i++) { 1768 uint32_t base = mapp->base_port[i]; 1769 if ((base != EFX_EXT_PORT_NA) && (base <= port)) { 1770 if ((port - base) < delta) { 1771 delta = (port - base); 1772 ext_index = i; 1773 } 1774 } 1775 } 1776 } 1777 *external_portp = (uint8_t)(ext_index + 1); 1778 1779 return (0); 1780 1781 fail1: 1782 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1783 1784 return (rc); 1785 } 1786 1787 static __checkReturn efx_rc_t 1788 ef10_nic_board_cfg( 1789 __in efx_nic_t *enp) 1790 { 1791 const efx_nic_ops_t *enop = enp->en_enop; 1792 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 1793 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1794 ef10_link_state_t els; 1795 efx_port_t *epp = &(enp->en_port); 1796 uint32_t board_type = 0; 1797 uint32_t base, nvec; 1798 uint32_t port; 1799 uint32_t mask; 1800 uint32_t pf; 1801 uint32_t vf; 1802 uint8_t mac_addr[6] = { 0 }; 1803 efx_rc_t rc; 1804 1805 /* Get the (zero-based) MCDI port number */ 1806 if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0) 1807 goto fail1; 1808 1809 /* EFX MCDI interface uses one-based port numbers */ 1810 emip->emi_port = port + 1; 1811 1812 if ((rc = ef10_external_port_mapping(enp, port, 1813 &encp->enc_external_port)) != 0) 1814 goto fail2; 1815 1816 /* 1817 * Get PCIe function number from firmware (used for 1818 * per-function privilege and dynamic config info). 1819 * - PCIe PF: pf = PF number, vf = 0xffff. 1820 * - PCIe VF: pf = parent PF, vf = VF number. 1821 */ 1822 if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0) 1823 goto fail3; 1824 1825 encp->enc_pf = pf; 1826 encp->enc_vf = vf; 1827 1828 /* MAC address for this function */ 1829 if (EFX_PCI_FUNCTION_IS_PF(encp)) { 1830 rc = efx_mcdi_get_mac_address_pf(enp, mac_addr); 1831 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 1832 /* 1833 * Disable static config checking, ONLY for manufacturing test 1834 * and setup at the factory, to allow the static config to be 1835 * installed. 1836 */ 1837 #else /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */ 1838 if ((rc == 0) && (mac_addr[0] & 0x02)) { 1839 /* 1840 * If the static config does not include a global MAC 1841 * address pool then the board may return a locally 1842 * administered MAC address (this should only happen on 1843 * incorrectly programmed boards). 1844 */ 1845 rc = EINVAL; 1846 } 1847 #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */ 1848 } else { 1849 rc = efx_mcdi_get_mac_address_vf(enp, mac_addr); 1850 } 1851 if (rc != 0) 1852 goto fail4; 1853 1854 EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr); 1855 1856 /* Board configuration (legacy) */ 1857 rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL); 1858 if (rc != 0) { 1859 /* Unprivileged functions may not be able to read board cfg */ 1860 if (rc == EACCES) 1861 board_type = 0; 1862 else 1863 goto fail5; 1864 } 1865 1866 encp->enc_board_type = board_type; 1867 encp->enc_clk_mult = 1; /* not used for EF10 */ 1868 1869 /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */ 1870 if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0) 1871 goto fail6; 1872 1873 /* 1874 * Firmware with support for *_FEC capability bits does not 1875 * report that the corresponding *_FEC_REQUESTED bits are supported. 1876 * Add them here so that drivers understand that they are supported. 1877 */ 1878 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_BASER_FEC)) 1879 epp->ep_phy_cap_mask |= 1880 (1u << EFX_PHY_CAP_BASER_FEC_REQUESTED); 1881 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_RS_FEC)) 1882 epp->ep_phy_cap_mask |= 1883 (1u << EFX_PHY_CAP_RS_FEC_REQUESTED); 1884 if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_25G_BASER_FEC)) 1885 epp->ep_phy_cap_mask |= 1886 (1u << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED); 1887 1888 /* Obtain the default PHY advertised capabilities */ 1889 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 1890 goto fail7; 1891 epp->ep_default_adv_cap_mask = els.epls.epls_adv_cap_mask; 1892 epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask; 1893 1894 /* Check capabilities of running datapath firmware */ 1895 if ((rc = ef10_get_datapath_caps(enp)) != 0) 1896 goto fail8; 1897 1898 /* Alignment for WPTR updates */ 1899 encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; 1900 1901 encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); 1902 /* No boundary crossing limits */ 1903 encp->enc_tx_dma_desc_boundary = 0; 1904 1905 /* 1906 * Maximum number of bytes into the frame the TCP header can start for 1907 * firmware assisted TSO to work. 1908 */ 1909 encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT; 1910 1911 /* 1912 * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use 1913 * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available 1914 * resources (allocated to this PCIe function), which is zero until 1915 * after we have allocated VIs. 1916 */ 1917 encp->enc_evq_limit = 1024; 1918 encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET; 1919 encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET; 1920 1921 encp->enc_buftbl_limit = 0xFFFFFFFF; 1922 1923 /* Get interrupt vector limits */ 1924 if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) { 1925 if (EFX_PCI_FUNCTION_IS_PF(encp)) 1926 goto fail9; 1927 1928 /* Ignore error (cannot query vector limits from a VF). */ 1929 base = 0; 1930 nvec = 1024; 1931 } 1932 encp->enc_intr_vec_base = base; 1933 encp->enc_intr_limit = nvec; 1934 1935 /* 1936 * Get the current privilege mask. Note that this may be modified 1937 * dynamically, so this value is informational only. DO NOT use 1938 * the privilege mask to check for sufficient privileges, as that 1939 * can result in time-of-check/time-of-use bugs. 1940 */ 1941 if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0) 1942 goto fail10; 1943 encp->enc_privilege_mask = mask; 1944 1945 /* Get remaining controller-specific board config */ 1946 if ((rc = enop->eno_board_cfg(enp)) != 0) 1947 if (rc != EACCES) 1948 goto fail11; 1949 1950 return (0); 1951 1952 fail11: 1953 EFSYS_PROBE(fail11); 1954 fail10: 1955 EFSYS_PROBE(fail10); 1956 fail9: 1957 EFSYS_PROBE(fail9); 1958 fail8: 1959 EFSYS_PROBE(fail8); 1960 fail7: 1961 EFSYS_PROBE(fail7); 1962 fail6: 1963 EFSYS_PROBE(fail6); 1964 fail5: 1965 EFSYS_PROBE(fail5); 1966 fail4: 1967 EFSYS_PROBE(fail4); 1968 fail3: 1969 EFSYS_PROBE(fail3); 1970 fail2: 1971 EFSYS_PROBE(fail2); 1972 fail1: 1973 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1974 1975 return (rc); 1976 } 1977 1978 __checkReturn efx_rc_t 1979 ef10_nic_probe( 1980 __in efx_nic_t *enp) 1981 { 1982 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1983 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 1984 efx_rc_t rc; 1985 1986 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 1987 enp->en_family == EFX_FAMILY_MEDFORD || 1988 enp->en_family == EFX_FAMILY_MEDFORD2); 1989 1990 /* Read and clear any assertion state */ 1991 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 1992 goto fail1; 1993 1994 /* Exit the assertion handler */ 1995 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 1996 if (rc != EACCES) 1997 goto fail2; 1998 1999 if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0) 2000 goto fail3; 2001 2002 if ((rc = ef10_nic_board_cfg(enp)) != 0) 2003 goto fail4; 2004 2005 /* 2006 * Set default driver config limits (based on board config). 2007 * 2008 * FIXME: For now allocate a fixed number of VIs which is likely to be 2009 * sufficient and small enough to allow multiple functions on the same 2010 * port. 2011 */ 2012 edcp->edc_min_vi_count = edcp->edc_max_vi_count = 2013 MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit)); 2014 2015 /* The client driver must configure and enable PIO buffer support */ 2016 edcp->edc_max_piobuf_count = 0; 2017 edcp->edc_pio_alloc_size = 0; 2018 2019 #if EFSYS_OPT_MAC_STATS 2020 /* Wipe the MAC statistics */ 2021 if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0) 2022 goto fail5; 2023 #endif 2024 2025 #if EFSYS_OPT_LOOPBACK 2026 if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0) 2027 goto fail6; 2028 #endif 2029 2030 #if EFSYS_OPT_MON_STATS 2031 if ((rc = mcdi_mon_cfg_build(enp)) != 0) { 2032 /* Unprivileged functions do not have access to sensors */ 2033 if (rc != EACCES) 2034 goto fail7; 2035 } 2036 #endif 2037 2038 encp->enc_features = enp->en_features; 2039 2040 return (0); 2041 2042 #if EFSYS_OPT_MON_STATS 2043 fail7: 2044 EFSYS_PROBE(fail7); 2045 #endif 2046 #if EFSYS_OPT_LOOPBACK 2047 fail6: 2048 EFSYS_PROBE(fail6); 2049 #endif 2050 #if EFSYS_OPT_MAC_STATS 2051 fail5: 2052 EFSYS_PROBE(fail5); 2053 #endif 2054 fail4: 2055 EFSYS_PROBE(fail4); 2056 fail3: 2057 EFSYS_PROBE(fail3); 2058 fail2: 2059 EFSYS_PROBE(fail2); 2060 fail1: 2061 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2062 2063 return (rc); 2064 } 2065 2066 __checkReturn efx_rc_t 2067 ef10_nic_set_drv_limits( 2068 __inout efx_nic_t *enp, 2069 __in efx_drv_limits_t *edlp) 2070 { 2071 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 2072 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 2073 uint32_t min_evq_count, max_evq_count; 2074 uint32_t min_rxq_count, max_rxq_count; 2075 uint32_t min_txq_count, max_txq_count; 2076 efx_rc_t rc; 2077 2078 if (edlp == NULL) { 2079 rc = EINVAL; 2080 goto fail1; 2081 } 2082 2083 /* Get minimum required and maximum usable VI limits */ 2084 min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit); 2085 min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit); 2086 min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit); 2087 2088 edcp->edc_min_vi_count = 2089 MAX(min_evq_count, MAX(min_rxq_count, min_txq_count)); 2090 2091 max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit); 2092 max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit); 2093 max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit); 2094 2095 edcp->edc_max_vi_count = 2096 MAX(max_evq_count, MAX(max_rxq_count, max_txq_count)); 2097 2098 /* 2099 * Check limits for sub-allocated piobuf blocks. 2100 * PIO is optional, so don't fail if the limits are incorrect. 2101 */ 2102 if ((encp->enc_piobuf_size == 0) || 2103 (encp->enc_piobuf_limit == 0) || 2104 (edlp->edl_min_pio_alloc_size == 0) || 2105 (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) { 2106 /* Disable PIO */ 2107 edcp->edc_max_piobuf_count = 0; 2108 edcp->edc_pio_alloc_size = 0; 2109 } else { 2110 uint32_t blk_size, blk_count, blks_per_piobuf; 2111 2112 blk_size = 2113 MAX(edlp->edl_min_pio_alloc_size, 2114 encp->enc_piobuf_min_alloc_size); 2115 2116 blks_per_piobuf = encp->enc_piobuf_size / blk_size; 2117 EFSYS_ASSERT3U(blks_per_piobuf, <=, 32); 2118 2119 blk_count = (encp->enc_piobuf_limit * blks_per_piobuf); 2120 2121 /* A zero max pio alloc count means unlimited */ 2122 if ((edlp->edl_max_pio_alloc_count > 0) && 2123 (edlp->edl_max_pio_alloc_count < blk_count)) { 2124 blk_count = edlp->edl_max_pio_alloc_count; 2125 } 2126 2127 edcp->edc_pio_alloc_size = blk_size; 2128 edcp->edc_max_piobuf_count = 2129 (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf; 2130 } 2131 2132 return (0); 2133 2134 fail1: 2135 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2136 2137 return (rc); 2138 } 2139 2140 2141 __checkReturn efx_rc_t 2142 ef10_nic_reset( 2143 __in efx_nic_t *enp) 2144 { 2145 efx_mcdi_req_t req; 2146 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN, 2147 MC_CMD_ENTITY_RESET_OUT_LEN); 2148 efx_rc_t rc; 2149 2150 /* ef10_nic_reset() is called to recover from BADASSERT failures. */ 2151 if ((rc = efx_mcdi_read_assertion(enp)) != 0) 2152 goto fail1; 2153 if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0) 2154 goto fail2; 2155 2156 req.emr_cmd = MC_CMD_ENTITY_RESET; 2157 req.emr_in_buf = payload; 2158 req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN; 2159 req.emr_out_buf = payload; 2160 req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN; 2161 2162 MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG, 2163 ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1); 2164 2165 efx_mcdi_execute(enp, &req); 2166 2167 if (req.emr_rc != 0) { 2168 rc = req.emr_rc; 2169 goto fail3; 2170 } 2171 2172 /* Clear RX/TX DMA queue errors */ 2173 enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR); 2174 2175 return (0); 2176 2177 fail3: 2178 EFSYS_PROBE(fail3); 2179 fail2: 2180 EFSYS_PROBE(fail2); 2181 fail1: 2182 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2183 2184 return (rc); 2185 } 2186 2187 __checkReturn efx_rc_t 2188 ef10_nic_init( 2189 __in efx_nic_t *enp) 2190 { 2191 efx_drv_cfg_t *edcp = &(enp->en_drv_cfg); 2192 uint32_t min_vi_count, max_vi_count; 2193 uint32_t vi_count, vi_base, vi_shift; 2194 uint32_t i; 2195 uint32_t retry; 2196 uint32_t delay_us; 2197 uint32_t vi_window_size; 2198 efx_rc_t rc; 2199 2200 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2201 enp->en_family == EFX_FAMILY_MEDFORD || 2202 enp->en_family == EFX_FAMILY_MEDFORD2); 2203 2204 /* Enable reporting of some events (e.g. link change) */ 2205 if ((rc = efx_mcdi_log_ctrl(enp)) != 0) 2206 goto fail1; 2207 2208 /* Allocate (optional) on-chip PIO buffers */ 2209 ef10_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count); 2210 2211 /* 2212 * For best performance, PIO writes should use a write-combined 2213 * (WC) memory mapping. Using a separate WC mapping for the PIO 2214 * aperture of each VI would be a burden to drivers (and not 2215 * possible if the host page size is >4Kbyte). 2216 * 2217 * To avoid this we use a single uncached (UC) mapping for VI 2218 * register access, and a single WC mapping for extra VIs used 2219 * for PIO writes. 2220 * 2221 * Each piobuf must be linked to a VI in the WC mapping, and to 2222 * each VI that is using a sub-allocated block from the piobuf. 2223 */ 2224 min_vi_count = edcp->edc_min_vi_count; 2225 max_vi_count = 2226 edcp->edc_max_vi_count + enp->en_arch.ef10.ena_piobuf_count; 2227 2228 /* Ensure that the previously attached driver's VIs are freed */ 2229 if ((rc = efx_mcdi_free_vis(enp)) != 0) 2230 goto fail2; 2231 2232 /* 2233 * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this 2234 * fails then retrying the request for fewer VI resources may succeed. 2235 */ 2236 vi_count = 0; 2237 if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count, 2238 &vi_base, &vi_count, &vi_shift)) != 0) 2239 goto fail3; 2240 2241 EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count); 2242 2243 if (vi_count < min_vi_count) { 2244 rc = ENOMEM; 2245 goto fail4; 2246 } 2247 2248 enp->en_arch.ef10.ena_vi_base = vi_base; 2249 enp->en_arch.ef10.ena_vi_count = vi_count; 2250 enp->en_arch.ef10.ena_vi_shift = vi_shift; 2251 2252 if (vi_count < min_vi_count + enp->en_arch.ef10.ena_piobuf_count) { 2253 /* Not enough extra VIs to map piobufs */ 2254 ef10_nic_free_piobufs(enp); 2255 } 2256 2257 enp->en_arch.ef10.ena_pio_write_vi_base = 2258 vi_count - enp->en_arch.ef10.ena_piobuf_count; 2259 2260 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=, 2261 EFX_VI_WINDOW_SHIFT_INVALID); 2262 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=, 2263 EFX_VI_WINDOW_SHIFT_64K); 2264 vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift; 2265 2266 /* Save UC memory mapping details */ 2267 enp->en_arch.ef10.ena_uc_mem_map_offset = 0; 2268 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2269 enp->en_arch.ef10.ena_uc_mem_map_size = 2270 (vi_window_size * 2271 enp->en_arch.ef10.ena_pio_write_vi_base); 2272 } else { 2273 enp->en_arch.ef10.ena_uc_mem_map_size = 2274 (vi_window_size * 2275 enp->en_arch.ef10.ena_vi_count); 2276 } 2277 2278 /* Save WC memory mapping details */ 2279 enp->en_arch.ef10.ena_wc_mem_map_offset = 2280 enp->en_arch.ef10.ena_uc_mem_map_offset + 2281 enp->en_arch.ef10.ena_uc_mem_map_size; 2282 2283 enp->en_arch.ef10.ena_wc_mem_map_size = 2284 (vi_window_size * 2285 enp->en_arch.ef10.ena_piobuf_count); 2286 2287 /* Link piobufs to extra VIs in WC mapping */ 2288 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2289 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 2290 rc = efx_mcdi_link_piobuf(enp, 2291 enp->en_arch.ef10.ena_pio_write_vi_base + i, 2292 enp->en_arch.ef10.ena_piobuf_handle[i]); 2293 if (rc != 0) 2294 break; 2295 } 2296 } 2297 2298 /* 2299 * Allocate a vAdaptor attached to our upstream vPort/pPort. 2300 * 2301 * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF 2302 * driver has yet to bring up the EVB port. See bug 56147. In this case, 2303 * retry the request several times after waiting a while. The wait time 2304 * between retries starts small (10ms) and exponentially increases. 2305 * Total wait time is a little over two seconds. Retry logic in the 2306 * client driver may mean this whole loop is repeated if it continues to 2307 * fail. 2308 */ 2309 retry = 0; 2310 delay_us = 10000; 2311 while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { 2312 if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || 2313 (rc != ENOENT)) { 2314 /* 2315 * Do not retry alloc for PF, or for other errors on 2316 * a VF. 2317 */ 2318 goto fail5; 2319 } 2320 2321 /* VF startup before PF is ready. Retry allocation. */ 2322 if (retry > 5) { 2323 /* Too many attempts */ 2324 rc = EINVAL; 2325 goto fail6; 2326 } 2327 EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); 2328 EFSYS_SLEEP(delay_us); 2329 retry++; 2330 if (delay_us < 500000) 2331 delay_us <<= 2; 2332 } 2333 2334 enp->en_vport_id = EVB_PORT_ID_ASSIGNED; 2335 enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2; 2336 2337 return (0); 2338 2339 fail6: 2340 EFSYS_PROBE(fail6); 2341 fail5: 2342 EFSYS_PROBE(fail5); 2343 fail4: 2344 EFSYS_PROBE(fail4); 2345 fail3: 2346 EFSYS_PROBE(fail3); 2347 fail2: 2348 EFSYS_PROBE(fail2); 2349 2350 ef10_nic_free_piobufs(enp); 2351 2352 fail1: 2353 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2354 2355 return (rc); 2356 } 2357 2358 __checkReturn efx_rc_t 2359 ef10_nic_get_vi_pool( 2360 __in efx_nic_t *enp, 2361 __out uint32_t *vi_countp) 2362 { 2363 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2364 enp->en_family == EFX_FAMILY_MEDFORD || 2365 enp->en_family == EFX_FAMILY_MEDFORD2); 2366 2367 /* 2368 * Report VIs that the client driver can use. 2369 * Do not include VIs used for PIO buffer writes. 2370 */ 2371 *vi_countp = enp->en_arch.ef10.ena_pio_write_vi_base; 2372 2373 return (0); 2374 } 2375 2376 __checkReturn efx_rc_t 2377 ef10_nic_get_bar_region( 2378 __in efx_nic_t *enp, 2379 __in efx_nic_region_t region, 2380 __out uint32_t *offsetp, 2381 __out size_t *sizep) 2382 { 2383 efx_rc_t rc; 2384 2385 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 2386 enp->en_family == EFX_FAMILY_MEDFORD || 2387 enp->en_family == EFX_FAMILY_MEDFORD2); 2388 2389 /* 2390 * TODO: Specify host memory mapping alignment and granularity 2391 * in efx_drv_limits_t so that they can be taken into account 2392 * when allocating extra VIs for PIO writes. 2393 */ 2394 switch (region) { 2395 case EFX_REGION_VI: 2396 /* UC mapped memory BAR region for VI registers */ 2397 *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset; 2398 *sizep = enp->en_arch.ef10.ena_uc_mem_map_size; 2399 break; 2400 2401 case EFX_REGION_PIO_WRITE_VI: 2402 /* WC mapped memory BAR region for piobuf writes */ 2403 *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset; 2404 *sizep = enp->en_arch.ef10.ena_wc_mem_map_size; 2405 break; 2406 2407 default: 2408 rc = EINVAL; 2409 goto fail1; 2410 } 2411 2412 return (0); 2413 2414 fail1: 2415 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2416 2417 return (rc); 2418 } 2419 2420 __checkReturn boolean_t 2421 ef10_nic_hw_unavailable( 2422 __in efx_nic_t *enp) 2423 { 2424 efx_dword_t dword; 2425 2426 if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL) 2427 return (B_TRUE); 2428 2429 EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE); 2430 if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff) 2431 goto unavail; 2432 2433 return (B_FALSE); 2434 2435 unavail: 2436 ef10_nic_set_hw_unavailable(enp); 2437 2438 return (B_TRUE); 2439 } 2440 2441 void 2442 ef10_nic_set_hw_unavailable( 2443 __in efx_nic_t *enp) 2444 { 2445 EFSYS_PROBE(hw_unavail); 2446 enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL; 2447 } 2448 2449 2450 void 2451 ef10_nic_fini( 2452 __in efx_nic_t *enp) 2453 { 2454 uint32_t i; 2455 efx_rc_t rc; 2456 2457 (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id); 2458 enp->en_vport_id = 0; 2459 2460 /* Unlink piobufs from extra VIs in WC mapping */ 2461 if (enp->en_arch.ef10.ena_piobuf_count > 0) { 2462 for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) { 2463 rc = efx_mcdi_unlink_piobuf(enp, 2464 enp->en_arch.ef10.ena_pio_write_vi_base + i); 2465 if (rc != 0) 2466 break; 2467 } 2468 } 2469 2470 ef10_nic_free_piobufs(enp); 2471 2472 (void) efx_mcdi_free_vis(enp); 2473 enp->en_arch.ef10.ena_vi_count = 0; 2474 } 2475 2476 void 2477 ef10_nic_unprobe( 2478 __in efx_nic_t *enp) 2479 { 2480 #if EFSYS_OPT_MON_STATS 2481 mcdi_mon_cfg_free(enp); 2482 #endif /* EFSYS_OPT_MON_STATS */ 2483 (void) efx_mcdi_drv_attach(enp, B_FALSE); 2484 } 2485 2486 #if EFSYS_OPT_DIAG 2487 2488 __checkReturn efx_rc_t 2489 ef10_nic_register_test( 2490 __in efx_nic_t *enp) 2491 { 2492 efx_rc_t rc; 2493 2494 /* FIXME */ 2495 _NOTE(ARGUNUSED(enp)) 2496 _NOTE(CONSTANTCONDITION) 2497 if (B_FALSE) { 2498 rc = ENOTSUP; 2499 goto fail1; 2500 } 2501 /* FIXME */ 2502 2503 return (0); 2504 2505 fail1: 2506 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2507 2508 return (rc); 2509 } 2510 2511 #endif /* EFSYS_OPT_DIAG */ 2512 2513 #if EFSYS_OPT_FW_SUBVARIANT_AWARE 2514 2515 __checkReturn efx_rc_t 2516 efx_mcdi_get_nic_global( 2517 __in efx_nic_t *enp, 2518 __in uint32_t key, 2519 __out uint32_t *valuep) 2520 { 2521 efx_mcdi_req_t req; 2522 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN, 2523 MC_CMD_GET_NIC_GLOBAL_OUT_LEN); 2524 efx_rc_t rc; 2525 2526 req.emr_cmd = MC_CMD_GET_NIC_GLOBAL; 2527 req.emr_in_buf = payload; 2528 req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN; 2529 req.emr_out_buf = payload; 2530 req.emr_out_length = MC_CMD_GET_NIC_GLOBAL_OUT_LEN; 2531 2532 MCDI_IN_SET_DWORD(req, GET_NIC_GLOBAL_IN_KEY, key); 2533 2534 efx_mcdi_execute(enp, &req); 2535 2536 if (req.emr_rc != 0) { 2537 rc = req.emr_rc; 2538 goto fail1; 2539 } 2540 2541 if (req.emr_out_length_used != MC_CMD_GET_NIC_GLOBAL_OUT_LEN) { 2542 rc = EMSGSIZE; 2543 goto fail2; 2544 } 2545 2546 *valuep = MCDI_OUT_DWORD(req, GET_NIC_GLOBAL_OUT_VALUE); 2547 2548 return (0); 2549 2550 fail2: 2551 EFSYS_PROBE(fail2); 2552 fail1: 2553 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2554 2555 return (rc); 2556 } 2557 2558 __checkReturn efx_rc_t 2559 efx_mcdi_set_nic_global( 2560 __in efx_nic_t *enp, 2561 __in uint32_t key, 2562 __in uint32_t value) 2563 { 2564 efx_mcdi_req_t req; 2565 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0); 2566 efx_rc_t rc; 2567 2568 req.emr_cmd = MC_CMD_SET_NIC_GLOBAL; 2569 req.emr_in_buf = payload; 2570 req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN; 2571 req.emr_out_buf = NULL; 2572 req.emr_out_length = 0; 2573 2574 MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_KEY, key); 2575 MCDI_IN_SET_DWORD(req, SET_NIC_GLOBAL_IN_VALUE, value); 2576 2577 efx_mcdi_execute(enp, &req); 2578 2579 if (req.emr_rc != 0) { 2580 rc = req.emr_rc; 2581 goto fail1; 2582 } 2583 2584 return (0); 2585 2586 fail1: 2587 EFSYS_PROBE1(fail1, efx_rc_t, rc); 2588 2589 return (rc); 2590 } 2591 2592 #endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */ 2593 2594 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ 2595