1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2019 Solarflare Communications Inc.
6 * This software was jointly developed between OKTET Labs (under contract
7 * for Solarflare) and Solarflare Communications, Inc.
10 #include <rte_service.h>
11 #include <rte_service_component.h>
14 #include "sfc_service.h"
15 #include "sfc_repr_proxy.h"
16 #include "sfc_repr_proxy_api.h"
23 * Amount of time to wait for the representor proxy routine (which is
24 * running on a service core) to handle a request sent via mbox.
26 #define SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS 1000
28 static struct sfc_repr_proxy *
29 sfc_repr_proxy_by_adapter(struct sfc_adapter *sa)
31 return &sa->repr_proxy;
34 static struct sfc_adapter *
35 sfc_get_adapter_by_pf_port_id(uint16_t pf_port_id)
37 struct rte_eth_dev *dev;
38 struct sfc_adapter *sa;
40 SFC_ASSERT(pf_port_id < RTE_MAX_ETHPORTS);
42 dev = &rte_eth_devices[pf_port_id];
43 sa = sfc_adapter_by_eth_dev(dev);
51 sfc_put_adapter(struct sfc_adapter *sa)
53 sfc_adapter_unlock(sa);
56 static struct sfc_repr_proxy_port *
57 sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id)
59 struct sfc_repr_proxy_port *port;
61 TAILQ_FOREACH(port, &rp->ports, entries) {
62 if (port->repr_id == repr_id)
70 sfc_repr_proxy_mbox_send(struct sfc_repr_proxy_mbox *mbox,
71 struct sfc_repr_proxy_port *port,
72 enum sfc_repr_proxy_mbox_op op)
74 const unsigned int wait_ms = SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS;
82 * Release ordering enforces marker set after data is populated.
83 * Paired with acquire ordering in sfc_repr_proxy_mbox_handle().
85 __atomic_store_n(&mbox->write_marker, true, __ATOMIC_RELEASE);
88 * Wait for the representor routine to process the request.
91 for (i = 0; i < wait_ms; i++) {
93 * Paired with release ordering in sfc_repr_proxy_mbox_handle()
94 * on acknowledge write.
96 if (__atomic_load_n(&mbox->ack, __ATOMIC_ACQUIRE))
104 "%s() failed to wait for representor proxy routine ack",
113 sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp)
115 struct sfc_repr_proxy_mbox *mbox = &rp->mbox;
118 * Paired with release ordering in sfc_repr_proxy_mbox_send()
121 if (!__atomic_load_n(&mbox->write_marker, __ATOMIC_ACQUIRE))
124 mbox->write_marker = false;
127 case SFC_REPR_PROXY_MBOX_ADD_PORT:
128 TAILQ_INSERT_TAIL(&rp->ports, mbox->port, entries);
130 case SFC_REPR_PROXY_MBOX_DEL_PORT:
131 TAILQ_REMOVE(&rp->ports, mbox->port, entries);
133 case SFC_REPR_PROXY_MBOX_START_PORT:
134 mbox->port->started = true;
136 case SFC_REPR_PROXY_MBOX_STOP_PORT:
137 mbox->port->started = false;
145 * Paired with acquire ordering in sfc_repr_proxy_mbox_send()
146 * on acknowledge read.
148 __atomic_store_n(&mbox->ack, true, __ATOMIC_RELEASE);
152 sfc_repr_proxy_routine(void *arg)
154 struct sfc_repr_proxy *rp = arg;
156 sfc_repr_proxy_mbox_handle(rp);
162 sfc_repr_proxy_txq_attach(struct sfc_adapter *sa)
164 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
165 struct sfc_repr_proxy *rp = &sa->repr_proxy;
168 sfc_log_init(sa, "entry");
170 for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
171 sfc_sw_index_t sw_index = sfc_repr_txq_sw_index(sas, i);
173 rp->dp_txq[i].sw_index = sw_index;
176 sfc_log_init(sa, "done");
182 sfc_repr_proxy_txq_detach(struct sfc_adapter *sa)
184 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
185 struct sfc_repr_proxy *rp = &sa->repr_proxy;
188 sfc_log_init(sa, "entry");
190 for (i = 0; i < sfc_repr_nb_txq(sas); i++)
191 rp->dp_txq[i].sw_index = 0;
193 sfc_log_init(sa, "done");
197 sfc_repr_proxy_txq_init(struct sfc_adapter *sa)
199 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
200 struct sfc_repr_proxy *rp = &sa->repr_proxy;
201 const struct rte_eth_txconf tx_conf = {
202 .tx_free_thresh = SFC_REPR_PROXY_TXQ_FREE_THRESH,
204 struct sfc_txq_info *txq_info;
209 sfc_log_init(sa, "entry");
211 if (!sfc_repr_available(sas)) {
212 sfc_log_init(sa, "representors not supported - skip");
216 for (init_i = 0; init_i < sfc_repr_nb_txq(sas); init_i++) {
217 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[init_i];
219 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
220 if (txq_info->state == SFC_TXQ_INITIALIZED) {
222 "representor proxy TxQ %u is already initialized - skip",
227 sfc_tx_qinit_info(sa, txq->sw_index);
229 rc = sfc_tx_qinit(sa, txq->sw_index,
230 SFC_REPR_PROXY_TX_DESC_COUNT, sa->socket_id,
234 sfc_err(sa, "failed to init representor proxy TxQ %u",
240 sfc_log_init(sa, "done");
245 for (i = 0; i < init_i; i++) {
246 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
248 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
249 if (txq_info->state == SFC_TXQ_INITIALIZED)
250 sfc_tx_qfini(sa, txq->sw_index);
252 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
258 sfc_repr_proxy_txq_fini(struct sfc_adapter *sa)
260 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
261 struct sfc_repr_proxy *rp = &sa->repr_proxy;
262 struct sfc_txq_info *txq_info;
265 sfc_log_init(sa, "entry");
267 if (!sfc_repr_available(sas)) {
268 sfc_log_init(sa, "representors not supported - skip");
272 for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
273 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
275 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
276 if (txq_info->state != SFC_TXQ_INITIALIZED) {
278 "representor proxy TxQ %u is already finalized - skip",
283 sfc_tx_qfini(sa, txq->sw_index);
286 sfc_log_init(sa, "done");
290 sfc_repr_proxy_txq_start(struct sfc_adapter *sa)
292 struct sfc_repr_proxy *rp = &sa->repr_proxy;
294 sfc_log_init(sa, "entry");
298 sfc_log_init(sa, "done");
304 sfc_repr_proxy_txq_stop(struct sfc_adapter *sa)
306 sfc_log_init(sa, "entry");
307 sfc_log_init(sa, "done");
311 sfc_repr_proxy_rxq_attach(struct sfc_adapter *sa)
313 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
314 struct sfc_repr_proxy *rp = &sa->repr_proxy;
317 sfc_log_init(sa, "entry");
319 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
320 sfc_sw_index_t sw_index = sfc_repr_rxq_sw_index(sas, i);
322 rp->dp_rxq[i].sw_index = sw_index;
325 sfc_log_init(sa, "done");
331 sfc_repr_proxy_rxq_detach(struct sfc_adapter *sa)
333 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
334 struct sfc_repr_proxy *rp = &sa->repr_proxy;
337 sfc_log_init(sa, "entry");
339 for (i = 0; i < sfc_repr_nb_rxq(sas); i++)
340 rp->dp_rxq[i].sw_index = 0;
342 sfc_log_init(sa, "done");
346 sfc_repr_proxy_rxq_init(struct sfc_adapter *sa,
347 struct sfc_repr_proxy_dp_rxq *rxq)
349 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
350 uint16_t nb_rx_desc = SFC_REPR_PROXY_RX_DESC_COUNT;
351 struct sfc_rxq_info *rxq_info;
352 struct rte_eth_rxconf rxconf = {
353 .rx_free_thresh = SFC_REPR_PROXY_RXQ_REFILL_LEVEL,
358 sfc_log_init(sa, "entry");
360 rxq_info = &sas->rxq_info[rxq->sw_index];
361 if (rxq_info->state & SFC_RXQ_INITIALIZED) {
362 sfc_log_init(sa, "RxQ is already initialized - skip");
366 nb_rx_desc = RTE_MIN(nb_rx_desc, sa->rxq_max_entries);
367 nb_rx_desc = RTE_MAX(nb_rx_desc, sa->rxq_min_entries);
369 rc = sfc_rx_qinit_info(sa, rxq->sw_index, EFX_RXQ_FLAG_INGRESS_MPORT);
371 sfc_err(sa, "failed to init representor proxy RxQ info");
372 goto fail_repr_rxq_init_info;
375 rc = sfc_rx_qinit(sa, rxq->sw_index, nb_rx_desc, sa->socket_id, &rxconf,
378 sfc_err(sa, "failed to init representor proxy RxQ");
379 goto fail_repr_rxq_init;
382 sfc_log_init(sa, "done");
387 fail_repr_rxq_init_info:
388 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
394 sfc_repr_proxy_rxq_fini(struct sfc_adapter *sa)
396 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
397 struct sfc_repr_proxy *rp = &sa->repr_proxy;
398 struct sfc_rxq_info *rxq_info;
401 sfc_log_init(sa, "entry");
403 if (!sfc_repr_available(sas)) {
404 sfc_log_init(sa, "representors not supported - skip");
408 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
409 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i];
411 rxq_info = &sas->rxq_info[rxq->sw_index];
412 if (rxq_info->state != SFC_RXQ_INITIALIZED) {
414 "representor RxQ %u is already finalized - skip",
419 sfc_rx_qfini(sa, rxq->sw_index);
422 sfc_log_init(sa, "done");
426 sfc_repr_proxy_rxq_stop(struct sfc_adapter *sa)
428 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
431 sfc_log_init(sa, "entry");
433 for (i = 0; i < sfc_repr_nb_rxq(sas); i++)
434 sfc_rx_qstop(sa, sa->repr_proxy.dp_rxq[i].sw_index);
436 sfc_repr_proxy_rxq_fini(sa);
438 sfc_log_init(sa, "done");
442 sfc_repr_proxy_rxq_start(struct sfc_adapter *sa)
444 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
445 struct sfc_repr_proxy *rp = &sa->repr_proxy;
449 sfc_log_init(sa, "entry");
451 if (!sfc_repr_available(sas)) {
452 sfc_log_init(sa, "representors not supported - skip");
456 for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
457 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i];
459 rc = sfc_repr_proxy_rxq_init(sa, rxq);
461 sfc_err(sa, "failed to init representor proxy RxQ %u",
466 rc = sfc_rx_qstart(sa, rxq->sw_index);
468 sfc_err(sa, "failed to start representor proxy RxQ %u",
474 sfc_log_init(sa, "done");
480 sfc_repr_proxy_rxq_stop(sa);
481 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
486 sfc_repr_proxy_mae_rule_insert(struct sfc_adapter *sa,
487 struct sfc_repr_proxy_port *port)
489 struct sfc_repr_proxy *rp = &sa->repr_proxy;
490 efx_mport_sel_t mport_alias_selector;
491 efx_mport_sel_t mport_vf_selector;
492 struct sfc_mae_rule *mae_rule;
495 sfc_log_init(sa, "entry");
497 rc = efx_mae_mport_by_id(&port->egress_mport,
500 sfc_err(sa, "failed to get VF mport for repr %u",
505 rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector);
507 sfc_err(sa, "failed to get mport selector for repr %u",
512 rc = sfc_mae_rule_add_mport_match_deliver(sa, &mport_vf_selector,
513 &mport_alias_selector, -1,
516 sfc_err(sa, "failed to insert MAE rule for repr %u",
521 port->mae_rule = mae_rule;
523 sfc_log_init(sa, "done");
530 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
535 sfc_repr_proxy_mae_rule_remove(struct sfc_adapter *sa,
536 struct sfc_repr_proxy_port *port)
538 struct sfc_mae_rule *mae_rule = port->mae_rule;
540 sfc_mae_rule_del(sa, mae_rule);
544 sfc_repr_proxy_mport_filter_insert(struct sfc_adapter *sa)
546 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
547 struct sfc_repr_proxy *rp = &sa->repr_proxy;
548 struct sfc_rxq *rxq_ctrl;
549 struct sfc_repr_proxy_filter *filter = &rp->mport_filter;
550 efx_mport_sel_t mport_alias_selector;
551 static const efx_filter_match_flags_t flags[RTE_DIM(filter->specs)] = {
552 EFX_FILTER_MATCH_UNKNOWN_UCAST_DST,
553 EFX_FILTER_MATCH_UNKNOWN_MCAST_DST };
557 sfc_log_init(sa, "entry");
559 if (sfc_repr_nb_rxq(sas) == 1) {
560 rxq_ctrl = &sa->rxq_ctrl[rp->dp_rxq[0].sw_index];
562 sfc_err(sa, "multiple representor proxy RxQs not supported");
564 goto fail_multiple_queues;
567 rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector);
569 sfc_err(sa, "failed to get repr proxy mport by ID");
570 goto fail_get_selector;
573 memset(filter->specs, 0, sizeof(filter->specs));
574 for (i = 0; i < RTE_DIM(filter->specs); i++) {
575 filter->specs[i].efs_priority = EFX_FILTER_PRI_MANUAL;
576 filter->specs[i].efs_flags = EFX_FILTER_FLAG_RX;
577 filter->specs[i].efs_dmaq_id = rxq_ctrl->hw_index;
578 filter->specs[i].efs_match_flags = flags[i] |
579 EFX_FILTER_MATCH_MPORT;
580 filter->specs[i].efs_ingress_mport = mport_alias_selector.sel;
582 rc = efx_filter_insert(sa->nic, &filter->specs[i]);
584 sfc_err(sa, "failed to insert repr proxy filter");
589 sfc_log_init(sa, "done");
595 efx_filter_remove(sa->nic, &filter->specs[i]);
598 fail_multiple_queues:
599 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
604 sfc_repr_proxy_mport_filter_remove(struct sfc_adapter *sa)
606 struct sfc_repr_proxy *rp = &sa->repr_proxy;
607 struct sfc_repr_proxy_filter *filter = &rp->mport_filter;
610 for (i = 0; i < RTE_DIM(filter->specs); i++)
611 efx_filter_remove(sa->nic, &filter->specs[i]);
615 sfc_repr_proxy_port_rule_insert(struct sfc_adapter *sa,
616 struct sfc_repr_proxy_port *port)
620 rc = sfc_repr_proxy_mae_rule_insert(sa, port);
622 goto fail_mae_rule_insert;
626 fail_mae_rule_insert:
631 sfc_repr_proxy_port_rule_remove(struct sfc_adapter *sa,
632 struct sfc_repr_proxy_port *port)
634 sfc_repr_proxy_mae_rule_remove(sa, port);
638 sfc_repr_proxy_ports_init(struct sfc_adapter *sa)
640 struct sfc_repr_proxy *rp = &sa->repr_proxy;
643 sfc_log_init(sa, "entry");
645 rc = efx_mcdi_mport_alloc_alias(sa->nic, &rp->mport_alias, NULL);
647 sfc_err(sa, "failed to alloc mport alias: %s",
649 goto fail_alloc_mport_alias;
652 TAILQ_INIT(&rp->ports);
654 sfc_log_init(sa, "done");
658 fail_alloc_mport_alias:
660 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
665 sfc_repr_proxy_pre_detach(struct sfc_adapter *sa)
667 struct sfc_repr_proxy *rp = &sa->repr_proxy;
668 bool close_ports[RTE_MAX_ETHPORTS] = {0};
669 struct sfc_repr_proxy_port *port;
672 SFC_ASSERT(!sfc_adapter_is_locked(sa));
674 sfc_adapter_lock(sa);
676 if (sfc_repr_available(sfc_sa2shared(sa))) {
677 TAILQ_FOREACH(port, &rp->ports, entries)
678 close_ports[port->rte_port_id] = true;
680 sfc_log_init(sa, "representors not supported - skip");
683 sfc_adapter_unlock(sa);
685 for (i = 0; i < RTE_DIM(close_ports); i++) {
686 if (close_ports[i]) {
688 rte_eth_dev_close(i);
694 sfc_repr_proxy_ports_fini(struct sfc_adapter *sa)
696 struct sfc_repr_proxy *rp = &sa->repr_proxy;
698 efx_mae_mport_free(sa->nic, &rp->mport_alias);
702 sfc_repr_proxy_attach(struct sfc_adapter *sa)
704 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
705 struct sfc_repr_proxy *rp = &sa->repr_proxy;
706 struct rte_service_spec service;
711 sfc_log_init(sa, "entry");
713 if (!sfc_repr_available(sas)) {
714 sfc_log_init(sa, "representors not supported - skip");
718 rc = sfc_repr_proxy_rxq_attach(sa);
720 goto fail_rxq_attach;
722 rc = sfc_repr_proxy_txq_attach(sa);
724 goto fail_txq_attach;
726 rc = sfc_repr_proxy_ports_init(sa);
728 goto fail_ports_init;
730 cid = sfc_get_service_lcore(sa->socket_id);
731 if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) {
732 /* Warn and try to allocate on any NUMA node */
734 "repr proxy: unable to get service lcore at socket %d",
737 cid = sfc_get_service_lcore(SOCKET_ID_ANY);
739 if (cid == RTE_MAX_LCORE) {
741 sfc_err(sa, "repr proxy: failed to get service lcore");
742 goto fail_get_service_lcore;
745 memset(&service, 0, sizeof(service));
746 snprintf(service.name, sizeof(service.name),
747 "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id);
748 service.socket_id = rte_lcore_to_socket_id(cid);
749 service.callback = sfc_repr_proxy_routine;
750 service.callback_userdata = rp;
752 rc = rte_service_component_register(&service, &sid);
755 sfc_err(sa, "repr proxy: failed to register service component");
759 rc = rte_service_map_lcore_set(sid, cid, 1);
762 sfc_err(sa, "repr proxy: failed to map lcore");
766 rp->service_core_id = cid;
767 rp->service_id = sid;
769 sfc_log_init(sa, "done");
774 rte_service_component_unregister(sid);
778 * No need to rollback service lcore get since
779 * it just makes socket_id based search and remembers it.
782 fail_get_service_lcore:
783 sfc_repr_proxy_ports_fini(sa);
786 sfc_repr_proxy_txq_detach(sa);
789 sfc_repr_proxy_rxq_detach(sa);
792 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
797 sfc_repr_proxy_detach(struct sfc_adapter *sa)
799 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
800 struct sfc_repr_proxy *rp = &sa->repr_proxy;
802 sfc_log_init(sa, "entry");
804 if (!sfc_repr_available(sas)) {
805 sfc_log_init(sa, "representors not supported - skip");
809 rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0);
810 rte_service_component_unregister(rp->service_id);
811 sfc_repr_proxy_ports_fini(sa);
812 sfc_repr_proxy_rxq_detach(sa);
813 sfc_repr_proxy_txq_detach(sa);
815 sfc_log_init(sa, "done");
819 sfc_repr_proxy_do_start_port(struct sfc_adapter *sa,
820 struct sfc_repr_proxy_port *port)
822 struct sfc_repr_proxy *rp = &sa->repr_proxy;
825 rc = sfc_repr_proxy_port_rule_insert(sa, port);
827 goto fail_filter_insert;
830 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
831 SFC_REPR_PROXY_MBOX_START_PORT);
833 sfc_err(sa, "failed to start proxy port %u",
835 goto fail_port_start;
838 port->started = true;
844 sfc_repr_proxy_port_rule_remove(sa, port);
846 sfc_err(sa, "%s() failed %s", __func__, rte_strerror(rc));
852 sfc_repr_proxy_do_stop_port(struct sfc_adapter *sa,
853 struct sfc_repr_proxy_port *port)
856 struct sfc_repr_proxy *rp = &sa->repr_proxy;
860 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
861 SFC_REPR_PROXY_MBOX_STOP_PORT);
863 sfc_err(sa, "failed to stop proxy port %u: %s",
864 port->repr_id, rte_strerror(rc));
868 port->started = false;
871 sfc_repr_proxy_port_rule_remove(sa, port);
877 sfc_repr_proxy_port_enabled(struct sfc_repr_proxy_port *port)
879 return port->rte_port_id != RTE_MAX_ETHPORTS && port->enabled;
883 sfc_repr_proxy_ports_disabled(struct sfc_repr_proxy *rp)
885 struct sfc_repr_proxy_port *port;
887 TAILQ_FOREACH(port, &rp->ports, entries) {
888 if (sfc_repr_proxy_port_enabled(port))
896 sfc_repr_proxy_start(struct sfc_adapter *sa)
898 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
899 struct sfc_repr_proxy *rp = &sa->repr_proxy;
900 struct sfc_repr_proxy_port *last_port = NULL;
901 struct sfc_repr_proxy_port *port;
904 sfc_log_init(sa, "entry");
906 /* Representor proxy is not started when no representors are started */
907 if (!sfc_repr_available(sas)) {
908 sfc_log_init(sa, "representors not supported - skip");
912 if (sfc_repr_proxy_ports_disabled(rp)) {
913 sfc_log_init(sa, "no started representor ports - skip");
917 rc = sfc_repr_proxy_rxq_start(sa);
921 rc = sfc_repr_proxy_txq_start(sa);
925 /* Service core may be in "stopped" state, start it */
926 rc = rte_service_lcore_start(rp->service_core_id);
927 if (rc != 0 && rc != -EALREADY) {
929 sfc_err(sa, "failed to start service core for %s: %s",
930 rte_service_get_name(rp->service_id),
932 goto fail_start_core;
935 /* Run the service */
936 rc = rte_service_component_runstate_set(rp->service_id, 1);
939 sfc_err(sa, "failed to run %s component: %s",
940 rte_service_get_name(rp->service_id),
942 goto fail_component_runstate_set;
944 rc = rte_service_runstate_set(rp->service_id, 1);
947 sfc_err(sa, "failed to run %s: %s",
948 rte_service_get_name(rp->service_id),
950 goto fail_runstate_set;
953 TAILQ_FOREACH(port, &rp->ports, entries) {
954 if (sfc_repr_proxy_port_enabled(port)) {
955 rc = sfc_repr_proxy_do_start_port(sa, port);
963 rc = sfc_repr_proxy_mport_filter_insert(sa);
965 goto fail_mport_filter_insert;
969 sfc_log_init(sa, "done");
973 fail_mport_filter_insert:
975 if (last_port != NULL) {
976 TAILQ_FOREACH(port, &rp->ports, entries) {
977 if (sfc_repr_proxy_port_enabled(port)) {
978 (void)sfc_repr_proxy_do_stop_port(sa, port);
979 if (port == last_port)
985 rte_service_runstate_set(rp->service_id, 0);
988 rte_service_component_runstate_set(rp->service_id, 0);
990 fail_component_runstate_set:
991 /* Service lcore may be shared and we never stop it */
994 sfc_repr_proxy_txq_stop(sa);
997 sfc_repr_proxy_rxq_stop(sa);
1000 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
1005 sfc_repr_proxy_stop(struct sfc_adapter *sa)
1007 struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
1008 struct sfc_repr_proxy *rp = &sa->repr_proxy;
1009 struct sfc_repr_proxy_port *port;
1012 sfc_log_init(sa, "entry");
1014 if (!sfc_repr_available(sas)) {
1015 sfc_log_init(sa, "representors not supported - skip");
1019 if (sfc_repr_proxy_ports_disabled(rp)) {
1020 sfc_log_init(sa, "no started representor ports - skip");
1024 TAILQ_FOREACH(port, &rp->ports, entries) {
1025 if (sfc_repr_proxy_port_enabled(port)) {
1026 rc = sfc_repr_proxy_do_stop_port(sa, port);
1029 "failed to stop representor proxy port %u: %s",
1030 port->repr_id, rte_strerror(rc));
1035 sfc_repr_proxy_mport_filter_remove(sa);
1037 rc = rte_service_runstate_set(rp->service_id, 0);
1039 sfc_err(sa, "failed to stop %s: %s",
1040 rte_service_get_name(rp->service_id),
1044 rc = rte_service_component_runstate_set(rp->service_id, 0);
1046 sfc_err(sa, "failed to stop %s component: %s",
1047 rte_service_get_name(rp->service_id),
1051 /* Service lcore may be shared and we never stop it */
1053 sfc_repr_proxy_rxq_stop(sa);
1054 sfc_repr_proxy_txq_stop(sa);
1056 rp->started = false;
1058 sfc_log_init(sa, "done");
1062 sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id,
1063 uint16_t rte_port_id, const efx_mport_sel_t *mport_sel)
1065 struct sfc_repr_proxy_port *port;
1066 struct sfc_repr_proxy *rp;
1067 struct sfc_adapter *sa;
1070 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1071 rp = sfc_repr_proxy_by_adapter(sa);
1073 sfc_log_init(sa, "entry");
1074 TAILQ_FOREACH(port, &rp->ports, entries) {
1075 if (port->rte_port_id == rte_port_id) {
1077 sfc_err(sa, "%s() failed: port exists", __func__);
1078 goto fail_port_exists;
1082 port = rte_zmalloc("sfc-repr-proxy-port", sizeof(*port),
1086 sfc_err(sa, "failed to alloc memory for proxy port");
1087 goto fail_alloc_port;
1090 rc = efx_mae_mport_id_by_selector(sa->nic, mport_sel,
1091 &port->egress_mport);
1094 "failed get MAE mport id by selector (repr_id %u): %s",
1095 repr_id, rte_strerror(rc));
1099 port->rte_port_id = rte_port_id;
1100 port->repr_id = repr_id;
1103 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
1104 SFC_REPR_PROXY_MBOX_ADD_PORT);
1106 sfc_err(sa, "failed to add proxy port %u",
1111 TAILQ_INSERT_TAIL(&rp->ports, port, entries);
1114 sfc_log_init(sa, "done");
1115 sfc_put_adapter(sa);
1124 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
1125 sfc_put_adapter(sa);
1131 sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id)
1133 struct sfc_repr_proxy_port *port;
1134 struct sfc_repr_proxy *rp;
1135 struct sfc_adapter *sa;
1138 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1139 rp = sfc_repr_proxy_by_adapter(sa);
1141 sfc_log_init(sa, "entry");
1143 port = sfc_repr_proxy_find_port(rp, repr_id);
1145 sfc_err(sa, "failed: no such port");
1151 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
1152 SFC_REPR_PROXY_MBOX_DEL_PORT);
1154 sfc_err(sa, "failed to remove proxy port %u",
1156 goto fail_port_remove;
1159 TAILQ_REMOVE(&rp->ports, port, entries);
1164 sfc_log_init(sa, "done");
1166 sfc_put_adapter(sa);
1172 sfc_log_init(sa, "failed: %s", rte_strerror(rc));
1173 sfc_put_adapter(sa);
1179 sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id,
1180 uint16_t queue_id, struct rte_ring *rx_ring,
1181 struct rte_mempool *mp)
1183 struct sfc_repr_proxy_port *port;
1184 struct sfc_repr_proxy_rxq *rxq;
1185 struct sfc_repr_proxy *rp;
1186 struct sfc_adapter *sa;
1188 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1189 rp = sfc_repr_proxy_by_adapter(sa);
1191 sfc_log_init(sa, "entry");
1193 port = sfc_repr_proxy_find_port(rp, repr_id);
1195 sfc_err(sa, "%s() failed: no such port", __func__);
1199 rxq = &port->rxq[queue_id];
1200 if (rp->dp_rxq[queue_id].mp != NULL && rp->dp_rxq[queue_id].mp != mp) {
1201 sfc_err(sa, "multiple mempools per queue are not supported");
1202 sfc_put_adapter(sa);
1206 rxq->ring = rx_ring;
1208 rp->dp_rxq[queue_id].mp = mp;
1209 rp->dp_rxq[queue_id].ref_count++;
1211 sfc_log_init(sa, "done");
1212 sfc_put_adapter(sa);
1218 sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id,
1221 struct sfc_repr_proxy_port *port;
1222 struct sfc_repr_proxy_rxq *rxq;
1223 struct sfc_repr_proxy *rp;
1224 struct sfc_adapter *sa;
1226 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1227 rp = sfc_repr_proxy_by_adapter(sa);
1229 sfc_log_init(sa, "entry");
1231 port = sfc_repr_proxy_find_port(rp, repr_id);
1233 sfc_err(sa, "%s() failed: no such port", __func__);
1237 rxq = &port->rxq[queue_id];
1240 rxq->mb_pool = NULL;
1241 rp->dp_rxq[queue_id].ref_count--;
1242 if (rp->dp_rxq[queue_id].ref_count == 0)
1243 rp->dp_rxq[queue_id].mp = NULL;
1245 sfc_log_init(sa, "done");
1246 sfc_put_adapter(sa);
1250 sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id,
1251 uint16_t queue_id, struct rte_ring *tx_ring,
1252 efx_mport_id_t *egress_mport)
1254 struct sfc_repr_proxy_port *port;
1255 struct sfc_repr_proxy_txq *txq;
1256 struct sfc_repr_proxy *rp;
1257 struct sfc_adapter *sa;
1259 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1260 rp = sfc_repr_proxy_by_adapter(sa);
1262 sfc_log_init(sa, "entry");
1264 port = sfc_repr_proxy_find_port(rp, repr_id);
1266 sfc_err(sa, "%s() failed: no such port", __func__);
1270 txq = &port->txq[queue_id];
1272 txq->ring = tx_ring;
1274 *egress_mport = port->egress_mport;
1276 sfc_log_init(sa, "done");
1277 sfc_put_adapter(sa);
1283 sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id,
1286 struct sfc_repr_proxy_port *port;
1287 struct sfc_repr_proxy_txq *txq;
1288 struct sfc_repr_proxy *rp;
1289 struct sfc_adapter *sa;
1291 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1292 rp = sfc_repr_proxy_by_adapter(sa);
1294 sfc_log_init(sa, "entry");
1296 port = sfc_repr_proxy_find_port(rp, repr_id);
1298 sfc_err(sa, "%s() failed: no such port", __func__);
1302 txq = &port->txq[queue_id];
1306 sfc_log_init(sa, "done");
1307 sfc_put_adapter(sa);
1311 sfc_repr_proxy_start_repr(uint16_t pf_port_id, uint16_t repr_id)
1313 bool proxy_start_required = false;
1314 struct sfc_repr_proxy_port *port;
1315 struct sfc_repr_proxy *rp;
1316 struct sfc_adapter *sa;
1319 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1320 rp = sfc_repr_proxy_by_adapter(sa);
1322 sfc_log_init(sa, "entry");
1324 port = sfc_repr_proxy_find_port(rp, repr_id);
1326 sfc_err(sa, "%s() failed: no such port", __func__);
1328 goto fail_not_found;
1331 if (port->enabled) {
1333 sfc_err(sa, "failed: repr %u proxy port already started",
1335 goto fail_already_started;
1338 if (sa->state == SFC_ETHDEV_STARTED) {
1339 if (sfc_repr_proxy_ports_disabled(rp)) {
1340 proxy_start_required = true;
1342 rc = sfc_repr_proxy_do_start_port(sa, port);
1345 "failed to start repr %u proxy port",
1352 port->enabled = true;
1354 if (proxy_start_required) {
1355 rc = sfc_repr_proxy_start(sa);
1357 sfc_err(sa, "failed to start proxy");
1358 goto fail_proxy_start;
1362 sfc_log_init(sa, "done");
1363 sfc_put_adapter(sa);
1368 port->enabled = false;
1371 fail_already_started:
1373 sfc_err(sa, "failed to start repr %u proxy port: %s", repr_id,
1375 sfc_put_adapter(sa);
1381 sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id)
1383 struct sfc_repr_proxy_port *port;
1384 struct sfc_repr_proxy_port *p;
1385 struct sfc_repr_proxy *rp;
1386 struct sfc_adapter *sa;
1389 sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1390 rp = sfc_repr_proxy_by_adapter(sa);
1392 sfc_log_init(sa, "entry");
1394 port = sfc_repr_proxy_find_port(rp, repr_id);
1396 sfc_err(sa, "%s() failed: no such port", __func__);
1400 if (!port->enabled) {
1401 sfc_log_init(sa, "repr %u proxy port is not started - skip",
1403 sfc_put_adapter(sa);
1407 if (sa->state == SFC_ETHDEV_STARTED) {
1408 bool last_enabled = true;
1410 TAILQ_FOREACH(p, &rp->ports, entries) {
1414 if (sfc_repr_proxy_port_enabled(p)) {
1415 last_enabled = false;
1422 sfc_repr_proxy_stop(sa);
1424 rc = sfc_repr_proxy_do_stop_port(sa, port);
1428 "failed to stop representor proxy TxQ %u: %s",
1429 repr_id, rte_strerror(rc));
1430 sfc_put_adapter(sa);
1435 port->enabled = false;
1437 sfc_log_init(sa, "done");
1438 sfc_put_adapter(sa);