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 "rte_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[8] = {0};
674 uint64_t agg_count[8] = {0};
675 uint16_t default_slave = 0;
676 uint16_t mode_count_id;
677 uint16_t mode_band_id;
678 struct rte_eth_link link_info;
681 slaves = internals->active_slaves;
682 slaves_count = internals->active_slave_count;
683 port = &bond_mode_8023ad_ports[slave_id];
685 /* Search for aggregator suitable for this port */
686 for (i = 0; i < slaves_count; ++i) {
687 agg = &bond_mode_8023ad_ports[slaves[i]];
688 /* Skip ports that are not aggreagators */
689 if (agg->aggregator_port_id != slaves[i])
692 ret = rte_eth_link_get_nowait(slaves[i], &link_info);
695 "Slave (port %u) link get failed: %s\n",
696 slaves[i], rte_strerror(-ret));
699 agg_count[agg->aggregator_port_id] += 1;
700 agg_bandwidth[agg->aggregator_port_id] += link_info.link_speed;
702 /* Actors system ID is not checked since all slave device have the same
703 * ID (MAC address). */
704 if ((agg->actor.key == port->actor.key &&
705 agg->partner.system_priority == port->partner.system_priority &&
706 rte_is_same_ether_addr(&agg->partner.system,
707 &port->partner.system) == 1
708 && (agg->partner.key == port->partner.key)) &&
709 rte_is_zero_ether_addr(&port->partner.system) != 1 &&
711 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
719 switch (internals->mode4.agg_selection) {
721 mode_count_id = max_index(agg_count, slaves_count);
722 new_agg_id = mode_count_id;
725 mode_band_id = max_index(agg_bandwidth, slaves_count);
726 new_agg_id = mode_band_id;
729 if (default_slave == slaves_count)
730 new_agg_id = slave_id;
732 new_agg_id = slaves[default_slave];
735 if (default_slave == slaves_count)
736 new_agg_id = slave_id;
738 new_agg_id = slaves[default_slave];
742 if (new_agg_id != port->aggregator_port_id) {
743 port->aggregator_port_id = new_agg_id;
745 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
746 "\t%s aggregator ID=%3u\n",
747 port->aggregator_port_id,
748 port->aggregator_port_id == slave_id ?
749 "aggregator not found, using default" : "aggregator found",
750 port->aggregator_port_id);
753 port->selected = SELECTED;
756 /* Function maps DPDK speed to bonding speed stored in key field */
758 link_speed_key(uint16_t speed) {
762 case ETH_SPEED_NUM_NONE:
765 case ETH_SPEED_NUM_10M:
766 key_speed = BOND_LINK_SPEED_KEY_10M;
768 case ETH_SPEED_NUM_100M:
769 key_speed = BOND_LINK_SPEED_KEY_100M;
771 case ETH_SPEED_NUM_1G:
772 key_speed = BOND_LINK_SPEED_KEY_1000M;
774 case ETH_SPEED_NUM_10G:
775 key_speed = BOND_LINK_SPEED_KEY_10G;
777 case ETH_SPEED_NUM_20G:
778 key_speed = BOND_LINK_SPEED_KEY_20G;
780 case ETH_SPEED_NUM_40G:
781 key_speed = BOND_LINK_SPEED_KEY_40G;
792 rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id,
793 struct rte_mbuf *lacp_pkt) {
794 struct lacpdu_header *lacp;
795 struct lacpdu_actor_partner_params *partner;
797 if (lacp_pkt != NULL) {
798 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
799 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
801 partner = &lacp->lacpdu.partner;
802 if (rte_is_same_ether_addr(&partner->port_params.system,
803 &internals->mode4.mac_addr)) {
804 /* This LACP frame is sending to the bonding port
805 * so pass it to rx_machine.
807 rx_machine(internals, slave_id, &lacp->lacpdu);
809 rte_pktmbuf_free(lacp_pkt);
811 rx_machine(internals, slave_id, NULL);
815 bond_mode_8023ad_periodic_cb(void *arg)
817 struct rte_eth_dev *bond_dev = arg;
818 struct bond_dev_private *internals = bond_dev->data->dev_private;
820 struct rte_eth_link link_info;
821 struct rte_ether_addr slave_addr;
822 struct rte_mbuf *lacp_pkt = NULL;
827 /* Update link status on each port */
828 for (i = 0; i < internals->active_slave_count; i++) {
832 slave_id = internals->active_slaves[i];
833 ret = rte_eth_link_get_nowait(slave_id, &link_info);
836 "Slave (port %u) link get failed: %s\n",
837 slave_id, rte_strerror(-ret));
840 if (ret >= 0 && link_info.link_status != 0) {
841 key = link_speed_key(link_info.link_speed) << 1;
842 if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
843 key |= BOND_LINK_FULL_DUPLEX_KEY;
848 rte_eth_macaddr_get(slave_id, &slave_addr);
849 port = &bond_mode_8023ad_ports[slave_id];
851 key = rte_cpu_to_be_16(key);
852 if (key != port->actor.key) {
853 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
854 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
856 port->actor.key = key;
857 SM_FLAG_SET(port, NTT);
860 if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
861 rte_ether_addr_copy(&slave_addr, &port->actor.system);
862 if (port->aggregator_port_id == slave_id)
863 SM_FLAG_SET(port, NTT);
867 for (i = 0; i < internals->active_slave_count; i++) {
868 slave_id = internals->active_slaves[i];
869 port = &bond_mode_8023ad_ports[slave_id];
871 if ((port->actor.key &
872 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
874 SM_FLAG_SET(port, BEGIN);
876 /* LACP is disabled on half duples or link is down */
877 if (SM_FLAG(port, LACP_ENABLED)) {
878 /* If port was enabled set it to BEGIN state */
879 SM_FLAG_CLR(port, LACP_ENABLED);
880 ACTOR_STATE_CLR(port, DISTRIBUTING);
881 ACTOR_STATE_CLR(port, COLLECTING);
884 /* Skip this port processing */
888 SM_FLAG_SET(port, LACP_ENABLED);
890 if (internals->mode4.dedicated_queues.enabled == 0) {
891 /* Find LACP packet to this port. Do not check subtype,
892 * it is done in function that queued packet
894 int retval = rte_ring_dequeue(port->rx_ring,
900 rx_machine_update(internals, slave_id, lacp_pkt);
902 uint16_t rx_count = rte_eth_rx_burst(slave_id,
903 internals->mode4.dedicated_queues.rx_qid,
907 bond_mode_8023ad_handle_slow_pkt(internals,
910 rx_machine_update(internals, slave_id, NULL);
913 periodic_machine(internals, slave_id);
914 mux_machine(internals, slave_id);
915 tx_machine(internals, slave_id);
916 selection_logic(internals, slave_id);
918 SM_FLAG_CLR(port, BEGIN);
919 show_warnings(slave_id);
922 rte_eal_alarm_set(internals->mode4.update_timeout_us,
923 bond_mode_8023ad_periodic_cb, arg);
927 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
931 ret = rte_eth_allmulticast_enable(slave_id);
934 "failed to enable allmulti mode for port %u: %s",
935 slave_id, rte_strerror(-ret));
937 if (rte_eth_allmulticast_get(slave_id)) {
938 RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
940 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
941 BOND_8023AD_FORCED_ALLMULTI;
945 ret = rte_eth_promiscuous_enable(slave_id);
948 "failed to enable promiscuous mode for port %u: %s",
949 slave_id, rte_strerror(-ret));
951 if (rte_eth_promiscuous_get(slave_id)) {
952 RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
954 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
955 BOND_8023AD_FORCED_PROMISC;
963 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
967 switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
968 case BOND_8023AD_FORCED_ALLMULTI:
969 RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
970 ret = rte_eth_allmulticast_disable(slave_id);
973 "failed to disable allmulti mode for port %u: %s",
974 slave_id, rte_strerror(-ret));
977 case BOND_8023AD_FORCED_PROMISC:
978 RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
979 ret = rte_eth_promiscuous_disable(slave_id);
982 "failed to disable promiscuous mode for port %u: %s",
983 slave_id, rte_strerror(-ret));
992 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
995 struct bond_dev_private *internals = bond_dev->data->dev_private;
997 struct port *port = &bond_mode_8023ad_ports[slave_id];
998 struct port_params initial = {
1000 .system_priority = rte_cpu_to_be_16(0xFFFF),
1001 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1002 .port_priority = rte_cpu_to_be_16(0x00FF),
1006 char mem_name[RTE_ETH_NAME_MAX_LEN];
1008 unsigned element_size;
1009 uint32_t total_tx_desc;
1010 struct bond_tx_queue *bd_tx_q;
1013 /* Given slave mus not be in active list */
1014 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1015 internals->active_slave_count, slave_id) == internals->active_slave_count);
1016 RTE_SET_USED(internals); /* used only for assert when enabled */
1018 memcpy(&port->actor, &initial, sizeof(struct port_params));
1019 /* Standard requires that port ID must be grater than 0.
1020 * Add 1 do get corresponding port_number */
1021 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1023 memcpy(&port->partner, &initial, sizeof(struct port_params));
1025 /* default states */
1026 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1027 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1028 port->sm_flags = SM_FLAGS_BEGIN;
1030 /* use this port as agregator */
1031 port->aggregator_port_id = slave_id;
1033 if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1034 RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1038 timer_cancel(&port->warning_timer);
1040 if (port->mbuf_pool != NULL)
1043 RTE_ASSERT(port->rx_ring == NULL);
1044 RTE_ASSERT(port->tx_ring == NULL);
1046 socket_id = rte_eth_dev_socket_id(slave_id);
1047 if (socket_id == (int)LCORE_ID_ANY)
1048 socket_id = rte_socket_id();
1050 element_size = sizeof(struct slow_protocol_frame) +
1051 RTE_PKTMBUF_HEADROOM;
1053 /* The size of the mempool should be at least:
1054 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1055 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1056 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1057 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1058 total_tx_desc += bd_tx_q->nb_tx_desc;
1061 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1062 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1063 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1064 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1065 0, element_size, socket_id);
1067 /* Any memory allocation failure in initialization is critical because
1068 * resources can't be free, so reinitialization is impossible. */
1069 if (port->mbuf_pool == NULL) {
1070 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1071 slave_id, mem_name, rte_strerror(rte_errno));
1074 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1075 port->rx_ring = rte_ring_create(mem_name,
1076 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1078 if (port->rx_ring == NULL) {
1079 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1080 mem_name, rte_strerror(rte_errno));
1083 /* TX ring is at least one pkt longer to make room for marker packet. */
1084 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1085 port->tx_ring = rte_ring_create(mem_name,
1086 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1088 if (port->tx_ring == NULL) {
1089 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1090 mem_name, rte_strerror(rte_errno));
1095 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1099 struct port *port = NULL;
1100 uint8_t old_partner_state;
1102 port = &bond_mode_8023ad_ports[slave_id];
1104 ACTOR_STATE_CLR(port, AGGREGATION);
1105 port->selected = UNSELECTED;
1107 old_partner_state = port->partner_state;
1108 record_default(port);
1110 bond_mode_8023ad_unregister_lacp_mac(slave_id);
1112 /* If partner timeout state changes then disable timer */
1113 if (!((old_partner_state ^ port->partner_state) &
1114 STATE_LACP_SHORT_TIMEOUT))
1115 timer_cancel(&port->current_while_timer);
1117 PARTNER_STATE_CLR(port, AGGREGATION);
1118 ACTOR_STATE_CLR(port, EXPIRED);
1120 /* flush rx/tx rings */
1121 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1122 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1124 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1125 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1130 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1132 struct bond_dev_private *internals = bond_dev->data->dev_private;
1133 struct rte_ether_addr slave_addr;
1134 struct port *slave, *agg_slave;
1135 uint16_t slave_id, i, j;
1137 bond_mode_8023ad_stop(bond_dev);
1139 for (i = 0; i < internals->active_slave_count; i++) {
1140 slave_id = internals->active_slaves[i];
1141 slave = &bond_mode_8023ad_ports[slave_id];
1142 rte_eth_macaddr_get(slave_id, &slave_addr);
1144 if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1147 rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1148 /* Do nothing if this port is not an aggregator. In other case
1149 * Set NTT flag on every port that use this aggregator. */
1150 if (slave->aggregator_port_id != slave_id)
1153 for (j = 0; j < internals->active_slave_count; j++) {
1154 agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1155 if (agg_slave->aggregator_port_id == slave_id)
1156 SM_FLAG_SET(agg_slave, NTT);
1160 if (bond_dev->data->dev_started)
1161 bond_mode_8023ad_start(bond_dev);
1165 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1166 struct rte_eth_bond_8023ad_conf *conf)
1168 struct bond_dev_private *internals = dev->data->dev_private;
1169 struct mode8023ad_private *mode4 = &internals->mode4;
1170 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1172 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1173 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1174 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1175 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1176 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1177 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1178 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1179 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1180 conf->slowrx_cb = mode4->slowrx_cb;
1181 conf->agg_selection = mode4->agg_selection;
1185 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1187 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1188 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1189 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1190 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1191 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1192 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1193 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1194 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1195 conf->slowrx_cb = NULL;
1196 conf->agg_selection = AGG_STABLE;
1200 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1201 struct rte_eth_bond_8023ad_conf *conf)
1203 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1205 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1206 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1207 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1208 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1209 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1210 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1211 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1212 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1214 mode4->dedicated_queues.enabled = 0;
1215 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1216 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1220 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1221 struct rte_eth_bond_8023ad_conf *conf)
1223 struct rte_eth_bond_8023ad_conf def_conf;
1224 struct bond_dev_private *internals = dev->data->dev_private;
1225 struct mode8023ad_private *mode4 = &internals->mode4;
1229 bond_mode_8023ad_conf_get_default(conf);
1232 bond_mode_8023ad_stop(dev);
1233 bond_mode_8023ad_conf_assign(mode4, conf);
1234 mode4->slowrx_cb = conf->slowrx_cb;
1235 mode4->agg_selection = AGG_STABLE;
1237 if (dev->data->dev_started)
1238 bond_mode_8023ad_start(dev);
1242 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1244 struct bond_dev_private *internals = bond_dev->data->dev_private;
1247 for (i = 0; i < internals->active_slave_count; i++)
1248 bond_mode_8023ad_activate_slave(bond_dev,
1249 internals->active_slaves[i]);
1255 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1257 struct bond_dev_private *internals = bond_dev->data->dev_private;
1258 struct mode8023ad_private *mode4 = &internals->mode4;
1259 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1261 rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1262 if (mode4->slowrx_cb)
1263 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1266 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1270 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1272 struct bond_dev_private *internals = bond_dev->data->dev_private;
1273 struct mode8023ad_private *mode4 = &internals->mode4;
1275 if (mode4->slowrx_cb) {
1276 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1280 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1284 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1285 uint16_t slave_id, struct rte_mbuf *pkt)
1287 struct mode8023ad_private *mode4 = &internals->mode4;
1288 struct port *port = &bond_mode_8023ad_ports[slave_id];
1289 struct marker_header *m_hdr;
1290 uint64_t marker_timer, old_marker_timer;
1292 uint8_t wrn, subtype;
1293 /* If packet is a marker, we send response now by reusing given packet
1294 * and update only source MAC, destination MAC is multicast so don't
1295 * update it. Other frames will be handled later by state machines */
1296 subtype = rte_pktmbuf_mtod(pkt,
1297 struct slow_protocol_frame *)->slow_protocol.subtype;
1299 if (subtype == SLOW_SUBTYPE_MARKER) {
1300 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1302 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1303 wrn = WRN_UNKNOWN_MARKER_TYPE;
1307 /* Setup marker timer. Do it in loop in case concurrent access. */
1309 old_marker_timer = port->rx_marker_timer;
1310 if (!timer_is_expired(&old_marker_timer)) {
1311 wrn = WRN_RX_MARKER_TO_FAST;
1315 timer_set(&marker_timer, mode4->rx_marker_timeout);
1316 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1317 old_marker_timer, marker_timer);
1318 } while (unlikely(retval == 0));
1320 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1321 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1323 if (internals->mode4.dedicated_queues.enabled == 0) {
1324 int retval = rte_ring_enqueue(port->tx_ring, pkt);
1327 port->rx_marker_timer = 0;
1328 wrn = WRN_TX_QUEUE_FULL;
1332 /* Send packet directly to the slow queue */
1333 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1334 internals->mode4.dedicated_queues.tx_qid,
1336 if (tx_count != 1) {
1338 port->rx_marker_timer = 0;
1339 wrn = WRN_TX_QUEUE_FULL;
1343 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1344 if (internals->mode4.dedicated_queues.enabled == 0) {
1345 int retval = rte_ring_enqueue(port->rx_ring, pkt);
1347 /* If RX fing full free lacpdu message and drop packet */
1348 wrn = WRN_RX_QUEUE_FULL;
1352 rx_machine_update(internals, slave_id, pkt);
1354 wrn = WRN_UNKNOWN_SLOW_TYPE;
1361 set_warning_flags(port, wrn);
1362 rte_pktmbuf_free(pkt);
1366 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1367 struct rte_eth_bond_8023ad_conf *conf)
1369 struct rte_eth_dev *bond_dev;
1371 if (valid_bonded_port_id(port_id) != 0)
1377 bond_dev = &rte_eth_devices[port_id];
1378 bond_mode_8023ad_conf_get(bond_dev, conf);
1383 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1384 enum rte_bond_8023ad_agg_selection agg_selection)
1386 struct rte_eth_dev *bond_dev;
1387 struct bond_dev_private *internals;
1388 struct mode8023ad_private *mode4;
1390 bond_dev = &rte_eth_devices[port_id];
1391 internals = bond_dev->data->dev_private;
1393 if (valid_bonded_port_id(port_id) != 0)
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 bond_dev = &rte_eth_devices[port_id];
1412 internals = bond_dev->data->dev_private;
1414 if (valid_bonded_port_id(port_id) != 0)
1416 if (internals->mode != 4)
1418 mode4 = &internals->mode4;
1420 return mode4->agg_selection;
1426 bond_8023ad_setup_validate(uint16_t port_id,
1427 struct rte_eth_bond_8023ad_conf *conf)
1429 if (valid_bonded_port_id(port_id) != 0)
1433 /* Basic sanity check */
1434 if (conf->slow_periodic_ms == 0 ||
1435 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1436 conf->long_timeout_ms == 0 ||
1437 conf->short_timeout_ms >= conf->long_timeout_ms ||
1438 conf->aggregate_wait_timeout_ms == 0 ||
1439 conf->tx_period_ms == 0 ||
1440 conf->rx_marker_period_ms == 0 ||
1441 conf->update_timeout_ms == 0) {
1442 RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1452 rte_eth_bond_8023ad_setup(uint16_t port_id,
1453 struct rte_eth_bond_8023ad_conf *conf)
1455 struct rte_eth_dev *bond_dev;
1458 err = bond_8023ad_setup_validate(port_id, conf);
1462 bond_dev = &rte_eth_devices[port_id];
1463 bond_mode_8023ad_setup(bond_dev, conf);
1473 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1474 struct rte_eth_bond_8023ad_slave_info *info)
1476 struct rte_eth_dev *bond_dev;
1477 struct bond_dev_private *internals;
1480 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1481 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1484 bond_dev = &rte_eth_devices[port_id];
1486 internals = bond_dev->data->dev_private;
1487 if (find_slave_by_id(internals->active_slaves,
1488 internals->active_slave_count, slave_id) ==
1489 internals->active_slave_count)
1492 port = &bond_mode_8023ad_ports[slave_id];
1493 info->selected = port->selected;
1495 info->actor_state = port->actor_state;
1496 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1498 info->partner_state = port->partner_state;
1499 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1501 info->agg_port_id = port->aggregator_port_id;
1506 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1508 struct rte_eth_dev *bond_dev;
1509 struct bond_dev_private *internals;
1510 struct mode8023ad_private *mode4;
1512 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1515 bond_dev = &rte_eth_devices[port_id];
1517 if (!bond_dev->data->dev_started)
1520 internals = bond_dev->data->dev_private;
1521 if (find_slave_by_id(internals->active_slaves,
1522 internals->active_slave_count, slave_id) ==
1523 internals->active_slave_count)
1526 mode4 = &internals->mode4;
1527 if (mode4->slowrx_cb == NULL)
1534 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1540 res = bond_8023ad_ext_validate(port_id, slave_id);
1544 port = &bond_mode_8023ad_ports[slave_id];
1547 ACTOR_STATE_SET(port, COLLECTING);
1549 ACTOR_STATE_CLR(port, COLLECTING);
1555 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1561 res = bond_8023ad_ext_validate(port_id, slave_id);
1565 port = &bond_mode_8023ad_ports[slave_id];
1568 ACTOR_STATE_SET(port, DISTRIBUTING);
1570 ACTOR_STATE_CLR(port, DISTRIBUTING);
1576 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1581 err = bond_8023ad_ext_validate(port_id, slave_id);
1585 port = &bond_mode_8023ad_ports[slave_id];
1586 return ACTOR_STATE(port, DISTRIBUTING);
1590 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1595 err = bond_8023ad_ext_validate(port_id, slave_id);
1599 port = &bond_mode_8023ad_ports[slave_id];
1600 return ACTOR_STATE(port, COLLECTING);
1604 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1605 struct rte_mbuf *lacp_pkt)
1610 res = bond_8023ad_ext_validate(port_id, slave_id);
1614 port = &bond_mode_8023ad_ports[slave_id];
1616 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1619 struct lacpdu_header *lacp;
1621 /* only enqueue LACPDUs */
1622 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1623 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1626 MODE4_DEBUG("sending LACP frame\n");
1628 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1632 bond_mode_8023ad_ext_periodic_cb(void *arg)
1634 struct rte_eth_dev *bond_dev = arg;
1635 struct bond_dev_private *internals = bond_dev->data->dev_private;
1636 struct mode8023ad_private *mode4 = &internals->mode4;
1639 uint16_t i, slave_id;
1641 for (i = 0; i < internals->active_slave_count; i++) {
1642 slave_id = internals->active_slaves[i];
1643 port = &bond_mode_8023ad_ports[slave_id];
1645 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1646 struct rte_mbuf *lacp_pkt = pkt;
1647 struct lacpdu_header *lacp;
1649 lacp = rte_pktmbuf_mtod(lacp_pkt,
1650 struct lacpdu_header *);
1651 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1653 /* This is LACP frame so pass it to rx callback.
1654 * Callback is responsible for freeing mbuf.
1656 mode4->slowrx_cb(slave_id, lacp_pkt);
1660 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1661 bond_mode_8023ad_ext_periodic_cb, arg);
1665 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1668 struct rte_eth_dev *dev = &rte_eth_devices[port];
1669 struct bond_dev_private *internals = (struct bond_dev_private *)
1670 dev->data->dev_private;
1672 if (check_for_bonded_ethdev(dev) != 0)
1675 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1678 /* Device must be stopped to set up slow queue */
1679 if (dev->data->dev_started)
1682 internals->mode4.dedicated_queues.enabled = 1;
1684 bond_ethdev_mode_set(dev, internals->mode);
1689 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1692 struct rte_eth_dev *dev = &rte_eth_devices[port];
1693 struct bond_dev_private *internals = (struct bond_dev_private *)
1694 dev->data->dev_private;
1696 if (check_for_bonded_ethdev(dev) != 0)
1699 /* Device must be stopped to set up slow queue */
1700 if (dev->data->dev_started)
1703 internals->mode4.dedicated_queues.enabled = 0;
1705 bond_ethdev_mode_set(dev, internals->mode);