1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2016-2019 Solarflare Communications Inc. 5 * 6 * This software was jointly developed between OKTET Labs (under contract 7 * for Solarflare) and Solarflare Communications, Inc. 8 */ 9 10 /* sysconf() */ 11 #include <unistd.h> 12 13 #include <rte_errno.h> 14 #include <rte_alarm.h> 15 16 #include "efx.h" 17 18 #include "sfc.h" 19 #include "sfc_debug.h" 20 #include "sfc_log.h" 21 #include "sfc_ev.h" 22 #include "sfc_rx.h" 23 #include "sfc_mae_counter.h" 24 #include "sfc_tx.h" 25 #include "sfc_kvargs.h" 26 #include "sfc_tweak.h" 27 #include "sfc_sw_stats.h" 28 #include "sfc_switch.h" 29 30 bool 31 sfc_repr_supported(const struct sfc_adapter *sa) 32 { 33 if (!sa->switchdev) 34 return false; 35 36 /* 37 * Representor proxy should use service lcore on PF's socket 38 * (sa->socket_id) to be efficient. But the proxy will fall back 39 * to any socket if it is not possible to get the service core 40 * on the same socket. Check that at least service core on any 41 * socket is available. 42 */ 43 if (sfc_get_service_lcore(SOCKET_ID_ANY) == RTE_MAX_LCORE) 44 return false; 45 46 return true; 47 } 48 49 bool 50 sfc_repr_available(const struct sfc_adapter_shared *sas) 51 { 52 return sas->nb_repr_rxq > 0 && sas->nb_repr_txq > 0; 53 } 54 55 int 56 sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id, 57 size_t len, int socket_id, efsys_mem_t *esmp) 58 { 59 const struct rte_memzone *mz; 60 61 sfc_log_init(sa, "name=%s id=%u len=%zu socket_id=%d", 62 name, id, len, socket_id); 63 64 mz = rte_eth_dma_zone_reserve(sa->eth_dev, name, id, len, 65 sysconf(_SC_PAGESIZE), socket_id); 66 if (mz == NULL) { 67 sfc_err(sa, "cannot reserve DMA zone for %s:%u %#x@%d: %s", 68 name, (unsigned int)id, (unsigned int)len, socket_id, 69 rte_strerror(rte_errno)); 70 return ENOMEM; 71 } 72 73 esmp->esm_addr = mz->iova; 74 if (esmp->esm_addr == RTE_BAD_IOVA) { 75 (void)rte_memzone_free(mz); 76 return EFAULT; 77 } 78 79 esmp->esm_mz = mz; 80 esmp->esm_base = mz->addr; 81 82 sfc_info(sa, 83 "DMA name=%s id=%u len=%lu socket_id=%d => virt=%p iova=%lx", 84 name, id, len, socket_id, esmp->esm_base, 85 (unsigned long)esmp->esm_addr); 86 87 return 0; 88 } 89 90 void 91 sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp) 92 { 93 int rc; 94 95 sfc_log_init(sa, "name=%s", esmp->esm_mz->name); 96 97 rc = rte_memzone_free(esmp->esm_mz); 98 if (rc != 0) 99 sfc_err(sa, "rte_memzone_free(() failed: %d", rc); 100 101 memset(esmp, 0, sizeof(*esmp)); 102 } 103 104 static uint32_t 105 sfc_phy_cap_from_link_speeds(uint32_t speeds) 106 { 107 uint32_t phy_caps = 0; 108 109 if (~speeds & RTE_ETH_LINK_SPEED_FIXED) { 110 phy_caps |= (1 << EFX_PHY_CAP_AN); 111 /* 112 * If no speeds are specified in the mask, any supported 113 * may be negotiated 114 */ 115 if (speeds == RTE_ETH_LINK_SPEED_AUTONEG) 116 phy_caps |= 117 (1 << EFX_PHY_CAP_1000FDX) | 118 (1 << EFX_PHY_CAP_10000FDX) | 119 (1 << EFX_PHY_CAP_25000FDX) | 120 (1 << EFX_PHY_CAP_40000FDX) | 121 (1 << EFX_PHY_CAP_50000FDX) | 122 (1 << EFX_PHY_CAP_100000FDX); 123 } 124 if (speeds & RTE_ETH_LINK_SPEED_1G) 125 phy_caps |= (1 << EFX_PHY_CAP_1000FDX); 126 if (speeds & RTE_ETH_LINK_SPEED_10G) 127 phy_caps |= (1 << EFX_PHY_CAP_10000FDX); 128 if (speeds & RTE_ETH_LINK_SPEED_25G) 129 phy_caps |= (1 << EFX_PHY_CAP_25000FDX); 130 if (speeds & RTE_ETH_LINK_SPEED_40G) 131 phy_caps |= (1 << EFX_PHY_CAP_40000FDX); 132 if (speeds & RTE_ETH_LINK_SPEED_50G) 133 phy_caps |= (1 << EFX_PHY_CAP_50000FDX); 134 if (speeds & RTE_ETH_LINK_SPEED_100G) 135 phy_caps |= (1 << EFX_PHY_CAP_100000FDX); 136 137 return phy_caps; 138 } 139 140 /* 141 * Check requested device level configuration. 142 * Receive and transmit configuration is checked in corresponding 143 * modules. 144 */ 145 static int 146 sfc_check_conf(struct sfc_adapter *sa) 147 { 148 const struct rte_eth_conf *conf = &sa->eth_dev->data->dev_conf; 149 int rc = 0; 150 151 sa->port.phy_adv_cap = 152 sfc_phy_cap_from_link_speeds(conf->link_speeds) & 153 sa->port.phy_adv_cap_mask; 154 if ((sa->port.phy_adv_cap & ~(1 << EFX_PHY_CAP_AN)) == 0) { 155 sfc_err(sa, "No link speeds from mask %#x are supported", 156 conf->link_speeds); 157 rc = EINVAL; 158 } 159 160 #if !EFSYS_OPT_LOOPBACK 161 if (conf->lpbk_mode != 0) { 162 sfc_err(sa, "Loopback not supported"); 163 rc = EINVAL; 164 } 165 #endif 166 167 if (conf->dcb_capability_en != 0) { 168 sfc_err(sa, "Priority-based flow control not supported"); 169 rc = EINVAL; 170 } 171 172 if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) { 173 sfc_err(sa, "Flow Director not supported"); 174 rc = EINVAL; 175 } 176 177 if ((conf->intr_conf.lsc != 0) && 178 (sa->intr.type != EFX_INTR_LINE) && 179 (sa->intr.type != EFX_INTR_MESSAGE)) { 180 sfc_err(sa, "Link status change interrupt not supported"); 181 rc = EINVAL; 182 } 183 184 if (conf->intr_conf.rxq != 0 && 185 (sa->priv.dp_rx->features & SFC_DP_RX_FEAT_INTR) == 0) { 186 sfc_err(sa, "Receive queue interrupt not supported"); 187 rc = EINVAL; 188 } 189 190 return rc; 191 } 192 193 /* 194 * Find out maximum number of receive and transmit queues which could be 195 * advertised. 196 * 197 * NIC is kept initialized on success to allow other modules acquire 198 * defaults and capabilities. 199 */ 200 static int 201 sfc_estimate_resource_limits(struct sfc_adapter *sa) 202 { 203 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); 204 struct sfc_adapter_shared *sas = sfc_sa2shared(sa); 205 efx_drv_limits_t limits; 206 int rc; 207 uint32_t evq_allocated; 208 uint32_t rxq_allocated; 209 uint32_t txq_allocated; 210 211 memset(&limits, 0, sizeof(limits)); 212 213 /* Request at least one Rx and Tx queue */ 214 limits.edl_min_rxq_count = 1; 215 limits.edl_min_txq_count = 1; 216 /* Management event queue plus event queue for each Tx and Rx queue */ 217 limits.edl_min_evq_count = 218 1 + limits.edl_min_rxq_count + limits.edl_min_txq_count; 219 220 /* Divide by number of functions to guarantee that all functions 221 * will get promised resources 222 */ 223 /* FIXME Divide by number of functions (not 2) below */ 224 limits.edl_max_evq_count = encp->enc_evq_limit / 2; 225 SFC_ASSERT(limits.edl_max_evq_count >= limits.edl_min_rxq_count); 226 227 /* Split equally between receive and transmit */ 228 limits.edl_max_rxq_count = 229 MIN(encp->enc_rxq_limit, (limits.edl_max_evq_count - 1) / 2); 230 SFC_ASSERT(limits.edl_max_rxq_count >= limits.edl_min_rxq_count); 231 232 limits.edl_max_txq_count = 233 MIN(encp->enc_txq_limit, 234 limits.edl_max_evq_count - 1 - limits.edl_max_rxq_count); 235 236 if (sa->tso && encp->enc_fw_assisted_tso_v2_enabled) 237 limits.edl_max_txq_count = 238 MIN(limits.edl_max_txq_count, 239 encp->enc_fw_assisted_tso_v2_n_contexts / 240 encp->enc_hw_pf_count); 241 242 SFC_ASSERT(limits.edl_max_txq_count >= limits.edl_min_rxq_count); 243 244 /* Configure the minimum required resources needed for the 245 * driver to operate, and the maximum desired resources that the 246 * driver is capable of using. 247 */ 248 efx_nic_set_drv_limits(sa->nic, &limits); 249 250 sfc_log_init(sa, "init nic"); 251 rc = efx_nic_init(sa->nic); 252 if (rc != 0) 253 goto fail_nic_init; 254 255 /* Find resource dimensions assigned by firmware to this function */ 256 rc = efx_nic_get_vi_pool(sa->nic, &evq_allocated, &rxq_allocated, 257 &txq_allocated); 258 if (rc != 0) 259 goto fail_get_vi_pool; 260 261 /* It still may allocate more than maximum, ensure limit */ 262 evq_allocated = MIN(evq_allocated, limits.edl_max_evq_count); 263 rxq_allocated = MIN(rxq_allocated, limits.edl_max_rxq_count); 264 txq_allocated = MIN(txq_allocated, limits.edl_max_txq_count); 265 266 /* 267 * Subtract management EVQ not used for traffic 268 * The resource allocation strategy is as follows: 269 * - one EVQ for management 270 * - one EVQ for each ethdev RXQ 271 * - one EVQ for each ethdev TXQ 272 * - one EVQ and one RXQ for optional MAE counters. 273 */ 274 if (evq_allocated == 0) { 275 sfc_err(sa, "count of allocated EvQ is 0"); 276 rc = ENOMEM; 277 goto fail_allocate_evq; 278 } 279 evq_allocated--; 280 281 /* 282 * Reserve absolutely required minimum. 283 * Right now we use separate EVQ for Rx and Tx. 284 */ 285 if (rxq_allocated > 0 && evq_allocated > 0) { 286 sa->rxq_max = 1; 287 rxq_allocated--; 288 evq_allocated--; 289 } 290 if (txq_allocated > 0 && evq_allocated > 0) { 291 sa->txq_max = 1; 292 txq_allocated--; 293 evq_allocated--; 294 } 295 296 if (sfc_mae_counter_rxq_required(sa) && 297 rxq_allocated > 0 && evq_allocated > 0) { 298 rxq_allocated--; 299 evq_allocated--; 300 sas->counters_rxq_allocated = true; 301 } else { 302 sas->counters_rxq_allocated = false; 303 } 304 305 if (sfc_repr_supported(sa) && 306 evq_allocated >= SFC_REPR_PROXY_NB_RXQ_MIN + 307 SFC_REPR_PROXY_NB_TXQ_MIN && 308 rxq_allocated >= SFC_REPR_PROXY_NB_RXQ_MIN && 309 txq_allocated >= SFC_REPR_PROXY_NB_TXQ_MIN) { 310 unsigned int extra; 311 312 txq_allocated -= SFC_REPR_PROXY_NB_TXQ_MIN; 313 rxq_allocated -= SFC_REPR_PROXY_NB_RXQ_MIN; 314 evq_allocated -= SFC_REPR_PROXY_NB_RXQ_MIN + 315 SFC_REPR_PROXY_NB_TXQ_MIN; 316 317 sas->nb_repr_rxq = SFC_REPR_PROXY_NB_RXQ_MIN; 318 sas->nb_repr_txq = SFC_REPR_PROXY_NB_TXQ_MIN; 319 320 /* Allocate extra representor RxQs up to the maximum */ 321 extra = MIN(evq_allocated, rxq_allocated); 322 extra = MIN(extra, 323 SFC_REPR_PROXY_NB_RXQ_MAX - sas->nb_repr_rxq); 324 evq_allocated -= extra; 325 rxq_allocated -= extra; 326 sas->nb_repr_rxq += extra; 327 328 /* Allocate extra representor TxQs up to the maximum */ 329 extra = MIN(evq_allocated, txq_allocated); 330 extra = MIN(extra, 331 SFC_REPR_PROXY_NB_TXQ_MAX - sas->nb_repr_txq); 332 evq_allocated -= extra; 333 txq_allocated -= extra; 334 sas->nb_repr_txq += extra; 335 } else { 336 sas->nb_repr_rxq = 0; 337 sas->nb_repr_txq = 0; 338 } 339 340 /* Add remaining allocated queues */ 341 sa->rxq_max += MIN(rxq_allocated, evq_allocated / 2); 342 sa->txq_max += MIN(txq_allocated, evq_allocated - sa->rxq_max); 343 344 /* Keep NIC initialized */ 345 return 0; 346 347 fail_allocate_evq: 348 fail_get_vi_pool: 349 efx_nic_fini(sa->nic); 350 fail_nic_init: 351 return rc; 352 } 353 354 static int 355 sfc_set_drv_limits(struct sfc_adapter *sa) 356 { 357 struct sfc_adapter_shared *sas = sfc_sa2shared(sa); 358 const struct rte_eth_dev_data *data = sa->eth_dev->data; 359 uint32_t rxq_reserved = sfc_nb_reserved_rxq(sas); 360 uint32_t txq_reserved = sfc_nb_txq_reserved(sas); 361 efx_drv_limits_t lim; 362 363 memset(&lim, 0, sizeof(lim)); 364 365 /* 366 * Limits are strict since take into account initial estimation. 367 * Resource allocation stategy is described in 368 * sfc_estimate_resource_limits(). 369 */ 370 lim.edl_min_evq_count = lim.edl_max_evq_count = 371 1 + data->nb_rx_queues + data->nb_tx_queues + 372 rxq_reserved + txq_reserved; 373 lim.edl_min_rxq_count = lim.edl_max_rxq_count = 374 data->nb_rx_queues + rxq_reserved; 375 lim.edl_min_txq_count = lim.edl_max_txq_count = 376 data->nb_tx_queues + txq_reserved; 377 378 return efx_nic_set_drv_limits(sa->nic, &lim); 379 } 380 381 static int 382 sfc_set_fw_subvariant(struct sfc_adapter *sa) 383 { 384 struct sfc_adapter_shared *sas = sfc_sa2shared(sa); 385 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); 386 uint64_t tx_offloads = sa->eth_dev->data->dev_conf.txmode.offloads; 387 unsigned int txq_index; 388 efx_nic_fw_subvariant_t req_fw_subvariant; 389 efx_nic_fw_subvariant_t cur_fw_subvariant; 390 int rc; 391 392 if (!encp->enc_fw_subvariant_no_tx_csum_supported) { 393 sfc_info(sa, "no-Tx-checksum subvariant not supported"); 394 return 0; 395 } 396 397 for (txq_index = 0; txq_index < sas->txq_count; ++txq_index) { 398 struct sfc_txq_info *txq_info = &sas->txq_info[txq_index]; 399 400 if (txq_info->state & SFC_TXQ_INITIALIZED) 401 tx_offloads |= txq_info->offloads; 402 } 403 404 if (tx_offloads & (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | 405 RTE_ETH_TX_OFFLOAD_TCP_CKSUM | 406 RTE_ETH_TX_OFFLOAD_UDP_CKSUM | 407 RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM)) 408 req_fw_subvariant = EFX_NIC_FW_SUBVARIANT_DEFAULT; 409 else 410 req_fw_subvariant = EFX_NIC_FW_SUBVARIANT_NO_TX_CSUM; 411 412 rc = efx_nic_get_fw_subvariant(sa->nic, &cur_fw_subvariant); 413 if (rc != 0) { 414 sfc_err(sa, "failed to get FW subvariant: %d", rc); 415 return rc; 416 } 417 sfc_info(sa, "FW subvariant is %u vs required %u", 418 cur_fw_subvariant, req_fw_subvariant); 419 420 if (cur_fw_subvariant == req_fw_subvariant) 421 return 0; 422 423 rc = efx_nic_set_fw_subvariant(sa->nic, req_fw_subvariant); 424 if (rc != 0) { 425 sfc_err(sa, "failed to set FW subvariant %u: %d", 426 req_fw_subvariant, rc); 427 return rc; 428 } 429 sfc_info(sa, "FW subvariant set to %u", req_fw_subvariant); 430 431 return 0; 432 } 433 434 static int 435 sfc_try_start(struct sfc_adapter *sa) 436 { 437 const efx_nic_cfg_t *encp; 438 int rc; 439 440 sfc_log_init(sa, "entry"); 441 442 SFC_ASSERT(sfc_adapter_is_locked(sa)); 443 SFC_ASSERT(sa->state == SFC_ETHDEV_STARTING); 444 445 sfc_log_init(sa, "set FW subvariant"); 446 rc = sfc_set_fw_subvariant(sa); 447 if (rc != 0) 448 goto fail_set_fw_subvariant; 449 450 sfc_log_init(sa, "set resource limits"); 451 rc = sfc_set_drv_limits(sa); 452 if (rc != 0) 453 goto fail_set_drv_limits; 454 455 sfc_log_init(sa, "init nic"); 456 rc = efx_nic_init(sa->nic); 457 if (rc != 0) 458 goto fail_nic_init; 459 460 encp = efx_nic_cfg_get(sa->nic); 461 462 /* 463 * Refresh (since it may change on NIC reset/restart) a copy of 464 * supported tunnel encapsulations in shared memory to be used 465 * on supported Rx packet type classes get. 466 */ 467 sa->priv.shared->tunnel_encaps = 468 encp->enc_tunnel_encapsulations_supported; 469 470 if (encp->enc_tunnel_encapsulations_supported != 0) { 471 sfc_log_init(sa, "apply tunnel config"); 472 rc = efx_tunnel_reconfigure(sa->nic); 473 if (rc != 0) 474 goto fail_tunnel_reconfigure; 475 } 476 477 rc = sfc_intr_start(sa); 478 if (rc != 0) 479 goto fail_intr_start; 480 481 rc = sfc_ev_start(sa); 482 if (rc != 0) 483 goto fail_ev_start; 484 485 rc = sfc_port_start(sa); 486 if (rc != 0) 487 goto fail_port_start; 488 489 rc = sfc_rx_start(sa); 490 if (rc != 0) 491 goto fail_rx_start; 492 493 rc = sfc_tx_start(sa); 494 if (rc != 0) 495 goto fail_tx_start; 496 497 rc = sfc_flow_start(sa); 498 if (rc != 0) 499 goto fail_flows_insert; 500 501 rc = sfc_repr_proxy_start(sa); 502 if (rc != 0) 503 goto fail_repr_proxy_start; 504 505 sfc_log_init(sa, "done"); 506 return 0; 507 508 fail_repr_proxy_start: 509 sfc_flow_stop(sa); 510 511 fail_flows_insert: 512 sfc_tx_stop(sa); 513 514 fail_tx_start: 515 sfc_rx_stop(sa); 516 517 fail_rx_start: 518 sfc_port_stop(sa); 519 520 fail_port_start: 521 sfc_ev_stop(sa); 522 523 fail_ev_start: 524 sfc_intr_stop(sa); 525 526 fail_intr_start: 527 fail_tunnel_reconfigure: 528 efx_nic_fini(sa->nic); 529 530 fail_nic_init: 531 fail_set_drv_limits: 532 fail_set_fw_subvariant: 533 sfc_log_init(sa, "failed %d", rc); 534 return rc; 535 } 536 537 int 538 sfc_start(struct sfc_adapter *sa) 539 { 540 unsigned int start_tries = 3; 541 int rc; 542 543 sfc_log_init(sa, "entry"); 544 545 SFC_ASSERT(sfc_adapter_is_locked(sa)); 546 547 switch (sa->state) { 548 case SFC_ETHDEV_CONFIGURED: 549 break; 550 case SFC_ETHDEV_STARTED: 551 sfc_notice(sa, "already started"); 552 return 0; 553 default: 554 rc = EINVAL; 555 goto fail_bad_state; 556 } 557 558 sa->state = SFC_ETHDEV_STARTING; 559 560 rc = 0; 561 do { 562 /* 563 * FIXME Try to recreate vSwitch on start retry. 564 * vSwitch is absent after MC reboot like events and 565 * we should recreate it. May be we need proper 566 * indication instead of guessing. 567 */ 568 if (rc != 0) { 569 sfc_sriov_vswitch_destroy(sa); 570 rc = sfc_sriov_vswitch_create(sa); 571 if (rc != 0) 572 goto fail_sriov_vswitch_create; 573 } 574 rc = sfc_try_start(sa); 575 } while ((--start_tries > 0) && 576 (rc == EIO || rc == EAGAIN || rc == ENOENT || rc == EINVAL)); 577 578 if (rc != 0) 579 goto fail_try_start; 580 581 sa->state = SFC_ETHDEV_STARTED; 582 sfc_log_init(sa, "done"); 583 return 0; 584 585 fail_try_start: 586 fail_sriov_vswitch_create: 587 sa->state = SFC_ETHDEV_CONFIGURED; 588 fail_bad_state: 589 sfc_log_init(sa, "failed %d", rc); 590 return rc; 591 } 592 593 void 594 sfc_stop(struct sfc_adapter *sa) 595 { 596 sfc_log_init(sa, "entry"); 597 598 SFC_ASSERT(sfc_adapter_is_locked(sa)); 599 600 switch (sa->state) { 601 case SFC_ETHDEV_STARTED: 602 break; 603 case SFC_ETHDEV_CONFIGURED: 604 sfc_notice(sa, "already stopped"); 605 return; 606 default: 607 sfc_err(sa, "stop in unexpected state %u", sa->state); 608 SFC_ASSERT(B_FALSE); 609 return; 610 } 611 612 sa->state = SFC_ETHDEV_STOPPING; 613 614 sfc_repr_proxy_stop(sa); 615 sfc_flow_stop(sa); 616 sfc_tx_stop(sa); 617 sfc_rx_stop(sa); 618 sfc_port_stop(sa); 619 sfc_ev_stop(sa); 620 sfc_intr_stop(sa); 621 efx_nic_fini(sa->nic); 622 623 sa->state = SFC_ETHDEV_CONFIGURED; 624 sfc_log_init(sa, "done"); 625 } 626 627 static int 628 sfc_restart(struct sfc_adapter *sa) 629 { 630 int rc; 631 632 SFC_ASSERT(sfc_adapter_is_locked(sa)); 633 634 if (sa->state != SFC_ETHDEV_STARTED) 635 return EINVAL; 636 637 sfc_stop(sa); 638 639 rc = sfc_start(sa); 640 if (rc != 0) 641 sfc_err(sa, "restart failed"); 642 643 return rc; 644 } 645 646 static void 647 sfc_restart_if_required(void *arg) 648 { 649 struct sfc_adapter *sa = arg; 650 651 /* If restart is scheduled, clear the flag and do it */ 652 if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required, 653 1, 0)) { 654 sfc_adapter_lock(sa); 655 if (sa->state == SFC_ETHDEV_STARTED) 656 (void)sfc_restart(sa); 657 sfc_adapter_unlock(sa); 658 } 659 } 660 661 void 662 sfc_schedule_restart(struct sfc_adapter *sa) 663 { 664 int rc; 665 666 /* Schedule restart alarm if it is not scheduled yet */ 667 if (!rte_atomic32_test_and_set(&sa->restart_required)) 668 return; 669 670 rc = rte_eal_alarm_set(1, sfc_restart_if_required, sa); 671 if (rc == -ENOTSUP) 672 sfc_warn(sa, "alarms are not supported, restart is pending"); 673 else if (rc != 0) 674 sfc_err(sa, "cannot arm restart alarm (rc=%d)", rc); 675 else 676 sfc_notice(sa, "restart scheduled"); 677 } 678 679 int 680 sfc_configure(struct sfc_adapter *sa) 681 { 682 int rc; 683 684 sfc_log_init(sa, "entry"); 685 686 SFC_ASSERT(sfc_adapter_is_locked(sa)); 687 688 SFC_ASSERT(sa->state == SFC_ETHDEV_INITIALIZED || 689 sa->state == SFC_ETHDEV_CONFIGURED); 690 sa->state = SFC_ETHDEV_CONFIGURING; 691 692 rc = sfc_check_conf(sa); 693 if (rc != 0) 694 goto fail_check_conf; 695 696 rc = sfc_intr_configure(sa); 697 if (rc != 0) 698 goto fail_intr_configure; 699 700 rc = sfc_port_configure(sa); 701 if (rc != 0) 702 goto fail_port_configure; 703 704 rc = sfc_rx_configure(sa); 705 if (rc != 0) 706 goto fail_rx_configure; 707 708 rc = sfc_tx_configure(sa); 709 if (rc != 0) 710 goto fail_tx_configure; 711 712 rc = sfc_sw_xstats_configure(sa); 713 if (rc != 0) 714 goto fail_sw_xstats_configure; 715 716 sa->state = SFC_ETHDEV_CONFIGURED; 717 sfc_log_init(sa, "done"); 718 return 0; 719 720 fail_sw_xstats_configure: 721 sfc_tx_close(sa); 722 723 fail_tx_configure: 724 sfc_rx_close(sa); 725 726 fail_rx_configure: 727 sfc_port_close(sa); 728 729 fail_port_configure: 730 sfc_intr_close(sa); 731 732 fail_intr_configure: 733 fail_check_conf: 734 sa->state = SFC_ETHDEV_INITIALIZED; 735 sfc_log_init(sa, "failed %d", rc); 736 return rc; 737 } 738 739 void 740 sfc_close(struct sfc_adapter *sa) 741 { 742 sfc_log_init(sa, "entry"); 743 744 SFC_ASSERT(sfc_adapter_is_locked(sa)); 745 746 SFC_ASSERT(sa->state == SFC_ETHDEV_CONFIGURED); 747 sa->state = SFC_ETHDEV_CLOSING; 748 749 sfc_sw_xstats_close(sa); 750 sfc_tx_close(sa); 751 sfc_rx_close(sa); 752 sfc_port_close(sa); 753 sfc_intr_close(sa); 754 755 sa->state = SFC_ETHDEV_INITIALIZED; 756 sfc_log_init(sa, "done"); 757 } 758 759 static int 760 sfc_mem_bar_init(struct sfc_adapter *sa, const efx_bar_region_t *mem_ebrp) 761 { 762 struct rte_eth_dev *eth_dev = sa->eth_dev; 763 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 764 efsys_bar_t *ebp = &sa->mem_bar; 765 struct rte_mem_resource *res = 766 &pci_dev->mem_resource[mem_ebrp->ebr_index]; 767 768 SFC_BAR_LOCK_INIT(ebp, eth_dev->data->name); 769 ebp->esb_rid = mem_ebrp->ebr_index; 770 ebp->esb_dev = pci_dev; 771 ebp->esb_base = res->addr; 772 773 sa->fcw_offset = mem_ebrp->ebr_offset; 774 775 return 0; 776 } 777 778 static void 779 sfc_mem_bar_fini(struct sfc_adapter *sa) 780 { 781 efsys_bar_t *ebp = &sa->mem_bar; 782 783 SFC_BAR_LOCK_DESTROY(ebp); 784 memset(ebp, 0, sizeof(*ebp)); 785 } 786 787 /* 788 * A fixed RSS key which has a property of being symmetric 789 * (symmetrical flows are distributed to the same CPU) 790 * and also known to give a uniform distribution 791 * (a good distribution of traffic between different CPUs) 792 */ 793 static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { 794 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 795 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 796 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 797 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 798 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 799 }; 800 801 static int 802 sfc_rss_attach(struct sfc_adapter *sa) 803 { 804 struct sfc_rss *rss = &sfc_sa2shared(sa)->rss; 805 int rc; 806 807 rc = efx_intr_init(sa->nic, sa->intr.type, NULL); 808 if (rc != 0) 809 goto fail_intr_init; 810 811 rc = efx_ev_init(sa->nic); 812 if (rc != 0) 813 goto fail_ev_init; 814 815 rc = efx_rx_init(sa->nic); 816 if (rc != 0) 817 goto fail_rx_init; 818 819 rc = efx_rx_scale_default_support_get(sa->nic, &rss->context_type); 820 if (rc != 0) 821 goto fail_scale_support_get; 822 823 rc = efx_rx_hash_default_support_get(sa->nic, &rss->hash_support); 824 if (rc != 0) 825 goto fail_hash_support_get; 826 827 rc = sfc_rx_hash_init(sa); 828 if (rc != 0) 829 goto fail_rx_hash_init; 830 831 efx_rx_fini(sa->nic); 832 efx_ev_fini(sa->nic); 833 efx_intr_fini(sa->nic); 834 835 rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); 836 rss->dummy_rss_context = EFX_RSS_CONTEXT_DEFAULT; 837 838 return 0; 839 840 fail_rx_hash_init: 841 fail_hash_support_get: 842 fail_scale_support_get: 843 efx_rx_fini(sa->nic); 844 845 fail_rx_init: 846 efx_ev_fini(sa->nic); 847 848 fail_ev_init: 849 efx_intr_fini(sa->nic); 850 851 fail_intr_init: 852 return rc; 853 } 854 855 static void 856 sfc_rss_detach(struct sfc_adapter *sa) 857 { 858 sfc_rx_hash_fini(sa); 859 } 860 861 int 862 sfc_attach(struct sfc_adapter *sa) 863 { 864 const efx_nic_cfg_t *encp; 865 efx_nic_t *enp = sa->nic; 866 int rc; 867 868 sfc_log_init(sa, "entry"); 869 870 SFC_ASSERT(sfc_adapter_is_locked(sa)); 871 872 efx_mcdi_new_epoch(enp); 873 874 sfc_log_init(sa, "reset nic"); 875 rc = efx_nic_reset(enp); 876 if (rc != 0) 877 goto fail_nic_reset; 878 879 rc = sfc_sriov_attach(sa); 880 if (rc != 0) 881 goto fail_sriov_attach; 882 883 /* 884 * Probed NIC is sufficient for tunnel init. 885 * Initialize tunnel support to be able to use libefx 886 * efx_tunnel_config_udp_{add,remove}() in any state and 887 * efx_tunnel_reconfigure() on start up. 888 */ 889 rc = efx_tunnel_init(enp); 890 if (rc != 0) 891 goto fail_tunnel_init; 892 893 encp = efx_nic_cfg_get(sa->nic); 894 895 /* 896 * Make a copy of supported tunnel encapsulations in shared 897 * memory to be used on supported Rx packet type classes get. 898 */ 899 sa->priv.shared->tunnel_encaps = 900 encp->enc_tunnel_encapsulations_supported; 901 902 if (sfc_dp_tx_offload_capa(sa->priv.dp_tx) & RTE_ETH_TX_OFFLOAD_TCP_TSO) { 903 sa->tso = encp->enc_fw_assisted_tso_v2_enabled || 904 encp->enc_tso_v3_enabled; 905 if (!sa->tso) 906 sfc_info(sa, "TSO support isn't available on this adapter"); 907 } 908 909 if (sa->tso && 910 (sfc_dp_tx_offload_capa(sa->priv.dp_tx) & 911 (RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | 912 RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO)) != 0) { 913 sa->tso_encap = encp->enc_fw_assisted_tso_v2_encap_enabled || 914 encp->enc_tso_v3_enabled; 915 if (!sa->tso_encap) 916 sfc_info(sa, "Encapsulated TSO support isn't available on this adapter"); 917 } 918 919 sfc_log_init(sa, "estimate resource limits"); 920 rc = sfc_estimate_resource_limits(sa); 921 if (rc != 0) 922 goto fail_estimate_rsrc_limits; 923 924 sa->evq_max_entries = encp->enc_evq_max_nevs; 925 SFC_ASSERT(rte_is_power_of_2(sa->evq_max_entries)); 926 927 sa->evq_min_entries = encp->enc_evq_min_nevs; 928 SFC_ASSERT(rte_is_power_of_2(sa->evq_min_entries)); 929 930 sa->rxq_max_entries = encp->enc_rxq_max_ndescs; 931 SFC_ASSERT(rte_is_power_of_2(sa->rxq_max_entries)); 932 933 sa->rxq_min_entries = encp->enc_rxq_min_ndescs; 934 SFC_ASSERT(rte_is_power_of_2(sa->rxq_min_entries)); 935 936 sa->txq_max_entries = encp->enc_txq_max_ndescs; 937 SFC_ASSERT(rte_is_power_of_2(sa->txq_max_entries)); 938 939 sa->txq_min_entries = encp->enc_txq_min_ndescs; 940 SFC_ASSERT(rte_is_power_of_2(sa->txq_min_entries)); 941 942 rc = sfc_intr_attach(sa); 943 if (rc != 0) 944 goto fail_intr_attach; 945 946 rc = sfc_ev_attach(sa); 947 if (rc != 0) 948 goto fail_ev_attach; 949 950 rc = sfc_port_attach(sa); 951 if (rc != 0) 952 goto fail_port_attach; 953 954 rc = sfc_rss_attach(sa); 955 if (rc != 0) 956 goto fail_rss_attach; 957 958 rc = sfc_filter_attach(sa); 959 if (rc != 0) 960 goto fail_filter_attach; 961 962 rc = sfc_mae_counter_rxq_attach(sa); 963 if (rc != 0) 964 goto fail_mae_counter_rxq_attach; 965 966 rc = sfc_mae_attach(sa); 967 if (rc != 0) 968 goto fail_mae_attach; 969 970 rc = sfc_mae_switchdev_init(sa); 971 if (rc != 0) 972 goto fail_mae_switchdev_init; 973 974 rc = sfc_repr_proxy_attach(sa); 975 if (rc != 0) 976 goto fail_repr_proxy_attach; 977 978 sfc_log_init(sa, "fini nic"); 979 efx_nic_fini(enp); 980 981 sfc_flow_init(sa); 982 983 rc = sfc_sw_xstats_init(sa); 984 if (rc != 0) 985 goto fail_sw_xstats_init; 986 987 /* 988 * Create vSwitch to be able to use VFs when PF is not started yet 989 * as DPDK port. VFs should be able to talk to each other even 990 * if PF is down. 991 */ 992 rc = sfc_sriov_vswitch_create(sa); 993 if (rc != 0) 994 goto fail_sriov_vswitch_create; 995 996 sa->state = SFC_ETHDEV_INITIALIZED; 997 998 sfc_log_init(sa, "done"); 999 return 0; 1000 1001 fail_sriov_vswitch_create: 1002 sfc_sw_xstats_close(sa); 1003 1004 fail_sw_xstats_init: 1005 sfc_flow_fini(sa); 1006 sfc_repr_proxy_detach(sa); 1007 1008 fail_repr_proxy_attach: 1009 sfc_mae_switchdev_fini(sa); 1010 1011 fail_mae_switchdev_init: 1012 sfc_mae_detach(sa); 1013 1014 fail_mae_attach: 1015 sfc_mae_counter_rxq_detach(sa); 1016 1017 fail_mae_counter_rxq_attach: 1018 sfc_filter_detach(sa); 1019 1020 fail_filter_attach: 1021 sfc_rss_detach(sa); 1022 1023 fail_rss_attach: 1024 sfc_port_detach(sa); 1025 1026 fail_port_attach: 1027 sfc_ev_detach(sa); 1028 1029 fail_ev_attach: 1030 sfc_intr_detach(sa); 1031 1032 fail_intr_attach: 1033 efx_nic_fini(sa->nic); 1034 1035 fail_estimate_rsrc_limits: 1036 fail_tunnel_init: 1037 efx_tunnel_fini(sa->nic); 1038 sfc_sriov_detach(sa); 1039 1040 fail_sriov_attach: 1041 fail_nic_reset: 1042 1043 sfc_log_init(sa, "failed %d", rc); 1044 return rc; 1045 } 1046 1047 void 1048 sfc_pre_detach(struct sfc_adapter *sa) 1049 { 1050 sfc_log_init(sa, "entry"); 1051 1052 SFC_ASSERT(!sfc_adapter_is_locked(sa)); 1053 1054 sfc_repr_proxy_pre_detach(sa); 1055 1056 sfc_log_init(sa, "done"); 1057 } 1058 1059 void 1060 sfc_detach(struct sfc_adapter *sa) 1061 { 1062 sfc_log_init(sa, "entry"); 1063 1064 SFC_ASSERT(sfc_adapter_is_locked(sa)); 1065 1066 sfc_sriov_vswitch_destroy(sa); 1067 1068 sfc_flow_fini(sa); 1069 1070 sfc_repr_proxy_detach(sa); 1071 sfc_mae_switchdev_fini(sa); 1072 sfc_mae_detach(sa); 1073 sfc_mae_counter_rxq_detach(sa); 1074 sfc_filter_detach(sa); 1075 sfc_rss_detach(sa); 1076 sfc_port_detach(sa); 1077 sfc_ev_detach(sa); 1078 sfc_intr_detach(sa); 1079 efx_tunnel_fini(sa->nic); 1080 sfc_sriov_detach(sa); 1081 1082 sa->state = SFC_ETHDEV_UNINITIALIZED; 1083 } 1084 1085 static int 1086 sfc_kvarg_fv_variant_handler(__rte_unused const char *key, 1087 const char *value_str, void *opaque) 1088 { 1089 uint32_t *value = opaque; 1090 1091 if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_DONT_CARE) == 0) 1092 *value = EFX_FW_VARIANT_DONT_CARE; 1093 else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_FULL_FEATURED) == 0) 1094 *value = EFX_FW_VARIANT_FULL_FEATURED; 1095 else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_LOW_LATENCY) == 0) 1096 *value = EFX_FW_VARIANT_LOW_LATENCY; 1097 else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_PACKED_STREAM) == 0) 1098 *value = EFX_FW_VARIANT_PACKED_STREAM; 1099 else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_DPDK) == 0) 1100 *value = EFX_FW_VARIANT_DPDK; 1101 else 1102 return -EINVAL; 1103 1104 return 0; 1105 } 1106 1107 static int 1108 sfc_get_fw_variant(struct sfc_adapter *sa, efx_fw_variant_t *efv) 1109 { 1110 efx_nic_fw_info_t enfi; 1111 int rc; 1112 1113 rc = efx_nic_get_fw_version(sa->nic, &enfi); 1114 if (rc != 0) 1115 return rc; 1116 else if (!enfi.enfi_dpcpu_fw_ids_valid) 1117 return ENOTSUP; 1118 1119 /* 1120 * Firmware variant can be uniquely identified by the RxDPCPU 1121 * firmware id 1122 */ 1123 switch (enfi.enfi_rx_dpcpu_fw_id) { 1124 case EFX_RXDP_FULL_FEATURED_FW_ID: 1125 *efv = EFX_FW_VARIANT_FULL_FEATURED; 1126 break; 1127 1128 case EFX_RXDP_LOW_LATENCY_FW_ID: 1129 *efv = EFX_FW_VARIANT_LOW_LATENCY; 1130 break; 1131 1132 case EFX_RXDP_PACKED_STREAM_FW_ID: 1133 *efv = EFX_FW_VARIANT_PACKED_STREAM; 1134 break; 1135 1136 case EFX_RXDP_DPDK_FW_ID: 1137 *efv = EFX_FW_VARIANT_DPDK; 1138 break; 1139 1140 default: 1141 /* 1142 * Other firmware variants are not considered, since they are 1143 * not supported in the device parameters 1144 */ 1145 *efv = EFX_FW_VARIANT_DONT_CARE; 1146 break; 1147 } 1148 1149 return 0; 1150 } 1151 1152 static const char * 1153 sfc_fw_variant2str(efx_fw_variant_t efv) 1154 { 1155 switch (efv) { 1156 case EFX_RXDP_FULL_FEATURED_FW_ID: 1157 return SFC_KVARG_FW_VARIANT_FULL_FEATURED; 1158 case EFX_RXDP_LOW_LATENCY_FW_ID: 1159 return SFC_KVARG_FW_VARIANT_LOW_LATENCY; 1160 case EFX_RXDP_PACKED_STREAM_FW_ID: 1161 return SFC_KVARG_FW_VARIANT_PACKED_STREAM; 1162 case EFX_RXDP_DPDK_FW_ID: 1163 return SFC_KVARG_FW_VARIANT_DPDK; 1164 default: 1165 return "unknown"; 1166 } 1167 } 1168 1169 static int 1170 sfc_kvarg_rxd_wait_timeout_ns(struct sfc_adapter *sa) 1171 { 1172 int rc; 1173 long value; 1174 1175 value = SFC_RXD_WAIT_TIMEOUT_NS_DEF; 1176 1177 rc = sfc_kvargs_process(sa, SFC_KVARG_RXD_WAIT_TIMEOUT_NS, 1178 sfc_kvarg_long_handler, &value); 1179 if (rc != 0) 1180 return rc; 1181 1182 if (value < 0 || 1183 (unsigned long)value > EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX) { 1184 sfc_err(sa, "wrong '" SFC_KVARG_RXD_WAIT_TIMEOUT_NS "' " 1185 "was set (%ld);", value); 1186 sfc_err(sa, "it must not be less than 0 or greater than %u", 1187 EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX); 1188 return EINVAL; 1189 } 1190 1191 sa->rxd_wait_timeout_ns = value; 1192 return 0; 1193 } 1194 1195 static int 1196 sfc_nic_probe(struct sfc_adapter *sa) 1197 { 1198 efx_nic_t *enp = sa->nic; 1199 efx_fw_variant_t preferred_efv; 1200 efx_fw_variant_t efv; 1201 int rc; 1202 1203 preferred_efv = EFX_FW_VARIANT_DONT_CARE; 1204 rc = sfc_kvargs_process(sa, SFC_KVARG_FW_VARIANT, 1205 sfc_kvarg_fv_variant_handler, 1206 &preferred_efv); 1207 if (rc != 0) { 1208 sfc_err(sa, "invalid %s parameter value", SFC_KVARG_FW_VARIANT); 1209 return rc; 1210 } 1211 1212 rc = sfc_kvarg_rxd_wait_timeout_ns(sa); 1213 if (rc != 0) 1214 return rc; 1215 1216 rc = efx_nic_probe(enp, preferred_efv); 1217 if (rc == EACCES) { 1218 /* Unprivileged functions cannot set FW variant */ 1219 rc = efx_nic_probe(enp, EFX_FW_VARIANT_DONT_CARE); 1220 } 1221 if (rc != 0) 1222 return rc; 1223 1224 rc = sfc_get_fw_variant(sa, &efv); 1225 if (rc == ENOTSUP) { 1226 sfc_warn(sa, "FW variant can not be obtained"); 1227 return 0; 1228 } 1229 if (rc != 0) 1230 return rc; 1231 1232 /* Check that firmware variant was changed to the requested one */ 1233 if (preferred_efv != EFX_FW_VARIANT_DONT_CARE && preferred_efv != efv) { 1234 sfc_warn(sa, "FW variant has not changed to the requested %s", 1235 sfc_fw_variant2str(preferred_efv)); 1236 } 1237 1238 sfc_notice(sa, "running FW variant is %s", sfc_fw_variant2str(efv)); 1239 1240 return 0; 1241 } 1242 1243 int 1244 sfc_probe(struct sfc_adapter *sa) 1245 { 1246 efx_bar_region_t mem_ebrp; 1247 struct rte_eth_dev *eth_dev = sa->eth_dev; 1248 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 1249 efx_nic_t *enp; 1250 int rc; 1251 1252 sfc_log_init(sa, "entry"); 1253 1254 SFC_ASSERT(sfc_adapter_is_locked(sa)); 1255 1256 sa->socket_id = rte_socket_id(); 1257 rte_atomic32_init(&sa->restart_required); 1258 1259 sfc_log_init(sa, "get family"); 1260 rc = sfc_efx_family(pci_dev, &mem_ebrp, &sa->family); 1261 1262 if (rc != 0) 1263 goto fail_family; 1264 sfc_log_init(sa, 1265 "family is %u, membar is %u, function control window offset is %lu", 1266 sa->family, mem_ebrp.ebr_index, mem_ebrp.ebr_offset); 1267 1268 sfc_log_init(sa, "init mem bar"); 1269 rc = sfc_mem_bar_init(sa, &mem_ebrp); 1270 if (rc != 0) 1271 goto fail_mem_bar_init; 1272 1273 sfc_log_init(sa, "create nic"); 1274 rte_spinlock_init(&sa->nic_lock); 1275 rc = efx_nic_create(sa->family, (efsys_identifier_t *)sa, 1276 &sa->mem_bar, mem_ebrp.ebr_offset, 1277 &sa->nic_lock, &enp); 1278 if (rc != 0) 1279 goto fail_nic_create; 1280 sa->nic = enp; 1281 1282 rc = sfc_mcdi_init(sa); 1283 if (rc != 0) 1284 goto fail_mcdi_init; 1285 1286 sfc_log_init(sa, "probe nic"); 1287 rc = sfc_nic_probe(sa); 1288 if (rc != 0) 1289 goto fail_nic_probe; 1290 1291 sfc_log_init(sa, "done"); 1292 return 0; 1293 1294 fail_nic_probe: 1295 sfc_mcdi_fini(sa); 1296 1297 fail_mcdi_init: 1298 sfc_log_init(sa, "destroy nic"); 1299 sa->nic = NULL; 1300 efx_nic_destroy(enp); 1301 1302 fail_nic_create: 1303 sfc_mem_bar_fini(sa); 1304 1305 fail_mem_bar_init: 1306 fail_family: 1307 sfc_log_init(sa, "failed %d", rc); 1308 return rc; 1309 } 1310 1311 void 1312 sfc_unprobe(struct sfc_adapter *sa) 1313 { 1314 efx_nic_t *enp = sa->nic; 1315 1316 sfc_log_init(sa, "entry"); 1317 1318 SFC_ASSERT(sfc_adapter_is_locked(sa)); 1319 1320 sfc_log_init(sa, "unprobe nic"); 1321 efx_nic_unprobe(enp); 1322 1323 sfc_mcdi_fini(sa); 1324 1325 /* 1326 * Make sure there is no pending alarm to restart since we are 1327 * going to free device private which is passed as the callback 1328 * opaque data. A new alarm cannot be scheduled since MCDI is 1329 * shut down. 1330 */ 1331 rte_eal_alarm_cancel(sfc_restart_if_required, sa); 1332 1333 sfc_mae_clear_switch_port(sa->mae.switch_domain_id, 1334 sa->mae.switch_port_id); 1335 1336 sfc_log_init(sa, "destroy nic"); 1337 sa->nic = NULL; 1338 efx_nic_destroy(enp); 1339 1340 sfc_mem_bar_fini(sa); 1341 1342 sfc_flow_fini(sa); 1343 sa->state = SFC_ETHDEV_UNINITIALIZED; 1344 } 1345 1346 uint32_t 1347 sfc_register_logtype(const struct rte_pci_addr *pci_addr, 1348 const char *lt_prefix_str, uint32_t ll_default) 1349 { 1350 size_t lt_prefix_str_size = strlen(lt_prefix_str); 1351 size_t lt_str_size_max; 1352 char *lt_str = NULL; 1353 int ret; 1354 1355 if (SIZE_MAX - PCI_PRI_STR_SIZE - 1 > lt_prefix_str_size) { 1356 ++lt_prefix_str_size; /* Reserve space for prefix separator */ 1357 lt_str_size_max = lt_prefix_str_size + PCI_PRI_STR_SIZE + 1; 1358 } else { 1359 return sfc_logtype_driver; 1360 } 1361 1362 lt_str = rte_zmalloc("logtype_str", lt_str_size_max, 0); 1363 if (lt_str == NULL) 1364 return sfc_logtype_driver; 1365 1366 strncpy(lt_str, lt_prefix_str, lt_prefix_str_size); 1367 lt_str[lt_prefix_str_size - 1] = '.'; 1368 rte_pci_device_name(pci_addr, lt_str + lt_prefix_str_size, 1369 lt_str_size_max - lt_prefix_str_size); 1370 lt_str[lt_str_size_max - 1] = '\0'; 1371 1372 ret = rte_log_register_type_and_pick_level(lt_str, ll_default); 1373 rte_free(lt_str); 1374 1375 if (ret < 0) 1376 return sfc_logtype_driver; 1377 1378 return ret; 1379 } 1380 1381 struct sfc_hw_switch_id { 1382 char board_sn[RTE_SIZEOF_FIELD(efx_nic_board_info_t, enbi_serial)]; 1383 }; 1384 1385 int 1386 sfc_hw_switch_id_init(struct sfc_adapter *sa, 1387 struct sfc_hw_switch_id **idp) 1388 { 1389 efx_nic_board_info_t board_info; 1390 struct sfc_hw_switch_id *id; 1391 int rc; 1392 1393 if (idp == NULL) 1394 return EINVAL; 1395 1396 id = rte_zmalloc("sfc_hw_switch_id", sizeof(*id), 0); 1397 if (id == NULL) 1398 return ENOMEM; 1399 1400 rc = efx_nic_get_board_info(sa->nic, &board_info); 1401 if (rc != 0) 1402 return rc; 1403 1404 memcpy(id->board_sn, board_info.enbi_serial, sizeof(id->board_sn)); 1405 1406 *idp = id; 1407 1408 return 0; 1409 } 1410 1411 void 1412 sfc_hw_switch_id_fini(__rte_unused struct sfc_adapter *sa, 1413 struct sfc_hw_switch_id *id) 1414 { 1415 rte_free(id); 1416 } 1417 1418 bool 1419 sfc_hw_switch_ids_equal(const struct sfc_hw_switch_id *left, 1420 const struct sfc_hw_switch_id *right) 1421 { 1422 return strncmp(left->board_sn, right->board_sn, 1423 sizeof(left->board_sn)) == 0; 1424 } 1425