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