1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2015 Intel Corporation
3  */
4 
5 #include <stddef.h>
6 #include <string.h>
7 #include <stdbool.h>
8 
9 #include <rte_alarm.h>
10 #include <rte_malloc.h>
11 #include <rte_errno.h>
12 #include <rte_cycles.h>
13 #include <rte_compat.h>
14 
15 #include "eth_bond_private.h"
16 
17 static void bond_mode_8023ad_ext_periodic_cb(void *arg);
18 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
19 
20 #define MODE4_DEBUG(fmt, ...)				\
21 	rte_log(RTE_LOG_DEBUG, bond_logtype,		\
22 		"%6u [Port %u: %s] " fmt,		\
23 		bond_dbg_get_time_diff_ms(), slave_id,	\
24 		__func__, ##__VA_ARGS__)
25 
26 static uint64_t start_time;
27 
28 static unsigned
bond_dbg_get_time_diff_ms(void)29 bond_dbg_get_time_diff_ms(void)
30 {
31 	uint64_t now;
32 
33 	now = rte_rdtsc();
34 	if (start_time == 0)
35 		start_time = now;
36 
37 	return ((now - start_time) * 1000) / rte_get_tsc_hz();
38 }
39 
40 static void
bond_print_lacp(struct lacpdu * l)41 bond_print_lacp(struct lacpdu *l)
42 {
43 	char a_address[18];
44 	char p_address[18];
45 	char a_state[256] = { 0 };
46 	char p_state[256] = { 0 };
47 
48 	static const char * const state_labels[] = {
49 		"ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
50 	};
51 
52 	int a_len = 0;
53 	int p_len = 0;
54 	uint8_t i;
55 	uint8_t *addr;
56 
57 	addr = l->actor.port_params.system.addr_bytes;
58 	snprintf(a_address, sizeof(a_address), RTE_ETHER_ADDR_PRT_FMT,
59 		addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
60 
61 	addr = l->partner.port_params.system.addr_bytes;
62 	snprintf(p_address, sizeof(p_address), RTE_ETHER_ADDR_PRT_FMT,
63 		addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
64 
65 	for (i = 0; i < 8; i++) {
66 		if ((l->actor.state >> i) & 1) {
67 			a_len += snprintf(&a_state[a_len], RTE_DIM(a_state) - a_len, "%s ",
68 				state_labels[i]);
69 		}
70 
71 		if ((l->partner.state >> i) & 1) {
72 			p_len += snprintf(&p_state[p_len], RTE_DIM(p_state) - p_len, "%s ",
73 				state_labels[i]);
74 		}
75 	}
76 
77 	if (a_len && a_state[a_len-1] == ' ')
78 		a_state[a_len-1] = '\0';
79 
80 	if (p_len && p_state[p_len-1] == ' ')
81 		p_state[p_len-1] = '\0';
82 
83 	RTE_BOND_LOG(DEBUG,
84 		     "LACP: {\n"
85 		     "  subtype= %02X\n"
86 		     "  ver_num=%02X\n"
87 		     "  actor={ tlv=%02X, len=%02X\n"
88 		     "    pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"
89 		     "       state={ %s }\n"
90 		     "  }\n"
91 		     "  partner={ tlv=%02X, len=%02X\n"
92 		     "    pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"
93 		     "       state={ %s }\n"
94 		     "  }\n"
95 		     "  collector={info=%02X, length=%02X, max_delay=%04X\n, "
96 		     "type_term=%02X, terminator_length = %02X }",
97 		     l->subtype,
98 		     l->version_number,
99 		     l->actor.tlv_type_info,
100 		     l->actor.info_length,
101 		     l->actor.port_params.system_priority,
102 		     a_address,
103 		     l->actor.port_params.key,
104 		     l->actor.port_params.port_priority,
105 		     l->actor.port_params.port_number,
106 		     a_state,
107 		     l->partner.tlv_type_info,
108 		     l->partner.info_length,
109 		     l->partner.port_params.system_priority,
110 		     p_address,
111 		     l->partner.port_params.key,
112 		     l->partner.port_params.port_priority,
113 		     l->partner.port_params.port_number,
114 		     p_state,
115 		     l->tlv_type_collector_info,
116 		     l->collector_info_length,
117 		     l->collector_max_delay,
118 		     l->tlv_type_terminator,
119 		     l->terminator_length);
120 
121 }
122 
123 #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu)
124 #else
125 #define BOND_PRINT_LACP(lacpdu) do { } while (0)
126 #define MODE4_DEBUG(fmt, ...) do { } while (0)
127 #endif
128 
129 static const struct rte_ether_addr lacp_mac_addr = {
130 	.addr_bytes = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
131 };
132 
133 struct port bond_mode_8023ad_ports[RTE_MAX_ETHPORTS];
134 
135 static void
timer_cancel(uint64_t * timer)136 timer_cancel(uint64_t *timer)
137 {
138 	*timer = 0;
139 }
140 
141 static void
timer_set(uint64_t * timer,uint64_t timeout)142 timer_set(uint64_t *timer, uint64_t timeout)
143 {
144 	*timer = rte_rdtsc() + timeout;
145 }
146 
147 /* Forces given timer to be in expired state. */
148 static void
timer_force_expired(uint64_t * timer)149 timer_force_expired(uint64_t *timer)
150 {
151 	*timer = rte_rdtsc();
152 }
153 
154 static bool
timer_is_stopped(uint64_t * timer)155 timer_is_stopped(uint64_t *timer)
156 {
157 	return *timer == 0;
158 }
159 
160 static bool
timer_is_expired(uint64_t * timer)161 timer_is_expired(uint64_t *timer)
162 {
163 	return *timer < rte_rdtsc();
164 }
165 
166 /* Timer is in running state if it is not stopped nor expired */
167 static bool
timer_is_running(uint64_t * timer)168 timer_is_running(uint64_t *timer)
169 {
170 	return !timer_is_stopped(timer) && !timer_is_expired(timer);
171 }
172 
173 static void
set_warning_flags(struct port * port,uint16_t flags)174 set_warning_flags(struct port *port, uint16_t flags)
175 {
176 	int retval;
177 	uint16_t old;
178 	uint16_t new_flag = 0;
179 
180 	do {
181 		old = port->warnings_to_show;
182 		new_flag = old | flags;
183 		retval = rte_atomic16_cmpset(&port->warnings_to_show, old, new_flag);
184 	} while (unlikely(retval == 0));
185 }
186 
187 static void
show_warnings(uint16_t slave_id)188 show_warnings(uint16_t slave_id)
189 {
190 	struct port *port = &bond_mode_8023ad_ports[slave_id];
191 	uint8_t warnings;
192 
193 	do {
194 		warnings = port->warnings_to_show;
195 	} while (rte_atomic16_cmpset(&port->warnings_to_show, warnings, 0) == 0);
196 
197 	if (!warnings)
198 		return;
199 
200 	if (!timer_is_expired(&port->warning_timer))
201 		return;
202 
203 
204 	timer_set(&port->warning_timer, BOND_8023AD_WARNINGS_PERIOD_MS *
205 			rte_get_tsc_hz() / 1000);
206 
207 	if (warnings & WRN_RX_QUEUE_FULL) {
208 		RTE_BOND_LOG(DEBUG,
209 			     "Slave %u: failed to enqueue LACP packet into RX ring.\n"
210 			     "Receive and transmit functions must be invoked on bonded"
211 			     "interface at least 10 times per second or LACP will notwork correctly",
212 			     slave_id);
213 	}
214 
215 	if (warnings & WRN_TX_QUEUE_FULL) {
216 		RTE_BOND_LOG(DEBUG,
217 			     "Slave %u: failed to enqueue LACP packet into TX ring.\n"
218 			     "Receive and transmit functions must be invoked on bonded"
219 			     "interface at least 10 times per second or LACP will not work correctly",
220 			     slave_id);
221 	}
222 
223 	if (warnings & WRN_RX_MARKER_TO_FAST)
224 		RTE_BOND_LOG(INFO, "Slave %u: marker to early - ignoring.",
225 			     slave_id);
226 
227 	if (warnings & WRN_UNKNOWN_SLOW_TYPE) {
228 		RTE_BOND_LOG(INFO,
229 			"Slave %u: ignoring unknown slow protocol frame type",
230 			     slave_id);
231 	}
232 
233 	if (warnings & WRN_UNKNOWN_MARKER_TYPE)
234 		RTE_BOND_LOG(INFO, "Slave %u: ignoring unknown marker type",
235 			     slave_id);
236 
237 	if (warnings & WRN_NOT_LACP_CAPABLE)
238 		MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id);
239 }
240 
241 static void
record_default(struct port * port)242 record_default(struct port *port)
243 {
244 	/* Record default parameters for partner. Partner admin parameters
245 	 * are not implemented so set them to arbitrary default (last known) and
246 	 * mark actor that partner is in defaulted state. */
247 	port->partner_state = STATE_LACP_ACTIVE;
248 	ACTOR_STATE_SET(port, DEFAULTED);
249 }
250 
251 /** Function handles rx state machine.
252  *
253  * This function implements Receive State Machine from point 5.4.12 in
254  * 802.1AX documentation. It should be called periodically.
255  *
256  * @param lacpdu		LACPDU received.
257  * @param port			Port on which LACPDU was received.
258  */
259 static void
rx_machine(struct bond_dev_private * internals,uint16_t slave_id,struct lacpdu * lacp)260 rx_machine(struct bond_dev_private *internals, uint16_t slave_id,
261 		struct lacpdu *lacp)
262 {
263 	struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
264 	uint64_t timeout;
265 
266 	if (SM_FLAG(port, BEGIN)) {
267 		/* Initialize stuff */
268 		MODE4_DEBUG("-> INITIALIZE\n");
269 		SM_FLAG_CLR(port, MOVED);
270 		port->selected = UNSELECTED;
271 
272 		record_default(port);
273 
274 		ACTOR_STATE_CLR(port, EXPIRED);
275 		timer_cancel(&port->current_while_timer);
276 
277 		/* DISABLED: On initialization partner is out of sync */
278 		PARTNER_STATE_CLR(port, SYNCHRONIZATION);
279 
280 		/* LACP DISABLED stuff if LACP not enabled on this port */
281 		if (!SM_FLAG(port, LACP_ENABLED))
282 			PARTNER_STATE_CLR(port, AGGREGATION);
283 		else
284 			PARTNER_STATE_SET(port, AGGREGATION);
285 	}
286 
287 	if (!SM_FLAG(port, LACP_ENABLED)) {
288 		/* Update parameters only if state changed */
289 		if (!timer_is_stopped(&port->current_while_timer)) {
290 			port->selected = UNSELECTED;
291 			record_default(port);
292 			PARTNER_STATE_CLR(port, AGGREGATION);
293 			ACTOR_STATE_CLR(port, EXPIRED);
294 			timer_cancel(&port->current_while_timer);
295 		}
296 		return;
297 	}
298 
299 	if (lacp) {
300 		MODE4_DEBUG("LACP -> CURRENT\n");
301 		BOND_PRINT_LACP(lacp);
302 		/* Update selected flag. If partner parameters are defaulted assume they
303 		 * are match. If not defaulted  compare LACP actor with ports partner
304 		 * params. */
305 		if (!ACTOR_STATE(port, DEFAULTED) &&
306 			(ACTOR_STATE(port, AGGREGATION) != PARTNER_STATE(port, AGGREGATION)
307 			|| memcmp(&port->partner, &lacp->actor.port_params,
308 				sizeof(port->partner)) != 0)) {
309 			MODE4_DEBUG("selected <- UNSELECTED\n");
310 			port->selected = UNSELECTED;
311 		}
312 
313 		/* Record this PDU actor params as partner params */
314 		memcpy(&port->partner, &lacp->actor.port_params,
315 			sizeof(struct port_params));
316 		port->partner_state = lacp->actor.state;
317 
318 		/* Partner parameters are not defaulted any more */
319 		ACTOR_STATE_CLR(port, DEFAULTED);
320 
321 		/* If LACP partner params match this port actor params */
322 		agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
323 		bool match = port->actor.system_priority ==
324 			lacp->partner.port_params.system_priority &&
325 			rte_is_same_ether_addr(&agg->actor.system,
326 			&lacp->partner.port_params.system) &&
327 			port->actor.port_priority ==
328 			lacp->partner.port_params.port_priority &&
329 			port->actor.port_number ==
330 			lacp->partner.port_params.port_number;
331 
332 		/* Update NTT if partners information are outdated (xored and masked
333 		 * bits are set)*/
334 		uint8_t state_mask = STATE_LACP_ACTIVE | STATE_LACP_SHORT_TIMEOUT |
335 			STATE_SYNCHRONIZATION | STATE_AGGREGATION;
336 
337 		if (((port->actor_state ^ lacp->partner.state) & state_mask) ||
338 				match == false) {
339 			SM_FLAG_SET(port, NTT);
340 		}
341 
342 		/* If LACP partner params match this port actor params */
343 		if (match == true && ACTOR_STATE(port, AGGREGATION) ==
344 				PARTNER_STATE(port,	AGGREGATION))
345 			PARTNER_STATE_SET(port, SYNCHRONIZATION);
346 		else if (!PARTNER_STATE(port, AGGREGATION) && ACTOR_STATE(port,
347 				AGGREGATION))
348 			PARTNER_STATE_SET(port, SYNCHRONIZATION);
349 		else
350 			PARTNER_STATE_CLR(port, SYNCHRONIZATION);
351 
352 		if (ACTOR_STATE(port, LACP_SHORT_TIMEOUT))
353 			timeout = internals->mode4.short_timeout;
354 		else
355 			timeout = internals->mode4.long_timeout;
356 
357 		timer_set(&port->current_while_timer, timeout);
358 		ACTOR_STATE_CLR(port, EXPIRED);
359 		SM_FLAG_CLR(port, EXPIRED);
360 		return; /* No state change */
361 	}
362 
363 	/* If CURRENT state timer is not running (stopped or expired)
364 	 * transit to EXPIRED state from DISABLED or CURRENT */
365 	if (!timer_is_running(&port->current_while_timer)) {
366 		if (SM_FLAG(port, EXPIRED)) {
367 			port->selected = UNSELECTED;
368 			memcpy(&port->partner, &port->partner_admin,
369 				sizeof(struct port_params));
370 			record_default(port);
371 			ACTOR_STATE_CLR(port, EXPIRED);
372 			timer_cancel(&port->current_while_timer);
373 		} else {
374 			SM_FLAG_SET(port, EXPIRED);
375 			ACTOR_STATE_SET(port, EXPIRED);
376 			PARTNER_STATE_CLR(port, SYNCHRONIZATION);
377 			PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
378 			timer_set(&port->current_while_timer,
379 				internals->mode4.short_timeout);
380 		}
381 	}
382 }
383 
384 /**
385  * Function handles periodic tx state machine.
386  *
387  * Function implements Periodic Transmission state machine from point 5.4.13
388  * in 802.1AX documentation. It should be called periodically.
389  *
390  * @param port			Port to handle state machine.
391  */
392 static void
periodic_machine(struct bond_dev_private * internals,uint16_t slave_id)393 periodic_machine(struct bond_dev_private *internals, uint16_t slave_id)
394 {
395 	struct port *port = &bond_mode_8023ad_ports[slave_id];
396 	/* Calculate if either site is LACP enabled */
397 	uint64_t timeout;
398 	uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
399 		PARTNER_STATE(port, LACP_ACTIVE);
400 
401 	uint8_t is_partner_fast, was_partner_fast;
402 	/* No periodic is on BEGIN, LACP DISABLE or when both sides are passive */
403 	if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
404 		timer_cancel(&port->periodic_timer);
405 		timer_force_expired(&port->tx_machine_timer);
406 		SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
407 
408 		MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
409 			SM_FLAG(port, BEGIN) ? "begin " : "",
410 			SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
411 			active ? "LACP active " : "LACP passive ");
412 		return;
413 	}
414 
415 	is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
416 	was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
417 
418 	/* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
419 	 * Other case: check if timer expire or partners settings changed. */
420 	if (!timer_is_stopped(&port->periodic_timer)) {
421 		if (timer_is_expired(&port->periodic_timer)) {
422 			SM_FLAG_SET(port, NTT);
423 		} else if (is_partner_fast != was_partner_fast) {
424 			/* Partners timeout  was slow and now it is fast -> send LACP.
425 			 * In other case (was fast and now it is slow) just switch
426 			 * timeout to slow without forcing send of LACP (because standard
427 			 * say so)*/
428 			if (is_partner_fast)
429 				SM_FLAG_SET(port, NTT);
430 		} else
431 			return; /* Nothing changed */
432 	}
433 
434 	/* Handle state transition to FAST/SLOW LACP timeout */
435 	if (is_partner_fast) {
436 		timeout = internals->mode4.fast_periodic_timeout;
437 		SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
438 	} else {
439 		timeout = internals->mode4.slow_periodic_timeout;
440 		SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
441 	}
442 
443 	timer_set(&port->periodic_timer, timeout);
444 }
445 
446 /**
447  * Function handles mux state machine.
448  *
449  * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
450  * It should be called periodically.
451  *
452  * @param port			Port to handle state machine.
453  */
454 static void
mux_machine(struct bond_dev_private * internals,uint16_t slave_id)455 mux_machine(struct bond_dev_private *internals, uint16_t slave_id)
456 {
457 	struct port *port = &bond_mode_8023ad_ports[slave_id];
458 
459 	/* Save current state for later use */
460 	const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
461 		STATE_COLLECTING;
462 
463 	/* Enter DETACHED state on BEGIN condition or from any other state if
464 	 * port was unselected */
465 	if (SM_FLAG(port, BEGIN) ||
466 			port->selected == UNSELECTED || (port->selected == STANDBY &&
467 				(port->actor_state & state_mask) != 0)) {
468 		/* detach mux from aggregator */
469 		port->actor_state &= ~state_mask;
470 		/* Set ntt to true if BEGIN condition or transition from any other state
471 		 * which is indicated that wait_while_timer was started */
472 		if (SM_FLAG(port, BEGIN) ||
473 				!timer_is_stopped(&port->wait_while_timer)) {
474 			SM_FLAG_SET(port, NTT);
475 			MODE4_DEBUG("-> DETACHED\n");
476 		}
477 		timer_cancel(&port->wait_while_timer);
478 	}
479 
480 	if (timer_is_stopped(&port->wait_while_timer)) {
481 		if (port->selected == SELECTED || port->selected == STANDBY) {
482 			timer_set(&port->wait_while_timer,
483 				internals->mode4.aggregate_wait_timeout);
484 
485 			MODE4_DEBUG("DETACHED -> WAITING\n");
486 		}
487 		/* Waiting state entered */
488 		return;
489 	}
490 
491 	/* Transit next state if port is ready */
492 	if (!timer_is_expired(&port->wait_while_timer))
493 		return;
494 
495 	if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
496 		!PARTNER_STATE(port, SYNCHRONIZATION)) {
497 		/* If in COLLECTING or DISTRIBUTING state and partner becomes out of
498 		 * sync transit to ATTACHED state.  */
499 		ACTOR_STATE_CLR(port, DISTRIBUTING);
500 		ACTOR_STATE_CLR(port, COLLECTING);
501 		/* Clear actor sync to activate transit ATTACHED in condition bellow */
502 		ACTOR_STATE_CLR(port, SYNCHRONIZATION);
503 		MODE4_DEBUG("Out of sync -> ATTACHED\n");
504 	}
505 
506 	if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
507 		/* attach mux to aggregator */
508 		RTE_ASSERT((port->actor_state & (STATE_COLLECTING |
509 			STATE_DISTRIBUTING)) == 0);
510 
511 		ACTOR_STATE_SET(port, SYNCHRONIZATION);
512 		SM_FLAG_SET(port, NTT);
513 		MODE4_DEBUG("ATTACHED Entered\n");
514 	} else if (!ACTOR_STATE(port, COLLECTING)) {
515 		/* Start collecting if in sync */
516 		if (PARTNER_STATE(port, SYNCHRONIZATION)) {
517 			MODE4_DEBUG("ATTACHED -> COLLECTING\n");
518 			ACTOR_STATE_SET(port, COLLECTING);
519 			SM_FLAG_SET(port, NTT);
520 		}
521 	} else if (ACTOR_STATE(port, COLLECTING)) {
522 		/* Check if partner is in COLLECTING state. If so this port can
523 		 * distribute frames to it */
524 		if (!ACTOR_STATE(port, DISTRIBUTING)) {
525 			if (PARTNER_STATE(port, COLLECTING)) {
526 				/* Enable  DISTRIBUTING if partner is collecting */
527 				ACTOR_STATE_SET(port, DISTRIBUTING);
528 				SM_FLAG_SET(port, NTT);
529 				MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
530 				RTE_BOND_LOG(INFO,
531 					"Bond %u: slave id %u distributing started.",
532 					internals->port_id, slave_id);
533 			}
534 		} else {
535 			if (!PARTNER_STATE(port, COLLECTING)) {
536 				/* Disable DISTRIBUTING (enter COLLECTING state) if partner
537 				 * is not collecting */
538 				ACTOR_STATE_CLR(port, DISTRIBUTING);
539 				SM_FLAG_SET(port, NTT);
540 				MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
541 				RTE_BOND_LOG(INFO,
542 					"Bond %u: slave id %u distributing stopped.",
543 					internals->port_id, slave_id);
544 			}
545 		}
546 	}
547 }
548 
549 /**
550  * Function handles transmit state machine.
551  *
552  * Function implements Transmit Machine from point 5.4.16 in 802.1AX
553  * documentation.
554  *
555  * @param port
556  */
557 static void
tx_machine(struct bond_dev_private * internals,uint16_t slave_id)558 tx_machine(struct bond_dev_private *internals, uint16_t slave_id)
559 {
560 	struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
561 
562 	struct rte_mbuf *lacp_pkt = NULL;
563 	struct lacpdu_header *hdr;
564 	struct lacpdu *lacpdu;
565 
566 	/* If periodic timer is not running periodic machine is in NO PERIODIC and
567 	 * according to 802.3ax standard tx machine should not transmit any frames
568 	 * and set ntt to false. */
569 	if (timer_is_stopped(&port->periodic_timer))
570 		SM_FLAG_CLR(port, NTT);
571 
572 	if (!SM_FLAG(port, NTT))
573 		return;
574 
575 	if (!timer_is_expired(&port->tx_machine_timer))
576 		return;
577 
578 	lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
579 	if (lacp_pkt == NULL) {
580 		RTE_BOND_LOG(ERR, "Failed to allocate LACP packet from pool");
581 		return;
582 	}
583 
584 	lacp_pkt->data_len = sizeof(*hdr);
585 	lacp_pkt->pkt_len = sizeof(*hdr);
586 
587 	hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
588 
589 	/* Source and destination MAC */
590 	rte_ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.dst_addr);
591 	rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.src_addr);
592 	hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW);
593 
594 	lacpdu = &hdr->lacpdu;
595 	memset(lacpdu, 0, sizeof(*lacpdu));
596 
597 	/* Initialize LACP part */
598 	lacpdu->subtype = SLOW_SUBTYPE_LACP;
599 	lacpdu->version_number = 1;
600 
601 	/* ACTOR */
602 	lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
603 	lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
604 	memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
605 			sizeof(port->actor));
606 	agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
607 	rte_ether_addr_copy(&agg->actor.system,
608 			&hdr->lacpdu.actor.port_params.system);
609 	lacpdu->actor.state = port->actor_state;
610 
611 	/* PARTNER */
612 	lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
613 	lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
614 	memcpy(&lacpdu->partner.port_params, &port->partner,
615 			sizeof(struct port_params));
616 	lacpdu->partner.state = port->partner_state;
617 
618 	/* Other fields */
619 	lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
620 	lacpdu->collector_info_length = 0x10;
621 	lacpdu->collector_max_delay = 0;
622 
623 	lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
624 	lacpdu->terminator_length = 0;
625 
626 	MODE4_DEBUG("Sending LACP frame\n");
627 	BOND_PRINT_LACP(lacpdu);
628 
629 	if (internals->mode4.dedicated_queues.enabled == 0) {
630 		int retval = rte_ring_enqueue(port->tx_ring, lacp_pkt);
631 		if (retval != 0) {
632 			/* If TX ring full, drop packet and free message.
633 			   Retransmission will happen in next function call. */
634 			rte_pktmbuf_free(lacp_pkt);
635 			set_warning_flags(port, WRN_TX_QUEUE_FULL);
636 			return;
637 		}
638 	} else {
639 		uint16_t pkts_sent = rte_eth_tx_burst(slave_id,
640 				internals->mode4.dedicated_queues.tx_qid,
641 				&lacp_pkt, 1);
642 		if (pkts_sent != 1) {
643 			rte_pktmbuf_free(lacp_pkt);
644 			set_warning_flags(port, WRN_TX_QUEUE_FULL);
645 			return;
646 		}
647 	}
648 
649 
650 	timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
651 	SM_FLAG_CLR(port, NTT);
652 }
653 
654 static uint16_t
max_index(uint64_t * a,int n)655 max_index(uint64_t *a, int n)
656 {
657 	if (n <= 0)
658 		return -1;
659 
660 	int i, max_i = 0;
661 	uint64_t max = a[0];
662 
663 	for (i = 1; i < n; ++i) {
664 		if (a[i] > max) {
665 			max = a[i];
666 			max_i = i;
667 		}
668 	}
669 
670 	return max_i;
671 }
672 
673 /**
674  * Function assigns port to aggregator.
675  *
676  * @param bond_dev_private	Pointer to bond_dev_private structure.
677  * @param port_pos			Port to assign.
678  */
679 static void
selection_logic(struct bond_dev_private * internals,uint16_t slave_id)680 selection_logic(struct bond_dev_private *internals, uint16_t slave_id)
681 {
682 	struct port *agg, *port;
683 	uint16_t slaves_count, new_agg_id, i, j = 0;
684 	uint16_t *slaves;
685 	uint64_t agg_bandwidth[RTE_MAX_ETHPORTS] = {0};
686 	uint64_t agg_count[RTE_MAX_ETHPORTS] = {0};
687 	uint16_t default_slave = 0;
688 	struct rte_eth_link link_info;
689 	uint16_t agg_new_idx = 0;
690 	int ret;
691 
692 	slaves = internals->active_slaves;
693 	slaves_count = internals->active_slave_count;
694 	port = &bond_mode_8023ad_ports[slave_id];
695 
696 	/* Search for aggregator suitable for this port */
697 	for (i = 0; i < slaves_count; ++i) {
698 		agg = &bond_mode_8023ad_ports[slaves[i]];
699 		/* Skip ports that are not aggregators */
700 		if (agg->aggregator_port_id != slaves[i])
701 			continue;
702 
703 		ret = rte_eth_link_get_nowait(slaves[i], &link_info);
704 		if (ret < 0) {
705 			RTE_BOND_LOG(ERR,
706 				"Slave (port %u) link get failed: %s\n",
707 				slaves[i], rte_strerror(-ret));
708 			continue;
709 		}
710 		agg_count[i] += 1;
711 		agg_bandwidth[i] += link_info.link_speed;
712 
713 		/* Actors system ID is not checked since all slave device have the same
714 		 * ID (MAC address). */
715 		if ((agg->actor.key == port->actor.key &&
716 			agg->partner.system_priority == port->partner.system_priority &&
717 			rte_is_same_ether_addr(&agg->partner.system,
718 					&port->partner.system) == 1
719 			&& (agg->partner.key == port->partner.key)) &&
720 			rte_is_zero_ether_addr(&port->partner.system) != 1 &&
721 			(agg->actor.key &
722 				rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
723 
724 			if (j == 0)
725 				default_slave = i;
726 			j++;
727 		}
728 	}
729 
730 	switch (internals->mode4.agg_selection) {
731 	case AGG_COUNT:
732 		agg_new_idx = max_index(agg_count, slaves_count);
733 		new_agg_id = slaves[agg_new_idx];
734 		break;
735 	case AGG_BANDWIDTH:
736 		agg_new_idx = max_index(agg_bandwidth, slaves_count);
737 		new_agg_id = slaves[agg_new_idx];
738 		break;
739 	case AGG_STABLE:
740 		if (default_slave == slaves_count)
741 			new_agg_id = slaves[slave_id];
742 		else
743 			new_agg_id = slaves[default_slave];
744 		break;
745 	default:
746 		if (default_slave == slaves_count)
747 			new_agg_id = slaves[slave_id];
748 		else
749 			new_agg_id = slaves[default_slave];
750 		break;
751 	}
752 
753 	if (new_agg_id != port->aggregator_port_id) {
754 		port->aggregator_port_id = new_agg_id;
755 
756 		MODE4_DEBUG("-> SELECTED: ID=%3u\n"
757 			"\t%s aggregator ID=%3u\n",
758 			port->aggregator_port_id,
759 			port->aggregator_port_id == slave_id ?
760 				"aggregator not found, using default" : "aggregator found",
761 			port->aggregator_port_id);
762 	}
763 
764 	port->selected = SELECTED;
765 }
766 
767 /* Function maps DPDK speed to bonding speed stored in key field */
768 static uint16_t
link_speed_key(uint16_t speed)769 link_speed_key(uint16_t speed) {
770 	uint16_t key_speed;
771 
772 	switch (speed) {
773 	case RTE_ETH_SPEED_NUM_NONE:
774 		key_speed = 0x00;
775 		break;
776 	case RTE_ETH_SPEED_NUM_10M:
777 		key_speed = BOND_LINK_SPEED_KEY_10M;
778 		break;
779 	case RTE_ETH_SPEED_NUM_100M:
780 		key_speed = BOND_LINK_SPEED_KEY_100M;
781 		break;
782 	case RTE_ETH_SPEED_NUM_1G:
783 		key_speed = BOND_LINK_SPEED_KEY_1000M;
784 		break;
785 	case RTE_ETH_SPEED_NUM_10G:
786 		key_speed = BOND_LINK_SPEED_KEY_10G;
787 		break;
788 	case RTE_ETH_SPEED_NUM_20G:
789 		key_speed = BOND_LINK_SPEED_KEY_20G;
790 		break;
791 	case RTE_ETH_SPEED_NUM_40G:
792 		key_speed = BOND_LINK_SPEED_KEY_40G;
793 		break;
794 	default:
795 		/* Unknown speed*/
796 		key_speed = 0xFFFF;
797 	}
798 
799 	return key_speed;
800 }
801 
802 static void
rx_machine_update(struct bond_dev_private * internals,uint16_t slave_id,struct rte_mbuf * lacp_pkt)803 rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id,
804 		struct rte_mbuf *lacp_pkt) {
805 	struct lacpdu_header *lacp;
806 	struct lacpdu_actor_partner_params *partner;
807 	struct port *port, *agg;
808 
809 	if (lacp_pkt != NULL) {
810 		lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
811 		RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
812 
813 		partner = &lacp->lacpdu.partner;
814 		port = &bond_mode_8023ad_ports[slave_id];
815 		agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
816 
817 		if (rte_is_zero_ether_addr(&partner->port_params.system) ||
818 			rte_is_same_ether_addr(&partner->port_params.system,
819 				&agg->actor.system)) {
820 			/* This LACP frame is sending to the bonding port
821 			 * so pass it to rx_machine.
822 			 */
823 			rx_machine(internals, slave_id, &lacp->lacpdu);
824 		} else {
825 			char preferred_system_name[RTE_ETHER_ADDR_FMT_SIZE];
826 			char self_system_name[RTE_ETHER_ADDR_FMT_SIZE];
827 
828 			rte_ether_format_addr(preferred_system_name,
829 				RTE_ETHER_ADDR_FMT_SIZE, &partner->port_params.system);
830 			rte_ether_format_addr(self_system_name,
831 				RTE_ETHER_ADDR_FMT_SIZE, &agg->actor.system);
832 			MODE4_DEBUG("preferred partner system %s "
833 				"is not equal with self system: %s\n",
834 				preferred_system_name, self_system_name);
835 		}
836 		rte_pktmbuf_free(lacp_pkt);
837 	} else
838 		rx_machine(internals, slave_id, NULL);
839 }
840 
841 static void
bond_mode_8023ad_dedicated_rxq_process(struct bond_dev_private * internals,uint16_t slave_id)842 bond_mode_8023ad_dedicated_rxq_process(struct bond_dev_private *internals,
843 			uint16_t slave_id)
844 {
845 #define DEDICATED_QUEUE_BURST_SIZE 32
846 	struct rte_mbuf *lacp_pkt[DEDICATED_QUEUE_BURST_SIZE];
847 	uint16_t rx_count = rte_eth_rx_burst(slave_id,
848 				internals->mode4.dedicated_queues.rx_qid,
849 				lacp_pkt, DEDICATED_QUEUE_BURST_SIZE);
850 
851 	if (rx_count) {
852 		uint16_t i;
853 
854 		for (i = 0; i < rx_count; i++)
855 			bond_mode_8023ad_handle_slow_pkt(internals, slave_id,
856 					lacp_pkt[i]);
857 	} else {
858 		rx_machine_update(internals, slave_id, NULL);
859 	}
860 }
861 
862 static void
bond_mode_8023ad_periodic_cb(void * arg)863 bond_mode_8023ad_periodic_cb(void *arg)
864 {
865 	struct rte_eth_dev *bond_dev = arg;
866 	struct bond_dev_private *internals = bond_dev->data->dev_private;
867 	struct port *port;
868 	struct rte_eth_link link_info;
869 	struct rte_ether_addr slave_addr;
870 	struct rte_mbuf *lacp_pkt = NULL;
871 	uint16_t slave_id;
872 	uint16_t i;
873 
874 
875 	/* Update link status on each port */
876 	for (i = 0; i < internals->active_slave_count; i++) {
877 		uint16_t key;
878 		int ret;
879 
880 		slave_id = internals->active_slaves[i];
881 		ret = rte_eth_link_get_nowait(slave_id, &link_info);
882 		if (ret < 0) {
883 			RTE_BOND_LOG(ERR,
884 				"Slave (port %u) link get failed: %s\n",
885 				slave_id, rte_strerror(-ret));
886 		}
887 
888 		if (ret >= 0 && link_info.link_status != 0) {
889 			key = link_speed_key(link_info.link_speed) << 1;
890 			if (link_info.link_duplex == RTE_ETH_LINK_FULL_DUPLEX)
891 				key |= BOND_LINK_FULL_DUPLEX_KEY;
892 		} else {
893 			key = 0;
894 		}
895 
896 		rte_eth_macaddr_get(slave_id, &slave_addr);
897 		port = &bond_mode_8023ad_ports[slave_id];
898 
899 		key = rte_cpu_to_be_16(key);
900 		if (key != port->actor.key) {
901 			if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
902 				set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
903 
904 			port->actor.key = key;
905 			SM_FLAG_SET(port, NTT);
906 		}
907 
908 		if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
909 			rte_ether_addr_copy(&slave_addr, &port->actor.system);
910 			if (port->aggregator_port_id == slave_id)
911 				SM_FLAG_SET(port, NTT);
912 		}
913 	}
914 
915 	for (i = 0; i < internals->active_slave_count; i++) {
916 		slave_id = internals->active_slaves[i];
917 		port = &bond_mode_8023ad_ports[slave_id];
918 
919 		if ((port->actor.key &
920 				rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
921 
922 			SM_FLAG_SET(port, BEGIN);
923 
924 			/* LACP is disabled on half duplex or link is down */
925 			if (SM_FLAG(port, LACP_ENABLED)) {
926 				/* If port was enabled set it to BEGIN state */
927 				SM_FLAG_CLR(port, LACP_ENABLED);
928 				ACTOR_STATE_CLR(port, DISTRIBUTING);
929 				ACTOR_STATE_CLR(port, COLLECTING);
930 			}
931 
932 			/* Skip this port processing */
933 			continue;
934 		}
935 
936 		SM_FLAG_SET(port, LACP_ENABLED);
937 
938 		if (internals->mode4.dedicated_queues.enabled == 0) {
939 			/* Find LACP packet to this port. Do not check subtype,
940 			 * it is done in function that queued packet
941 			 */
942 			int retval = rte_ring_dequeue(port->rx_ring,
943 					(void **)&lacp_pkt);
944 
945 			if (retval != 0)
946 				lacp_pkt = NULL;
947 
948 			rx_machine_update(internals, slave_id, lacp_pkt);
949 		} else {
950 			bond_mode_8023ad_dedicated_rxq_process(internals,
951 					slave_id);
952 		}
953 
954 		periodic_machine(internals, slave_id);
955 		mux_machine(internals, slave_id);
956 		tx_machine(internals, slave_id);
957 		selection_logic(internals, slave_id);
958 
959 		SM_FLAG_CLR(port, BEGIN);
960 		show_warnings(slave_id);
961 	}
962 
963 	rte_eal_alarm_set(internals->mode4.update_timeout_us,
964 			bond_mode_8023ad_periodic_cb, arg);
965 }
966 
967 static int
bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)968 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
969 {
970 	int ret;
971 
972 	ret = rte_eth_allmulticast_enable(slave_id);
973 	if (ret != 0) {
974 		RTE_BOND_LOG(ERR,
975 			"failed to enable allmulti mode for port %u: %s",
976 			slave_id, rte_strerror(-ret));
977 	}
978 	if (rte_eth_allmulticast_get(slave_id)) {
979 		RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
980 			     slave_id);
981 		bond_mode_8023ad_ports[slave_id].forced_rx_flags =
982 				BOND_8023AD_FORCED_ALLMULTI;
983 		return 0;
984 	}
985 
986 	ret = rte_eth_promiscuous_enable(slave_id);
987 	if (ret != 0) {
988 		RTE_BOND_LOG(ERR,
989 			"failed to enable promiscuous mode for port %u: %s",
990 			slave_id, rte_strerror(-ret));
991 	}
992 	if (rte_eth_promiscuous_get(slave_id)) {
993 		RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
994 			     slave_id);
995 		bond_mode_8023ad_ports[slave_id].forced_rx_flags =
996 				BOND_8023AD_FORCED_PROMISC;
997 		return 0;
998 	}
999 
1000 	return -1;
1001 }
1002 
1003 static void
bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)1004 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
1005 {
1006 	int ret;
1007 
1008 	switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
1009 	case BOND_8023AD_FORCED_ALLMULTI:
1010 		RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
1011 		ret = rte_eth_allmulticast_disable(slave_id);
1012 		if (ret != 0)
1013 			RTE_BOND_LOG(ERR,
1014 				"failed to disable allmulti mode for port %u: %s",
1015 				slave_id, rte_strerror(-ret));
1016 		break;
1017 
1018 	case BOND_8023AD_FORCED_PROMISC:
1019 		RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
1020 		ret = rte_eth_promiscuous_disable(slave_id);
1021 		if (ret != 0)
1022 			RTE_BOND_LOG(ERR,
1023 				"failed to disable promiscuous mode for port %u: %s",
1024 				slave_id, rte_strerror(-ret));
1025 		break;
1026 
1027 	default:
1028 		break;
1029 	}
1030 }
1031 
1032 void
bond_mode_8023ad_activate_slave(struct rte_eth_dev * bond_dev,uint16_t slave_id)1033 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
1034 				uint16_t slave_id)
1035 {
1036 	struct bond_dev_private *internals = bond_dev->data->dev_private;
1037 
1038 	struct port *port = &bond_mode_8023ad_ports[slave_id];
1039 	struct port_params initial = {
1040 			.system = { { 0 } },
1041 			.system_priority = rte_cpu_to_be_16(0xFFFF),
1042 			.key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1043 			.port_priority = rte_cpu_to_be_16(0x00FF),
1044 			.port_number = 0,
1045 	};
1046 
1047 	char mem_name[RTE_ETH_NAME_MAX_LEN];
1048 	int socket_id;
1049 	unsigned element_size;
1050 	uint32_t total_tx_desc;
1051 	struct bond_tx_queue *bd_tx_q;
1052 	uint16_t q_id;
1053 
1054 	/* Given slave mus not be in active list */
1055 	RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1056 	internals->active_slave_count, slave_id) == internals->active_slave_count);
1057 	RTE_SET_USED(internals); /* used only for assert when enabled */
1058 
1059 	memcpy(&port->actor, &initial, sizeof(struct port_params));
1060 	/* Standard requires that port ID must be grater than 0.
1061 	 * Add 1 do get corresponding port_number */
1062 	port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1063 
1064 	memcpy(&port->partner, &initial, sizeof(struct port_params));
1065 	memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
1066 
1067 	/* default states */
1068 	port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1069 	port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1070 	port->sm_flags = SM_FLAGS_BEGIN;
1071 
1072 	/* use this port as aggregator */
1073 	port->aggregator_port_id = slave_id;
1074 
1075 	if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1076 		RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1077 			     slave_id);
1078 	}
1079 
1080 	timer_cancel(&port->warning_timer);
1081 
1082 	if (port->mbuf_pool != NULL)
1083 		return;
1084 
1085 	RTE_ASSERT(port->rx_ring == NULL);
1086 	RTE_ASSERT(port->tx_ring == NULL);
1087 
1088 	socket_id = rte_eth_dev_socket_id(slave_id);
1089 	if (socket_id == -1)
1090 		socket_id = rte_socket_id();
1091 
1092 	element_size = sizeof(struct slow_protocol_frame) +
1093 				RTE_PKTMBUF_HEADROOM;
1094 
1095 	/* The size of the mempool should be at least:
1096 	 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1097 	total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1098 	for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1099 		bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1100 		total_tx_desc += bd_tx_q->nb_tx_desc;
1101 	}
1102 
1103 	snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1104 	port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1105 		RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1106 			32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1107 		0, element_size, socket_id);
1108 
1109 	/* Any memory allocation failure in initialization is critical because
1110 	 * resources can't be free, so reinitialization is impossible. */
1111 	if (port->mbuf_pool == NULL) {
1112 		rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1113 			slave_id, mem_name, rte_strerror(rte_errno));
1114 	}
1115 
1116 	snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1117 	port->rx_ring = rte_ring_create(mem_name,
1118 			rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1119 
1120 	if (port->rx_ring == NULL) {
1121 		rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1122 			mem_name, rte_strerror(rte_errno));
1123 	}
1124 
1125 	/* TX ring is at least one pkt longer to make room for marker packet. */
1126 	snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1127 	port->tx_ring = rte_ring_create(mem_name,
1128 			rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1129 
1130 	if (port->tx_ring == NULL) {
1131 		rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1132 			mem_name, rte_strerror(rte_errno));
1133 	}
1134 }
1135 
1136 int
bond_mode_8023ad_deactivate_slave(struct rte_eth_dev * bond_dev __rte_unused,uint16_t slave_id)1137 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1138 		uint16_t slave_id)
1139 {
1140 	void *pkt = NULL;
1141 	struct port *port = NULL;
1142 	uint8_t old_partner_state;
1143 
1144 	port = &bond_mode_8023ad_ports[slave_id];
1145 
1146 	ACTOR_STATE_CLR(port, AGGREGATION);
1147 	port->selected = UNSELECTED;
1148 
1149 	old_partner_state = port->partner_state;
1150 	record_default(port);
1151 
1152 	bond_mode_8023ad_unregister_lacp_mac(slave_id);
1153 
1154 	/* If partner timeout state changes then disable timer */
1155 	if (!((old_partner_state ^ port->partner_state) &
1156 			STATE_LACP_SHORT_TIMEOUT))
1157 		timer_cancel(&port->current_while_timer);
1158 
1159 	PARTNER_STATE_CLR(port, AGGREGATION);
1160 	ACTOR_STATE_CLR(port, EXPIRED);
1161 
1162 	/* flush rx/tx rings */
1163 	while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1164 		rte_pktmbuf_free((struct rte_mbuf *)pkt);
1165 
1166 	while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1167 			rte_pktmbuf_free((struct rte_mbuf *)pkt);
1168 	return 0;
1169 }
1170 
1171 void
bond_mode_8023ad_mac_address_update(struct rte_eth_dev * bond_dev)1172 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1173 {
1174 	struct bond_dev_private *internals = bond_dev->data->dev_private;
1175 	struct rte_ether_addr slave_addr;
1176 	struct port *slave, *agg_slave;
1177 	uint16_t slave_id, i, j;
1178 
1179 	bond_mode_8023ad_stop(bond_dev);
1180 
1181 	for (i = 0; i < internals->active_slave_count; i++) {
1182 		slave_id = internals->active_slaves[i];
1183 		slave = &bond_mode_8023ad_ports[slave_id];
1184 		rte_eth_macaddr_get(slave_id, &slave_addr);
1185 
1186 		if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1187 			continue;
1188 
1189 		rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1190 		/* Do nothing if this port is not an aggregator. In other case
1191 		 * Set NTT flag on every port that use this aggregator. */
1192 		if (slave->aggregator_port_id != slave_id)
1193 			continue;
1194 
1195 		for (j = 0; j < internals->active_slave_count; j++) {
1196 			agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1197 			if (agg_slave->aggregator_port_id == slave_id)
1198 				SM_FLAG_SET(agg_slave, NTT);
1199 		}
1200 	}
1201 
1202 	if (bond_dev->data->dev_started)
1203 		bond_mode_8023ad_start(bond_dev);
1204 }
1205 
1206 static void
bond_mode_8023ad_conf_get(struct rte_eth_dev * dev,struct rte_eth_bond_8023ad_conf * conf)1207 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1208 		struct rte_eth_bond_8023ad_conf *conf)
1209 {
1210 	struct bond_dev_private *internals = dev->data->dev_private;
1211 	struct mode8023ad_private *mode4 = &internals->mode4;
1212 	uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1213 
1214 	conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1215 	conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1216 	conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1217 	conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1218 	conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1219 	conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1220 	conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1221 	conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1222 	conf->slowrx_cb = mode4->slowrx_cb;
1223 	conf->agg_selection = mode4->agg_selection;
1224 }
1225 
1226 static void
bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf * conf)1227 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1228 {
1229 	conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1230 	conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1231 	conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1232 	conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1233 	conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1234 	conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1235 	conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1236 	conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1237 	conf->slowrx_cb = NULL;
1238 	conf->agg_selection = AGG_STABLE;
1239 }
1240 
1241 static void
bond_mode_8023ad_conf_assign(struct mode8023ad_private * mode4,struct rte_eth_bond_8023ad_conf * conf)1242 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1243 		struct rte_eth_bond_8023ad_conf *conf)
1244 {
1245 	uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1246 
1247 	mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1248 	mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1249 	mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1250 	mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1251 	mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1252 	mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1253 	mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1254 	mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1255 
1256 	mode4->dedicated_queues.enabled = 0;
1257 	mode4->dedicated_queues.rx_qid = UINT16_MAX;
1258 	mode4->dedicated_queues.tx_qid = UINT16_MAX;
1259 }
1260 
1261 void
bond_mode_8023ad_setup(struct rte_eth_dev * dev,struct rte_eth_bond_8023ad_conf * conf)1262 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1263 		struct rte_eth_bond_8023ad_conf *conf)
1264 {
1265 	struct rte_eth_bond_8023ad_conf def_conf;
1266 	struct bond_dev_private *internals = dev->data->dev_private;
1267 	struct mode8023ad_private *mode4 = &internals->mode4;
1268 
1269 	if (conf == NULL) {
1270 		conf = &def_conf;
1271 		bond_mode_8023ad_conf_get_default(conf);
1272 	}
1273 
1274 	bond_mode_8023ad_stop(dev);
1275 	bond_mode_8023ad_conf_assign(mode4, conf);
1276 	mode4->slowrx_cb = conf->slowrx_cb;
1277 	mode4->agg_selection = AGG_STABLE;
1278 
1279 	if (dev->data->dev_started)
1280 		bond_mode_8023ad_start(dev);
1281 }
1282 
1283 int
bond_mode_8023ad_enable(struct rte_eth_dev * bond_dev)1284 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1285 {
1286 	struct bond_dev_private *internals = bond_dev->data->dev_private;
1287 	uint16_t i;
1288 
1289 	for (i = 0; i < internals->active_slave_count; i++)
1290 		bond_mode_8023ad_activate_slave(bond_dev,
1291 				internals->active_slaves[i]);
1292 
1293 	return 0;
1294 }
1295 
1296 int
bond_mode_8023ad_start(struct rte_eth_dev * bond_dev)1297 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1298 {
1299 	struct bond_dev_private *internals = bond_dev->data->dev_private;
1300 	struct mode8023ad_private *mode4 = &internals->mode4;
1301 	static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1302 
1303 	rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1304 	if (mode4->slowrx_cb)
1305 		return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1306 					 bond_dev);
1307 
1308 	return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1309 }
1310 
1311 void
bond_mode_8023ad_stop(struct rte_eth_dev * bond_dev)1312 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1313 {
1314 	struct bond_dev_private *internals = bond_dev->data->dev_private;
1315 	struct mode8023ad_private *mode4 = &internals->mode4;
1316 
1317 	if (mode4->slowrx_cb) {
1318 		rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1319 				     bond_dev);
1320 		return;
1321 	}
1322 	rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1323 }
1324 
1325 void
bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private * internals,uint16_t slave_id,struct rte_mbuf * pkt)1326 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1327 				  uint16_t slave_id, struct rte_mbuf *pkt)
1328 {
1329 	struct mode8023ad_private *mode4 = &internals->mode4;
1330 	struct port *port = &bond_mode_8023ad_ports[slave_id];
1331 	struct marker_header *m_hdr;
1332 	uint64_t marker_timer, old_marker_timer;
1333 	int retval;
1334 	uint8_t wrn, subtype;
1335 	/* If packet is a marker, we send response now by reusing given packet
1336 	 * and update only source MAC, destination MAC is multicast so don't
1337 	 * update it. Other frames will be handled later by state machines */
1338 	subtype = rte_pktmbuf_mtod(pkt,
1339 			struct slow_protocol_frame *)->slow_protocol.subtype;
1340 
1341 	if (subtype == SLOW_SUBTYPE_MARKER) {
1342 		m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1343 
1344 		if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1345 			wrn = WRN_UNKNOWN_MARKER_TYPE;
1346 			goto free_out;
1347 		}
1348 
1349 		/* Setup marker timer. Do it in loop in case concurrent access. */
1350 		do {
1351 			old_marker_timer = port->rx_marker_timer;
1352 			if (!timer_is_expired(&old_marker_timer)) {
1353 				wrn = WRN_RX_MARKER_TO_FAST;
1354 				goto free_out;
1355 			}
1356 
1357 			timer_set(&marker_timer, mode4->rx_marker_timeout);
1358 			retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1359 				old_marker_timer, marker_timer);
1360 		} while (unlikely(retval == 0));
1361 
1362 		m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1363 		rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.src_addr);
1364 
1365 		if (internals->mode4.dedicated_queues.enabled == 0) {
1366 			if (rte_ring_enqueue(port->tx_ring, pkt) != 0) {
1367 				/* reset timer */
1368 				port->rx_marker_timer = 0;
1369 				wrn = WRN_TX_QUEUE_FULL;
1370 				goto free_out;
1371 			}
1372 		} else {
1373 			/* Send packet directly to the slow queue */
1374 			uint16_t tx_count = rte_eth_tx_burst(slave_id,
1375 					internals->mode4.dedicated_queues.tx_qid,
1376 					&pkt, 1);
1377 			if (tx_count != 1) {
1378 				/* reset timer */
1379 				port->rx_marker_timer = 0;
1380 				wrn = WRN_TX_QUEUE_FULL;
1381 				goto free_out;
1382 			}
1383 		}
1384 	} else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1385 		if (internals->mode4.dedicated_queues.enabled == 0) {
1386 			if (rte_ring_enqueue(port->rx_ring, pkt) != 0) {
1387 				/* If RX fing full free lacpdu message and drop packet */
1388 				wrn = WRN_RX_QUEUE_FULL;
1389 				goto free_out;
1390 			}
1391 		} else
1392 			rx_machine_update(internals, slave_id, pkt);
1393 	} else {
1394 		wrn = WRN_UNKNOWN_SLOW_TYPE;
1395 		goto free_out;
1396 	}
1397 
1398 	return;
1399 
1400 free_out:
1401 	set_warning_flags(port, wrn);
1402 	rte_pktmbuf_free(pkt);
1403 }
1404 
1405 int
rte_eth_bond_8023ad_conf_get(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1406 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1407 		struct rte_eth_bond_8023ad_conf *conf)
1408 {
1409 	struct rte_eth_dev *bond_dev;
1410 
1411 	if (valid_bonded_port_id(port_id) != 0)
1412 		return -EINVAL;
1413 
1414 	if (conf == NULL)
1415 		return -EINVAL;
1416 
1417 	bond_dev = &rte_eth_devices[port_id];
1418 	bond_mode_8023ad_conf_get(bond_dev, conf);
1419 	return 0;
1420 }
1421 
1422 int
rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,enum rte_bond_8023ad_agg_selection agg_selection)1423 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1424 		enum rte_bond_8023ad_agg_selection agg_selection)
1425 {
1426 	struct rte_eth_dev *bond_dev;
1427 	struct bond_dev_private *internals;
1428 	struct mode8023ad_private *mode4;
1429 
1430 	if (valid_bonded_port_id(port_id) != 0)
1431 		return -EINVAL;
1432 
1433 	bond_dev = &rte_eth_devices[port_id];
1434 	internals = bond_dev->data->dev_private;
1435 
1436 	if (internals->mode != 4)
1437 		return -EINVAL;
1438 
1439 	mode4 = &internals->mode4;
1440 	if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1441 			|| agg_selection == AGG_STABLE)
1442 		mode4->agg_selection = agg_selection;
1443 	return 0;
1444 }
1445 
rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)1446 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1447 {
1448 	struct rte_eth_dev *bond_dev;
1449 	struct bond_dev_private *internals;
1450 	struct mode8023ad_private *mode4;
1451 
1452 	if (valid_bonded_port_id(port_id) != 0)
1453 		return -EINVAL;
1454 
1455 	bond_dev = &rte_eth_devices[port_id];
1456 	internals = bond_dev->data->dev_private;
1457 
1458 	if (internals->mode != 4)
1459 		return -EINVAL;
1460 	mode4 = &internals->mode4;
1461 
1462 	return mode4->agg_selection;
1463 }
1464 
1465 
1466 
1467 static int
bond_8023ad_setup_validate(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1468 bond_8023ad_setup_validate(uint16_t port_id,
1469 		struct rte_eth_bond_8023ad_conf *conf)
1470 {
1471 	if (valid_bonded_port_id(port_id) != 0)
1472 		return -EINVAL;
1473 
1474 	if (conf != NULL) {
1475 		/* Basic sanity check */
1476 		if (conf->slow_periodic_ms == 0 ||
1477 				conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1478 				conf->long_timeout_ms == 0 ||
1479 				conf->short_timeout_ms >= conf->long_timeout_ms ||
1480 				conf->aggregate_wait_timeout_ms == 0 ||
1481 				conf->tx_period_ms == 0 ||
1482 				conf->rx_marker_period_ms == 0 ||
1483 				conf->update_timeout_ms == 0) {
1484 			RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1485 			return -EINVAL;
1486 		}
1487 	}
1488 
1489 	return 0;
1490 }
1491 
1492 
1493 int
rte_eth_bond_8023ad_setup(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1494 rte_eth_bond_8023ad_setup(uint16_t port_id,
1495 		struct rte_eth_bond_8023ad_conf *conf)
1496 {
1497 	struct rte_eth_dev *bond_dev;
1498 	int err;
1499 
1500 	err = bond_8023ad_setup_validate(port_id, conf);
1501 	if (err != 0)
1502 		return err;
1503 
1504 	bond_dev = &rte_eth_devices[port_id];
1505 	bond_mode_8023ad_setup(bond_dev, conf);
1506 
1507 	return 0;
1508 }
1509 
1510 
1511 
1512 
1513 
1514 int
rte_eth_bond_8023ad_slave_info(uint16_t port_id,uint16_t slave_id,struct rte_eth_bond_8023ad_slave_info * info)1515 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1516 		struct rte_eth_bond_8023ad_slave_info *info)
1517 {
1518 	struct rte_eth_dev *bond_dev;
1519 	struct bond_dev_private *internals;
1520 	struct port *port;
1521 
1522 	if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1523 			rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1524 		return -EINVAL;
1525 
1526 	bond_dev = &rte_eth_devices[port_id];
1527 
1528 	internals = bond_dev->data->dev_private;
1529 	if (find_slave_by_id(internals->active_slaves,
1530 			internals->active_slave_count, slave_id) ==
1531 				internals->active_slave_count)
1532 		return -EINVAL;
1533 
1534 	port = &bond_mode_8023ad_ports[slave_id];
1535 	info->selected = port->selected;
1536 
1537 	info->actor_state = port->actor_state;
1538 	rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1539 
1540 	info->partner_state = port->partner_state;
1541 	rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1542 
1543 	info->agg_port_id = port->aggregator_port_id;
1544 	return 0;
1545 }
1546 
1547 static int
bond_8023ad_ext_validate(uint16_t port_id,uint16_t slave_id)1548 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1549 {
1550 	struct rte_eth_dev *bond_dev;
1551 	struct bond_dev_private *internals;
1552 	struct mode8023ad_private *mode4;
1553 
1554 	if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1555 		return -EINVAL;
1556 
1557 	bond_dev = &rte_eth_devices[port_id];
1558 
1559 	if (!bond_dev->data->dev_started)
1560 		return -EINVAL;
1561 
1562 	internals = bond_dev->data->dev_private;
1563 	if (find_slave_by_id(internals->active_slaves,
1564 			internals->active_slave_count, slave_id) ==
1565 				internals->active_slave_count)
1566 		return -EINVAL;
1567 
1568 	mode4 = &internals->mode4;
1569 	if (mode4->slowrx_cb == NULL)
1570 		return -EINVAL;
1571 
1572 	return 0;
1573 }
1574 
1575 int
rte_eth_bond_8023ad_ext_collect(uint16_t port_id,uint16_t slave_id,int enabled)1576 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1577 				int enabled)
1578 {
1579 	struct port *port;
1580 	int res;
1581 
1582 	res = bond_8023ad_ext_validate(port_id, slave_id);
1583 	if (res != 0)
1584 		return res;
1585 
1586 	port = &bond_mode_8023ad_ports[slave_id];
1587 
1588 	if (enabled)
1589 		ACTOR_STATE_SET(port, COLLECTING);
1590 	else
1591 		ACTOR_STATE_CLR(port, COLLECTING);
1592 
1593 	return 0;
1594 }
1595 
1596 int
rte_eth_bond_8023ad_ext_distrib(uint16_t port_id,uint16_t slave_id,int enabled)1597 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1598 				int enabled)
1599 {
1600 	struct port *port;
1601 	int res;
1602 
1603 	res = bond_8023ad_ext_validate(port_id, slave_id);
1604 	if (res != 0)
1605 		return res;
1606 
1607 	port = &bond_mode_8023ad_ports[slave_id];
1608 
1609 	if (enabled)
1610 		ACTOR_STATE_SET(port, DISTRIBUTING);
1611 	else
1612 		ACTOR_STATE_CLR(port, DISTRIBUTING);
1613 
1614 	return 0;
1615 }
1616 
1617 int
rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id,uint16_t slave_id)1618 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1619 {
1620 	struct port *port;
1621 	int err;
1622 
1623 	err = bond_8023ad_ext_validate(port_id, slave_id);
1624 	if (err != 0)
1625 		return err;
1626 
1627 	port = &bond_mode_8023ad_ports[slave_id];
1628 	return ACTOR_STATE(port, DISTRIBUTING);
1629 }
1630 
1631 int
rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id,uint16_t slave_id)1632 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1633 {
1634 	struct port *port;
1635 	int err;
1636 
1637 	err = bond_8023ad_ext_validate(port_id, slave_id);
1638 	if (err != 0)
1639 		return err;
1640 
1641 	port = &bond_mode_8023ad_ports[slave_id];
1642 	return ACTOR_STATE(port, COLLECTING);
1643 }
1644 
1645 int
rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id,uint16_t slave_id,struct rte_mbuf * lacp_pkt)1646 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1647 		struct rte_mbuf *lacp_pkt)
1648 {
1649 	struct port *port;
1650 	int res;
1651 
1652 	res = bond_8023ad_ext_validate(port_id, slave_id);
1653 	if (res != 0)
1654 		return res;
1655 
1656 	port = &bond_mode_8023ad_ports[slave_id];
1657 
1658 	if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1659 		return -EINVAL;
1660 
1661 	struct lacpdu_header *lacp;
1662 
1663 	/* only enqueue LACPDUs */
1664 	lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1665 	if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1666 		return -EINVAL;
1667 
1668 	MODE4_DEBUG("sending LACP frame\n");
1669 
1670 	return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1671 }
1672 
1673 static void
bond_mode_8023ad_ext_periodic_cb(void * arg)1674 bond_mode_8023ad_ext_periodic_cb(void *arg)
1675 {
1676 	struct rte_eth_dev *bond_dev = arg;
1677 	struct bond_dev_private *internals = bond_dev->data->dev_private;
1678 	struct mode8023ad_private *mode4 = &internals->mode4;
1679 	struct port *port;
1680 	void *pkt = NULL;
1681 	uint16_t i, slave_id;
1682 
1683 	for (i = 0; i < internals->active_slave_count; i++) {
1684 		slave_id = internals->active_slaves[i];
1685 		port = &bond_mode_8023ad_ports[slave_id];
1686 
1687 		if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1688 			struct rte_mbuf *lacp_pkt = pkt;
1689 			struct lacpdu_header *lacp;
1690 
1691 			lacp = rte_pktmbuf_mtod(lacp_pkt,
1692 						struct lacpdu_header *);
1693 			RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1694 
1695 			/* This is LACP frame so pass it to rx callback.
1696 			 * Callback is responsible for freeing mbuf.
1697 			 */
1698 			mode4->slowrx_cb(slave_id, lacp_pkt);
1699 		}
1700 	}
1701 
1702 	rte_eal_alarm_set(internals->mode4.update_timeout_us,
1703 			bond_mode_8023ad_ext_periodic_cb, arg);
1704 }
1705 
1706 int
rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)1707 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1708 {
1709 	int retval = 0;
1710 	struct rte_eth_dev *dev;
1711 	struct bond_dev_private *internals;
1712 
1713 	if (valid_bonded_port_id(port) != 0)
1714 		return -EINVAL;
1715 
1716 	dev = &rte_eth_devices[port];
1717 	internals = dev->data->dev_private;
1718 
1719 	if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1720 		return -1;
1721 
1722 	/* Device must be stopped to set up slow queue */
1723 	if (dev->data->dev_started)
1724 		return -1;
1725 
1726 	internals->mode4.dedicated_queues.enabled = 1;
1727 
1728 	bond_ethdev_mode_set(dev, internals->mode);
1729 	return retval;
1730 }
1731 
1732 int
rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)1733 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1734 {
1735 	int retval = 0;
1736 	struct rte_eth_dev *dev;
1737 	struct bond_dev_private *internals;
1738 
1739 	if (valid_bonded_port_id(port) != 0)
1740 		return -EINVAL;
1741 
1742 	dev = &rte_eth_devices[port];
1743 	internals = dev->data->dev_private;
1744 
1745 	/* Device must be stopped to set up slow queue */
1746 	if (dev->data->dev_started)
1747 		return -1;
1748 
1749 	internals->mode4.dedicated_queues.enabled = 0;
1750 
1751 	bond_ethdev_mode_set(dev, internals->mode);
1752 
1753 	return retval;
1754 }
1755