xref: /dpdk/drivers/net/sfc/sfc_repr_proxy.c (revision 671f47e1876f2f69389ca471c4811bf00f9463e5)
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