1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 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 #include <stdint.h> 11 12 #include <rte_flow_driver.h> 13 #include <rte_flow.h> 14 #include <rte_mbuf.h> 15 #include <rte_ethdev.h> 16 #include <rte_malloc.h> 17 #include <ethdev_driver.h> 18 19 #include "efx.h" 20 21 #include "sfc_log.h" 22 #include "sfc_debug.h" 23 #include "sfc_repr.h" 24 #include "sfc_ethdev_state.h" 25 #include "sfc_repr_proxy_api.h" 26 #include "sfc_switch.h" 27 #include "sfc_dp_tx.h" 28 29 /** Multi-process shared representor private data */ 30 struct sfc_repr_shared { 31 uint16_t pf_port_id; 32 uint16_t repr_id; 33 uint16_t switch_domain_id; 34 uint16_t switch_port_id; 35 }; 36 37 struct sfc_repr_queue_stats { 38 union sfc_pkts_bytes packets_bytes; 39 }; 40 41 struct sfc_repr_rxq { 42 /* Datapath members */ 43 struct rte_ring *ring; 44 struct sfc_repr_queue_stats stats; 45 }; 46 47 struct sfc_repr_txq { 48 /* Datapath members */ 49 struct rte_ring *ring; 50 efx_mport_id_t egress_mport; 51 struct sfc_repr_queue_stats stats; 52 }; 53 54 /** Primary process representor private data */ 55 struct sfc_repr { 56 /** 57 * PMD setup and configuration is not thread safe. Since it is not 58 * performance sensitive, it is better to guarantee thread-safety 59 * and add device level lock. Adapter control operations which 60 * change its state should acquire the lock. 61 */ 62 rte_spinlock_t lock; 63 enum sfc_ethdev_state state; 64 }; 65 66 #define sfcr_err(sr, ...) \ 67 do { \ 68 const struct sfc_repr *_sr = (sr); \ 69 \ 70 (void)_sr; \ 71 SFC_GENERIC_LOG(ERR, __VA_ARGS__); \ 72 } while (0) 73 74 #define sfcr_warn(sr, ...) \ 75 do { \ 76 const struct sfc_repr *_sr = (sr); \ 77 \ 78 (void)_sr; \ 79 SFC_GENERIC_LOG(WARNING, __VA_ARGS__); \ 80 } while (0) 81 82 #define sfcr_info(sr, ...) \ 83 do { \ 84 const struct sfc_repr *_sr = (sr); \ 85 \ 86 (void)_sr; \ 87 SFC_GENERIC_LOG(INFO, \ 88 RTE_FMT("%s() " \ 89 RTE_FMT_HEAD(__VA_ARGS__ ,), \ 90 __func__, \ 91 RTE_FMT_TAIL(__VA_ARGS__ ,))); \ 92 } while (0) 93 94 static inline struct sfc_repr_shared * 95 sfc_repr_shared_by_eth_dev(struct rte_eth_dev *eth_dev) 96 { 97 struct sfc_repr_shared *srs = eth_dev->data->dev_private; 98 99 return srs; 100 } 101 102 static inline struct sfc_repr * 103 sfc_repr_by_eth_dev(struct rte_eth_dev *eth_dev) 104 { 105 struct sfc_repr *sr = eth_dev->process_private; 106 107 return sr; 108 } 109 110 /* 111 * Add wrapper functions to acquire/release lock to be able to remove or 112 * change the lock in one place. 113 */ 114 115 static inline void 116 sfc_repr_lock_init(struct sfc_repr *sr) 117 { 118 rte_spinlock_init(&sr->lock); 119 } 120 121 #if defined(RTE_LIBRTE_SFC_EFX_DEBUG) || defined(RTE_ENABLE_ASSERT) 122 123 static inline int 124 sfc_repr_lock_is_locked(struct sfc_repr *sr) 125 { 126 return rte_spinlock_is_locked(&sr->lock); 127 } 128 129 #endif 130 131 static inline void 132 sfc_repr_lock(struct sfc_repr *sr) 133 { 134 rte_spinlock_lock(&sr->lock); 135 } 136 137 static inline void 138 sfc_repr_unlock(struct sfc_repr *sr) 139 { 140 rte_spinlock_unlock(&sr->lock); 141 } 142 143 static inline void 144 sfc_repr_lock_fini(__rte_unused struct sfc_repr *sr) 145 { 146 /* Just for symmetry of the API */ 147 } 148 149 static void 150 sfc_repr_rx_queue_stop(void *queue) 151 { 152 struct sfc_repr_rxq *rxq = queue; 153 154 if (rxq == NULL) 155 return; 156 157 rte_ring_reset(rxq->ring); 158 } 159 160 static void 161 sfc_repr_tx_queue_stop(void *queue) 162 { 163 struct sfc_repr_txq *txq = queue; 164 165 if (txq == NULL) 166 return; 167 168 rte_ring_reset(txq->ring); 169 } 170 171 static uint16_t 172 sfc_repr_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 173 { 174 struct sfc_repr_rxq *rxq = rx_queue; 175 void **objs = (void *)&rx_pkts[0]; 176 unsigned int n_rx; 177 178 /* mbufs port is already filled correctly by representors proxy */ 179 n_rx = rte_ring_sc_dequeue_burst(rxq->ring, objs, nb_pkts, NULL); 180 181 if (n_rx > 0) { 182 unsigned int n_bytes = 0; 183 unsigned int i = 0; 184 185 do { 186 n_bytes += rx_pkts[i]->pkt_len; 187 } while (++i < n_rx); 188 189 sfc_pkts_bytes_add(&rxq->stats.packets_bytes, n_rx, n_bytes); 190 } 191 192 return n_rx; 193 } 194 195 static uint16_t 196 sfc_repr_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 197 { 198 struct sfc_repr_txq *txq = tx_queue; 199 unsigned int n_bytes = 0; 200 unsigned int n_tx; 201 void **objs; 202 uint16_t i; 203 204 /* 205 * mbuf is likely cache-hot. Set flag and egress m-port here instead of 206 * doing that in representors proxy. Also, it should help to avoid 207 * cache bounce. Moreover, potentially, it allows to use one 208 * multi-producer single-consumer ring for all representors. 209 * 210 * The only potential problem is doing so many times if enqueue 211 * fails and sender retries. 212 */ 213 for (i = 0; i < nb_pkts; ++i) { 214 struct rte_mbuf *m = tx_pkts[i]; 215 216 m->ol_flags |= sfc_dp_mport_override; 217 *RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, 218 efx_mport_id_t *) = txq->egress_mport; 219 n_bytes += tx_pkts[i]->pkt_len; 220 } 221 222 objs = (void *)&tx_pkts[0]; 223 n_tx = rte_ring_sp_enqueue_burst(txq->ring, objs, nb_pkts, NULL); 224 225 /* 226 * Remove m-port override flag from packets that were not enqueued 227 * Setting the flag only for enqueued packets after the burst is 228 * not possible since the ownership of enqueued packets is 229 * transferred to representor proxy. The same logic applies to 230 * counting the enqueued packets' bytes. 231 */ 232 for (i = n_tx; i < nb_pkts; ++i) { 233 struct rte_mbuf *m = tx_pkts[i]; 234 235 m->ol_flags &= ~sfc_dp_mport_override; 236 n_bytes -= m->pkt_len; 237 } 238 239 sfc_pkts_bytes_add(&txq->stats.packets_bytes, n_tx, n_bytes); 240 241 return n_tx; 242 } 243 244 static int 245 sfc_repr_start(struct rte_eth_dev *dev) 246 { 247 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 248 struct sfc_repr_shared *srs; 249 int ret; 250 251 sfcr_info(sr, "entry"); 252 253 SFC_ASSERT(sfc_repr_lock_is_locked(sr)); 254 255 switch (sr->state) { 256 case SFC_ETHDEV_CONFIGURED: 257 break; 258 case SFC_ETHDEV_STARTED: 259 sfcr_info(sr, "already started"); 260 return 0; 261 default: 262 ret = -EINVAL; 263 goto fail_bad_state; 264 } 265 266 sr->state = SFC_ETHDEV_STARTING; 267 268 srs = sfc_repr_shared_by_eth_dev(dev); 269 ret = sfc_repr_proxy_start_repr(srs->pf_port_id, srs->repr_id); 270 if (ret != 0) { 271 SFC_ASSERT(ret > 0); 272 ret = -ret; 273 goto fail_start; 274 } 275 276 sr->state = SFC_ETHDEV_STARTED; 277 278 sfcr_info(sr, "done"); 279 280 return 0; 281 282 fail_start: 283 sr->state = SFC_ETHDEV_CONFIGURED; 284 285 fail_bad_state: 286 sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); 287 return ret; 288 } 289 290 static int 291 sfc_repr_dev_start(struct rte_eth_dev *dev) 292 { 293 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 294 int ret; 295 296 sfcr_info(sr, "entry"); 297 298 sfc_repr_lock(sr); 299 ret = sfc_repr_start(dev); 300 sfc_repr_unlock(sr); 301 302 if (ret != 0) 303 goto fail_start; 304 305 sfcr_info(sr, "done"); 306 307 return 0; 308 309 fail_start: 310 sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); 311 return ret; 312 } 313 314 static int 315 sfc_repr_stop(struct rte_eth_dev *dev) 316 { 317 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 318 struct sfc_repr_shared *srs; 319 unsigned int i; 320 int ret; 321 322 sfcr_info(sr, "entry"); 323 324 SFC_ASSERT(sfc_repr_lock_is_locked(sr)); 325 326 switch (sr->state) { 327 case SFC_ETHDEV_STARTED: 328 break; 329 case SFC_ETHDEV_CONFIGURED: 330 sfcr_info(sr, "already stopped"); 331 return 0; 332 default: 333 sfcr_err(sr, "stop in unexpected state %u", sr->state); 334 SFC_ASSERT(B_FALSE); 335 ret = -EINVAL; 336 goto fail_bad_state; 337 } 338 339 srs = sfc_repr_shared_by_eth_dev(dev); 340 ret = sfc_repr_proxy_stop_repr(srs->pf_port_id, srs->repr_id); 341 if (ret != 0) { 342 SFC_ASSERT(ret > 0); 343 ret = -ret; 344 goto fail_stop; 345 } 346 347 for (i = 0; i < dev->data->nb_rx_queues; i++) 348 sfc_repr_rx_queue_stop(dev->data->rx_queues[i]); 349 350 for (i = 0; i < dev->data->nb_tx_queues; i++) 351 sfc_repr_tx_queue_stop(dev->data->tx_queues[i]); 352 353 sr->state = SFC_ETHDEV_CONFIGURED; 354 sfcr_info(sr, "done"); 355 356 return 0; 357 358 fail_bad_state: 359 fail_stop: 360 sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); 361 362 return ret; 363 } 364 365 static int 366 sfc_repr_dev_stop(struct rte_eth_dev *dev) 367 { 368 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 369 int ret; 370 371 sfcr_info(sr, "entry"); 372 373 sfc_repr_lock(sr); 374 375 ret = sfc_repr_stop(dev); 376 if (ret != 0) { 377 sfcr_err(sr, "%s() failed to stop representor", __func__); 378 goto fail_stop; 379 } 380 381 sfc_repr_unlock(sr); 382 383 sfcr_info(sr, "done"); 384 385 return 0; 386 387 fail_stop: 388 sfc_repr_unlock(sr); 389 390 sfcr_err(sr, "%s() failed %s", __func__, rte_strerror(-ret)); 391 392 return ret; 393 } 394 395 static int 396 sfc_repr_check_conf(struct sfc_repr *sr, uint16_t nb_rx_queues, 397 const struct rte_eth_conf *conf) 398 { 399 const struct rte_eth_rss_conf *rss_conf; 400 int ret = 0; 401 402 sfcr_info(sr, "entry"); 403 404 if (conf->link_speeds != 0) { 405 sfcr_err(sr, "specific link speeds not supported"); 406 ret = -EINVAL; 407 } 408 409 switch (conf->rxmode.mq_mode) { 410 case RTE_ETH_MQ_RX_RSS: 411 if (nb_rx_queues != 1) { 412 sfcr_err(sr, "Rx RSS is not supported with %u queues", 413 nb_rx_queues); 414 ret = -EINVAL; 415 break; 416 } 417 418 rss_conf = &conf->rx_adv_conf.rss_conf; 419 if (rss_conf->rss_key != NULL || rss_conf->rss_key_len != 0 || 420 rss_conf->rss_hf != 0) { 421 sfcr_err(sr, "Rx RSS configuration is not supported"); 422 ret = -EINVAL; 423 } 424 break; 425 case RTE_ETH_MQ_RX_NONE: 426 break; 427 default: 428 sfcr_err(sr, "Rx mode MQ modes other than RSS not supported"); 429 ret = -EINVAL; 430 break; 431 } 432 433 if (conf->txmode.mq_mode != RTE_ETH_MQ_TX_NONE) { 434 sfcr_err(sr, "Tx mode MQ modes not supported"); 435 ret = -EINVAL; 436 } 437 438 if (conf->lpbk_mode != 0) { 439 sfcr_err(sr, "loopback not supported"); 440 ret = -EINVAL; 441 } 442 443 if (conf->dcb_capability_en != 0) { 444 sfcr_err(sr, "priority-based flow control not supported"); 445 ret = -EINVAL; 446 } 447 448 if (conf->intr_conf.lsc != 0) { 449 sfcr_err(sr, "link status change interrupt not supported"); 450 ret = -EINVAL; 451 } 452 453 if (conf->intr_conf.rxq != 0) { 454 sfcr_err(sr, "receive queue interrupt not supported"); 455 ret = -EINVAL; 456 } 457 458 if (conf->intr_conf.rmv != 0) { 459 sfcr_err(sr, "remove interrupt not supported"); 460 ret = -EINVAL; 461 } 462 463 sfcr_info(sr, "done %d", ret); 464 465 return ret; 466 } 467 468 469 static int 470 sfc_repr_configure(struct sfc_repr *sr, uint16_t nb_rx_queues, 471 const struct rte_eth_conf *conf) 472 { 473 int ret; 474 475 sfcr_info(sr, "entry"); 476 477 SFC_ASSERT(sfc_repr_lock_is_locked(sr)); 478 479 ret = sfc_repr_check_conf(sr, nb_rx_queues, conf); 480 if (ret != 0) 481 goto fail_check_conf; 482 483 sr->state = SFC_ETHDEV_CONFIGURED; 484 485 sfcr_info(sr, "done"); 486 487 return 0; 488 489 fail_check_conf: 490 sfcr_info(sr, "failed %s", rte_strerror(-ret)); 491 return ret; 492 } 493 494 static int 495 sfc_repr_dev_configure(struct rte_eth_dev *dev) 496 { 497 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 498 struct rte_eth_dev_data *dev_data = dev->data; 499 int ret; 500 501 sfcr_info(sr, "entry n_rxq=%u n_txq=%u", 502 dev_data->nb_rx_queues, dev_data->nb_tx_queues); 503 504 sfc_repr_lock(sr); 505 switch (sr->state) { 506 case SFC_ETHDEV_CONFIGURED: 507 /* FALLTHROUGH */ 508 case SFC_ETHDEV_INITIALIZED: 509 ret = sfc_repr_configure(sr, dev_data->nb_rx_queues, 510 &dev_data->dev_conf); 511 break; 512 default: 513 sfcr_err(sr, "unexpected adapter state %u to configure", 514 sr->state); 515 ret = -EINVAL; 516 break; 517 } 518 sfc_repr_unlock(sr); 519 520 sfcr_info(sr, "done %s", rte_strerror(-ret)); 521 522 return ret; 523 } 524 525 static int 526 sfc_repr_dev_infos_get(struct rte_eth_dev *dev, 527 struct rte_eth_dev_info *dev_info) 528 { 529 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 530 531 dev_info->device = dev->device; 532 533 dev_info->max_rx_queues = SFC_REPR_RXQ_MAX; 534 dev_info->max_tx_queues = SFC_REPR_TXQ_MAX; 535 dev_info->default_rxconf.rx_drop_en = 1; 536 dev_info->switch_info.domain_id = srs->switch_domain_id; 537 dev_info->switch_info.port_id = srs->switch_port_id; 538 539 return 0; 540 } 541 542 static int 543 sfc_repr_dev_link_update(struct rte_eth_dev *dev, 544 __rte_unused int wait_to_complete) 545 { 546 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 547 struct rte_eth_link link; 548 549 if (sr->state != SFC_ETHDEV_STARTED) { 550 sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, &link); 551 } else { 552 memset(&link, 0, sizeof(link)); 553 link.link_status = RTE_ETH_LINK_UP; 554 link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN; 555 } 556 557 return rte_eth_linkstatus_set(dev, &link); 558 } 559 560 static int 561 sfc_repr_ring_create(uint16_t pf_port_id, uint16_t repr_id, 562 const char *type_name, uint16_t qid, uint16_t nb_desc, 563 unsigned int socket_id, struct rte_ring **ring) 564 { 565 char ring_name[RTE_RING_NAMESIZE]; 566 int ret; 567 568 ret = snprintf(ring_name, sizeof(ring_name), "sfc_%u_repr_%u_%sq%u", 569 pf_port_id, repr_id, type_name, qid); 570 if (ret >= (int)sizeof(ring_name)) 571 return -ENAMETOOLONG; 572 573 /* 574 * Single producer/consumer rings are used since the API for Tx/Rx 575 * packet burst for representors are guaranteed to be called from 576 * a single thread, and the user of the other end (representor proxy) 577 * is also single-threaded. 578 */ 579 *ring = rte_ring_create(ring_name, nb_desc, socket_id, 580 RING_F_SP_ENQ | RING_F_SC_DEQ); 581 if (*ring == NULL) 582 return -rte_errno; 583 584 return 0; 585 } 586 587 static int 588 sfc_repr_rx_qcheck_conf(struct sfc_repr *sr, 589 const struct rte_eth_rxconf *rx_conf) 590 { 591 int ret = 0; 592 593 sfcr_info(sr, "entry"); 594 595 if (rx_conf->rx_thresh.pthresh != 0 || 596 rx_conf->rx_thresh.hthresh != 0 || 597 rx_conf->rx_thresh.wthresh != 0) { 598 sfcr_warn(sr, 599 "RxQ prefetch/host/writeback thresholds are not supported"); 600 } 601 602 if (rx_conf->rx_free_thresh != 0) 603 sfcr_warn(sr, "RxQ free threshold is not supported"); 604 605 if (rx_conf->rx_drop_en == 0) 606 sfcr_warn(sr, "RxQ drop disable is not supported"); 607 608 if (rx_conf->rx_deferred_start) { 609 sfcr_err(sr, "Deferred start is not supported"); 610 ret = -EINVAL; 611 } 612 613 sfcr_info(sr, "done: %s", rte_strerror(-ret)); 614 615 return ret; 616 } 617 618 static int 619 sfc_repr_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, 620 uint16_t nb_rx_desc, unsigned int socket_id, 621 __rte_unused const struct rte_eth_rxconf *rx_conf, 622 struct rte_mempool *mb_pool) 623 { 624 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 625 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 626 struct sfc_repr_rxq *rxq; 627 int ret; 628 629 sfcr_info(sr, "entry"); 630 631 ret = sfc_repr_rx_qcheck_conf(sr, rx_conf); 632 if (ret != 0) 633 goto fail_check_conf; 634 635 ret = -ENOMEM; 636 rxq = rte_zmalloc_socket("sfc-repr-rxq", sizeof(*rxq), 637 RTE_CACHE_LINE_SIZE, socket_id); 638 if (rxq == NULL) { 639 sfcr_err(sr, "%s() failed to alloc RxQ", __func__); 640 goto fail_rxq_alloc; 641 } 642 643 ret = sfc_repr_ring_create(srs->pf_port_id, srs->repr_id, 644 "rx", rx_queue_id, nb_rx_desc, 645 socket_id, &rxq->ring); 646 if (ret != 0) { 647 sfcr_err(sr, "%s() failed to create ring", __func__); 648 goto fail_ring_create; 649 } 650 651 ret = sfc_repr_proxy_add_rxq(srs->pf_port_id, srs->repr_id, 652 rx_queue_id, rxq->ring, mb_pool); 653 if (ret != 0) { 654 SFC_ASSERT(ret > 0); 655 ret = -ret; 656 sfcr_err(sr, "%s() failed to add proxy RxQ", __func__); 657 goto fail_proxy_add_rxq; 658 } 659 660 dev->data->rx_queues[rx_queue_id] = rxq; 661 662 sfcr_info(sr, "done"); 663 664 return 0; 665 666 fail_proxy_add_rxq: 667 rte_ring_free(rxq->ring); 668 669 fail_ring_create: 670 rte_free(rxq); 671 672 fail_rxq_alloc: 673 fail_check_conf: 674 sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); 675 return ret; 676 } 677 678 static void 679 sfc_repr_rx_queue_release(struct rte_eth_dev *dev, uint16_t rx_queue_id) 680 { 681 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 682 struct sfc_repr_rxq *rxq = dev->data->rx_queues[rx_queue_id]; 683 684 sfc_repr_proxy_del_rxq(srs->pf_port_id, srs->repr_id, rx_queue_id); 685 rte_ring_free(rxq->ring); 686 rte_free(rxq); 687 } 688 689 static int 690 sfc_repr_tx_qcheck_conf(struct sfc_repr *sr, 691 const struct rte_eth_txconf *tx_conf) 692 { 693 int ret = 0; 694 695 sfcr_info(sr, "entry"); 696 697 if (tx_conf->tx_rs_thresh != 0) 698 sfcr_warn(sr, "RS bit in transmit descriptor is not supported"); 699 700 if (tx_conf->tx_free_thresh != 0) 701 sfcr_warn(sr, "TxQ free threshold is not supported"); 702 703 if (tx_conf->tx_thresh.pthresh != 0 || 704 tx_conf->tx_thresh.hthresh != 0 || 705 tx_conf->tx_thresh.wthresh != 0) { 706 sfcr_warn(sr, 707 "prefetch/host/writeback thresholds are not supported"); 708 } 709 710 if (tx_conf->tx_deferred_start) { 711 sfcr_err(sr, "Deferred start is not supported"); 712 ret = -EINVAL; 713 } 714 715 sfcr_info(sr, "done: %s", rte_strerror(-ret)); 716 717 return ret; 718 } 719 720 static int 721 sfc_repr_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, 722 uint16_t nb_tx_desc, unsigned int socket_id, 723 const struct rte_eth_txconf *tx_conf) 724 { 725 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 726 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 727 struct sfc_repr_txq *txq; 728 int ret; 729 730 sfcr_info(sr, "entry"); 731 732 ret = sfc_repr_tx_qcheck_conf(sr, tx_conf); 733 if (ret != 0) 734 goto fail_check_conf; 735 736 ret = -ENOMEM; 737 txq = rte_zmalloc_socket("sfc-repr-txq", sizeof(*txq), 738 RTE_CACHE_LINE_SIZE, socket_id); 739 if (txq == NULL) 740 goto fail_txq_alloc; 741 742 ret = sfc_repr_ring_create(srs->pf_port_id, srs->repr_id, 743 "tx", tx_queue_id, nb_tx_desc, 744 socket_id, &txq->ring); 745 if (ret != 0) 746 goto fail_ring_create; 747 748 ret = sfc_repr_proxy_add_txq(srs->pf_port_id, srs->repr_id, 749 tx_queue_id, txq->ring, 750 &txq->egress_mport); 751 if (ret != 0) 752 goto fail_proxy_add_txq; 753 754 dev->data->tx_queues[tx_queue_id] = txq; 755 756 sfcr_info(sr, "done"); 757 758 return 0; 759 760 fail_proxy_add_txq: 761 rte_ring_free(txq->ring); 762 763 fail_ring_create: 764 rte_free(txq); 765 766 fail_txq_alloc: 767 fail_check_conf: 768 sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); 769 return ret; 770 } 771 772 static void 773 sfc_repr_tx_queue_release(struct rte_eth_dev *dev, uint16_t tx_queue_id) 774 { 775 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 776 struct sfc_repr_txq *txq = dev->data->tx_queues[tx_queue_id]; 777 778 sfc_repr_proxy_del_txq(srs->pf_port_id, srs->repr_id, tx_queue_id); 779 rte_ring_free(txq->ring); 780 rte_free(txq); 781 } 782 783 static void 784 sfc_repr_close(struct sfc_repr *sr) 785 { 786 SFC_ASSERT(sfc_repr_lock_is_locked(sr)); 787 788 SFC_ASSERT(sr->state == SFC_ETHDEV_CONFIGURED); 789 sr->state = SFC_ETHDEV_CLOSING; 790 791 /* Put representor close actions here */ 792 793 sr->state = SFC_ETHDEV_INITIALIZED; 794 } 795 796 static int 797 sfc_repr_dev_close(struct rte_eth_dev *dev) 798 { 799 struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); 800 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 801 unsigned int i; 802 803 sfcr_info(sr, "entry"); 804 805 sfc_repr_lock(sr); 806 switch (sr->state) { 807 case SFC_ETHDEV_STARTED: 808 sfc_repr_stop(dev); 809 SFC_ASSERT(sr->state == SFC_ETHDEV_CONFIGURED); 810 /* FALLTHROUGH */ 811 case SFC_ETHDEV_CONFIGURED: 812 sfc_repr_close(sr); 813 SFC_ASSERT(sr->state == SFC_ETHDEV_INITIALIZED); 814 /* FALLTHROUGH */ 815 case SFC_ETHDEV_INITIALIZED: 816 break; 817 default: 818 sfcr_err(sr, "unexpected adapter state %u on close", sr->state); 819 break; 820 } 821 822 for (i = 0; i < dev->data->nb_rx_queues; i++) { 823 sfc_repr_rx_queue_release(dev, i); 824 dev->data->rx_queues[i] = NULL; 825 } 826 827 for (i = 0; i < dev->data->nb_tx_queues; i++) { 828 sfc_repr_tx_queue_release(dev, i); 829 dev->data->tx_queues[i] = NULL; 830 } 831 832 /* 833 * Cleanup all resources. 834 * Rollback primary process sfc_repr_eth_dev_init() below. 835 */ 836 837 (void)sfc_repr_proxy_del_port(srs->pf_port_id, srs->repr_id); 838 839 dev->rx_pkt_burst = NULL; 840 dev->tx_pkt_burst = NULL; 841 dev->dev_ops = NULL; 842 843 sfc_repr_unlock(sr); 844 sfc_repr_lock_fini(sr); 845 846 sfcr_info(sr, "done"); 847 848 free(sr); 849 850 return 0; 851 } 852 853 static int 854 sfc_repr_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) 855 { 856 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 857 int ret; 858 859 ret = sfc_repr_proxy_repr_entity_mac_addr_set(srs->pf_port_id, 860 srs->repr_id, mac_addr); 861 return -ret; 862 } 863 864 static int 865 sfc_repr_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 866 { 867 union sfc_pkts_bytes queue_stats; 868 uint16_t i; 869 870 for (i = 0; i < dev->data->nb_rx_queues; i++) { 871 struct sfc_repr_rxq *rxq = dev->data->rx_queues[i]; 872 873 sfc_pkts_bytes_get(&rxq->stats.packets_bytes, 874 &queue_stats); 875 876 stats->ipackets += queue_stats.pkts; 877 stats->ibytes += queue_stats.bytes; 878 } 879 880 for (i = 0; i < dev->data->nb_tx_queues; i++) { 881 struct sfc_repr_txq *txq = dev->data->tx_queues[i]; 882 883 sfc_pkts_bytes_get(&txq->stats.packets_bytes, 884 &queue_stats); 885 886 stats->opackets += queue_stats.pkts; 887 stats->obytes += queue_stats.bytes; 888 } 889 890 return 0; 891 } 892 893 static int 894 sfc_repr_flow_pick_transfer_proxy(struct rte_eth_dev *dev, 895 uint16_t *transfer_proxy_port, 896 struct rte_flow_error *error) 897 { 898 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 899 900 return rte_flow_pick_transfer_proxy(srs->pf_port_id, 901 transfer_proxy_port, error); 902 } 903 904 const struct rte_flow_ops sfc_repr_flow_ops = { 905 .pick_transfer_proxy = sfc_repr_flow_pick_transfer_proxy, 906 }; 907 908 static int 909 sfc_repr_dev_flow_ops_get(struct rte_eth_dev *dev __rte_unused, 910 const struct rte_flow_ops **ops) 911 { 912 *ops = &sfc_repr_flow_ops; 913 return 0; 914 } 915 916 static const struct eth_dev_ops sfc_repr_dev_ops = { 917 .dev_configure = sfc_repr_dev_configure, 918 .dev_start = sfc_repr_dev_start, 919 .dev_stop = sfc_repr_dev_stop, 920 .dev_close = sfc_repr_dev_close, 921 .dev_infos_get = sfc_repr_dev_infos_get, 922 .link_update = sfc_repr_dev_link_update, 923 .mac_addr_set = sfc_repr_mac_addr_set, 924 .stats_get = sfc_repr_stats_get, 925 .rx_queue_setup = sfc_repr_rx_queue_setup, 926 .rx_queue_release = sfc_repr_rx_queue_release, 927 .tx_queue_setup = sfc_repr_tx_queue_setup, 928 .tx_queue_release = sfc_repr_tx_queue_release, 929 .flow_ops_get = sfc_repr_dev_flow_ops_get, 930 }; 931 932 933 struct sfc_repr_init_data { 934 uint16_t pf_port_id; 935 uint16_t switch_domain_id; 936 efx_mport_sel_t mport_sel; 937 efx_pcie_interface_t intf; 938 uint16_t pf; 939 uint16_t vf; 940 }; 941 942 static int 943 sfc_repr_assign_mae_switch_port(uint16_t switch_domain_id, 944 const struct sfc_mae_switch_port_request *req, 945 uint16_t *switch_port_id) 946 { 947 int rc; 948 949 rc = sfc_mae_assign_switch_port(switch_domain_id, req, switch_port_id); 950 951 SFC_ASSERT(rc >= 0); 952 return -rc; 953 } 954 955 static int 956 sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) 957 { 958 const struct sfc_repr_init_data *repr_data = init_params; 959 struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); 960 struct sfc_mae_switch_port_request switch_port_request; 961 efx_mport_sel_t ethdev_mport_sel; 962 struct sfc_repr *sr; 963 int ret; 964 965 /* 966 * Currently there is no mport we can use for representor's 967 * ethdev. Use an invalid one for now. This way representors 968 * can be instantiated. 969 */ 970 efx_mae_mport_invalid(ðdev_mport_sel); 971 972 memset(&switch_port_request, 0, sizeof(switch_port_request)); 973 switch_port_request.type = SFC_MAE_SWITCH_PORT_REPRESENTOR; 974 switch_port_request.ethdev_mportp = ðdev_mport_sel; 975 switch_port_request.entity_mportp = &repr_data->mport_sel; 976 switch_port_request.ethdev_port_id = dev->data->port_id; 977 switch_port_request.port_data.repr.intf = repr_data->intf; 978 switch_port_request.port_data.repr.pf = repr_data->pf; 979 switch_port_request.port_data.repr.vf = repr_data->vf; 980 981 ret = sfc_repr_assign_mae_switch_port(repr_data->switch_domain_id, 982 &switch_port_request, 983 &srs->switch_port_id); 984 if (ret != 0) { 985 SFC_GENERIC_LOG(ERR, 986 "%s() failed to assign MAE switch port (domain id %u)", 987 __func__, repr_data->switch_domain_id); 988 goto fail_mae_assign_switch_port; 989 } 990 991 ret = sfc_repr_proxy_add_port(repr_data->pf_port_id, 992 srs->switch_port_id, dev->data->port_id, 993 &repr_data->mport_sel, repr_data->intf, 994 repr_data->pf, repr_data->vf); 995 if (ret != 0) { 996 SFC_GENERIC_LOG(ERR, "%s() failed to add repr proxy port", 997 __func__); 998 SFC_ASSERT(ret > 0); 999 ret = -ret; 1000 goto fail_create_port; 1001 } 1002 1003 /* 1004 * Allocate process private data from heap, since it should not 1005 * be located in shared memory allocated using rte_malloc() API. 1006 */ 1007 sr = calloc(1, sizeof(*sr)); 1008 if (sr == NULL) { 1009 ret = -ENOMEM; 1010 goto fail_alloc_sr; 1011 } 1012 1013 sfc_repr_lock_init(sr); 1014 sfc_repr_lock(sr); 1015 1016 dev->process_private = sr; 1017 1018 srs->pf_port_id = repr_data->pf_port_id; 1019 srs->repr_id = srs->switch_port_id; 1020 srs->switch_domain_id = repr_data->switch_domain_id; 1021 1022 dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR; 1023 dev->data->representor_id = srs->repr_id; 1024 dev->data->backer_port_id = srs->pf_port_id; 1025 1026 dev->data->mac_addrs = rte_zmalloc("sfcr", RTE_ETHER_ADDR_LEN, 0); 1027 if (dev->data->mac_addrs == NULL) { 1028 ret = -ENOMEM; 1029 goto fail_mac_addrs; 1030 } 1031 1032 rte_eth_random_addr(dev->data->mac_addrs[0].addr_bytes); 1033 1034 ret = sfc_repr_proxy_repr_entity_mac_addr_set(repr_data->pf_port_id, 1035 srs->repr_id, 1036 &dev->data->mac_addrs[0]); 1037 if (ret != 0) { 1038 ret = -ret; 1039 goto fail_mac_addr_set; 1040 } 1041 1042 dev->rx_pkt_burst = sfc_repr_rx_burst; 1043 dev->tx_pkt_burst = sfc_repr_tx_burst; 1044 dev->dev_ops = &sfc_repr_dev_ops; 1045 1046 sr->state = SFC_ETHDEV_INITIALIZED; 1047 sfc_repr_unlock(sr); 1048 1049 return 0; 1050 1051 fail_mac_addr_set: 1052 fail_mac_addrs: 1053 sfc_repr_unlock(sr); 1054 free(sr); 1055 1056 fail_alloc_sr: 1057 (void)sfc_repr_proxy_del_port(repr_data->pf_port_id, 1058 srs->switch_port_id); 1059 1060 fail_create_port: 1061 fail_mae_assign_switch_port: 1062 SFC_GENERIC_LOG(ERR, "%s() failed: %s", __func__, rte_strerror(-ret)); 1063 return ret; 1064 } 1065 1066 int 1067 sfc_repr_create(struct rte_eth_dev *parent, 1068 struct sfc_repr_entity_info *entity, 1069 uint16_t switch_domain_id, 1070 const efx_mport_sel_t *mport_sel) 1071 { 1072 struct sfc_repr_init_data repr_data; 1073 char name[RTE_ETH_NAME_MAX_LEN]; 1074 int controller; 1075 int ret; 1076 int rc; 1077 struct rte_eth_dev *dev; 1078 1079 controller = -1; 1080 rc = sfc_mae_switch_domain_get_controller(switch_domain_id, 1081 entity->intf, &controller); 1082 if (rc != 0) { 1083 SFC_GENERIC_LOG(ERR, "%s() failed to get DPDK controller for %d", 1084 __func__, entity->intf); 1085 return -rc; 1086 } 1087 1088 switch (entity->type) { 1089 case RTE_ETH_REPRESENTOR_VF: 1090 ret = snprintf(name, sizeof(name), "net_%s_representor_c%upf%uvf%u", 1091 parent->device->name, controller, entity->pf, 1092 entity->vf); 1093 break; 1094 case RTE_ETH_REPRESENTOR_PF: 1095 ret = snprintf(name, sizeof(name), "net_%s_representor_c%upf%u", 1096 parent->device->name, controller, entity->pf); 1097 break; 1098 default: 1099 return -ENOTSUP; 1100 } 1101 1102 if (ret >= (int)sizeof(name)) { 1103 SFC_GENERIC_LOG(ERR, "%s() failed name too long", __func__); 1104 return -ENAMETOOLONG; 1105 } 1106 1107 dev = rte_eth_dev_allocated(name); 1108 if (dev == NULL) { 1109 memset(&repr_data, 0, sizeof(repr_data)); 1110 repr_data.pf_port_id = parent->data->port_id; 1111 repr_data.switch_domain_id = switch_domain_id; 1112 repr_data.mport_sel = *mport_sel; 1113 repr_data.intf = entity->intf; 1114 repr_data.pf = entity->pf; 1115 repr_data.vf = entity->vf; 1116 1117 ret = rte_eth_dev_create(parent->device, name, 1118 sizeof(struct sfc_repr_shared), 1119 NULL, NULL, 1120 sfc_repr_eth_dev_init, &repr_data); 1121 if (ret != 0) { 1122 SFC_GENERIC_LOG(ERR, "%s() failed to create device", 1123 __func__); 1124 return ret; 1125 } 1126 } 1127 1128 return 0; 1129 } 1130