net/sfc: implement representor Tx queue start/stop
[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
22 /**
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.
25  */
26 #define SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS     1000
27
28 static struct sfc_repr_proxy *
29 sfc_repr_proxy_by_adapter(struct sfc_adapter *sa)
30 {
31         return &sa->repr_proxy;
32 }
33
34 static struct sfc_adapter *
35 sfc_get_adapter_by_pf_port_id(uint16_t pf_port_id)
36 {
37         struct rte_eth_dev *dev;
38         struct sfc_adapter *sa;
39
40         SFC_ASSERT(pf_port_id < RTE_MAX_ETHPORTS);
41
42         dev = &rte_eth_devices[pf_port_id];
43         sa = sfc_adapter_by_eth_dev(dev);
44
45         sfc_adapter_lock(sa);
46
47         return sa;
48 }
49
50 static void
51 sfc_put_adapter(struct sfc_adapter *sa)
52 {
53         sfc_adapter_unlock(sa);
54 }
55
56 static int
57 sfc_repr_proxy_mbox_send(struct sfc_repr_proxy_mbox *mbox,
58                          struct sfc_repr_proxy_port *port,
59                          enum sfc_repr_proxy_mbox_op op)
60 {
61         const unsigned int wait_ms = SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS;
62         unsigned int i;
63
64         mbox->op = op;
65         mbox->port = port;
66         mbox->ack = false;
67
68         /*
69          * Release ordering enforces marker set after data is populated.
70          * Paired with acquire ordering in sfc_repr_proxy_mbox_handle().
71          */
72         __atomic_store_n(&mbox->write_marker, true, __ATOMIC_RELEASE);
73
74         /*
75          * Wait for the representor routine to process the request.
76          * Give up on timeout.
77          */
78         for (i = 0; i < wait_ms; i++) {
79                 /*
80                  * Paired with release ordering in sfc_repr_proxy_mbox_handle()
81                  * on acknowledge write.
82                  */
83                 if (__atomic_load_n(&mbox->ack, __ATOMIC_ACQUIRE))
84                         break;
85
86                 rte_delay_ms(1);
87         }
88
89         if (i == wait_ms) {
90                 SFC_GENERIC_LOG(ERR,
91                         "%s() failed to wait for representor proxy routine ack",
92                         __func__);
93                 return ETIMEDOUT;
94         }
95
96         return 0;
97 }
98
99 static void
100 sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp)
101 {
102         struct sfc_repr_proxy_mbox *mbox = &rp->mbox;
103
104         /*
105          * Paired with release ordering in sfc_repr_proxy_mbox_send()
106          * on marker set.
107          */
108         if (!__atomic_load_n(&mbox->write_marker, __ATOMIC_ACQUIRE))
109                 return;
110
111         mbox->write_marker = false;
112
113         switch (mbox->op) {
114         case SFC_REPR_PROXY_MBOX_ADD_PORT:
115                 TAILQ_INSERT_TAIL(&rp->ports, mbox->port, entries);
116                 break;
117         case SFC_REPR_PROXY_MBOX_DEL_PORT:
118                 TAILQ_REMOVE(&rp->ports, mbox->port, entries);
119                 break;
120         default:
121                 SFC_ASSERT(0);
122                 return;
123         }
124
125         /*
126          * Paired with acquire ordering in sfc_repr_proxy_mbox_send()
127          * on acknowledge read.
128          */
129         __atomic_store_n(&mbox->ack, true, __ATOMIC_RELEASE);
130 }
131
132 static int32_t
133 sfc_repr_proxy_routine(void *arg)
134 {
135         struct sfc_repr_proxy *rp = arg;
136
137         sfc_repr_proxy_mbox_handle(rp);
138
139         return 0;
140 }
141
142 static int
143 sfc_repr_proxy_txq_attach(struct sfc_adapter *sa)
144 {
145         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
146         struct sfc_repr_proxy *rp = &sa->repr_proxy;
147         unsigned int i;
148
149         sfc_log_init(sa, "entry");
150
151         for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
152                 sfc_sw_index_t sw_index = sfc_repr_txq_sw_index(sas, i);
153
154                 rp->dp_txq[i].sw_index = sw_index;
155         }
156
157         sfc_log_init(sa, "done");
158
159         return 0;
160 }
161
162 static void
163 sfc_repr_proxy_txq_detach(struct sfc_adapter *sa)
164 {
165         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
166         struct sfc_repr_proxy *rp = &sa->repr_proxy;
167         unsigned int i;
168
169         sfc_log_init(sa, "entry");
170
171         for (i = 0; i < sfc_repr_nb_txq(sas); i++)
172                 rp->dp_txq[i].sw_index = 0;
173
174         sfc_log_init(sa, "done");
175 }
176
177 int
178 sfc_repr_proxy_txq_init(struct sfc_adapter *sa)
179 {
180         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
181         struct sfc_repr_proxy *rp = &sa->repr_proxy;
182         const struct rte_eth_txconf tx_conf = {
183                 .tx_free_thresh = SFC_REPR_PROXY_TXQ_FREE_THRESH,
184         };
185         struct sfc_txq_info *txq_info;
186         unsigned int init_i;
187         unsigned int i;
188         int rc;
189
190         sfc_log_init(sa, "entry");
191
192         if (!sfc_repr_available(sas)) {
193                 sfc_log_init(sa, "representors not supported - skip");
194                 return 0;
195         }
196
197         for (init_i = 0; init_i < sfc_repr_nb_txq(sas); init_i++) {
198                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[init_i];
199
200                 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
201                 if (txq_info->state == SFC_TXQ_INITIALIZED) {
202                         sfc_log_init(sa,
203                                 "representor proxy TxQ %u is already initialized - skip",
204                                 init_i);
205                         continue;
206                 }
207
208                 sfc_tx_qinit_info(sa, txq->sw_index);
209
210                 rc = sfc_tx_qinit(sa, txq->sw_index,
211                                   SFC_REPR_PROXY_TX_DESC_COUNT, sa->socket_id,
212                                   &tx_conf);
213
214                 if (rc != 0) {
215                         sfc_err(sa, "failed to init representor proxy TxQ %u",
216                                 init_i);
217                         goto fail_init;
218                 }
219         }
220
221         sfc_log_init(sa, "done");
222
223         return 0;
224
225 fail_init:
226         for (i = 0; i < init_i; i++) {
227                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
228
229                 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
230                 if (txq_info->state == SFC_TXQ_INITIALIZED)
231                         sfc_tx_qfini(sa, txq->sw_index);
232         }
233         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
234
235         return rc;
236 }
237
238 void
239 sfc_repr_proxy_txq_fini(struct sfc_adapter *sa)
240 {
241         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
242         struct sfc_repr_proxy *rp = &sa->repr_proxy;
243         struct sfc_txq_info *txq_info;
244         unsigned int i;
245
246         sfc_log_init(sa, "entry");
247
248         if (!sfc_repr_available(sas)) {
249                 sfc_log_init(sa, "representors not supported - skip");
250                 return;
251         }
252
253         for (i = 0; i < sfc_repr_nb_txq(sas); i++) {
254                 struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i];
255
256                 txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index];
257                 if (txq_info->state != SFC_TXQ_INITIALIZED) {
258                         sfc_log_init(sa,
259                                 "representor proxy TxQ %u is already finalized - skip",
260                                 i);
261                         continue;
262                 }
263
264                 sfc_tx_qfini(sa, txq->sw_index);
265         }
266
267         sfc_log_init(sa, "done");
268 }
269
270 static int
271 sfc_repr_proxy_txq_start(struct sfc_adapter *sa)
272 {
273         struct sfc_repr_proxy *rp = &sa->repr_proxy;
274
275         sfc_log_init(sa, "entry");
276
277         RTE_SET_USED(rp);
278
279         sfc_log_init(sa, "done");
280
281         return 0;
282 }
283
284 static void
285 sfc_repr_proxy_txq_stop(struct sfc_adapter *sa)
286 {
287         sfc_log_init(sa, "entry");
288         sfc_log_init(sa, "done");
289 }
290
291 static int
292 sfc_repr_proxy_rxq_attach(struct sfc_adapter *sa)
293 {
294         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
295         struct sfc_repr_proxy *rp = &sa->repr_proxy;
296         unsigned int i;
297
298         sfc_log_init(sa, "entry");
299
300         for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
301                 sfc_sw_index_t sw_index = sfc_repr_rxq_sw_index(sas, i);
302
303                 rp->dp_rxq[i].sw_index = sw_index;
304         }
305
306         sfc_log_init(sa, "done");
307
308         return 0;
309 }
310
311 static void
312 sfc_repr_proxy_rxq_detach(struct sfc_adapter *sa)
313 {
314         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
315         struct sfc_repr_proxy *rp = &sa->repr_proxy;
316         unsigned int i;
317
318         sfc_log_init(sa, "entry");
319
320         for (i = 0; i < sfc_repr_nb_rxq(sas); i++)
321                 rp->dp_rxq[i].sw_index = 0;
322
323         sfc_log_init(sa, "done");
324 }
325
326 static int
327 sfc_repr_proxy_rxq_init(struct sfc_adapter *sa,
328                         struct sfc_repr_proxy_dp_rxq *rxq)
329 {
330         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
331         uint16_t nb_rx_desc = SFC_REPR_PROXY_RX_DESC_COUNT;
332         struct sfc_rxq_info *rxq_info;
333         struct rte_eth_rxconf rxconf = {
334                 .rx_free_thresh = SFC_REPR_PROXY_RXQ_REFILL_LEVEL,
335                 .rx_drop_en = 1,
336         };
337         int rc;
338
339         sfc_log_init(sa, "entry");
340
341         rxq_info = &sas->rxq_info[rxq->sw_index];
342         if (rxq_info->state & SFC_RXQ_INITIALIZED) {
343                 sfc_log_init(sa, "RxQ is already initialized - skip");
344                 return 0;
345         }
346
347         nb_rx_desc = RTE_MIN(nb_rx_desc, sa->rxq_max_entries);
348         nb_rx_desc = RTE_MAX(nb_rx_desc, sa->rxq_min_entries);
349
350         rc = sfc_rx_qinit_info(sa, rxq->sw_index, EFX_RXQ_FLAG_INGRESS_MPORT);
351         if (rc != 0) {
352                 sfc_err(sa, "failed to init representor proxy RxQ info");
353                 goto fail_repr_rxq_init_info;
354         }
355
356         rc = sfc_rx_qinit(sa, rxq->sw_index, nb_rx_desc, sa->socket_id, &rxconf,
357                           rxq->mp);
358         if (rc != 0) {
359                 sfc_err(sa, "failed to init representor proxy RxQ");
360                 goto fail_repr_rxq_init;
361         }
362
363         sfc_log_init(sa, "done");
364
365         return 0;
366
367 fail_repr_rxq_init:
368 fail_repr_rxq_init_info:
369         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
370
371         return rc;
372 }
373
374 static void
375 sfc_repr_proxy_rxq_fini(struct sfc_adapter *sa)
376 {
377         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
378         struct sfc_repr_proxy *rp = &sa->repr_proxy;
379         struct sfc_rxq_info *rxq_info;
380         unsigned int i;
381
382         sfc_log_init(sa, "entry");
383
384         if (!sfc_repr_available(sas)) {
385                 sfc_log_init(sa, "representors not supported - skip");
386                 return;
387         }
388
389         for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
390                 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i];
391
392                 rxq_info = &sas->rxq_info[rxq->sw_index];
393                 if (rxq_info->state != SFC_RXQ_INITIALIZED) {
394                         sfc_log_init(sa,
395                                 "representor RxQ %u is already finalized - skip",
396                                 i);
397                         continue;
398                 }
399
400                 sfc_rx_qfini(sa, rxq->sw_index);
401         }
402
403         sfc_log_init(sa, "done");
404 }
405
406 static void
407 sfc_repr_proxy_rxq_stop(struct sfc_adapter *sa)
408 {
409         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
410         unsigned int i;
411
412         sfc_log_init(sa, "entry");
413
414         for (i = 0; i < sfc_repr_nb_rxq(sas); i++)
415                 sfc_rx_qstop(sa, sa->repr_proxy.dp_rxq[i].sw_index);
416
417         sfc_repr_proxy_rxq_fini(sa);
418
419         sfc_log_init(sa, "done");
420 }
421
422 static int
423 sfc_repr_proxy_rxq_start(struct sfc_adapter *sa)
424 {
425         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
426         struct sfc_repr_proxy *rp = &sa->repr_proxy;
427         unsigned int i;
428         int rc;
429
430         sfc_log_init(sa, "entry");
431
432         if (!sfc_repr_available(sas)) {
433                 sfc_log_init(sa, "representors not supported - skip");
434                 return 0;
435         }
436
437         for (i = 0; i < sfc_repr_nb_rxq(sas); i++) {
438                 struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i];
439
440                 rc = sfc_repr_proxy_rxq_init(sa, rxq);
441                 if (rc != 0) {
442                         sfc_err(sa, "failed to init representor proxy RxQ %u",
443                                 i);
444                         goto fail_init;
445                 }
446
447                 rc = sfc_rx_qstart(sa, rxq->sw_index);
448                 if (rc != 0) {
449                         sfc_err(sa, "failed to start representor proxy RxQ %u",
450                                 i);
451                         goto fail_start;
452                 }
453         }
454
455         sfc_log_init(sa, "done");
456
457         return 0;
458
459 fail_start:
460 fail_init:
461         sfc_repr_proxy_rxq_stop(sa);
462         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
463         return rc;
464 }
465
466 static int
467 sfc_repr_proxy_ports_init(struct sfc_adapter *sa)
468 {
469         struct sfc_repr_proxy *rp = &sa->repr_proxy;
470         int rc;
471
472         sfc_log_init(sa, "entry");
473
474         rc = efx_mcdi_mport_alloc_alias(sa->nic, &rp->mport_alias, NULL);
475         if (rc != 0) {
476                 sfc_err(sa, "failed to alloc mport alias: %s",
477                         rte_strerror(rc));
478                 goto fail_alloc_mport_alias;
479         }
480
481         TAILQ_INIT(&rp->ports);
482
483         sfc_log_init(sa, "done");
484
485         return 0;
486
487 fail_alloc_mport_alias:
488
489         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
490         return rc;
491 }
492
493 void
494 sfc_repr_proxy_pre_detach(struct sfc_adapter *sa)
495 {
496         struct sfc_repr_proxy *rp = &sa->repr_proxy;
497         bool close_ports[RTE_MAX_ETHPORTS] = {0};
498         struct sfc_repr_proxy_port *port;
499         unsigned int i;
500
501         SFC_ASSERT(!sfc_adapter_is_locked(sa));
502
503         sfc_adapter_lock(sa);
504
505         if (sfc_repr_available(sfc_sa2shared(sa))) {
506                 TAILQ_FOREACH(port, &rp->ports, entries)
507                         close_ports[port->rte_port_id] = true;
508         } else {
509                 sfc_log_init(sa, "representors not supported - skip");
510         }
511
512         sfc_adapter_unlock(sa);
513
514         for (i = 0; i < RTE_DIM(close_ports); i++) {
515                 if (close_ports[i]) {
516                         rte_eth_dev_stop(i);
517                         rte_eth_dev_close(i);
518                 }
519         }
520 }
521
522 static void
523 sfc_repr_proxy_ports_fini(struct sfc_adapter *sa)
524 {
525         struct sfc_repr_proxy *rp = &sa->repr_proxy;
526
527         efx_mae_mport_free(sa->nic, &rp->mport_alias);
528 }
529
530 int
531 sfc_repr_proxy_attach(struct sfc_adapter *sa)
532 {
533         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
534         struct sfc_repr_proxy *rp = &sa->repr_proxy;
535         struct rte_service_spec service;
536         uint32_t cid;
537         uint32_t sid;
538         int rc;
539
540         sfc_log_init(sa, "entry");
541
542         if (!sfc_repr_available(sas)) {
543                 sfc_log_init(sa, "representors not supported - skip");
544                 return 0;
545         }
546
547         rc = sfc_repr_proxy_rxq_attach(sa);
548         if (rc != 0)
549                 goto fail_rxq_attach;
550
551         rc = sfc_repr_proxy_txq_attach(sa);
552         if (rc != 0)
553                 goto fail_txq_attach;
554
555         rc = sfc_repr_proxy_ports_init(sa);
556         if (rc != 0)
557                 goto fail_ports_init;
558
559         cid = sfc_get_service_lcore(sa->socket_id);
560         if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) {
561                 /* Warn and try to allocate on any NUMA node */
562                 sfc_warn(sa,
563                         "repr proxy: unable to get service lcore at socket %d",
564                         sa->socket_id);
565
566                 cid = sfc_get_service_lcore(SOCKET_ID_ANY);
567         }
568         if (cid == RTE_MAX_LCORE) {
569                 rc = ENOTSUP;
570                 sfc_err(sa, "repr proxy: failed to get service lcore");
571                 goto fail_get_service_lcore;
572         }
573
574         memset(&service, 0, sizeof(service));
575         snprintf(service.name, sizeof(service.name),
576                  "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id);
577         service.socket_id = rte_lcore_to_socket_id(cid);
578         service.callback = sfc_repr_proxy_routine;
579         service.callback_userdata = rp;
580
581         rc = rte_service_component_register(&service, &sid);
582         if (rc != 0) {
583                 rc = ENOEXEC;
584                 sfc_err(sa, "repr proxy: failed to register service component");
585                 goto fail_register;
586         }
587
588         rc = rte_service_map_lcore_set(sid, cid, 1);
589         if (rc != 0) {
590                 rc = -rc;
591                 sfc_err(sa, "repr proxy: failed to map lcore");
592                 goto fail_map_lcore;
593         }
594
595         rp->service_core_id = cid;
596         rp->service_id = sid;
597
598         sfc_log_init(sa, "done");
599
600         return 0;
601
602 fail_map_lcore:
603         rte_service_component_unregister(sid);
604
605 fail_register:
606         /*
607          * No need to rollback service lcore get since
608          * it just makes socket_id based search and remembers it.
609          */
610
611 fail_get_service_lcore:
612         sfc_repr_proxy_ports_fini(sa);
613
614 fail_ports_init:
615         sfc_repr_proxy_txq_detach(sa);
616
617 fail_txq_attach:
618         sfc_repr_proxy_rxq_detach(sa);
619
620 fail_rxq_attach:
621         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
622         return rc;
623 }
624
625 void
626 sfc_repr_proxy_detach(struct sfc_adapter *sa)
627 {
628         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
629         struct sfc_repr_proxy *rp = &sa->repr_proxy;
630
631         sfc_log_init(sa, "entry");
632
633         if (!sfc_repr_available(sas)) {
634                 sfc_log_init(sa, "representors not supported - skip");
635                 return;
636         }
637
638         rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0);
639         rte_service_component_unregister(rp->service_id);
640         sfc_repr_proxy_ports_fini(sa);
641         sfc_repr_proxy_rxq_detach(sa);
642         sfc_repr_proxy_txq_detach(sa);
643
644         sfc_log_init(sa, "done");
645 }
646
647 int
648 sfc_repr_proxy_start(struct sfc_adapter *sa)
649 {
650         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
651         struct sfc_repr_proxy *rp = &sa->repr_proxy;
652         int rc;
653
654         sfc_log_init(sa, "entry");
655
656         /*
657          * The condition to start the proxy is insufficient. It will be
658          * complemented with representor port start/stop support.
659          */
660         if (!sfc_repr_available(sas)) {
661                 sfc_log_init(sa, "representors not supported - skip");
662                 return 0;
663         }
664
665         rc = sfc_repr_proxy_rxq_start(sa);
666         if (rc != 0)
667                 goto fail_rxq_start;
668
669         rc = sfc_repr_proxy_txq_start(sa);
670         if (rc != 0)
671                 goto fail_txq_start;
672
673         /* Service core may be in "stopped" state, start it */
674         rc = rte_service_lcore_start(rp->service_core_id);
675         if (rc != 0 && rc != -EALREADY) {
676                 rc = -rc;
677                 sfc_err(sa, "failed to start service core for %s: %s",
678                         rte_service_get_name(rp->service_id),
679                         rte_strerror(rc));
680                 goto fail_start_core;
681         }
682
683         /* Run the service */
684         rc = rte_service_component_runstate_set(rp->service_id, 1);
685         if (rc < 0) {
686                 rc = -rc;
687                 sfc_err(sa, "failed to run %s component: %s",
688                         rte_service_get_name(rp->service_id),
689                         rte_strerror(rc));
690                 goto fail_component_runstate_set;
691         }
692         rc = rte_service_runstate_set(rp->service_id, 1);
693         if (rc < 0) {
694                 rc = -rc;
695                 sfc_err(sa, "failed to run %s: %s",
696                         rte_service_get_name(rp->service_id),
697                         rte_strerror(rc));
698                 goto fail_runstate_set;
699         }
700
701         rp->started = true;
702
703         sfc_log_init(sa, "done");
704
705         return 0;
706
707 fail_runstate_set:
708         rte_service_component_runstate_set(rp->service_id, 0);
709
710 fail_component_runstate_set:
711         /* Service lcore may be shared and we never stop it */
712
713 fail_start_core:
714         sfc_repr_proxy_txq_stop(sa);
715
716 fail_txq_start:
717         sfc_repr_proxy_rxq_stop(sa);
718
719 fail_rxq_start:
720         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
721         return rc;
722 }
723
724 void
725 sfc_repr_proxy_stop(struct sfc_adapter *sa)
726 {
727         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
728         struct sfc_repr_proxy *rp = &sa->repr_proxy;
729         int rc;
730
731         sfc_log_init(sa, "entry");
732
733         if (!sfc_repr_available(sas)) {
734                 sfc_log_init(sa, "representors not supported - skip");
735                 return;
736         }
737
738         rc = rte_service_runstate_set(rp->service_id, 0);
739         if (rc < 0) {
740                 sfc_err(sa, "failed to stop %s: %s",
741                         rte_service_get_name(rp->service_id),
742                         rte_strerror(-rc));
743         }
744
745         rc = rte_service_component_runstate_set(rp->service_id, 0);
746         if (rc < 0) {
747                 sfc_err(sa, "failed to stop %s component: %s",
748                         rte_service_get_name(rp->service_id),
749                         rte_strerror(-rc));
750         }
751
752         /* Service lcore may be shared and we never stop it */
753
754         sfc_repr_proxy_rxq_stop(sa);
755         sfc_repr_proxy_txq_stop(sa);
756
757         rp->started = false;
758
759         sfc_log_init(sa, "done");
760 }
761
762 static struct sfc_repr_proxy_port *
763 sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id)
764 {
765         struct sfc_repr_proxy_port *port;
766
767         TAILQ_FOREACH(port, &rp->ports, entries) {
768                 if (port->repr_id == repr_id)
769                         return port;
770         }
771
772         return NULL;
773 }
774
775 int
776 sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id,
777                         uint16_t rte_port_id, const efx_mport_sel_t *mport_sel)
778 {
779         struct sfc_repr_proxy_port *port;
780         struct sfc_repr_proxy *rp;
781         struct sfc_adapter *sa;
782         int rc;
783
784         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
785         rp = sfc_repr_proxy_by_adapter(sa);
786
787         sfc_log_init(sa, "entry");
788         TAILQ_FOREACH(port, &rp->ports, entries) {
789                 if (port->rte_port_id == rte_port_id) {
790                         rc = EEXIST;
791                         sfc_err(sa, "%s() failed: port exists", __func__);
792                         goto fail_port_exists;
793                 }
794         }
795
796         port = rte_zmalloc("sfc-repr-proxy-port", sizeof(*port),
797                            sa->socket_id);
798         if (port == NULL) {
799                 rc = ENOMEM;
800                 sfc_err(sa, "failed to alloc memory for proxy port");
801                 goto fail_alloc_port;
802         }
803
804         rc = efx_mae_mport_id_by_selector(sa->nic, mport_sel,
805                                           &port->egress_mport);
806         if (rc != 0) {
807                 sfc_err(sa,
808                         "failed get MAE mport id by selector (repr_id %u): %s",
809                         repr_id, rte_strerror(rc));
810                 goto fail_mport_id;
811         }
812
813         port->rte_port_id = rte_port_id;
814         port->repr_id = repr_id;
815
816         if (rp->started) {
817                 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
818                                               SFC_REPR_PROXY_MBOX_ADD_PORT);
819                 if (rc != 0) {
820                         sfc_err(sa, "failed to add proxy port %u",
821                                 port->repr_id);
822                         goto fail_port_add;
823                 }
824         } else {
825                 TAILQ_INSERT_TAIL(&rp->ports, port, entries);
826         }
827
828         sfc_log_init(sa, "done");
829         sfc_put_adapter(sa);
830
831         return 0;
832
833 fail_port_add:
834 fail_mport_id:
835         rte_free(port);
836 fail_alloc_port:
837 fail_port_exists:
838         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
839         sfc_put_adapter(sa);
840
841         return rc;
842 }
843
844 int
845 sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id)
846 {
847         struct sfc_repr_proxy_port *port;
848         struct sfc_repr_proxy *rp;
849         struct sfc_adapter *sa;
850         int rc;
851
852         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
853         rp = sfc_repr_proxy_by_adapter(sa);
854
855         sfc_log_init(sa, "entry");
856
857         port = sfc_repr_proxy_find_port(rp, repr_id);
858         if (port == NULL) {
859                 sfc_err(sa, "failed: no such port");
860                 rc = ENOENT;
861                 goto fail_no_port;
862         }
863
864         if (rp->started) {
865                 rc = sfc_repr_proxy_mbox_send(&rp->mbox, port,
866                                               SFC_REPR_PROXY_MBOX_DEL_PORT);
867                 if (rc != 0) {
868                         sfc_err(sa, "failed to remove proxy port %u",
869                                 port->repr_id);
870                         goto fail_port_remove;
871                 }
872         } else {
873                 TAILQ_REMOVE(&rp->ports, port, entries);
874         }
875
876         rte_free(port);
877
878         sfc_log_init(sa, "done");
879
880         sfc_put_adapter(sa);
881
882         return 0;
883
884 fail_port_remove:
885 fail_no_port:
886         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
887         sfc_put_adapter(sa);
888
889         return rc;
890 }
891
892 int
893 sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id,
894                        uint16_t queue_id, struct rte_ring *rx_ring,
895                        struct rte_mempool *mp)
896 {
897         struct sfc_repr_proxy_port *port;
898         struct sfc_repr_proxy_rxq *rxq;
899         struct sfc_repr_proxy *rp;
900         struct sfc_adapter *sa;
901
902         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
903         rp = sfc_repr_proxy_by_adapter(sa);
904
905         sfc_log_init(sa, "entry");
906
907         port = sfc_repr_proxy_find_port(rp, repr_id);
908         if (port == NULL) {
909                 sfc_err(sa, "%s() failed: no such port", __func__);
910                 return ENOENT;
911         }
912
913         rxq = &port->rxq[queue_id];
914         if (rp->dp_rxq[queue_id].mp != NULL && rp->dp_rxq[queue_id].mp != mp) {
915                 sfc_err(sa, "multiple mempools per queue are not supported");
916                 sfc_put_adapter(sa);
917                 return ENOTSUP;
918         }
919
920         rxq->ring = rx_ring;
921         rxq->mb_pool = mp;
922         rp->dp_rxq[queue_id].mp = mp;
923         rp->dp_rxq[queue_id].ref_count++;
924
925         sfc_log_init(sa, "done");
926         sfc_put_adapter(sa);
927
928         return 0;
929 }
930
931 void
932 sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id,
933                        uint16_t queue_id)
934 {
935         struct sfc_repr_proxy_port *port;
936         struct sfc_repr_proxy_rxq *rxq;
937         struct sfc_repr_proxy *rp;
938         struct sfc_adapter *sa;
939
940         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
941         rp = sfc_repr_proxy_by_adapter(sa);
942
943         sfc_log_init(sa, "entry");
944
945         port = sfc_repr_proxy_find_port(rp, repr_id);
946         if (port == NULL) {
947                 sfc_err(sa, "%s() failed: no such port", __func__);
948                 return;
949         }
950
951         rxq = &port->rxq[queue_id];
952
953         rxq->ring = NULL;
954         rxq->mb_pool = NULL;
955         rp->dp_rxq[queue_id].ref_count--;
956         if (rp->dp_rxq[queue_id].ref_count == 0)
957                 rp->dp_rxq[queue_id].mp = NULL;
958
959         sfc_log_init(sa, "done");
960         sfc_put_adapter(sa);
961 }
962
963 int
964 sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id,
965                        uint16_t queue_id, struct rte_ring *tx_ring,
966                        efx_mport_id_t *egress_mport)
967 {
968         struct sfc_repr_proxy_port *port;
969         struct sfc_repr_proxy_txq *txq;
970         struct sfc_repr_proxy *rp;
971         struct sfc_adapter *sa;
972
973         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
974         rp = sfc_repr_proxy_by_adapter(sa);
975
976         sfc_log_init(sa, "entry");
977
978         port = sfc_repr_proxy_find_port(rp, repr_id);
979         if (port == NULL) {
980                 sfc_err(sa, "%s() failed: no such port", __func__);
981                 return ENOENT;
982         }
983
984         txq = &port->txq[queue_id];
985
986         txq->ring = tx_ring;
987
988         *egress_mport = port->egress_mport;
989
990         sfc_log_init(sa, "done");
991         sfc_put_adapter(sa);
992
993         return 0;
994 }
995
996 void
997 sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id,
998                        uint16_t queue_id)
999 {
1000         struct sfc_repr_proxy_port *port;
1001         struct sfc_repr_proxy_txq *txq;
1002         struct sfc_repr_proxy *rp;
1003         struct sfc_adapter *sa;
1004
1005         sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
1006         rp = sfc_repr_proxy_by_adapter(sa);
1007
1008         sfc_log_init(sa, "entry");
1009
1010         port = sfc_repr_proxy_find_port(rp, repr_id);
1011         if (port == NULL) {
1012                 sfc_err(sa, "%s() failed: no such port", __func__);
1013                 return;
1014         }
1015
1016         txq = &port->txq[queue_id];
1017
1018         txq->ring = NULL;
1019
1020         sfc_log_init(sa, "done");
1021         sfc_put_adapter(sa);
1022 }