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