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