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 <rte_service.h> 11 #include <rte_service_component.h> 12 13 #include "sfc_log.h" 14 #include "sfc_service.h" 15 #include "sfc_repr_proxy.h" 16 #include "sfc_repr_proxy_api.h" 17 #include "sfc.h" 18 #include "sfc_ev.h" 19 #include "sfc_rx.h" 20 #include "sfc_tx.h" 21 #include "sfc_dp_rx.h" 22 23 /** 24 * Amount of time to wait for the representor proxy routine (which is 25 * running on a service core) to handle a request sent via mbox. 26 */ 27 #define SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS 1000 28 29 /** 30 * Amount of time to wait for the representor proxy routine (which is 31 * running on a service core) to terminate after service core is stopped. 32 */ 33 #define SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS 10000 34 35 #define SFC_REPR_INVALID_ROUTE_PORT_ID (UINT16_MAX) 36 37 static struct sfc_repr_proxy * 38 sfc_repr_proxy_by_adapter(struct sfc_adapter *sa) 39 { 40 return &sa->repr_proxy; 41 } 42 43 static struct sfc_adapter * 44 sfc_get_adapter_by_pf_port_id(uint16_t pf_port_id) 45 { 46 struct rte_eth_dev *dev; 47 struct sfc_adapter *sa; 48 49 SFC_ASSERT(pf_port_id < RTE_MAX_ETHPORTS); 50 51 dev = &rte_eth_devices[pf_port_id]; 52 sa = sfc_adapter_by_eth_dev(dev); 53 54 sfc_adapter_lock(sa); 55 56 return sa; 57 } 58 59 static void 60 sfc_put_adapter(struct sfc_adapter *sa) 61 { 62 sfc_adapter_unlock(sa); 63 } 64 65 static struct sfc_repr_proxy_port * 66 sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id) 67 { 68 struct sfc_repr_proxy_port *port; 69 70 TAILQ_FOREACH(port, &rp->ports, entries) { 71 if (port->repr_id == repr_id) 72 return port; 73 } 74 75 return NULL; 76 } 77 78 static int 79 sfc_repr_proxy_mbox_send(struct sfc_repr_proxy_mbox *mbox, 80 struct sfc_repr_proxy_port *port, 81 enum sfc_repr_proxy_mbox_op op) 82 { 83 const unsigned int wait_ms = SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS; 84 unsigned int i; 85 86 mbox->op = op; 87 mbox->port = port; 88 mbox->ack = false; 89 90 /* 91 * Release ordering enforces marker set after data is populated. 92 * Paired with acquire ordering in sfc_repr_proxy_mbox_handle(). 93 */ 94 __atomic_store_n(&mbox->write_marker, true, __ATOMIC_RELEASE); 95 96 /* 97 * Wait for the representor routine to process the request. 98 * Give up on timeout. 99 */ 100 for (i = 0; i < wait_ms; i++) { 101 /* 102 * Paired with release ordering in sfc_repr_proxy_mbox_handle() 103 * on acknowledge write. 104 */ 105 if (__atomic_load_n(&mbox->ack, __ATOMIC_ACQUIRE)) 106 break; 107 108 rte_delay_ms(1); 109 } 110 111 if (i == wait_ms) { 112 SFC_GENERIC_LOG(ERR, 113 "%s() failed to wait for representor proxy routine ack", 114 __func__); 115 return ETIMEDOUT; 116 } 117 118 return 0; 119 } 120 121 static void 122 sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp) 123 { 124 struct sfc_repr_proxy_mbox *mbox = &rp->mbox; 125 126 /* 127 * Paired with release ordering in sfc_repr_proxy_mbox_send() 128 * on marker set. 129 */ 130 if (!__atomic_load_n(&mbox->write_marker, __ATOMIC_ACQUIRE)) 131 return; 132 133 mbox->write_marker = false; 134 135 switch (mbox->op) { 136 case SFC_REPR_PROXY_MBOX_ADD_PORT: 137 TAILQ_INSERT_TAIL(&rp->ports, mbox->port, entries); 138 break; 139 case SFC_REPR_PROXY_MBOX_DEL_PORT: 140 TAILQ_REMOVE(&rp->ports, mbox->port, entries); 141 break; 142 case SFC_REPR_PROXY_MBOX_START_PORT: 143 mbox->port->started = true; 144 break; 145 case SFC_REPR_PROXY_MBOX_STOP_PORT: 146 mbox->port->started = false; 147 break; 148 default: 149 SFC_ASSERT(0); 150 return; 151 } 152 153 /* 154 * Paired with acquire ordering in sfc_repr_proxy_mbox_send() 155 * on acknowledge read. 156 */ 157 __atomic_store_n(&mbox->ack, true, __ATOMIC_RELEASE); 158 } 159 160 static void 161 sfc_repr_proxy_handle_tx(struct sfc_repr_proxy_dp_txq *rp_txq, 162 struct sfc_repr_proxy_txq *repr_txq) 163 { 164 /* 165 * With multiple representor proxy queues configured it is 166 * possible that not all of the corresponding representor 167 * queues were created. Skip the queues that do not exist. 168 */ 169 if (repr_txq->ring == NULL) 170 return; 171 172 if (rp_txq->available < RTE_DIM(rp_txq->tx_pkts)) { 173 rp_txq->available += 174 rte_ring_sc_dequeue_burst(repr_txq->ring, 175 (void **)(&rp_txq->tx_pkts[rp_txq->available]), 176 RTE_DIM(rp_txq->tx_pkts) - rp_txq->available, 177 NULL); 178 179 if (rp_txq->available == rp_txq->transmitted) 180 return; 181 } 182 183 rp_txq->transmitted += rp_txq->pkt_burst(rp_txq->dp, 184 &rp_txq->tx_pkts[rp_txq->transmitted], 185 rp_txq->available - rp_txq->transmitted); 186 187 if (rp_txq->available == rp_txq->transmitted) { 188 rp_txq->available = 0; 189 rp_txq->transmitted = 0; 190 } 191 } 192 193 static struct sfc_repr_proxy_port * 194 sfc_repr_proxy_rx_route_mbuf(struct sfc_repr_proxy *rp, struct rte_mbuf *m) 195 { 196 struct sfc_repr_proxy_port *port; 197 efx_mport_id_t mport_id; 198 199 mport_id.id = *RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, 200 typeof(&((efx_mport_id_t *)0)->id)); 201 202 TAILQ_FOREACH(port, &rp->ports, entries) { 203 if (port->egress_mport.id == mport_id.id) { 204 m->port = port->rte_port_id; 205 m->ol_flags &= ~sfc_dp_mport_override; 206 return port; 207 } 208 } 209 210 return NULL; 211 } 212 213 /* 214 * Returns true if a packet is encountered which should be forwarded to a 215 * port which is different from the one that is currently routed. 216 */ 217 static bool 218 sfc_repr_proxy_rx_route(struct sfc_repr_proxy *rp, 219 struct sfc_repr_proxy_dp_rxq *rp_rxq) 220 { 221 unsigned int i; 222 223 for (i = rp_rxq->routed; 224 i < rp_rxq->available && !rp_rxq->stop_route; 225 i++, rp_rxq->routed++) { 226 struct sfc_repr_proxy_port *port; 227 struct rte_mbuf *m = rp_rxq->pkts[i]; 228 229 port = sfc_repr_proxy_rx_route_mbuf(rp, m); 230 /* Cannot find destination representor */ 231 if (port == NULL) { 232 /* Effectively drop the packet */ 233 rp_rxq->forwarded++; 234 continue; 235 } 236 237 /* Currently routed packets are mapped to a different port */ 238 if (port->repr_id != rp_rxq->route_port_id && 239 rp_rxq->route_port_id != SFC_REPR_INVALID_ROUTE_PORT_ID) 240 return true; 241 242 rp_rxq->route_port_id = port->repr_id; 243 } 244 245 return false; 246 } 247 248 static void 249 sfc_repr_proxy_rx_forward(struct sfc_repr_proxy *rp, 250 struct sfc_repr_proxy_dp_rxq *rp_rxq) 251 { 252 struct sfc_repr_proxy_port *port; 253 254 if (rp_rxq->route_port_id != SFC_REPR_INVALID_ROUTE_PORT_ID) { 255 port = sfc_repr_proxy_find_port(rp, rp_rxq->route_port_id); 256 257 if (port != NULL && port->started) { 258 rp_rxq->forwarded += 259 rte_ring_sp_enqueue_burst(port->rxq[0].ring, 260 (void **)(&rp_rxq->pkts[rp_rxq->forwarded]), 261 rp_rxq->routed - rp_rxq->forwarded, NULL); 262 } else { 263 /* Drop all routed packets if the port is not started */ 264 rp_rxq->forwarded = rp_rxq->routed; 265 } 266 } 267 268 if (rp_rxq->forwarded == rp_rxq->routed) { 269 rp_rxq->route_port_id = SFC_REPR_INVALID_ROUTE_PORT_ID; 270 rp_rxq->stop_route = false; 271 } else { 272 /* Stall packet routing if not all packets were forwarded */ 273 rp_rxq->stop_route = true; 274 } 275 276 if (rp_rxq->available == rp_rxq->forwarded) 277 rp_rxq->available = rp_rxq->forwarded = rp_rxq->routed = 0; 278 } 279 280 static void 281 sfc_repr_proxy_handle_rx(struct sfc_repr_proxy *rp, 282 struct sfc_repr_proxy_dp_rxq *rp_rxq) 283 { 284 bool route_again; 285 286 if (rp_rxq->available < RTE_DIM(rp_rxq->pkts)) { 287 rp_rxq->available += rp_rxq->pkt_burst(rp_rxq->dp, 288 &rp_rxq->pkts[rp_rxq->available], 289 RTE_DIM(rp_rxq->pkts) - rp_rxq->available); 290 if (rp_rxq->available == rp_rxq->forwarded) 291 return; 292 } 293 294 do { 295 route_again = sfc_repr_proxy_rx_route(rp, rp_rxq); 296 sfc_repr_proxy_rx_forward(rp, rp_rxq); 297 } while (route_again && !rp_rxq->stop_route); 298 } 299 300 static int32_t 301 sfc_repr_proxy_routine(void *arg) 302 { 303 struct sfc_repr_proxy_port *port; 304 struct sfc_repr_proxy *rp = arg; 305 unsigned int i; 306 307 sfc_repr_proxy_mbox_handle(rp); 308 309 TAILQ_FOREACH(port, &rp->ports, entries) { 310 if (!port->started) 311 continue; 312 313 for (i = 0; i < rp->nb_txq; i++) 314 sfc_repr_proxy_handle_tx(&rp->dp_txq[i], &port->txq[i]); 315 } 316 317 for (i = 0; i < rp->nb_rxq; i++) 318 sfc_repr_proxy_handle_rx(rp, &rp->dp_rxq[i]); 319 320 return 0; 321 } 322 323 static struct sfc_txq_info * 324 sfc_repr_proxy_txq_info_get(struct sfc_adapter *sa, unsigned int repr_queue_id) 325 { 326 struct sfc_adapter_shared *sas = sfc_sa2shared(sa); 327 struct sfc_repr_proxy_dp_txq *dp_txq; 328 329 SFC_ASSERT(repr_queue_id < sfc_repr_nb_txq(sas)); 330 dp_txq = &sa->repr_proxy.dp_txq[repr_queue_id]; 331 332 return &sas->txq_info[dp_txq->sw_index]; 333 } 334 335 static int 336 sfc_repr_proxy_txq_attach(struct sfc_adapter *sa) 337 { 338 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 339 struct sfc_repr_proxy *rp = &sa->repr_proxy; 340 unsigned int i; 341 342 sfc_log_init(sa, "entry"); 343 344 for (i = 0; i < sfc_repr_nb_txq(sas); i++) { 345 sfc_sw_index_t sw_index = sfc_repr_txq_sw_index(sas, i); 346 347 rp->dp_txq[i].sw_index = sw_index; 348 } 349 350 sfc_log_init(sa, "done"); 351 352 return 0; 353 } 354 355 static void 356 sfc_repr_proxy_txq_detach(struct sfc_adapter *sa) 357 { 358 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 359 struct sfc_repr_proxy *rp = &sa->repr_proxy; 360 unsigned int i; 361 362 sfc_log_init(sa, "entry"); 363 364 for (i = 0; i < sfc_repr_nb_txq(sas); i++) 365 rp->dp_txq[i].sw_index = 0; 366 367 sfc_log_init(sa, "done"); 368 } 369 370 int 371 sfc_repr_proxy_txq_init(struct sfc_adapter *sa) 372 { 373 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 374 struct sfc_repr_proxy *rp = &sa->repr_proxy; 375 const struct rte_eth_txconf tx_conf = { 376 .tx_free_thresh = SFC_REPR_PROXY_TXQ_FREE_THRESH, 377 }; 378 struct sfc_txq_info *txq_info; 379 unsigned int init_i; 380 unsigned int i; 381 int rc; 382 383 sfc_log_init(sa, "entry"); 384 385 if (!sfc_repr_available(sas)) { 386 sfc_log_init(sa, "representors not supported - skip"); 387 return 0; 388 } 389 390 for (init_i = 0; init_i < sfc_repr_nb_txq(sas); init_i++) { 391 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[init_i]; 392 393 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index]; 394 if (txq_info->state == SFC_TXQ_INITIALIZED) { 395 sfc_log_init(sa, 396 "representor proxy TxQ %u is already initialized - skip", 397 init_i); 398 continue; 399 } 400 401 sfc_tx_qinit_info(sa, txq->sw_index); 402 403 rc = sfc_tx_qinit(sa, txq->sw_index, 404 SFC_REPR_PROXY_TX_DESC_COUNT, sa->socket_id, 405 &tx_conf); 406 407 if (rc != 0) { 408 sfc_err(sa, "failed to init representor proxy TxQ %u", 409 init_i); 410 goto fail_init; 411 } 412 } 413 414 sfc_log_init(sa, "done"); 415 416 return 0; 417 418 fail_init: 419 for (i = 0; i < init_i; i++) { 420 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i]; 421 422 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index]; 423 if (txq_info->state == SFC_TXQ_INITIALIZED) 424 sfc_tx_qfini(sa, txq->sw_index); 425 } 426 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 427 428 return rc; 429 } 430 431 void 432 sfc_repr_proxy_txq_fini(struct sfc_adapter *sa) 433 { 434 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 435 struct sfc_repr_proxy *rp = &sa->repr_proxy; 436 struct sfc_txq_info *txq_info; 437 unsigned int i; 438 439 sfc_log_init(sa, "entry"); 440 441 if (!sfc_repr_available(sas)) { 442 sfc_log_init(sa, "representors not supported - skip"); 443 return; 444 } 445 446 for (i = 0; i < sfc_repr_nb_txq(sas); i++) { 447 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i]; 448 449 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index]; 450 if (txq_info->state != SFC_TXQ_INITIALIZED) { 451 sfc_log_init(sa, 452 "representor proxy TxQ %u is already finalized - skip", 453 i); 454 continue; 455 } 456 457 sfc_tx_qfini(sa, txq->sw_index); 458 } 459 460 sfc_log_init(sa, "done"); 461 } 462 463 static int 464 sfc_repr_proxy_txq_start(struct sfc_adapter *sa) 465 { 466 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 467 struct sfc_repr_proxy *rp = &sa->repr_proxy; 468 unsigned int i; 469 470 sfc_log_init(sa, "entry"); 471 472 for (i = 0; i < sfc_repr_nb_txq(sas); i++) { 473 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i]; 474 475 txq->dp = sfc_repr_proxy_txq_info_get(sa, i)->dp; 476 txq->pkt_burst = sa->eth_dev->tx_pkt_burst; 477 txq->available = 0; 478 txq->transmitted = 0; 479 } 480 481 sfc_log_init(sa, "done"); 482 483 return 0; 484 } 485 486 static void 487 sfc_repr_proxy_txq_stop(struct sfc_adapter *sa) 488 { 489 sfc_log_init(sa, "entry"); 490 sfc_log_init(sa, "done"); 491 } 492 493 static int 494 sfc_repr_proxy_rxq_attach(struct sfc_adapter *sa) 495 { 496 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 497 struct sfc_repr_proxy *rp = &sa->repr_proxy; 498 unsigned int i; 499 500 sfc_log_init(sa, "entry"); 501 502 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) { 503 sfc_sw_index_t sw_index = sfc_repr_rxq_sw_index(sas, i); 504 505 rp->dp_rxq[i].sw_index = sw_index; 506 } 507 508 sfc_log_init(sa, "done"); 509 510 return 0; 511 } 512 513 static void 514 sfc_repr_proxy_rxq_detach(struct sfc_adapter *sa) 515 { 516 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 517 struct sfc_repr_proxy *rp = &sa->repr_proxy; 518 unsigned int i; 519 520 sfc_log_init(sa, "entry"); 521 522 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) 523 rp->dp_rxq[i].sw_index = 0; 524 525 sfc_log_init(sa, "done"); 526 } 527 528 static struct sfc_rxq_info * 529 sfc_repr_proxy_rxq_info_get(struct sfc_adapter *sa, unsigned int repr_queue_id) 530 { 531 struct sfc_adapter_shared *sas = sfc_sa2shared(sa); 532 struct sfc_repr_proxy_dp_rxq *dp_rxq; 533 534 SFC_ASSERT(repr_queue_id < sfc_repr_nb_rxq(sas)); 535 dp_rxq = &sa->repr_proxy.dp_rxq[repr_queue_id]; 536 537 return &sas->rxq_info[dp_rxq->sw_index]; 538 } 539 540 static int 541 sfc_repr_proxy_rxq_init(struct sfc_adapter *sa, 542 struct sfc_repr_proxy_dp_rxq *rxq) 543 { 544 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 545 uint16_t nb_rx_desc = SFC_REPR_PROXY_RX_DESC_COUNT; 546 struct sfc_rxq_info *rxq_info; 547 struct rte_eth_rxconf rxconf = { 548 .rx_free_thresh = SFC_REPR_PROXY_RXQ_REFILL_LEVEL, 549 .rx_drop_en = 1, 550 }; 551 int rc; 552 553 sfc_log_init(sa, "entry"); 554 555 rxq_info = &sas->rxq_info[rxq->sw_index]; 556 if (rxq_info->state & SFC_RXQ_INITIALIZED) { 557 sfc_log_init(sa, "RxQ is already initialized - skip"); 558 return 0; 559 } 560 561 nb_rx_desc = RTE_MIN(nb_rx_desc, sa->rxq_max_entries); 562 nb_rx_desc = RTE_MAX(nb_rx_desc, sa->rxq_min_entries); 563 564 rc = sfc_rx_qinit_info(sa, rxq->sw_index, EFX_RXQ_FLAG_INGRESS_MPORT); 565 if (rc != 0) { 566 sfc_err(sa, "failed to init representor proxy RxQ info"); 567 goto fail_repr_rxq_init_info; 568 } 569 570 rc = sfc_rx_qinit(sa, rxq->sw_index, nb_rx_desc, sa->socket_id, &rxconf, 571 rxq->mp); 572 if (rc != 0) { 573 sfc_err(sa, "failed to init representor proxy RxQ"); 574 goto fail_repr_rxq_init; 575 } 576 577 sfc_log_init(sa, "done"); 578 579 return 0; 580 581 fail_repr_rxq_init: 582 fail_repr_rxq_init_info: 583 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 584 585 return rc; 586 } 587 588 static void 589 sfc_repr_proxy_rxq_fini(struct sfc_adapter *sa) 590 { 591 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 592 struct sfc_repr_proxy *rp = &sa->repr_proxy; 593 struct sfc_rxq_info *rxq_info; 594 unsigned int i; 595 596 sfc_log_init(sa, "entry"); 597 598 if (!sfc_repr_available(sas)) { 599 sfc_log_init(sa, "representors not supported - skip"); 600 return; 601 } 602 603 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) { 604 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i]; 605 606 rxq_info = &sas->rxq_info[rxq->sw_index]; 607 if (rxq_info->state != SFC_RXQ_INITIALIZED) { 608 sfc_log_init(sa, 609 "representor RxQ %u is already finalized - skip", 610 i); 611 continue; 612 } 613 614 sfc_rx_qfini(sa, rxq->sw_index); 615 } 616 617 sfc_log_init(sa, "done"); 618 } 619 620 static void 621 sfc_repr_proxy_rxq_stop(struct sfc_adapter *sa) 622 { 623 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 624 unsigned int i; 625 626 sfc_log_init(sa, "entry"); 627 628 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) 629 sfc_rx_qstop(sa, sa->repr_proxy.dp_rxq[i].sw_index); 630 631 sfc_repr_proxy_rxq_fini(sa); 632 633 sfc_log_init(sa, "done"); 634 } 635 636 static int 637 sfc_repr_proxy_rxq_start(struct sfc_adapter *sa) 638 { 639 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 640 struct sfc_repr_proxy *rp = &sa->repr_proxy; 641 unsigned int i; 642 int rc; 643 644 sfc_log_init(sa, "entry"); 645 646 if (!sfc_repr_available(sas)) { 647 sfc_log_init(sa, "representors not supported - skip"); 648 return 0; 649 } 650 651 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) { 652 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i]; 653 654 rc = sfc_repr_proxy_rxq_init(sa, rxq); 655 if (rc != 0) { 656 sfc_err(sa, "failed to init representor proxy RxQ %u", 657 i); 658 goto fail_init; 659 } 660 661 rc = sfc_rx_qstart(sa, rxq->sw_index); 662 if (rc != 0) { 663 sfc_err(sa, "failed to start representor proxy RxQ %u", 664 i); 665 goto fail_start; 666 } 667 668 rxq->dp = sfc_repr_proxy_rxq_info_get(sa, i)->dp; 669 rxq->pkt_burst = sa->eth_dev->rx_pkt_burst; 670 rxq->available = 0; 671 rxq->routed = 0; 672 rxq->forwarded = 0; 673 rxq->stop_route = false; 674 rxq->route_port_id = SFC_REPR_INVALID_ROUTE_PORT_ID; 675 } 676 677 sfc_log_init(sa, "done"); 678 679 return 0; 680 681 fail_start: 682 fail_init: 683 sfc_repr_proxy_rxq_stop(sa); 684 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 685 return rc; 686 } 687 688 static int 689 sfc_repr_proxy_mae_rule_insert(struct sfc_adapter *sa, 690 struct sfc_repr_proxy_port *port) 691 { 692 struct sfc_repr_proxy *rp = &sa->repr_proxy; 693 efx_mport_sel_t mport_alias_selector; 694 efx_mport_sel_t mport_vf_selector; 695 struct sfc_mae_rule *mae_rule; 696 int rc; 697 698 sfc_log_init(sa, "entry"); 699 700 rc = efx_mae_mport_by_id(&port->egress_mport, 701 &mport_vf_selector); 702 if (rc != 0) { 703 sfc_err(sa, "failed to get VF mport for repr %u", 704 port->repr_id); 705 goto fail_get_vf; 706 } 707 708 rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector); 709 if (rc != 0) { 710 sfc_err(sa, "failed to get mport selector for repr %u", 711 port->repr_id); 712 goto fail_get_alias; 713 } 714 715 rc = sfc_mae_rule_add_mport_match_deliver(sa, &mport_vf_selector, 716 &mport_alias_selector, -1, 717 &mae_rule); 718 if (rc != 0) { 719 sfc_err(sa, "failed to insert MAE rule for repr %u", 720 port->repr_id); 721 goto fail_rule_add; 722 } 723 724 port->mae_rule = mae_rule; 725 726 sfc_log_init(sa, "done"); 727 728 return 0; 729 730 fail_rule_add: 731 fail_get_alias: 732 fail_get_vf: 733 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 734 return rc; 735 } 736 737 static void 738 sfc_repr_proxy_mae_rule_remove(struct sfc_adapter *sa, 739 struct sfc_repr_proxy_port *port) 740 { 741 struct sfc_mae_rule *mae_rule = port->mae_rule; 742 743 sfc_mae_rule_del(sa, mae_rule); 744 } 745 746 static int 747 sfc_repr_proxy_mport_filter_insert(struct sfc_adapter *sa) 748 { 749 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 750 struct sfc_repr_proxy *rp = &sa->repr_proxy; 751 struct sfc_rxq *rxq_ctrl; 752 struct sfc_repr_proxy_filter *filter = &rp->mport_filter; 753 efx_mport_sel_t mport_alias_selector; 754 static const efx_filter_match_flags_t flags[RTE_DIM(filter->specs)] = { 755 EFX_FILTER_MATCH_UNKNOWN_UCAST_DST, 756 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST }; 757 unsigned int i; 758 int rc; 759 760 sfc_log_init(sa, "entry"); 761 762 if (sfc_repr_nb_rxq(sas) == 1) { 763 rxq_ctrl = &sa->rxq_ctrl[rp->dp_rxq[0].sw_index]; 764 } else { 765 sfc_err(sa, "multiple representor proxy RxQs not supported"); 766 rc = ENOTSUP; 767 goto fail_multiple_queues; 768 } 769 770 rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector); 771 if (rc != 0) { 772 sfc_err(sa, "failed to get repr proxy mport by ID"); 773 goto fail_get_selector; 774 } 775 776 memset(filter->specs, 0, sizeof(filter->specs)); 777 for (i = 0; i < RTE_DIM(filter->specs); i++) { 778 filter->specs[i].efs_priority = EFX_FILTER_PRI_MANUAL; 779 filter->specs[i].efs_flags = EFX_FILTER_FLAG_RX; 780 filter->specs[i].efs_dmaq_id = rxq_ctrl->hw_index; 781 filter->specs[i].efs_match_flags = flags[i] | 782 EFX_FILTER_MATCH_MPORT; 783 filter->specs[i].efs_ingress_mport = mport_alias_selector.sel; 784 785 rc = efx_filter_insert(sa->nic, &filter->specs[i]); 786 if (rc != 0) { 787 sfc_err(sa, "failed to insert repr proxy filter"); 788 goto fail_insert; 789 } 790 } 791 792 sfc_log_init(sa, "done"); 793 794 return 0; 795 796 fail_insert: 797 while (i-- > 0) 798 efx_filter_remove(sa->nic, &filter->specs[i]); 799 800 fail_get_selector: 801 fail_multiple_queues: 802 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 803 return rc; 804 } 805 806 static void 807 sfc_repr_proxy_mport_filter_remove(struct sfc_adapter *sa) 808 { 809 struct sfc_repr_proxy *rp = &sa->repr_proxy; 810 struct sfc_repr_proxy_filter *filter = &rp->mport_filter; 811 unsigned int i; 812 813 for (i = 0; i < RTE_DIM(filter->specs); i++) 814 efx_filter_remove(sa->nic, &filter->specs[i]); 815 } 816 817 static int 818 sfc_repr_proxy_port_rule_insert(struct sfc_adapter *sa, 819 struct sfc_repr_proxy_port *port) 820 { 821 int rc; 822 823 rc = sfc_repr_proxy_mae_rule_insert(sa, port); 824 if (rc != 0) 825 goto fail_mae_rule_insert; 826 827 return 0; 828 829 fail_mae_rule_insert: 830 return rc; 831 } 832 833 static void 834 sfc_repr_proxy_port_rule_remove(struct sfc_adapter *sa, 835 struct sfc_repr_proxy_port *port) 836 { 837 sfc_repr_proxy_mae_rule_remove(sa, port); 838 } 839 840 static int 841 sfc_repr_proxy_ports_init(struct sfc_adapter *sa) 842 { 843 struct sfc_repr_proxy *rp = &sa->repr_proxy; 844 int rc; 845 846 sfc_log_init(sa, "entry"); 847 848 rc = efx_mcdi_mport_alloc_alias(sa->nic, &rp->mport_alias, NULL); 849 if (rc != 0) { 850 sfc_err(sa, "failed to alloc mport alias: %s", 851 rte_strerror(rc)); 852 goto fail_alloc_mport_alias; 853 } 854 855 TAILQ_INIT(&rp->ports); 856 857 sfc_log_init(sa, "done"); 858 859 return 0; 860 861 fail_alloc_mport_alias: 862 863 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 864 return rc; 865 } 866 867 void 868 sfc_repr_proxy_pre_detach(struct sfc_adapter *sa) 869 { 870 struct sfc_repr_proxy *rp = &sa->repr_proxy; 871 bool close_ports[RTE_MAX_ETHPORTS] = {0}; 872 struct sfc_repr_proxy_port *port; 873 unsigned int i; 874 875 SFC_ASSERT(!sfc_adapter_is_locked(sa)); 876 877 sfc_adapter_lock(sa); 878 879 if (sfc_repr_available(sfc_sa2shared(sa))) { 880 TAILQ_FOREACH(port, &rp->ports, entries) 881 close_ports[port->rte_port_id] = true; 882 } else { 883 sfc_log_init(sa, "representors not supported - skip"); 884 } 885 886 sfc_adapter_unlock(sa); 887 888 for (i = 0; i < RTE_DIM(close_ports); i++) { 889 if (close_ports[i]) { 890 rte_eth_dev_stop(i); 891 rte_eth_dev_close(i); 892 } 893 } 894 } 895 896 static void 897 sfc_repr_proxy_ports_fini(struct sfc_adapter *sa) 898 { 899 struct sfc_repr_proxy *rp = &sa->repr_proxy; 900 901 efx_mae_mport_free(sa->nic, &rp->mport_alias); 902 } 903 904 int 905 sfc_repr_proxy_attach(struct sfc_adapter *sa) 906 { 907 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 908 struct sfc_repr_proxy *rp = &sa->repr_proxy; 909 struct rte_service_spec service; 910 uint32_t cid; 911 uint32_t sid; 912 int rc; 913 914 sfc_log_init(sa, "entry"); 915 916 if (!sfc_repr_available(sas)) { 917 sfc_log_init(sa, "representors not supported - skip"); 918 return 0; 919 } 920 921 rc = sfc_repr_proxy_rxq_attach(sa); 922 if (rc != 0) 923 goto fail_rxq_attach; 924 925 rc = sfc_repr_proxy_txq_attach(sa); 926 if (rc != 0) 927 goto fail_txq_attach; 928 929 rc = sfc_repr_proxy_ports_init(sa); 930 if (rc != 0) 931 goto fail_ports_init; 932 933 cid = sfc_get_service_lcore(sa->socket_id); 934 if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) { 935 /* Warn and try to allocate on any NUMA node */ 936 sfc_warn(sa, 937 "repr proxy: unable to get service lcore at socket %d", 938 sa->socket_id); 939 940 cid = sfc_get_service_lcore(SOCKET_ID_ANY); 941 } 942 if (cid == RTE_MAX_LCORE) { 943 rc = ENOTSUP; 944 sfc_err(sa, "repr proxy: failed to get service lcore"); 945 goto fail_get_service_lcore; 946 } 947 948 memset(&service, 0, sizeof(service)); 949 snprintf(service.name, sizeof(service.name), 950 "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id); 951 service.socket_id = rte_lcore_to_socket_id(cid); 952 service.callback = sfc_repr_proxy_routine; 953 service.callback_userdata = rp; 954 955 rc = rte_service_component_register(&service, &sid); 956 if (rc != 0) { 957 rc = ENOEXEC; 958 sfc_err(sa, "repr proxy: failed to register service component"); 959 goto fail_register; 960 } 961 962 rc = rte_service_map_lcore_set(sid, cid, 1); 963 if (rc != 0) { 964 rc = -rc; 965 sfc_err(sa, "repr proxy: failed to map lcore"); 966 goto fail_map_lcore; 967 } 968 969 rp->service_core_id = cid; 970 rp->service_id = sid; 971 972 sfc_log_init(sa, "done"); 973 974 return 0; 975 976 fail_map_lcore: 977 rte_service_component_unregister(sid); 978 979 fail_register: 980 /* 981 * No need to rollback service lcore get since 982 * it just makes socket_id based search and remembers it. 983 */ 984 985 fail_get_service_lcore: 986 sfc_repr_proxy_ports_fini(sa); 987 988 fail_ports_init: 989 sfc_repr_proxy_txq_detach(sa); 990 991 fail_txq_attach: 992 sfc_repr_proxy_rxq_detach(sa); 993 994 fail_rxq_attach: 995 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 996 return rc; 997 } 998 999 void 1000 sfc_repr_proxy_detach(struct sfc_adapter *sa) 1001 { 1002 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 1003 struct sfc_repr_proxy *rp = &sa->repr_proxy; 1004 1005 sfc_log_init(sa, "entry"); 1006 1007 if (!sfc_repr_available(sas)) { 1008 sfc_log_init(sa, "representors not supported - skip"); 1009 return; 1010 } 1011 1012 rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0); 1013 rte_service_component_unregister(rp->service_id); 1014 sfc_repr_proxy_ports_fini(sa); 1015 sfc_repr_proxy_rxq_detach(sa); 1016 sfc_repr_proxy_txq_detach(sa); 1017 1018 sfc_log_init(sa, "done"); 1019 } 1020 1021 static int 1022 sfc_repr_proxy_do_start_port(struct sfc_adapter *sa, 1023 struct sfc_repr_proxy_port *port) 1024 { 1025 struct sfc_repr_proxy *rp = &sa->repr_proxy; 1026 int rc; 1027 1028 rc = sfc_repr_proxy_port_rule_insert(sa, port); 1029 if (rc != 0) 1030 goto fail_filter_insert; 1031 1032 if (rp->started) { 1033 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, 1034 SFC_REPR_PROXY_MBOX_START_PORT); 1035 if (rc != 0) { 1036 sfc_err(sa, "failed to start proxy port %u", 1037 port->repr_id); 1038 goto fail_port_start; 1039 } 1040 } else { 1041 port->started = true; 1042 } 1043 1044 return 0; 1045 1046 fail_port_start: 1047 sfc_repr_proxy_port_rule_remove(sa, port); 1048 fail_filter_insert: 1049 sfc_err(sa, "%s() failed %s", __func__, rte_strerror(rc)); 1050 1051 return rc; 1052 } 1053 1054 static int 1055 sfc_repr_proxy_do_stop_port(struct sfc_adapter *sa, 1056 struct sfc_repr_proxy_port *port) 1057 1058 { 1059 struct sfc_repr_proxy *rp = &sa->repr_proxy; 1060 int rc; 1061 1062 if (rp->started) { 1063 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, 1064 SFC_REPR_PROXY_MBOX_STOP_PORT); 1065 if (rc != 0) { 1066 sfc_err(sa, "failed to stop proxy port %u: %s", 1067 port->repr_id, rte_strerror(rc)); 1068 return rc; 1069 } 1070 } else { 1071 port->started = false; 1072 } 1073 1074 sfc_repr_proxy_port_rule_remove(sa, port); 1075 1076 return 0; 1077 } 1078 1079 static bool 1080 sfc_repr_proxy_port_enabled(struct sfc_repr_proxy_port *port) 1081 { 1082 return port->rte_port_id != RTE_MAX_ETHPORTS && port->enabled; 1083 } 1084 1085 static bool 1086 sfc_repr_proxy_ports_disabled(struct sfc_repr_proxy *rp) 1087 { 1088 struct sfc_repr_proxy_port *port; 1089 1090 TAILQ_FOREACH(port, &rp->ports, entries) { 1091 if (sfc_repr_proxy_port_enabled(port)) 1092 return false; 1093 } 1094 1095 return true; 1096 } 1097 1098 int 1099 sfc_repr_proxy_start(struct sfc_adapter *sa) 1100 { 1101 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 1102 struct sfc_repr_proxy *rp = &sa->repr_proxy; 1103 struct sfc_repr_proxy_port *last_port = NULL; 1104 struct sfc_repr_proxy_port *port; 1105 int rc; 1106 1107 sfc_log_init(sa, "entry"); 1108 1109 /* Representor proxy is not started when no representors are started */ 1110 if (!sfc_repr_available(sas)) { 1111 sfc_log_init(sa, "representors not supported - skip"); 1112 return 0; 1113 } 1114 1115 if (sfc_repr_proxy_ports_disabled(rp)) { 1116 sfc_log_init(sa, "no started representor ports - skip"); 1117 return 0; 1118 } 1119 1120 rc = sfc_repr_proxy_rxq_start(sa); 1121 if (rc != 0) 1122 goto fail_rxq_start; 1123 1124 rc = sfc_repr_proxy_txq_start(sa); 1125 if (rc != 0) 1126 goto fail_txq_start; 1127 1128 rp->nb_txq = sfc_repr_nb_txq(sas); 1129 rp->nb_rxq = sfc_repr_nb_rxq(sas); 1130 1131 /* Service core may be in "stopped" state, start it */ 1132 rc = rte_service_lcore_start(rp->service_core_id); 1133 if (rc != 0 && rc != -EALREADY) { 1134 rc = -rc; 1135 sfc_err(sa, "failed to start service core for %s: %s", 1136 rte_service_get_name(rp->service_id), 1137 rte_strerror(rc)); 1138 goto fail_start_core; 1139 } 1140 1141 /* Run the service */ 1142 rc = rte_service_component_runstate_set(rp->service_id, 1); 1143 if (rc < 0) { 1144 rc = -rc; 1145 sfc_err(sa, "failed to run %s component: %s", 1146 rte_service_get_name(rp->service_id), 1147 rte_strerror(rc)); 1148 goto fail_component_runstate_set; 1149 } 1150 rc = rte_service_runstate_set(rp->service_id, 1); 1151 if (rc < 0) { 1152 rc = -rc; 1153 sfc_err(sa, "failed to run %s: %s", 1154 rte_service_get_name(rp->service_id), 1155 rte_strerror(rc)); 1156 goto fail_runstate_set; 1157 } 1158 1159 TAILQ_FOREACH(port, &rp->ports, entries) { 1160 if (sfc_repr_proxy_port_enabled(port)) { 1161 rc = sfc_repr_proxy_do_start_port(sa, port); 1162 if (rc != 0) 1163 goto fail_start_id; 1164 1165 last_port = port; 1166 } 1167 } 1168 1169 rc = sfc_repr_proxy_mport_filter_insert(sa); 1170 if (rc != 0) 1171 goto fail_mport_filter_insert; 1172 1173 rp->started = true; 1174 1175 sfc_log_init(sa, "done"); 1176 1177 return 0; 1178 1179 fail_mport_filter_insert: 1180 fail_start_id: 1181 if (last_port != NULL) { 1182 TAILQ_FOREACH(port, &rp->ports, entries) { 1183 if (sfc_repr_proxy_port_enabled(port)) { 1184 (void)sfc_repr_proxy_do_stop_port(sa, port); 1185 if (port == last_port) 1186 break; 1187 } 1188 } 1189 } 1190 1191 rte_service_runstate_set(rp->service_id, 0); 1192 1193 fail_runstate_set: 1194 rte_service_component_runstate_set(rp->service_id, 0); 1195 1196 fail_component_runstate_set: 1197 /* Service lcore may be shared and we never stop it */ 1198 1199 fail_start_core: 1200 sfc_repr_proxy_txq_stop(sa); 1201 1202 fail_txq_start: 1203 sfc_repr_proxy_rxq_stop(sa); 1204 1205 fail_rxq_start: 1206 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 1207 return rc; 1208 } 1209 1210 void 1211 sfc_repr_proxy_stop(struct sfc_adapter *sa) 1212 { 1213 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); 1214 struct sfc_repr_proxy *rp = &sa->repr_proxy; 1215 struct sfc_repr_proxy_port *port; 1216 const unsigned int wait_ms_total = 1217 SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS; 1218 unsigned int i; 1219 int rc; 1220 1221 sfc_log_init(sa, "entry"); 1222 1223 if (!sfc_repr_available(sas)) { 1224 sfc_log_init(sa, "representors not supported - skip"); 1225 return; 1226 } 1227 1228 if (sfc_repr_proxy_ports_disabled(rp)) { 1229 sfc_log_init(sa, "no started representor ports - skip"); 1230 return; 1231 } 1232 1233 TAILQ_FOREACH(port, &rp->ports, entries) { 1234 if (sfc_repr_proxy_port_enabled(port)) { 1235 rc = sfc_repr_proxy_do_stop_port(sa, port); 1236 if (rc != 0) { 1237 sfc_err(sa, 1238 "failed to stop representor proxy port %u: %s", 1239 port->repr_id, rte_strerror(rc)); 1240 } 1241 } 1242 } 1243 1244 sfc_repr_proxy_mport_filter_remove(sa); 1245 1246 rc = rte_service_runstate_set(rp->service_id, 0); 1247 if (rc < 0) { 1248 sfc_err(sa, "failed to stop %s: %s", 1249 rte_service_get_name(rp->service_id), 1250 rte_strerror(-rc)); 1251 } 1252 1253 rc = rte_service_component_runstate_set(rp->service_id, 0); 1254 if (rc < 0) { 1255 sfc_err(sa, "failed to stop %s component: %s", 1256 rte_service_get_name(rp->service_id), 1257 rte_strerror(-rc)); 1258 } 1259 1260 /* Service lcore may be shared and we never stop it */ 1261 1262 /* 1263 * Wait for the representor proxy routine to finish the last iteration. 1264 * Give up on timeout. 1265 */ 1266 for (i = 0; i < wait_ms_total; i++) { 1267 if (rte_service_may_be_active(rp->service_id) == 0) 1268 break; 1269 1270 rte_delay_ms(1); 1271 } 1272 1273 sfc_repr_proxy_rxq_stop(sa); 1274 sfc_repr_proxy_txq_stop(sa); 1275 1276 rp->started = false; 1277 1278 sfc_log_init(sa, "done"); 1279 } 1280 1281 int 1282 sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id, 1283 uint16_t rte_port_id, const efx_mport_sel_t *mport_sel) 1284 { 1285 struct sfc_repr_proxy_port *port; 1286 struct sfc_repr_proxy *rp; 1287 struct sfc_adapter *sa; 1288 int rc; 1289 1290 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1291 rp = sfc_repr_proxy_by_adapter(sa); 1292 1293 sfc_log_init(sa, "entry"); 1294 TAILQ_FOREACH(port, &rp->ports, entries) { 1295 if (port->rte_port_id == rte_port_id) { 1296 rc = EEXIST; 1297 sfc_err(sa, "%s() failed: port exists", __func__); 1298 goto fail_port_exists; 1299 } 1300 } 1301 1302 port = rte_zmalloc("sfc-repr-proxy-port", sizeof(*port), 1303 sa->socket_id); 1304 if (port == NULL) { 1305 rc = ENOMEM; 1306 sfc_err(sa, "failed to alloc memory for proxy port"); 1307 goto fail_alloc_port; 1308 } 1309 1310 rc = efx_mae_mport_id_by_selector(sa->nic, mport_sel, 1311 &port->egress_mport); 1312 if (rc != 0) { 1313 sfc_err(sa, 1314 "failed get MAE mport id by selector (repr_id %u): %s", 1315 repr_id, rte_strerror(rc)); 1316 goto fail_mport_id; 1317 } 1318 1319 port->rte_port_id = rte_port_id; 1320 port->repr_id = repr_id; 1321 1322 if (rp->started) { 1323 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, 1324 SFC_REPR_PROXY_MBOX_ADD_PORT); 1325 if (rc != 0) { 1326 sfc_err(sa, "failed to add proxy port %u", 1327 port->repr_id); 1328 goto fail_port_add; 1329 } 1330 } else { 1331 TAILQ_INSERT_TAIL(&rp->ports, port, entries); 1332 } 1333 1334 sfc_log_init(sa, "done"); 1335 sfc_put_adapter(sa); 1336 1337 return 0; 1338 1339 fail_port_add: 1340 fail_mport_id: 1341 rte_free(port); 1342 fail_alloc_port: 1343 fail_port_exists: 1344 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 1345 sfc_put_adapter(sa); 1346 1347 return rc; 1348 } 1349 1350 int 1351 sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id) 1352 { 1353 struct sfc_repr_proxy_port *port; 1354 struct sfc_repr_proxy *rp; 1355 struct sfc_adapter *sa; 1356 int rc; 1357 1358 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1359 rp = sfc_repr_proxy_by_adapter(sa); 1360 1361 sfc_log_init(sa, "entry"); 1362 1363 port = sfc_repr_proxy_find_port(rp, repr_id); 1364 if (port == NULL) { 1365 sfc_err(sa, "failed: no such port"); 1366 rc = ENOENT; 1367 goto fail_no_port; 1368 } 1369 1370 if (rp->started) { 1371 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, 1372 SFC_REPR_PROXY_MBOX_DEL_PORT); 1373 if (rc != 0) { 1374 sfc_err(sa, "failed to remove proxy port %u", 1375 port->repr_id); 1376 goto fail_port_remove; 1377 } 1378 } else { 1379 TAILQ_REMOVE(&rp->ports, port, entries); 1380 } 1381 1382 rte_free(port); 1383 1384 sfc_log_init(sa, "done"); 1385 1386 sfc_put_adapter(sa); 1387 1388 return 0; 1389 1390 fail_port_remove: 1391 fail_no_port: 1392 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 1393 sfc_put_adapter(sa); 1394 1395 return rc; 1396 } 1397 1398 int 1399 sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id, 1400 uint16_t queue_id, struct rte_ring *rx_ring, 1401 struct rte_mempool *mp) 1402 { 1403 struct sfc_repr_proxy_port *port; 1404 struct sfc_repr_proxy_rxq *rxq; 1405 struct sfc_repr_proxy *rp; 1406 struct sfc_adapter *sa; 1407 1408 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1409 rp = sfc_repr_proxy_by_adapter(sa); 1410 1411 sfc_log_init(sa, "entry"); 1412 1413 port = sfc_repr_proxy_find_port(rp, repr_id); 1414 if (port == NULL) { 1415 sfc_err(sa, "%s() failed: no such port", __func__); 1416 return ENOENT; 1417 } 1418 1419 rxq = &port->rxq[queue_id]; 1420 if (rp->dp_rxq[queue_id].mp != NULL && rp->dp_rxq[queue_id].mp != mp) { 1421 sfc_err(sa, "multiple mempools per queue are not supported"); 1422 sfc_put_adapter(sa); 1423 return ENOTSUP; 1424 } 1425 1426 rxq->ring = rx_ring; 1427 rxq->mb_pool = mp; 1428 rp->dp_rxq[queue_id].mp = mp; 1429 rp->dp_rxq[queue_id].ref_count++; 1430 1431 sfc_log_init(sa, "done"); 1432 sfc_put_adapter(sa); 1433 1434 return 0; 1435 } 1436 1437 void 1438 sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id, 1439 uint16_t queue_id) 1440 { 1441 struct sfc_repr_proxy_port *port; 1442 struct sfc_repr_proxy_rxq *rxq; 1443 struct sfc_repr_proxy *rp; 1444 struct sfc_adapter *sa; 1445 1446 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1447 rp = sfc_repr_proxy_by_adapter(sa); 1448 1449 sfc_log_init(sa, "entry"); 1450 1451 port = sfc_repr_proxy_find_port(rp, repr_id); 1452 if (port == NULL) { 1453 sfc_err(sa, "%s() failed: no such port", __func__); 1454 return; 1455 } 1456 1457 rxq = &port->rxq[queue_id]; 1458 1459 rxq->ring = NULL; 1460 rxq->mb_pool = NULL; 1461 rp->dp_rxq[queue_id].ref_count--; 1462 if (rp->dp_rxq[queue_id].ref_count == 0) 1463 rp->dp_rxq[queue_id].mp = NULL; 1464 1465 sfc_log_init(sa, "done"); 1466 sfc_put_adapter(sa); 1467 } 1468 1469 int 1470 sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id, 1471 uint16_t queue_id, struct rte_ring *tx_ring, 1472 efx_mport_id_t *egress_mport) 1473 { 1474 struct sfc_repr_proxy_port *port; 1475 struct sfc_repr_proxy_txq *txq; 1476 struct sfc_repr_proxy *rp; 1477 struct sfc_adapter *sa; 1478 1479 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1480 rp = sfc_repr_proxy_by_adapter(sa); 1481 1482 sfc_log_init(sa, "entry"); 1483 1484 port = sfc_repr_proxy_find_port(rp, repr_id); 1485 if (port == NULL) { 1486 sfc_err(sa, "%s() failed: no such port", __func__); 1487 return ENOENT; 1488 } 1489 1490 txq = &port->txq[queue_id]; 1491 1492 txq->ring = tx_ring; 1493 1494 *egress_mport = port->egress_mport; 1495 1496 sfc_log_init(sa, "done"); 1497 sfc_put_adapter(sa); 1498 1499 return 0; 1500 } 1501 1502 void 1503 sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id, 1504 uint16_t queue_id) 1505 { 1506 struct sfc_repr_proxy_port *port; 1507 struct sfc_repr_proxy_txq *txq; 1508 struct sfc_repr_proxy *rp; 1509 struct sfc_adapter *sa; 1510 1511 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1512 rp = sfc_repr_proxy_by_adapter(sa); 1513 1514 sfc_log_init(sa, "entry"); 1515 1516 port = sfc_repr_proxy_find_port(rp, repr_id); 1517 if (port == NULL) { 1518 sfc_err(sa, "%s() failed: no such port", __func__); 1519 return; 1520 } 1521 1522 txq = &port->txq[queue_id]; 1523 1524 txq->ring = NULL; 1525 1526 sfc_log_init(sa, "done"); 1527 sfc_put_adapter(sa); 1528 } 1529 1530 int 1531 sfc_repr_proxy_start_repr(uint16_t pf_port_id, uint16_t repr_id) 1532 { 1533 bool proxy_start_required = false; 1534 struct sfc_repr_proxy_port *port; 1535 struct sfc_repr_proxy *rp; 1536 struct sfc_adapter *sa; 1537 int rc; 1538 1539 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1540 rp = sfc_repr_proxy_by_adapter(sa); 1541 1542 sfc_log_init(sa, "entry"); 1543 1544 port = sfc_repr_proxy_find_port(rp, repr_id); 1545 if (port == NULL) { 1546 sfc_err(sa, "%s() failed: no such port", __func__); 1547 rc = ENOENT; 1548 goto fail_not_found; 1549 } 1550 1551 if (port->enabled) { 1552 rc = EALREADY; 1553 sfc_err(sa, "failed: repr %u proxy port already started", 1554 repr_id); 1555 goto fail_already_started; 1556 } 1557 1558 if (sa->state == SFC_ETHDEV_STARTED) { 1559 if (sfc_repr_proxy_ports_disabled(rp)) { 1560 proxy_start_required = true; 1561 } else { 1562 rc = sfc_repr_proxy_do_start_port(sa, port); 1563 if (rc != 0) { 1564 sfc_err(sa, 1565 "failed to start repr %u proxy port", 1566 repr_id); 1567 goto fail_start_id; 1568 } 1569 } 1570 } 1571 1572 port->enabled = true; 1573 1574 if (proxy_start_required) { 1575 rc = sfc_repr_proxy_start(sa); 1576 if (rc != 0) { 1577 sfc_err(sa, "failed to start proxy"); 1578 goto fail_proxy_start; 1579 } 1580 } 1581 1582 sfc_log_init(sa, "done"); 1583 sfc_put_adapter(sa); 1584 1585 return 0; 1586 1587 fail_proxy_start: 1588 port->enabled = false; 1589 1590 fail_start_id: 1591 fail_already_started: 1592 fail_not_found: 1593 sfc_err(sa, "failed to start repr %u proxy port: %s", repr_id, 1594 rte_strerror(rc)); 1595 sfc_put_adapter(sa); 1596 1597 return rc; 1598 } 1599 1600 int 1601 sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id) 1602 { 1603 struct sfc_repr_proxy_port *port; 1604 struct sfc_repr_proxy_port *p; 1605 struct sfc_repr_proxy *rp; 1606 struct sfc_adapter *sa; 1607 int rc; 1608 1609 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1610 rp = sfc_repr_proxy_by_adapter(sa); 1611 1612 sfc_log_init(sa, "entry"); 1613 1614 port = sfc_repr_proxy_find_port(rp, repr_id); 1615 if (port == NULL) { 1616 sfc_err(sa, "%s() failed: no such port", __func__); 1617 return ENOENT; 1618 } 1619 1620 if (!port->enabled) { 1621 sfc_log_init(sa, "repr %u proxy port is not started - skip", 1622 repr_id); 1623 sfc_put_adapter(sa); 1624 return 0; 1625 } 1626 1627 if (sa->state == SFC_ETHDEV_STARTED) { 1628 bool last_enabled = true; 1629 1630 TAILQ_FOREACH(p, &rp->ports, entries) { 1631 if (p == port) 1632 continue; 1633 1634 if (sfc_repr_proxy_port_enabled(p)) { 1635 last_enabled = false; 1636 break; 1637 } 1638 } 1639 1640 rc = 0; 1641 if (last_enabled) 1642 sfc_repr_proxy_stop(sa); 1643 else 1644 rc = sfc_repr_proxy_do_stop_port(sa, port); 1645 1646 if (rc != 0) { 1647 sfc_err(sa, 1648 "failed to stop representor proxy TxQ %u: %s", 1649 repr_id, rte_strerror(rc)); 1650 sfc_put_adapter(sa); 1651 return rc; 1652 } 1653 } 1654 1655 port->enabled = false; 1656 1657 sfc_log_init(sa, "done"); 1658 sfc_put_adapter(sa); 1659 1660 return 0; 1661 } 1662