1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2015 Intel Corporation
10 #include <rte_malloc.h>
11 #include <rte_errno.h>
12 #include <rte_cycles.h>
13 #include <rte_compat.h>
15 #include "eth_bond_private.h"
17 static void bond_mode_8023ad_ext_periodic_cb(void *arg);
18 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
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__)
26 static uint64_t start_time;
29 bond_dbg_get_time_diff_ms(void)
37 return ((now - start_time) * 1000) / rte_get_tsc_hz();
41 bond_print_lacp(struct lacpdu *l)
45 char a_state[256] = { 0 };
46 char p_state[256] = { 0 };
48 static const char * const state_labels[] = {
49 "ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
57 addr = l->actor.port_params.system.addr_bytes;
58 snprintf(a_address, sizeof(a_address), "%02X:%02X:%02X:%02X:%02X:%02X",
59 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
61 addr = l->partner.port_params.system.addr_bytes;
62 snprintf(p_address, sizeof(p_address), "%02X:%02X:%02X:%02X:%02X:%02X",
63 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
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 ",
71 if ((l->partner.state >> i) & 1) {
72 p_len += snprintf(&p_state[p_len], RTE_DIM(p_state) - p_len, "%s ",
77 if (a_len && a_state[a_len-1] == ' ')
78 a_state[a_len-1] = '\0';
80 if (p_len && p_state[p_len-1] == ' ')
81 p_state[p_len-1] = '\0';
87 " actor={ tlv=%02X, len=%02X\n"
88 " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"
91 " partner={ tlv=%02X, len=%02X\n"
92 " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"
95 " collector={info=%02X, length=%02X, max_delay=%04X\n, "
96 "type_term=%02X, terminator_length = %02X }",
99 l->actor.tlv_type_info,
100 l->actor.info_length,
101 l->actor.port_params.system_priority,
103 l->actor.port_params.key,
104 l->actor.port_params.port_priority,
105 l->actor.port_params.port_number,
107 l->partner.tlv_type_info,
108 l->partner.info_length,
109 l->partner.port_params.system_priority,
111 l->partner.port_params.key,
112 l->partner.port_params.port_priority,
113 l->partner.port_params.port_number,
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);
123 #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu)
125 #define BOND_PRINT_LACP(lacpdu) do { } while (0)
126 #define MODE4_DEBUG(fmt, ...) do { } while (0)
129 static const struct rte_ether_addr lacp_mac_addr = {
130 .addr_bytes = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
133 struct port bond_mode_8023ad_ports[RTE_MAX_ETHPORTS];
136 timer_cancel(uint64_t *timer)
142 timer_set(uint64_t *timer, uint64_t timeout)
144 *timer = rte_rdtsc() + timeout;
147 /* Forces given timer to be in expired state. */
149 timer_force_expired(uint64_t *timer)
151 *timer = rte_rdtsc();
155 timer_is_stopped(uint64_t *timer)
161 timer_is_expired(uint64_t *timer)
163 return *timer < rte_rdtsc();
166 /* Timer is in running state if it is not stopped nor expired */
168 timer_is_running(uint64_t *timer)
170 return !timer_is_stopped(timer) && !timer_is_expired(timer);
174 set_warning_flags(struct port *port, uint16_t flags)
178 uint16_t new_flag = 0;
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));
188 show_warnings(uint16_t slave_id)
190 struct port *port = &bond_mode_8023ad_ports[slave_id];
194 warnings = port->warnings_to_show;
195 } while (rte_atomic16_cmpset(&port->warnings_to_show, warnings, 0) == 0);
200 if (!timer_is_expired(&port->warning_timer))
204 timer_set(&port->warning_timer, BOND_8023AD_WARNINGS_PERIOD_MS *
205 rte_get_tsc_hz() / 1000);
207 if (warnings & WRN_RX_QUEUE_FULL) {
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",
215 if (warnings & WRN_TX_QUEUE_FULL) {
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",
223 if (warnings & WRN_RX_MARKER_TO_FAST)
224 RTE_BOND_LOG(INFO, "Slave %u: marker to early - ignoring.",
227 if (warnings & WRN_UNKNOWN_SLOW_TYPE) {
229 "Slave %u: ignoring unknown slow protocol frame type",
233 if (warnings & WRN_UNKNOWN_MARKER_TYPE)
234 RTE_BOND_LOG(INFO, "Slave %u: ignoring unknown marker type",
237 if (warnings & WRN_NOT_LACP_CAPABLE)
238 MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id);
242 record_default(struct port *port)
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 parner is in defaulted state. */
247 port->partner_state = STATE_LACP_ACTIVE;
248 ACTOR_STATE_SET(port, DEFAULTED);
251 /** Function handles rx state machine.
253 * This function implements Receive State Machine from point 5.4.12 in
254 * 802.1AX documentation. It should be called periodically.
256 * @param lacpdu LACPDU received.
257 * @param port Port on which LACPDU was received.
260 rx_machine(struct bond_dev_private *internals, uint16_t slave_id,
263 struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
266 if (SM_FLAG(port, BEGIN)) {
267 /* Initialize stuff */
268 MODE4_DEBUG("-> INITIALIZE\n");
269 SM_FLAG_CLR(port, MOVED);
270 port->selected = UNSELECTED;
272 record_default(port);
274 ACTOR_STATE_CLR(port, EXPIRED);
275 timer_cancel(&port->current_while_timer);
277 /* DISABLED: On initialization partner is out of sync */
278 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
280 /* LACP DISABLED stuff if LACP not enabled on this port */
281 if (!SM_FLAG(port, LACP_ENABLED))
282 PARTNER_STATE_CLR(port, AGGREGATION);
284 PARTNER_STATE_SET(port, AGGREGATION);
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);
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 parner
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;
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;
318 /* Partner parameters are not defaulted any more */
319 ACTOR_STATE_CLR(port, DEFAULTED);
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;
332 /* Update NTT if partners information are outdated (xored and masked
334 uint8_t state_mask = STATE_LACP_ACTIVE | STATE_LACP_SHORT_TIMEOUT |
335 STATE_SYNCHRONIZATION | STATE_AGGREGATION;
337 if (((port->actor_state ^ lacp->partner.state) & state_mask) ||
339 SM_FLAG_SET(port, NTT);
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,
348 PARTNER_STATE_SET(port, SYNCHRONIZATION);
350 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
352 if (ACTOR_STATE(port, LACP_SHORT_TIMEOUT))
353 timeout = internals->mode4.short_timeout;
355 timeout = internals->mode4.long_timeout;
357 timer_set(&port->current_while_timer, timeout);
358 ACTOR_STATE_CLR(port, EXPIRED);
359 return; /* No state change */
362 /* If CURRENT state timer is not running (stopped or expired)
363 * transit to EXPIRED state from DISABLED or CURRENT */
364 if (!timer_is_running(&port->current_while_timer)) {
365 ACTOR_STATE_SET(port, EXPIRED);
366 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
367 PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
368 timer_set(&port->current_while_timer, internals->mode4.short_timeout);
373 * Function handles periodic tx state machine.
375 * Function implements Periodic Transmission state machine from point 5.4.13
376 * in 802.1AX documentation. It should be called periodically.
378 * @param port Port to handle state machine.
381 periodic_machine(struct bond_dev_private *internals, uint16_t slave_id)
383 struct port *port = &bond_mode_8023ad_ports[slave_id];
384 /* Calculate if either site is LACP enabled */
386 uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
387 PARTNER_STATE(port, LACP_ACTIVE);
389 uint8_t is_partner_fast, was_partner_fast;
390 /* No periodic is on BEGIN, LACP DISABLE or when both sides are pasive */
391 if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
392 timer_cancel(&port->periodic_timer);
393 timer_force_expired(&port->tx_machine_timer);
394 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
396 MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
397 SM_FLAG(port, BEGIN) ? "begind " : "",
398 SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
399 active ? "LACP active " : "LACP pasive ");
403 is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
404 was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
406 /* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
407 * Other case: check if timer expire or partners settings changed. */
408 if (!timer_is_stopped(&port->periodic_timer)) {
409 if (timer_is_expired(&port->periodic_timer)) {
410 SM_FLAG_SET(port, NTT);
411 } else if (is_partner_fast != was_partner_fast) {
412 /* Partners timeout was slow and now it is fast -> send LACP.
413 * In other case (was fast and now it is slow) just switch
414 * timeout to slow without forcing send of LACP (because standard
417 SM_FLAG_SET(port, NTT);
419 return; /* Nothing changed */
422 /* Handle state transition to FAST/SLOW LACP timeout */
423 if (is_partner_fast) {
424 timeout = internals->mode4.fast_periodic_timeout;
425 SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
427 timeout = internals->mode4.slow_periodic_timeout;
428 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
431 timer_set(&port->periodic_timer, timeout);
435 * Function handles mux state machine.
437 * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
438 * It should be called periodically.
440 * @param port Port to handle state machine.
443 mux_machine(struct bond_dev_private *internals, uint16_t slave_id)
445 struct port *port = &bond_mode_8023ad_ports[slave_id];
447 /* Save current state for later use */
448 const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
451 /* Enter DETACHED state on BEGIN condition or from any other state if
452 * port was unselected */
453 if (SM_FLAG(port, BEGIN) ||
454 port->selected == UNSELECTED || (port->selected == STANDBY &&
455 (port->actor_state & state_mask) != 0)) {
456 /* detach mux from aggregator */
457 port->actor_state &= ~state_mask;
458 /* Set ntt to true if BEGIN condition or transition from any other state
459 * which is indicated that wait_while_timer was started */
460 if (SM_FLAG(port, BEGIN) ||
461 !timer_is_stopped(&port->wait_while_timer)) {
462 SM_FLAG_SET(port, NTT);
463 MODE4_DEBUG("-> DETACHED\n");
465 timer_cancel(&port->wait_while_timer);
468 if (timer_is_stopped(&port->wait_while_timer)) {
469 if (port->selected == SELECTED || port->selected == STANDBY) {
470 timer_set(&port->wait_while_timer,
471 internals->mode4.aggregate_wait_timeout);
473 MODE4_DEBUG("DETACHED -> WAITING\n");
475 /* Waiting state entered */
479 /* Transit next state if port is ready */
480 if (!timer_is_expired(&port->wait_while_timer))
483 if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
484 !PARTNER_STATE(port, SYNCHRONIZATION)) {
485 /* If in COLLECTING or DISTRIBUTING state and partner becomes out of
486 * sync transit to ATACHED state. */
487 ACTOR_STATE_CLR(port, DISTRIBUTING);
488 ACTOR_STATE_CLR(port, COLLECTING);
489 /* Clear actor sync to activate transit ATACHED in condition bellow */
490 ACTOR_STATE_CLR(port, SYNCHRONIZATION);
491 MODE4_DEBUG("Out of sync -> ATTACHED\n");
494 if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
495 /* attach mux to aggregator */
496 RTE_ASSERT((port->actor_state & (STATE_COLLECTING |
497 STATE_DISTRIBUTING)) == 0);
499 ACTOR_STATE_SET(port, SYNCHRONIZATION);
500 SM_FLAG_SET(port, NTT);
501 MODE4_DEBUG("ATTACHED Entered\n");
502 } else if (!ACTOR_STATE(port, COLLECTING)) {
503 /* Start collecting if in sync */
504 if (PARTNER_STATE(port, SYNCHRONIZATION)) {
505 MODE4_DEBUG("ATTACHED -> COLLECTING\n");
506 ACTOR_STATE_SET(port, COLLECTING);
507 SM_FLAG_SET(port, NTT);
509 } else if (ACTOR_STATE(port, COLLECTING)) {
510 /* Check if partner is in COLLECTING state. If so this port can
511 * distribute frames to it */
512 if (!ACTOR_STATE(port, DISTRIBUTING)) {
513 if (PARTNER_STATE(port, COLLECTING)) {
514 /* Enable DISTRIBUTING if partner is collecting */
515 ACTOR_STATE_SET(port, DISTRIBUTING);
516 SM_FLAG_SET(port, NTT);
517 MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
519 "Bond %u: slave id %u distributing started.",
520 internals->port_id, slave_id);
523 if (!PARTNER_STATE(port, COLLECTING)) {
524 /* Disable DISTRIBUTING (enter COLLECTING state) if partner
525 * is not collecting */
526 ACTOR_STATE_CLR(port, DISTRIBUTING);
527 SM_FLAG_SET(port, NTT);
528 MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
530 "Bond %u: slave id %u distributing stopped.",
531 internals->port_id, slave_id);
538 * Function handles transmit state machine.
540 * Function implements Transmit Machine from point 5.4.16 in 802.1AX
546 tx_machine(struct bond_dev_private *internals, uint16_t slave_id)
548 struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
550 struct rte_mbuf *lacp_pkt = NULL;
551 struct lacpdu_header *hdr;
552 struct lacpdu *lacpdu;
554 /* If periodic timer is not running periodic machine is in NO PERIODIC and
555 * according to 802.3ax standard tx machine should not transmit any frames
556 * and set ntt to false. */
557 if (timer_is_stopped(&port->periodic_timer))
558 SM_FLAG_CLR(port, NTT);
560 if (!SM_FLAG(port, NTT))
563 if (!timer_is_expired(&port->tx_machine_timer))
566 lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
567 if (lacp_pkt == NULL) {
568 RTE_BOND_LOG(ERR, "Failed to allocate LACP packet from pool");
572 lacp_pkt->data_len = sizeof(*hdr);
573 lacp_pkt->pkt_len = sizeof(*hdr);
575 hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
577 /* Source and destination MAC */
578 rte_ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.d_addr);
579 rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_addr);
580 hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW);
582 lacpdu = &hdr->lacpdu;
583 memset(lacpdu, 0, sizeof(*lacpdu));
585 /* Initialize LACP part */
586 lacpdu->subtype = SLOW_SUBTYPE_LACP;
587 lacpdu->version_number = 1;
590 lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
591 lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
592 memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
593 sizeof(port->actor));
594 agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
595 rte_ether_addr_copy(&agg->actor.system,
596 &hdr->lacpdu.actor.port_params.system);
597 lacpdu->actor.state = port->actor_state;
600 lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
601 lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
602 memcpy(&lacpdu->partner.port_params, &port->partner,
603 sizeof(struct port_params));
604 lacpdu->partner.state = port->partner_state;
607 lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
608 lacpdu->collector_info_length = 0x10;
609 lacpdu->collector_max_delay = 0;
611 lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
612 lacpdu->terminator_length = 0;
614 MODE4_DEBUG("Sending LACP frame\n");
615 BOND_PRINT_LACP(lacpdu);
617 if (internals->mode4.dedicated_queues.enabled == 0) {
618 int retval = rte_ring_enqueue(port->tx_ring, lacp_pkt);
620 /* If TX ring full, drop packet and free message.
621 Retransmission will happen in next function call. */
622 rte_pktmbuf_free(lacp_pkt);
623 set_warning_flags(port, WRN_TX_QUEUE_FULL);
627 uint16_t pkts_sent = rte_eth_tx_burst(slave_id,
628 internals->mode4.dedicated_queues.tx_qid,
630 if (pkts_sent != 1) {
631 rte_pktmbuf_free(lacp_pkt);
632 set_warning_flags(port, WRN_TX_QUEUE_FULL);
638 timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
639 SM_FLAG_CLR(port, NTT);
643 max_index(uint64_t *a, int n)
651 for (i = 1; i < n; ++i) {
662 * Function assigns port to aggregator.
664 * @param bond_dev_private Pointer to bond_dev_private structure.
665 * @param port_pos Port to assign.
668 selection_logic(struct bond_dev_private *internals, uint16_t slave_id)
670 struct port *agg, *port;
671 uint16_t slaves_count, new_agg_id, i, j = 0;
673 uint64_t agg_bandwidth[RTE_MAX_ETHPORTS] = {0};
674 uint64_t agg_count[RTE_MAX_ETHPORTS] = {0};
675 uint16_t default_slave = 0;
676 struct rte_eth_link link_info;
677 uint16_t agg_new_idx = 0;
680 slaves = internals->active_slaves;
681 slaves_count = internals->active_slave_count;
682 port = &bond_mode_8023ad_ports[slave_id];
684 /* Search for aggregator suitable for this port */
685 for (i = 0; i < slaves_count; ++i) {
686 agg = &bond_mode_8023ad_ports[slaves[i]];
687 /* Skip ports that are not aggreagators */
688 if (agg->aggregator_port_id != slaves[i])
691 ret = rte_eth_link_get_nowait(slaves[i], &link_info);
694 "Slave (port %u) link get failed: %s\n",
695 slaves[i], rte_strerror(-ret));
699 agg_bandwidth[i] += link_info.link_speed;
701 /* Actors system ID is not checked since all slave device have the same
702 * ID (MAC address). */
703 if ((agg->actor.key == port->actor.key &&
704 agg->partner.system_priority == port->partner.system_priority &&
705 rte_is_same_ether_addr(&agg->partner.system,
706 &port->partner.system) == 1
707 && (agg->partner.key == port->partner.key)) &&
708 rte_is_zero_ether_addr(&port->partner.system) != 1 &&
710 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
718 switch (internals->mode4.agg_selection) {
720 agg_new_idx = max_index(agg_count, slaves_count);
721 new_agg_id = slaves[agg_new_idx];
724 agg_new_idx = max_index(agg_bandwidth, slaves_count);
725 new_agg_id = slaves[agg_new_idx];
728 if (default_slave == slaves_count)
729 new_agg_id = slaves[slave_id];
731 new_agg_id = slaves[default_slave];
734 if (default_slave == slaves_count)
735 new_agg_id = slaves[slave_id];
737 new_agg_id = slaves[default_slave];
741 if (new_agg_id != port->aggregator_port_id) {
742 port->aggregator_port_id = new_agg_id;
744 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
745 "\t%s aggregator ID=%3u\n",
746 port->aggregator_port_id,
747 port->aggregator_port_id == slave_id ?
748 "aggregator not found, using default" : "aggregator found",
749 port->aggregator_port_id);
752 port->selected = SELECTED;
755 /* Function maps DPDK speed to bonding speed stored in key field */
757 link_speed_key(uint16_t speed) {
761 case ETH_SPEED_NUM_NONE:
764 case ETH_SPEED_NUM_10M:
765 key_speed = BOND_LINK_SPEED_KEY_10M;
767 case ETH_SPEED_NUM_100M:
768 key_speed = BOND_LINK_SPEED_KEY_100M;
770 case ETH_SPEED_NUM_1G:
771 key_speed = BOND_LINK_SPEED_KEY_1000M;
773 case ETH_SPEED_NUM_10G:
774 key_speed = BOND_LINK_SPEED_KEY_10G;
776 case ETH_SPEED_NUM_20G:
777 key_speed = BOND_LINK_SPEED_KEY_20G;
779 case ETH_SPEED_NUM_40G:
780 key_speed = BOND_LINK_SPEED_KEY_40G;
791 rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id,
792 struct rte_mbuf *lacp_pkt) {
793 struct lacpdu_header *lacp;
794 struct lacpdu_actor_partner_params *partner;
796 if (lacp_pkt != NULL) {
797 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
798 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
800 partner = &lacp->lacpdu.partner;
801 if (rte_is_same_ether_addr(&partner->port_params.system,
802 &internals->mode4.mac_addr)) {
803 /* This LACP frame is sending to the bonding port
804 * so pass it to rx_machine.
806 rx_machine(internals, slave_id, &lacp->lacpdu);
808 rte_pktmbuf_free(lacp_pkt);
810 rx_machine(internals, slave_id, NULL);
814 bond_mode_8023ad_periodic_cb(void *arg)
816 struct rte_eth_dev *bond_dev = arg;
817 struct bond_dev_private *internals = bond_dev->data->dev_private;
819 struct rte_eth_link link_info;
820 struct rte_ether_addr slave_addr;
821 struct rte_mbuf *lacp_pkt = NULL;
826 /* Update link status on each port */
827 for (i = 0; i < internals->active_slave_count; i++) {
831 slave_id = internals->active_slaves[i];
832 ret = rte_eth_link_get_nowait(slave_id, &link_info);
835 "Slave (port %u) link get failed: %s\n",
836 slave_id, rte_strerror(-ret));
839 if (ret >= 0 && link_info.link_status != 0) {
840 key = link_speed_key(link_info.link_speed) << 1;
841 if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
842 key |= BOND_LINK_FULL_DUPLEX_KEY;
847 rte_eth_macaddr_get(slave_id, &slave_addr);
848 port = &bond_mode_8023ad_ports[slave_id];
850 key = rte_cpu_to_be_16(key);
851 if (key != port->actor.key) {
852 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
853 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
855 port->actor.key = key;
856 SM_FLAG_SET(port, NTT);
859 if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
860 rte_ether_addr_copy(&slave_addr, &port->actor.system);
861 if (port->aggregator_port_id == slave_id)
862 SM_FLAG_SET(port, NTT);
866 for (i = 0; i < internals->active_slave_count; i++) {
867 slave_id = internals->active_slaves[i];
868 port = &bond_mode_8023ad_ports[slave_id];
870 if ((port->actor.key &
871 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
873 SM_FLAG_SET(port, BEGIN);
875 /* LACP is disabled on half duples or link is down */
876 if (SM_FLAG(port, LACP_ENABLED)) {
877 /* If port was enabled set it to BEGIN state */
878 SM_FLAG_CLR(port, LACP_ENABLED);
879 ACTOR_STATE_CLR(port, DISTRIBUTING);
880 ACTOR_STATE_CLR(port, COLLECTING);
883 /* Skip this port processing */
887 SM_FLAG_SET(port, LACP_ENABLED);
889 if (internals->mode4.dedicated_queues.enabled == 0) {
890 /* Find LACP packet to this port. Do not check subtype,
891 * it is done in function that queued packet
893 int retval = rte_ring_dequeue(port->rx_ring,
899 rx_machine_update(internals, slave_id, lacp_pkt);
901 uint16_t rx_count = rte_eth_rx_burst(slave_id,
902 internals->mode4.dedicated_queues.rx_qid,
906 bond_mode_8023ad_handle_slow_pkt(internals,
909 rx_machine_update(internals, slave_id, NULL);
912 periodic_machine(internals, slave_id);
913 mux_machine(internals, slave_id);
914 tx_machine(internals, slave_id);
915 selection_logic(internals, slave_id);
917 SM_FLAG_CLR(port, BEGIN);
918 show_warnings(slave_id);
921 rte_eal_alarm_set(internals->mode4.update_timeout_us,
922 bond_mode_8023ad_periodic_cb, arg);
926 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
930 ret = rte_eth_allmulticast_enable(slave_id);
933 "failed to enable allmulti mode for port %u: %s",
934 slave_id, rte_strerror(-ret));
936 if (rte_eth_allmulticast_get(slave_id)) {
937 RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
939 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
940 BOND_8023AD_FORCED_ALLMULTI;
944 ret = rte_eth_promiscuous_enable(slave_id);
947 "failed to enable promiscuous mode for port %u: %s",
948 slave_id, rte_strerror(-ret));
950 if (rte_eth_promiscuous_get(slave_id)) {
951 RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
953 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
954 BOND_8023AD_FORCED_PROMISC;
962 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
966 switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
967 case BOND_8023AD_FORCED_ALLMULTI:
968 RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
969 ret = rte_eth_allmulticast_disable(slave_id);
972 "failed to disable allmulti mode for port %u: %s",
973 slave_id, rte_strerror(-ret));
976 case BOND_8023AD_FORCED_PROMISC:
977 RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
978 ret = rte_eth_promiscuous_disable(slave_id);
981 "failed to disable promiscuous mode for port %u: %s",
982 slave_id, rte_strerror(-ret));
991 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
994 struct bond_dev_private *internals = bond_dev->data->dev_private;
996 struct port *port = &bond_mode_8023ad_ports[slave_id];
997 struct port_params initial = {
999 .system_priority = rte_cpu_to_be_16(0xFFFF),
1000 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1001 .port_priority = rte_cpu_to_be_16(0x00FF),
1005 char mem_name[RTE_ETH_NAME_MAX_LEN];
1007 unsigned element_size;
1008 uint32_t total_tx_desc;
1009 struct bond_tx_queue *bd_tx_q;
1012 /* Given slave mus not be in active list */
1013 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1014 internals->active_slave_count, slave_id) == internals->active_slave_count);
1015 RTE_SET_USED(internals); /* used only for assert when enabled */
1017 memcpy(&port->actor, &initial, sizeof(struct port_params));
1018 /* Standard requires that port ID must be grater than 0.
1019 * Add 1 do get corresponding port_number */
1020 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1022 memcpy(&port->partner, &initial, sizeof(struct port_params));
1024 /* default states */
1025 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1026 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1027 port->sm_flags = SM_FLAGS_BEGIN;
1029 /* use this port as agregator */
1030 port->aggregator_port_id = slave_id;
1032 if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1033 RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1037 timer_cancel(&port->warning_timer);
1039 if (port->mbuf_pool != NULL)
1042 RTE_ASSERT(port->rx_ring == NULL);
1043 RTE_ASSERT(port->tx_ring == NULL);
1045 socket_id = rte_eth_dev_socket_id(slave_id);
1046 if (socket_id == -1)
1047 socket_id = rte_socket_id();
1049 element_size = sizeof(struct slow_protocol_frame) +
1050 RTE_PKTMBUF_HEADROOM;
1052 /* The size of the mempool should be at least:
1053 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1054 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1055 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1056 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1057 total_tx_desc += bd_tx_q->nb_tx_desc;
1060 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1061 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1062 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1063 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1064 0, element_size, socket_id);
1066 /* Any memory allocation failure in initialization is critical because
1067 * resources can't be free, so reinitialization is impossible. */
1068 if (port->mbuf_pool == NULL) {
1069 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1070 slave_id, mem_name, rte_strerror(rte_errno));
1073 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1074 port->rx_ring = rte_ring_create(mem_name,
1075 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1077 if (port->rx_ring == NULL) {
1078 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1079 mem_name, rte_strerror(rte_errno));
1082 /* TX ring is at least one pkt longer to make room for marker packet. */
1083 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1084 port->tx_ring = rte_ring_create(mem_name,
1085 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1087 if (port->tx_ring == NULL) {
1088 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1089 mem_name, rte_strerror(rte_errno));
1094 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1098 struct port *port = NULL;
1099 uint8_t old_partner_state;
1101 port = &bond_mode_8023ad_ports[slave_id];
1103 ACTOR_STATE_CLR(port, AGGREGATION);
1104 port->selected = UNSELECTED;
1106 old_partner_state = port->partner_state;
1107 record_default(port);
1109 bond_mode_8023ad_unregister_lacp_mac(slave_id);
1111 /* If partner timeout state changes then disable timer */
1112 if (!((old_partner_state ^ port->partner_state) &
1113 STATE_LACP_SHORT_TIMEOUT))
1114 timer_cancel(&port->current_while_timer);
1116 PARTNER_STATE_CLR(port, AGGREGATION);
1117 ACTOR_STATE_CLR(port, EXPIRED);
1119 /* flush rx/tx rings */
1120 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1121 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1123 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1124 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1129 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1131 struct bond_dev_private *internals = bond_dev->data->dev_private;
1132 struct rte_ether_addr slave_addr;
1133 struct port *slave, *agg_slave;
1134 uint16_t slave_id, i, j;
1136 bond_mode_8023ad_stop(bond_dev);
1138 for (i = 0; i < internals->active_slave_count; i++) {
1139 slave_id = internals->active_slaves[i];
1140 slave = &bond_mode_8023ad_ports[slave_id];
1141 rte_eth_macaddr_get(slave_id, &slave_addr);
1143 if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1146 rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1147 /* Do nothing if this port is not an aggregator. In other case
1148 * Set NTT flag on every port that use this aggregator. */
1149 if (slave->aggregator_port_id != slave_id)
1152 for (j = 0; j < internals->active_slave_count; j++) {
1153 agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1154 if (agg_slave->aggregator_port_id == slave_id)
1155 SM_FLAG_SET(agg_slave, NTT);
1159 if (bond_dev->data->dev_started)
1160 bond_mode_8023ad_start(bond_dev);
1164 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1165 struct rte_eth_bond_8023ad_conf *conf)
1167 struct bond_dev_private *internals = dev->data->dev_private;
1168 struct mode8023ad_private *mode4 = &internals->mode4;
1169 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1171 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1172 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1173 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1174 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1175 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1176 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1177 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1178 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1179 conf->slowrx_cb = mode4->slowrx_cb;
1180 conf->agg_selection = mode4->agg_selection;
1184 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1186 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1187 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1188 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1189 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1190 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1191 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1192 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1193 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1194 conf->slowrx_cb = NULL;
1195 conf->agg_selection = AGG_STABLE;
1199 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1200 struct rte_eth_bond_8023ad_conf *conf)
1202 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1204 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1205 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1206 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1207 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1208 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1209 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1210 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1211 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1213 mode4->dedicated_queues.enabled = 0;
1214 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1215 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1219 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1220 struct rte_eth_bond_8023ad_conf *conf)
1222 struct rte_eth_bond_8023ad_conf def_conf;
1223 struct bond_dev_private *internals = dev->data->dev_private;
1224 struct mode8023ad_private *mode4 = &internals->mode4;
1228 bond_mode_8023ad_conf_get_default(conf);
1231 bond_mode_8023ad_stop(dev);
1232 bond_mode_8023ad_conf_assign(mode4, conf);
1233 mode4->slowrx_cb = conf->slowrx_cb;
1234 mode4->agg_selection = AGG_STABLE;
1236 if (dev->data->dev_started)
1237 bond_mode_8023ad_start(dev);
1241 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1243 struct bond_dev_private *internals = bond_dev->data->dev_private;
1246 for (i = 0; i < internals->active_slave_count; i++)
1247 bond_mode_8023ad_activate_slave(bond_dev,
1248 internals->active_slaves[i]);
1254 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1256 struct bond_dev_private *internals = bond_dev->data->dev_private;
1257 struct mode8023ad_private *mode4 = &internals->mode4;
1258 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1260 rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1261 if (mode4->slowrx_cb)
1262 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1265 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1269 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1271 struct bond_dev_private *internals = bond_dev->data->dev_private;
1272 struct mode8023ad_private *mode4 = &internals->mode4;
1274 if (mode4->slowrx_cb) {
1275 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1279 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1283 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1284 uint16_t slave_id, struct rte_mbuf *pkt)
1286 struct mode8023ad_private *mode4 = &internals->mode4;
1287 struct port *port = &bond_mode_8023ad_ports[slave_id];
1288 struct marker_header *m_hdr;
1289 uint64_t marker_timer, old_marker_timer;
1291 uint8_t wrn, subtype;
1292 /* If packet is a marker, we send response now by reusing given packet
1293 * and update only source MAC, destination MAC is multicast so don't
1294 * update it. Other frames will be handled later by state machines */
1295 subtype = rte_pktmbuf_mtod(pkt,
1296 struct slow_protocol_frame *)->slow_protocol.subtype;
1298 if (subtype == SLOW_SUBTYPE_MARKER) {
1299 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1301 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1302 wrn = WRN_UNKNOWN_MARKER_TYPE;
1306 /* Setup marker timer. Do it in loop in case concurrent access. */
1308 old_marker_timer = port->rx_marker_timer;
1309 if (!timer_is_expired(&old_marker_timer)) {
1310 wrn = WRN_RX_MARKER_TO_FAST;
1314 timer_set(&marker_timer, mode4->rx_marker_timeout);
1315 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1316 old_marker_timer, marker_timer);
1317 } while (unlikely(retval == 0));
1319 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1320 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1322 if (internals->mode4.dedicated_queues.enabled == 0) {
1323 int retval = rte_ring_enqueue(port->tx_ring, pkt);
1326 port->rx_marker_timer = 0;
1327 wrn = WRN_TX_QUEUE_FULL;
1331 /* Send packet directly to the slow queue */
1332 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1333 internals->mode4.dedicated_queues.tx_qid,
1335 if (tx_count != 1) {
1337 port->rx_marker_timer = 0;
1338 wrn = WRN_TX_QUEUE_FULL;
1342 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1343 if (internals->mode4.dedicated_queues.enabled == 0) {
1344 int retval = rte_ring_enqueue(port->rx_ring, pkt);
1346 /* If RX fing full free lacpdu message and drop packet */
1347 wrn = WRN_RX_QUEUE_FULL;
1351 rx_machine_update(internals, slave_id, pkt);
1353 wrn = WRN_UNKNOWN_SLOW_TYPE;
1360 set_warning_flags(port, wrn);
1361 rte_pktmbuf_free(pkt);
1365 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1366 struct rte_eth_bond_8023ad_conf *conf)
1368 struct rte_eth_dev *bond_dev;
1370 if (valid_bonded_port_id(port_id) != 0)
1376 bond_dev = &rte_eth_devices[port_id];
1377 bond_mode_8023ad_conf_get(bond_dev, conf);
1382 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1383 enum rte_bond_8023ad_agg_selection agg_selection)
1385 struct rte_eth_dev *bond_dev;
1386 struct bond_dev_private *internals;
1387 struct mode8023ad_private *mode4;
1389 if (valid_bonded_port_id(port_id) != 0)
1392 bond_dev = &rte_eth_devices[port_id];
1393 internals = bond_dev->data->dev_private;
1395 if (internals->mode != 4)
1398 mode4 = &internals->mode4;
1399 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1400 || agg_selection == AGG_STABLE)
1401 mode4->agg_selection = agg_selection;
1405 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1407 struct rte_eth_dev *bond_dev;
1408 struct bond_dev_private *internals;
1409 struct mode8023ad_private *mode4;
1411 if (valid_bonded_port_id(port_id) != 0)
1414 bond_dev = &rte_eth_devices[port_id];
1415 internals = bond_dev->data->dev_private;
1417 if (internals->mode != 4)
1419 mode4 = &internals->mode4;
1421 return mode4->agg_selection;
1427 bond_8023ad_setup_validate(uint16_t port_id,
1428 struct rte_eth_bond_8023ad_conf *conf)
1430 if (valid_bonded_port_id(port_id) != 0)
1434 /* Basic sanity check */
1435 if (conf->slow_periodic_ms == 0 ||
1436 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1437 conf->long_timeout_ms == 0 ||
1438 conf->short_timeout_ms >= conf->long_timeout_ms ||
1439 conf->aggregate_wait_timeout_ms == 0 ||
1440 conf->tx_period_ms == 0 ||
1441 conf->rx_marker_period_ms == 0 ||
1442 conf->update_timeout_ms == 0) {
1443 RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1453 rte_eth_bond_8023ad_setup(uint16_t port_id,
1454 struct rte_eth_bond_8023ad_conf *conf)
1456 struct rte_eth_dev *bond_dev;
1459 err = bond_8023ad_setup_validate(port_id, conf);
1463 bond_dev = &rte_eth_devices[port_id];
1464 bond_mode_8023ad_setup(bond_dev, conf);
1474 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1475 struct rte_eth_bond_8023ad_slave_info *info)
1477 struct rte_eth_dev *bond_dev;
1478 struct bond_dev_private *internals;
1481 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1482 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1485 bond_dev = &rte_eth_devices[port_id];
1487 internals = bond_dev->data->dev_private;
1488 if (find_slave_by_id(internals->active_slaves,
1489 internals->active_slave_count, slave_id) ==
1490 internals->active_slave_count)
1493 port = &bond_mode_8023ad_ports[slave_id];
1494 info->selected = port->selected;
1496 info->actor_state = port->actor_state;
1497 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1499 info->partner_state = port->partner_state;
1500 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1502 info->agg_port_id = port->aggregator_port_id;
1507 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1509 struct rte_eth_dev *bond_dev;
1510 struct bond_dev_private *internals;
1511 struct mode8023ad_private *mode4;
1513 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1516 bond_dev = &rte_eth_devices[port_id];
1518 if (!bond_dev->data->dev_started)
1521 internals = bond_dev->data->dev_private;
1522 if (find_slave_by_id(internals->active_slaves,
1523 internals->active_slave_count, slave_id) ==
1524 internals->active_slave_count)
1527 mode4 = &internals->mode4;
1528 if (mode4->slowrx_cb == NULL)
1535 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1541 res = bond_8023ad_ext_validate(port_id, slave_id);
1545 port = &bond_mode_8023ad_ports[slave_id];
1548 ACTOR_STATE_SET(port, COLLECTING);
1550 ACTOR_STATE_CLR(port, COLLECTING);
1556 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1562 res = bond_8023ad_ext_validate(port_id, slave_id);
1566 port = &bond_mode_8023ad_ports[slave_id];
1569 ACTOR_STATE_SET(port, DISTRIBUTING);
1571 ACTOR_STATE_CLR(port, DISTRIBUTING);
1577 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1582 err = bond_8023ad_ext_validate(port_id, slave_id);
1586 port = &bond_mode_8023ad_ports[slave_id];
1587 return ACTOR_STATE(port, DISTRIBUTING);
1591 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1596 err = bond_8023ad_ext_validate(port_id, slave_id);
1600 port = &bond_mode_8023ad_ports[slave_id];
1601 return ACTOR_STATE(port, COLLECTING);
1605 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1606 struct rte_mbuf *lacp_pkt)
1611 res = bond_8023ad_ext_validate(port_id, slave_id);
1615 port = &bond_mode_8023ad_ports[slave_id];
1617 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1620 struct lacpdu_header *lacp;
1622 /* only enqueue LACPDUs */
1623 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1624 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1627 MODE4_DEBUG("sending LACP frame\n");
1629 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1633 bond_mode_8023ad_ext_periodic_cb(void *arg)
1635 struct rte_eth_dev *bond_dev = arg;
1636 struct bond_dev_private *internals = bond_dev->data->dev_private;
1637 struct mode8023ad_private *mode4 = &internals->mode4;
1640 uint16_t i, slave_id;
1642 for (i = 0; i < internals->active_slave_count; i++) {
1643 slave_id = internals->active_slaves[i];
1644 port = &bond_mode_8023ad_ports[slave_id];
1646 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1647 struct rte_mbuf *lacp_pkt = pkt;
1648 struct lacpdu_header *lacp;
1650 lacp = rte_pktmbuf_mtod(lacp_pkt,
1651 struct lacpdu_header *);
1652 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1654 /* This is LACP frame so pass it to rx callback.
1655 * Callback is responsible for freeing mbuf.
1657 mode4->slowrx_cb(slave_id, lacp_pkt);
1661 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1662 bond_mode_8023ad_ext_periodic_cb, arg);
1666 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1669 struct rte_eth_dev *dev;
1670 struct bond_dev_private *internals;
1672 if (valid_bonded_port_id(port) != 0)
1675 dev = &rte_eth_devices[port];
1676 internals = dev->data->dev_private;
1678 if (check_for_bonded_ethdev(dev) != 0)
1681 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1684 /* Device must be stopped to set up slow queue */
1685 if (dev->data->dev_started)
1688 internals->mode4.dedicated_queues.enabled = 1;
1690 bond_ethdev_mode_set(dev, internals->mode);
1695 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1698 struct rte_eth_dev *dev;
1699 struct bond_dev_private *internals;
1701 if (valid_bonded_port_id(port) != 0)
1704 dev = &rte_eth_devices[port];
1705 internals = dev->data->dev_private;
1707 if (check_for_bonded_ethdev(dev) != 0)
1710 /* Device must be stopped to set up slow queue */
1711 if (dev->data->dev_started)
1714 internals->mode4.dedicated_queues.enabled = 0;
1716 bond_ethdev_mode_set(dev, internals->mode);