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