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