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 efx_pcie_interface_t intf, uint16_t pf, uint16_t vf) 1285 { 1286 struct sfc_repr_proxy_port *port; 1287 struct sfc_repr_proxy *rp; 1288 struct sfc_adapter *sa; 1289 int rc; 1290 1291 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1292 rp = sfc_repr_proxy_by_adapter(sa); 1293 1294 sfc_log_init(sa, "entry"); 1295 TAILQ_FOREACH(port, &rp->ports, entries) { 1296 if (port->rte_port_id == rte_port_id) { 1297 rc = EEXIST; 1298 sfc_err(sa, "%s() failed: port exists", __func__); 1299 goto fail_port_exists; 1300 } 1301 } 1302 1303 port = rte_zmalloc("sfc-repr-proxy-port", sizeof(*port), 1304 sa->socket_id); 1305 if (port == NULL) { 1306 rc = ENOMEM; 1307 sfc_err(sa, "failed to alloc memory for proxy port"); 1308 goto fail_alloc_port; 1309 } 1310 1311 rc = efx_mae_mport_id_by_selector(sa->nic, mport_sel, 1312 &port->egress_mport); 1313 if (rc != 0) { 1314 sfc_err(sa, 1315 "failed get MAE mport id by selector (repr_id %u): %s", 1316 repr_id, rte_strerror(rc)); 1317 goto fail_mport_id; 1318 } 1319 1320 port->rte_port_id = rte_port_id; 1321 port->repr_id = repr_id; 1322 1323 rc = efx_mcdi_get_client_handle(sa->nic, intf, pf, vf, 1324 &port->remote_vnic_mcdi_client_handle); 1325 if (rc != 0) { 1326 sfc_err(sa, "failed to get the represented VNIC's MCDI handle (repr_id=%u): %s", 1327 repr_id, rte_strerror(rc)); 1328 goto fail_client_handle; 1329 } 1330 1331 if (rp->started) { 1332 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, 1333 SFC_REPR_PROXY_MBOX_ADD_PORT); 1334 if (rc != 0) { 1335 sfc_err(sa, "failed to add proxy port %u", 1336 port->repr_id); 1337 goto fail_port_add; 1338 } 1339 } else { 1340 TAILQ_INSERT_TAIL(&rp->ports, port, entries); 1341 } 1342 1343 sfc_log_init(sa, "done"); 1344 sfc_put_adapter(sa); 1345 1346 return 0; 1347 1348 fail_port_add: 1349 fail_client_handle: 1350 fail_mport_id: 1351 rte_free(port); 1352 fail_alloc_port: 1353 fail_port_exists: 1354 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 1355 sfc_put_adapter(sa); 1356 1357 return rc; 1358 } 1359 1360 int 1361 sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id) 1362 { 1363 struct sfc_repr_proxy_port *port; 1364 struct sfc_repr_proxy *rp; 1365 struct sfc_adapter *sa; 1366 int rc; 1367 1368 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1369 rp = sfc_repr_proxy_by_adapter(sa); 1370 1371 sfc_log_init(sa, "entry"); 1372 1373 port = sfc_repr_proxy_find_port(rp, repr_id); 1374 if (port == NULL) { 1375 sfc_err(sa, "failed: no such port"); 1376 rc = ENOENT; 1377 goto fail_no_port; 1378 } 1379 1380 if (rp->started) { 1381 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, 1382 SFC_REPR_PROXY_MBOX_DEL_PORT); 1383 if (rc != 0) { 1384 sfc_err(sa, "failed to remove proxy port %u", 1385 port->repr_id); 1386 goto fail_port_remove; 1387 } 1388 } else { 1389 TAILQ_REMOVE(&rp->ports, port, entries); 1390 } 1391 1392 rte_free(port); 1393 1394 sfc_log_init(sa, "done"); 1395 1396 sfc_put_adapter(sa); 1397 1398 return 0; 1399 1400 fail_port_remove: 1401 fail_no_port: 1402 sfc_log_init(sa, "failed: %s", rte_strerror(rc)); 1403 sfc_put_adapter(sa); 1404 1405 return rc; 1406 } 1407 1408 int 1409 sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id, 1410 uint16_t queue_id, struct rte_ring *rx_ring, 1411 struct rte_mempool *mp) 1412 { 1413 struct sfc_repr_proxy_port *port; 1414 struct sfc_repr_proxy_rxq *rxq; 1415 struct sfc_repr_proxy *rp; 1416 struct sfc_adapter *sa; 1417 1418 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1419 rp = sfc_repr_proxy_by_adapter(sa); 1420 1421 sfc_log_init(sa, "entry"); 1422 1423 port = sfc_repr_proxy_find_port(rp, repr_id); 1424 if (port == NULL) { 1425 sfc_err(sa, "%s() failed: no such port", __func__); 1426 sfc_put_adapter(sa); 1427 return ENOENT; 1428 } 1429 1430 rxq = &port->rxq[queue_id]; 1431 if (rp->dp_rxq[queue_id].mp != NULL && rp->dp_rxq[queue_id].mp != mp) { 1432 sfc_err(sa, "multiple mempools per queue are not supported"); 1433 sfc_put_adapter(sa); 1434 return ENOTSUP; 1435 } 1436 1437 rxq->ring = rx_ring; 1438 rxq->mb_pool = mp; 1439 rp->dp_rxq[queue_id].mp = mp; 1440 rp->dp_rxq[queue_id].ref_count++; 1441 1442 sfc_log_init(sa, "done"); 1443 sfc_put_adapter(sa); 1444 1445 return 0; 1446 } 1447 1448 void 1449 sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id, 1450 uint16_t queue_id) 1451 { 1452 struct sfc_repr_proxy_port *port; 1453 struct sfc_repr_proxy_rxq *rxq; 1454 struct sfc_repr_proxy *rp; 1455 struct sfc_adapter *sa; 1456 1457 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1458 rp = sfc_repr_proxy_by_adapter(sa); 1459 1460 sfc_log_init(sa, "entry"); 1461 1462 port = sfc_repr_proxy_find_port(rp, repr_id); 1463 if (port == NULL) { 1464 sfc_err(sa, "%s() failed: no such port", __func__); 1465 sfc_put_adapter(sa); 1466 return; 1467 } 1468 1469 rxq = &port->rxq[queue_id]; 1470 1471 rxq->ring = NULL; 1472 rxq->mb_pool = NULL; 1473 rp->dp_rxq[queue_id].ref_count--; 1474 if (rp->dp_rxq[queue_id].ref_count == 0) 1475 rp->dp_rxq[queue_id].mp = NULL; 1476 1477 sfc_log_init(sa, "done"); 1478 sfc_put_adapter(sa); 1479 } 1480 1481 int 1482 sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id, 1483 uint16_t queue_id, struct rte_ring *tx_ring, 1484 efx_mport_id_t *egress_mport) 1485 { 1486 struct sfc_repr_proxy_port *port; 1487 struct sfc_repr_proxy_txq *txq; 1488 struct sfc_repr_proxy *rp; 1489 struct sfc_adapter *sa; 1490 1491 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1492 rp = sfc_repr_proxy_by_adapter(sa); 1493 1494 sfc_log_init(sa, "entry"); 1495 1496 port = sfc_repr_proxy_find_port(rp, repr_id); 1497 if (port == NULL) { 1498 sfc_err(sa, "%s() failed: no such port", __func__); 1499 sfc_put_adapter(sa); 1500 return ENOENT; 1501 } 1502 1503 txq = &port->txq[queue_id]; 1504 1505 txq->ring = tx_ring; 1506 1507 *egress_mport = port->egress_mport; 1508 1509 sfc_log_init(sa, "done"); 1510 sfc_put_adapter(sa); 1511 1512 return 0; 1513 } 1514 1515 void 1516 sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id, 1517 uint16_t queue_id) 1518 { 1519 struct sfc_repr_proxy_port *port; 1520 struct sfc_repr_proxy_txq *txq; 1521 struct sfc_repr_proxy *rp; 1522 struct sfc_adapter *sa; 1523 1524 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1525 rp = sfc_repr_proxy_by_adapter(sa); 1526 1527 sfc_log_init(sa, "entry"); 1528 1529 port = sfc_repr_proxy_find_port(rp, repr_id); 1530 if (port == NULL) { 1531 sfc_err(sa, "%s() failed: no such port", __func__); 1532 sfc_put_adapter(sa); 1533 return; 1534 } 1535 1536 txq = &port->txq[queue_id]; 1537 1538 txq->ring = NULL; 1539 1540 sfc_log_init(sa, "done"); 1541 sfc_put_adapter(sa); 1542 } 1543 1544 int 1545 sfc_repr_proxy_start_repr(uint16_t pf_port_id, uint16_t repr_id) 1546 { 1547 bool proxy_start_required = false; 1548 struct sfc_repr_proxy_port *port; 1549 struct sfc_repr_proxy *rp; 1550 struct sfc_adapter *sa; 1551 int rc; 1552 1553 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1554 rp = sfc_repr_proxy_by_adapter(sa); 1555 1556 sfc_log_init(sa, "entry"); 1557 1558 port = sfc_repr_proxy_find_port(rp, repr_id); 1559 if (port == NULL) { 1560 sfc_err(sa, "%s() failed: no such port", __func__); 1561 rc = ENOENT; 1562 goto fail_not_found; 1563 } 1564 1565 if (port->enabled) { 1566 rc = EALREADY; 1567 sfc_err(sa, "failed: repr %u proxy port already started", 1568 repr_id); 1569 goto fail_already_started; 1570 } 1571 1572 if (sa->state == SFC_ETHDEV_STARTED) { 1573 if (sfc_repr_proxy_ports_disabled(rp)) { 1574 proxy_start_required = true; 1575 } else { 1576 rc = sfc_repr_proxy_do_start_port(sa, port); 1577 if (rc != 0) { 1578 sfc_err(sa, 1579 "failed to start repr %u proxy port", 1580 repr_id); 1581 goto fail_start_id; 1582 } 1583 } 1584 } 1585 1586 port->enabled = true; 1587 1588 if (proxy_start_required) { 1589 rc = sfc_repr_proxy_start(sa); 1590 if (rc != 0) { 1591 sfc_err(sa, "failed to start proxy"); 1592 goto fail_proxy_start; 1593 } 1594 } 1595 1596 sfc_log_init(sa, "done"); 1597 sfc_put_adapter(sa); 1598 1599 return 0; 1600 1601 fail_proxy_start: 1602 port->enabled = false; 1603 1604 fail_start_id: 1605 fail_already_started: 1606 fail_not_found: 1607 sfc_err(sa, "failed to start repr %u proxy port: %s", repr_id, 1608 rte_strerror(rc)); 1609 sfc_put_adapter(sa); 1610 1611 return rc; 1612 } 1613 1614 int 1615 sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id) 1616 { 1617 struct sfc_repr_proxy_port *port; 1618 struct sfc_repr_proxy_port *p; 1619 struct sfc_repr_proxy *rp; 1620 struct sfc_adapter *sa; 1621 int rc; 1622 1623 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1624 rp = sfc_repr_proxy_by_adapter(sa); 1625 1626 sfc_log_init(sa, "entry"); 1627 1628 port = sfc_repr_proxy_find_port(rp, repr_id); 1629 if (port == NULL) { 1630 sfc_err(sa, "%s() failed: no such port", __func__); 1631 sfc_put_adapter(sa); 1632 return ENOENT; 1633 } 1634 1635 if (!port->enabled) { 1636 sfc_log_init(sa, "repr %u proxy port is not started - skip", 1637 repr_id); 1638 sfc_put_adapter(sa); 1639 return 0; 1640 } 1641 1642 if (sa->state == SFC_ETHDEV_STARTED) { 1643 bool last_enabled = true; 1644 1645 TAILQ_FOREACH(p, &rp->ports, entries) { 1646 if (p == port) 1647 continue; 1648 1649 if (sfc_repr_proxy_port_enabled(p)) { 1650 last_enabled = false; 1651 break; 1652 } 1653 } 1654 1655 rc = 0; 1656 if (last_enabled) 1657 sfc_repr_proxy_stop(sa); 1658 else 1659 rc = sfc_repr_proxy_do_stop_port(sa, port); 1660 1661 if (rc != 0) { 1662 sfc_err(sa, 1663 "failed to stop representor proxy TxQ %u: %s", 1664 repr_id, rte_strerror(rc)); 1665 sfc_put_adapter(sa); 1666 return rc; 1667 } 1668 } 1669 1670 port->enabled = false; 1671 1672 sfc_log_init(sa, "done"); 1673 sfc_put_adapter(sa); 1674 1675 return 0; 1676 } 1677 1678 int 1679 sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id, uint16_t repr_id, 1680 const struct rte_ether_addr *mac_addr) 1681 { 1682 struct sfc_repr_proxy_port *port; 1683 struct sfc_repr_proxy *rp; 1684 struct sfc_adapter *sa; 1685 int rc; 1686 1687 sa = sfc_get_adapter_by_pf_port_id(pf_port_id); 1688 rp = sfc_repr_proxy_by_adapter(sa); 1689 1690 port = sfc_repr_proxy_find_port(rp, repr_id); 1691 if (port == NULL) { 1692 sfc_err(sa, "%s() failed: no such port (repr_id=%u)", 1693 __func__, repr_id); 1694 sfc_put_adapter(sa); 1695 return ENOENT; 1696 } 1697 1698 rc = efx_mcdi_client_mac_addr_set(sa->nic, 1699 port->remote_vnic_mcdi_client_handle, 1700 mac_addr->addr_bytes); 1701 if (rc != 0) { 1702 sfc_err(sa, "%s() failed: cannot set MAC address (repr_id=%u): %s", 1703 __func__, repr_id, rte_strerror(rc)); 1704 } 1705 1706 sfc_put_adapter(sa); 1707 1708 return rc; 1709 } 1710