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), RTE_ETHER_ADDR_PRT_FMT,
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), RTE_ETHER_ADDR_PRT_FMT,
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 SM_FLAG_CLR(port, EXPIRED);
360 return; /* No state change */
363 /* If CURRENT state timer is not running (stopped or expired)
364 * transit to EXPIRED state from DISABLED or CURRENT */
365 if (!timer_is_running(&port->current_while_timer)) {
366 if (SM_FLAG(port, EXPIRED)) {
367 port->selected = UNSELECTED;
368 memcpy(&port->partner, &port->partner_admin,
369 sizeof(struct port_params));
370 record_default(port);
371 ACTOR_STATE_CLR(port, EXPIRED);
372 timer_cancel(&port->current_while_timer);
374 SM_FLAG_SET(port, EXPIRED);
375 ACTOR_STATE_SET(port, EXPIRED);
376 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
377 PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
378 timer_set(&port->current_while_timer,
379 internals->mode4.short_timeout);
385 * Function handles periodic tx state machine.
387 * Function implements Periodic Transmission state machine from point 5.4.13
388 * in 802.1AX documentation. It should be called periodically.
390 * @param port Port to handle state machine.
393 periodic_machine(struct bond_dev_private *internals, uint16_t slave_id)
395 struct port *port = &bond_mode_8023ad_ports[slave_id];
396 /* Calculate if either site is LACP enabled */
398 uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
399 PARTNER_STATE(port, LACP_ACTIVE);
401 uint8_t is_partner_fast, was_partner_fast;
402 /* No periodic is on BEGIN, LACP DISABLE or when both sides are pasive */
403 if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
404 timer_cancel(&port->periodic_timer);
405 timer_force_expired(&port->tx_machine_timer);
406 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
408 MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
409 SM_FLAG(port, BEGIN) ? "begind " : "",
410 SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
411 active ? "LACP active " : "LACP pasive ");
415 is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
416 was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
418 /* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
419 * Other case: check if timer expire or partners settings changed. */
420 if (!timer_is_stopped(&port->periodic_timer)) {
421 if (timer_is_expired(&port->periodic_timer)) {
422 SM_FLAG_SET(port, NTT);
423 } else if (is_partner_fast != was_partner_fast) {
424 /* Partners timeout was slow and now it is fast -> send LACP.
425 * In other case (was fast and now it is slow) just switch
426 * timeout to slow without forcing send of LACP (because standard
429 SM_FLAG_SET(port, NTT);
431 return; /* Nothing changed */
434 /* Handle state transition to FAST/SLOW LACP timeout */
435 if (is_partner_fast) {
436 timeout = internals->mode4.fast_periodic_timeout;
437 SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
439 timeout = internals->mode4.slow_periodic_timeout;
440 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
443 timer_set(&port->periodic_timer, timeout);
447 * Function handles mux state machine.
449 * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
450 * It should be called periodically.
452 * @param port Port to handle state machine.
455 mux_machine(struct bond_dev_private *internals, uint16_t slave_id)
457 struct port *port = &bond_mode_8023ad_ports[slave_id];
459 /* Save current state for later use */
460 const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
463 /* Enter DETACHED state on BEGIN condition or from any other state if
464 * port was unselected */
465 if (SM_FLAG(port, BEGIN) ||
466 port->selected == UNSELECTED || (port->selected == STANDBY &&
467 (port->actor_state & state_mask) != 0)) {
468 /* detach mux from aggregator */
469 port->actor_state &= ~state_mask;
470 /* Set ntt to true if BEGIN condition or transition from any other state
471 * which is indicated that wait_while_timer was started */
472 if (SM_FLAG(port, BEGIN) ||
473 !timer_is_stopped(&port->wait_while_timer)) {
474 SM_FLAG_SET(port, NTT);
475 MODE4_DEBUG("-> DETACHED\n");
477 timer_cancel(&port->wait_while_timer);
480 if (timer_is_stopped(&port->wait_while_timer)) {
481 if (port->selected == SELECTED || port->selected == STANDBY) {
482 timer_set(&port->wait_while_timer,
483 internals->mode4.aggregate_wait_timeout);
485 MODE4_DEBUG("DETACHED -> WAITING\n");
487 /* Waiting state entered */
491 /* Transit next state if port is ready */
492 if (!timer_is_expired(&port->wait_while_timer))
495 if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
496 !PARTNER_STATE(port, SYNCHRONIZATION)) {
497 /* If in COLLECTING or DISTRIBUTING state and partner becomes out of
498 * sync transit to ATACHED state. */
499 ACTOR_STATE_CLR(port, DISTRIBUTING);
500 ACTOR_STATE_CLR(port, COLLECTING);
501 /* Clear actor sync to activate transit ATACHED in condition bellow */
502 ACTOR_STATE_CLR(port, SYNCHRONIZATION);
503 MODE4_DEBUG("Out of sync -> ATTACHED\n");
506 if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
507 /* attach mux to aggregator */
508 RTE_ASSERT((port->actor_state & (STATE_COLLECTING |
509 STATE_DISTRIBUTING)) == 0);
511 ACTOR_STATE_SET(port, SYNCHRONIZATION);
512 SM_FLAG_SET(port, NTT);
513 MODE4_DEBUG("ATTACHED Entered\n");
514 } else if (!ACTOR_STATE(port, COLLECTING)) {
515 /* Start collecting if in sync */
516 if (PARTNER_STATE(port, SYNCHRONIZATION)) {
517 MODE4_DEBUG("ATTACHED -> COLLECTING\n");
518 ACTOR_STATE_SET(port, COLLECTING);
519 SM_FLAG_SET(port, NTT);
521 } else if (ACTOR_STATE(port, COLLECTING)) {
522 /* Check if partner is in COLLECTING state. If so this port can
523 * distribute frames to it */
524 if (!ACTOR_STATE(port, DISTRIBUTING)) {
525 if (PARTNER_STATE(port, COLLECTING)) {
526 /* Enable DISTRIBUTING if partner is collecting */
527 ACTOR_STATE_SET(port, DISTRIBUTING);
528 SM_FLAG_SET(port, NTT);
529 MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
531 "Bond %u: slave id %u distributing started.",
532 internals->port_id, slave_id);
535 if (!PARTNER_STATE(port, COLLECTING)) {
536 /* Disable DISTRIBUTING (enter COLLECTING state) if partner
537 * is not collecting */
538 ACTOR_STATE_CLR(port, DISTRIBUTING);
539 SM_FLAG_SET(port, NTT);
540 MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
542 "Bond %u: slave id %u distributing stopped.",
543 internals->port_id, slave_id);
550 * Function handles transmit state machine.
552 * Function implements Transmit Machine from point 5.4.16 in 802.1AX
558 tx_machine(struct bond_dev_private *internals, uint16_t slave_id)
560 struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
562 struct rte_mbuf *lacp_pkt = NULL;
563 struct lacpdu_header *hdr;
564 struct lacpdu *lacpdu;
566 /* If periodic timer is not running periodic machine is in NO PERIODIC and
567 * according to 802.3ax standard tx machine should not transmit any frames
568 * and set ntt to false. */
569 if (timer_is_stopped(&port->periodic_timer))
570 SM_FLAG_CLR(port, NTT);
572 if (!SM_FLAG(port, NTT))
575 if (!timer_is_expired(&port->tx_machine_timer))
578 lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
579 if (lacp_pkt == NULL) {
580 RTE_BOND_LOG(ERR, "Failed to allocate LACP packet from pool");
584 lacp_pkt->data_len = sizeof(*hdr);
585 lacp_pkt->pkt_len = sizeof(*hdr);
587 hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
589 /* Source and destination MAC */
590 rte_ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.dst_addr);
591 rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.src_addr);
592 hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW);
594 lacpdu = &hdr->lacpdu;
595 memset(lacpdu, 0, sizeof(*lacpdu));
597 /* Initialize LACP part */
598 lacpdu->subtype = SLOW_SUBTYPE_LACP;
599 lacpdu->version_number = 1;
602 lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
603 lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
604 memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
605 sizeof(port->actor));
606 agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
607 rte_ether_addr_copy(&agg->actor.system,
608 &hdr->lacpdu.actor.port_params.system);
609 lacpdu->actor.state = port->actor_state;
612 lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
613 lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
614 memcpy(&lacpdu->partner.port_params, &port->partner,
615 sizeof(struct port_params));
616 lacpdu->partner.state = port->partner_state;
619 lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
620 lacpdu->collector_info_length = 0x10;
621 lacpdu->collector_max_delay = 0;
623 lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
624 lacpdu->terminator_length = 0;
626 MODE4_DEBUG("Sending LACP frame\n");
627 BOND_PRINT_LACP(lacpdu);
629 if (internals->mode4.dedicated_queues.enabled == 0) {
630 int retval = rte_ring_enqueue(port->tx_ring, lacp_pkt);
632 /* If TX ring full, drop packet and free message.
633 Retransmission will happen in next function call. */
634 rte_pktmbuf_free(lacp_pkt);
635 set_warning_flags(port, WRN_TX_QUEUE_FULL);
639 uint16_t pkts_sent = rte_eth_tx_burst(slave_id,
640 internals->mode4.dedicated_queues.tx_qid,
642 if (pkts_sent != 1) {
643 rte_pktmbuf_free(lacp_pkt);
644 set_warning_flags(port, WRN_TX_QUEUE_FULL);
650 timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
651 SM_FLAG_CLR(port, NTT);
655 max_index(uint64_t *a, int n)
663 for (i = 1; i < n; ++i) {
674 * Function assigns port to aggregator.
676 * @param bond_dev_private Pointer to bond_dev_private structure.
677 * @param port_pos Port to assign.
680 selection_logic(struct bond_dev_private *internals, uint16_t slave_id)
682 struct port *agg, *port;
683 uint16_t slaves_count, new_agg_id, i, j = 0;
685 uint64_t agg_bandwidth[RTE_MAX_ETHPORTS] = {0};
686 uint64_t agg_count[RTE_MAX_ETHPORTS] = {0};
687 uint16_t default_slave = 0;
688 struct rte_eth_link link_info;
689 uint16_t agg_new_idx = 0;
692 slaves = internals->active_slaves;
693 slaves_count = internals->active_slave_count;
694 port = &bond_mode_8023ad_ports[slave_id];
696 /* Search for aggregator suitable for this port */
697 for (i = 0; i < slaves_count; ++i) {
698 agg = &bond_mode_8023ad_ports[slaves[i]];
699 /* Skip ports that are not aggreagators */
700 if (agg->aggregator_port_id != slaves[i])
703 ret = rte_eth_link_get_nowait(slaves[i], &link_info);
706 "Slave (port %u) link get failed: %s\n",
707 slaves[i], rte_strerror(-ret));
711 agg_bandwidth[i] += link_info.link_speed;
713 /* Actors system ID is not checked since all slave device have the same
714 * ID (MAC address). */
715 if ((agg->actor.key == port->actor.key &&
716 agg->partner.system_priority == port->partner.system_priority &&
717 rte_is_same_ether_addr(&agg->partner.system,
718 &port->partner.system) == 1
719 && (agg->partner.key == port->partner.key)) &&
720 rte_is_zero_ether_addr(&port->partner.system) != 1 &&
722 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
730 switch (internals->mode4.agg_selection) {
732 agg_new_idx = max_index(agg_count, slaves_count);
733 new_agg_id = slaves[agg_new_idx];
736 agg_new_idx = max_index(agg_bandwidth, slaves_count);
737 new_agg_id = slaves[agg_new_idx];
740 if (default_slave == slaves_count)
741 new_agg_id = slaves[slave_id];
743 new_agg_id = slaves[default_slave];
746 if (default_slave == slaves_count)
747 new_agg_id = slaves[slave_id];
749 new_agg_id = slaves[default_slave];
753 if (new_agg_id != port->aggregator_port_id) {
754 port->aggregator_port_id = new_agg_id;
756 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
757 "\t%s aggregator ID=%3u\n",
758 port->aggregator_port_id,
759 port->aggregator_port_id == slave_id ?
760 "aggregator not found, using default" : "aggregator found",
761 port->aggregator_port_id);
764 port->selected = SELECTED;
767 /* Function maps DPDK speed to bonding speed stored in key field */
769 link_speed_key(uint16_t speed) {
773 case ETH_SPEED_NUM_NONE:
776 case ETH_SPEED_NUM_10M:
777 key_speed = BOND_LINK_SPEED_KEY_10M;
779 case ETH_SPEED_NUM_100M:
780 key_speed = BOND_LINK_SPEED_KEY_100M;
782 case ETH_SPEED_NUM_1G:
783 key_speed = BOND_LINK_SPEED_KEY_1000M;
785 case ETH_SPEED_NUM_10G:
786 key_speed = BOND_LINK_SPEED_KEY_10G;
788 case ETH_SPEED_NUM_20G:
789 key_speed = BOND_LINK_SPEED_KEY_20G;
791 case ETH_SPEED_NUM_40G:
792 key_speed = BOND_LINK_SPEED_KEY_40G;
803 rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id,
804 struct rte_mbuf *lacp_pkt) {
805 struct lacpdu_header *lacp;
806 struct lacpdu_actor_partner_params *partner;
807 struct port *port, *agg;
809 if (lacp_pkt != NULL) {
810 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
811 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
813 partner = &lacp->lacpdu.partner;
814 port = &bond_mode_8023ad_ports[slave_id];
815 agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
817 if (rte_is_zero_ether_addr(&partner->port_params.system) ||
818 rte_is_same_ether_addr(&partner->port_params.system,
819 &agg->actor.system)) {
820 /* This LACP frame is sending to the bonding port
821 * so pass it to rx_machine.
823 rx_machine(internals, slave_id, &lacp->lacpdu);
825 char preferred_system_name[RTE_ETHER_ADDR_FMT_SIZE];
826 char self_system_name[RTE_ETHER_ADDR_FMT_SIZE];
828 rte_ether_format_addr(preferred_system_name,
829 RTE_ETHER_ADDR_FMT_SIZE, &partner->port_params.system);
830 rte_ether_format_addr(self_system_name,
831 RTE_ETHER_ADDR_FMT_SIZE, &agg->actor.system);
832 MODE4_DEBUG("preferred partner system %s "
833 "is not equal with self system: %s\n",
834 preferred_system_name, self_system_name);
836 rte_pktmbuf_free(lacp_pkt);
838 rx_machine(internals, slave_id, NULL);
842 bond_mode_8023ad_dedicated_rxq_process(struct bond_dev_private *internals,
845 #define DEDICATED_QUEUE_BURST_SIZE 32
846 struct rte_mbuf *lacp_pkt[DEDICATED_QUEUE_BURST_SIZE];
847 uint16_t rx_count = rte_eth_rx_burst(slave_id,
848 internals->mode4.dedicated_queues.rx_qid,
849 lacp_pkt, DEDICATED_QUEUE_BURST_SIZE);
854 for (i = 0; i < rx_count; i++)
855 bond_mode_8023ad_handle_slow_pkt(internals, slave_id,
858 rx_machine_update(internals, slave_id, NULL);
863 bond_mode_8023ad_periodic_cb(void *arg)
865 struct rte_eth_dev *bond_dev = arg;
866 struct bond_dev_private *internals = bond_dev->data->dev_private;
868 struct rte_eth_link link_info;
869 struct rte_ether_addr slave_addr;
870 struct rte_mbuf *lacp_pkt = NULL;
875 /* Update link status on each port */
876 for (i = 0; i < internals->active_slave_count; i++) {
880 slave_id = internals->active_slaves[i];
881 ret = rte_eth_link_get_nowait(slave_id, &link_info);
884 "Slave (port %u) link get failed: %s\n",
885 slave_id, rte_strerror(-ret));
888 if (ret >= 0 && link_info.link_status != 0) {
889 key = link_speed_key(link_info.link_speed) << 1;
890 if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
891 key |= BOND_LINK_FULL_DUPLEX_KEY;
896 rte_eth_macaddr_get(slave_id, &slave_addr);
897 port = &bond_mode_8023ad_ports[slave_id];
899 key = rte_cpu_to_be_16(key);
900 if (key != port->actor.key) {
901 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
902 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
904 port->actor.key = key;
905 SM_FLAG_SET(port, NTT);
908 if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
909 rte_ether_addr_copy(&slave_addr, &port->actor.system);
910 if (port->aggregator_port_id == slave_id)
911 SM_FLAG_SET(port, NTT);
915 for (i = 0; i < internals->active_slave_count; i++) {
916 slave_id = internals->active_slaves[i];
917 port = &bond_mode_8023ad_ports[slave_id];
919 if ((port->actor.key &
920 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
922 SM_FLAG_SET(port, BEGIN);
924 /* LACP is disabled on half duples or link is down */
925 if (SM_FLAG(port, LACP_ENABLED)) {
926 /* If port was enabled set it to BEGIN state */
927 SM_FLAG_CLR(port, LACP_ENABLED);
928 ACTOR_STATE_CLR(port, DISTRIBUTING);
929 ACTOR_STATE_CLR(port, COLLECTING);
932 /* Skip this port processing */
936 SM_FLAG_SET(port, LACP_ENABLED);
938 if (internals->mode4.dedicated_queues.enabled == 0) {
939 /* Find LACP packet to this port. Do not check subtype,
940 * it is done in function that queued packet
942 int retval = rte_ring_dequeue(port->rx_ring,
948 rx_machine_update(internals, slave_id, lacp_pkt);
950 bond_mode_8023ad_dedicated_rxq_process(internals,
954 periodic_machine(internals, slave_id);
955 mux_machine(internals, slave_id);
956 tx_machine(internals, slave_id);
957 selection_logic(internals, slave_id);
959 SM_FLAG_CLR(port, BEGIN);
960 show_warnings(slave_id);
963 rte_eal_alarm_set(internals->mode4.update_timeout_us,
964 bond_mode_8023ad_periodic_cb, arg);
968 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
972 ret = rte_eth_allmulticast_enable(slave_id);
975 "failed to enable allmulti mode for port %u: %s",
976 slave_id, rte_strerror(-ret));
978 if (rte_eth_allmulticast_get(slave_id)) {
979 RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
981 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
982 BOND_8023AD_FORCED_ALLMULTI;
986 ret = rte_eth_promiscuous_enable(slave_id);
989 "failed to enable promiscuous mode for port %u: %s",
990 slave_id, rte_strerror(-ret));
992 if (rte_eth_promiscuous_get(slave_id)) {
993 RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
995 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
996 BOND_8023AD_FORCED_PROMISC;
1004 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
1008 switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
1009 case BOND_8023AD_FORCED_ALLMULTI:
1010 RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
1011 ret = rte_eth_allmulticast_disable(slave_id);
1014 "failed to disable allmulti mode for port %u: %s",
1015 slave_id, rte_strerror(-ret));
1018 case BOND_8023AD_FORCED_PROMISC:
1019 RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
1020 ret = rte_eth_promiscuous_disable(slave_id);
1023 "failed to disable promiscuous mode for port %u: %s",
1024 slave_id, rte_strerror(-ret));
1033 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
1036 struct bond_dev_private *internals = bond_dev->data->dev_private;
1038 struct port *port = &bond_mode_8023ad_ports[slave_id];
1039 struct port_params initial = {
1040 .system = { { 0 } },
1041 .system_priority = rte_cpu_to_be_16(0xFFFF),
1042 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1043 .port_priority = rte_cpu_to_be_16(0x00FF),
1047 char mem_name[RTE_ETH_NAME_MAX_LEN];
1049 unsigned element_size;
1050 uint32_t total_tx_desc;
1051 struct bond_tx_queue *bd_tx_q;
1054 /* Given slave mus not be in active list */
1055 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1056 internals->active_slave_count, slave_id) == internals->active_slave_count);
1057 RTE_SET_USED(internals); /* used only for assert when enabled */
1059 memcpy(&port->actor, &initial, sizeof(struct port_params));
1060 /* Standard requires that port ID must be grater than 0.
1061 * Add 1 do get corresponding port_number */
1062 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1064 memcpy(&port->partner, &initial, sizeof(struct port_params));
1065 memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
1067 /* default states */
1068 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1069 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1070 port->sm_flags = SM_FLAGS_BEGIN;
1072 /* use this port as agregator */
1073 port->aggregator_port_id = slave_id;
1075 if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1076 RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1080 timer_cancel(&port->warning_timer);
1082 if (port->mbuf_pool != NULL)
1085 RTE_ASSERT(port->rx_ring == NULL);
1086 RTE_ASSERT(port->tx_ring == NULL);
1088 socket_id = rte_eth_dev_socket_id(slave_id);
1089 if (socket_id == -1)
1090 socket_id = rte_socket_id();
1092 element_size = sizeof(struct slow_protocol_frame) +
1093 RTE_PKTMBUF_HEADROOM;
1095 /* The size of the mempool should be at least:
1096 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1097 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1098 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1099 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1100 total_tx_desc += bd_tx_q->nb_tx_desc;
1103 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1104 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1105 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1106 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1107 0, element_size, socket_id);
1109 /* Any memory allocation failure in initialization is critical because
1110 * resources can't be free, so reinitialization is impossible. */
1111 if (port->mbuf_pool == NULL) {
1112 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1113 slave_id, mem_name, rte_strerror(rte_errno));
1116 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1117 port->rx_ring = rte_ring_create(mem_name,
1118 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1120 if (port->rx_ring == NULL) {
1121 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1122 mem_name, rte_strerror(rte_errno));
1125 /* TX ring is at least one pkt longer to make room for marker packet. */
1126 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1127 port->tx_ring = rte_ring_create(mem_name,
1128 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1130 if (port->tx_ring == NULL) {
1131 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1132 mem_name, rte_strerror(rte_errno));
1137 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1141 struct port *port = NULL;
1142 uint8_t old_partner_state;
1144 port = &bond_mode_8023ad_ports[slave_id];
1146 ACTOR_STATE_CLR(port, AGGREGATION);
1147 port->selected = UNSELECTED;
1149 old_partner_state = port->partner_state;
1150 record_default(port);
1152 bond_mode_8023ad_unregister_lacp_mac(slave_id);
1154 /* If partner timeout state changes then disable timer */
1155 if (!((old_partner_state ^ port->partner_state) &
1156 STATE_LACP_SHORT_TIMEOUT))
1157 timer_cancel(&port->current_while_timer);
1159 PARTNER_STATE_CLR(port, AGGREGATION);
1160 ACTOR_STATE_CLR(port, EXPIRED);
1162 /* flush rx/tx rings */
1163 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1164 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1166 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1167 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1172 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1174 struct bond_dev_private *internals = bond_dev->data->dev_private;
1175 struct rte_ether_addr slave_addr;
1176 struct port *slave, *agg_slave;
1177 uint16_t slave_id, i, j;
1179 bond_mode_8023ad_stop(bond_dev);
1181 for (i = 0; i < internals->active_slave_count; i++) {
1182 slave_id = internals->active_slaves[i];
1183 slave = &bond_mode_8023ad_ports[slave_id];
1184 rte_eth_macaddr_get(slave_id, &slave_addr);
1186 if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1189 rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1190 /* Do nothing if this port is not an aggregator. In other case
1191 * Set NTT flag on every port that use this aggregator. */
1192 if (slave->aggregator_port_id != slave_id)
1195 for (j = 0; j < internals->active_slave_count; j++) {
1196 agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1197 if (agg_slave->aggregator_port_id == slave_id)
1198 SM_FLAG_SET(agg_slave, NTT);
1202 if (bond_dev->data->dev_started)
1203 bond_mode_8023ad_start(bond_dev);
1207 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1208 struct rte_eth_bond_8023ad_conf *conf)
1210 struct bond_dev_private *internals = dev->data->dev_private;
1211 struct mode8023ad_private *mode4 = &internals->mode4;
1212 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1214 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1215 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1216 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1217 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1218 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1219 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1220 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1221 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1222 conf->slowrx_cb = mode4->slowrx_cb;
1223 conf->agg_selection = mode4->agg_selection;
1227 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1229 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1230 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1231 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1232 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1233 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1234 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1235 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1236 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1237 conf->slowrx_cb = NULL;
1238 conf->agg_selection = AGG_STABLE;
1242 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1243 struct rte_eth_bond_8023ad_conf *conf)
1245 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1247 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1248 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1249 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1250 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1251 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1252 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1253 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1254 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1256 mode4->dedicated_queues.enabled = 0;
1257 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1258 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1262 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1263 struct rte_eth_bond_8023ad_conf *conf)
1265 struct rte_eth_bond_8023ad_conf def_conf;
1266 struct bond_dev_private *internals = dev->data->dev_private;
1267 struct mode8023ad_private *mode4 = &internals->mode4;
1271 bond_mode_8023ad_conf_get_default(conf);
1274 bond_mode_8023ad_stop(dev);
1275 bond_mode_8023ad_conf_assign(mode4, conf);
1276 mode4->slowrx_cb = conf->slowrx_cb;
1277 mode4->agg_selection = AGG_STABLE;
1279 if (dev->data->dev_started)
1280 bond_mode_8023ad_start(dev);
1284 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1286 struct bond_dev_private *internals = bond_dev->data->dev_private;
1289 for (i = 0; i < internals->active_slave_count; i++)
1290 bond_mode_8023ad_activate_slave(bond_dev,
1291 internals->active_slaves[i]);
1297 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1299 struct bond_dev_private *internals = bond_dev->data->dev_private;
1300 struct mode8023ad_private *mode4 = &internals->mode4;
1301 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1303 rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1304 if (mode4->slowrx_cb)
1305 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1308 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1312 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1314 struct bond_dev_private *internals = bond_dev->data->dev_private;
1315 struct mode8023ad_private *mode4 = &internals->mode4;
1317 if (mode4->slowrx_cb) {
1318 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1322 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1326 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1327 uint16_t slave_id, struct rte_mbuf *pkt)
1329 struct mode8023ad_private *mode4 = &internals->mode4;
1330 struct port *port = &bond_mode_8023ad_ports[slave_id];
1331 struct marker_header *m_hdr;
1332 uint64_t marker_timer, old_marker_timer;
1334 uint8_t wrn, subtype;
1335 /* If packet is a marker, we send response now by reusing given packet
1336 * and update only source MAC, destination MAC is multicast so don't
1337 * update it. Other frames will be handled later by state machines */
1338 subtype = rte_pktmbuf_mtod(pkt,
1339 struct slow_protocol_frame *)->slow_protocol.subtype;
1341 if (subtype == SLOW_SUBTYPE_MARKER) {
1342 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1344 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1345 wrn = WRN_UNKNOWN_MARKER_TYPE;
1349 /* Setup marker timer. Do it in loop in case concurrent access. */
1351 old_marker_timer = port->rx_marker_timer;
1352 if (!timer_is_expired(&old_marker_timer)) {
1353 wrn = WRN_RX_MARKER_TO_FAST;
1357 timer_set(&marker_timer, mode4->rx_marker_timeout);
1358 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1359 old_marker_timer, marker_timer);
1360 } while (unlikely(retval == 0));
1362 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1363 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.src_addr);
1365 if (internals->mode4.dedicated_queues.enabled == 0) {
1366 if (rte_ring_enqueue(port->tx_ring, pkt) != 0) {
1368 port->rx_marker_timer = 0;
1369 wrn = WRN_TX_QUEUE_FULL;
1373 /* Send packet directly to the slow queue */
1374 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1375 internals->mode4.dedicated_queues.tx_qid,
1377 if (tx_count != 1) {
1379 port->rx_marker_timer = 0;
1380 wrn = WRN_TX_QUEUE_FULL;
1384 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1385 if (internals->mode4.dedicated_queues.enabled == 0) {
1386 if (rte_ring_enqueue(port->rx_ring, pkt) != 0) {
1387 /* If RX fing full free lacpdu message and drop packet */
1388 wrn = WRN_RX_QUEUE_FULL;
1392 rx_machine_update(internals, slave_id, pkt);
1394 wrn = WRN_UNKNOWN_SLOW_TYPE;
1401 set_warning_flags(port, wrn);
1402 rte_pktmbuf_free(pkt);
1406 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1407 struct rte_eth_bond_8023ad_conf *conf)
1409 struct rte_eth_dev *bond_dev;
1411 if (valid_bonded_port_id(port_id) != 0)
1417 bond_dev = &rte_eth_devices[port_id];
1418 bond_mode_8023ad_conf_get(bond_dev, conf);
1423 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1424 enum rte_bond_8023ad_agg_selection agg_selection)
1426 struct rte_eth_dev *bond_dev;
1427 struct bond_dev_private *internals;
1428 struct mode8023ad_private *mode4;
1430 if (valid_bonded_port_id(port_id) != 0)
1433 bond_dev = &rte_eth_devices[port_id];
1434 internals = bond_dev->data->dev_private;
1436 if (internals->mode != 4)
1439 mode4 = &internals->mode4;
1440 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1441 || agg_selection == AGG_STABLE)
1442 mode4->agg_selection = agg_selection;
1446 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1448 struct rte_eth_dev *bond_dev;
1449 struct bond_dev_private *internals;
1450 struct mode8023ad_private *mode4;
1452 if (valid_bonded_port_id(port_id) != 0)
1455 bond_dev = &rte_eth_devices[port_id];
1456 internals = bond_dev->data->dev_private;
1458 if (internals->mode != 4)
1460 mode4 = &internals->mode4;
1462 return mode4->agg_selection;
1468 bond_8023ad_setup_validate(uint16_t port_id,
1469 struct rte_eth_bond_8023ad_conf *conf)
1471 if (valid_bonded_port_id(port_id) != 0)
1475 /* Basic sanity check */
1476 if (conf->slow_periodic_ms == 0 ||
1477 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1478 conf->long_timeout_ms == 0 ||
1479 conf->short_timeout_ms >= conf->long_timeout_ms ||
1480 conf->aggregate_wait_timeout_ms == 0 ||
1481 conf->tx_period_ms == 0 ||
1482 conf->rx_marker_period_ms == 0 ||
1483 conf->update_timeout_ms == 0) {
1484 RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1494 rte_eth_bond_8023ad_setup(uint16_t port_id,
1495 struct rte_eth_bond_8023ad_conf *conf)
1497 struct rte_eth_dev *bond_dev;
1500 err = bond_8023ad_setup_validate(port_id, conf);
1504 bond_dev = &rte_eth_devices[port_id];
1505 bond_mode_8023ad_setup(bond_dev, conf);
1515 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1516 struct rte_eth_bond_8023ad_slave_info *info)
1518 struct rte_eth_dev *bond_dev;
1519 struct bond_dev_private *internals;
1522 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1523 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1526 bond_dev = &rte_eth_devices[port_id];
1528 internals = bond_dev->data->dev_private;
1529 if (find_slave_by_id(internals->active_slaves,
1530 internals->active_slave_count, slave_id) ==
1531 internals->active_slave_count)
1534 port = &bond_mode_8023ad_ports[slave_id];
1535 info->selected = port->selected;
1537 info->actor_state = port->actor_state;
1538 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1540 info->partner_state = port->partner_state;
1541 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1543 info->agg_port_id = port->aggregator_port_id;
1548 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1550 struct rte_eth_dev *bond_dev;
1551 struct bond_dev_private *internals;
1552 struct mode8023ad_private *mode4;
1554 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1557 bond_dev = &rte_eth_devices[port_id];
1559 if (!bond_dev->data->dev_started)
1562 internals = bond_dev->data->dev_private;
1563 if (find_slave_by_id(internals->active_slaves,
1564 internals->active_slave_count, slave_id) ==
1565 internals->active_slave_count)
1568 mode4 = &internals->mode4;
1569 if (mode4->slowrx_cb == NULL)
1576 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1582 res = bond_8023ad_ext_validate(port_id, slave_id);
1586 port = &bond_mode_8023ad_ports[slave_id];
1589 ACTOR_STATE_SET(port, COLLECTING);
1591 ACTOR_STATE_CLR(port, COLLECTING);
1597 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1603 res = bond_8023ad_ext_validate(port_id, slave_id);
1607 port = &bond_mode_8023ad_ports[slave_id];
1610 ACTOR_STATE_SET(port, DISTRIBUTING);
1612 ACTOR_STATE_CLR(port, DISTRIBUTING);
1618 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1623 err = bond_8023ad_ext_validate(port_id, slave_id);
1627 port = &bond_mode_8023ad_ports[slave_id];
1628 return ACTOR_STATE(port, DISTRIBUTING);
1632 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1637 err = bond_8023ad_ext_validate(port_id, slave_id);
1641 port = &bond_mode_8023ad_ports[slave_id];
1642 return ACTOR_STATE(port, COLLECTING);
1646 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1647 struct rte_mbuf *lacp_pkt)
1652 res = bond_8023ad_ext_validate(port_id, slave_id);
1656 port = &bond_mode_8023ad_ports[slave_id];
1658 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1661 struct lacpdu_header *lacp;
1663 /* only enqueue LACPDUs */
1664 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1665 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1668 MODE4_DEBUG("sending LACP frame\n");
1670 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1674 bond_mode_8023ad_ext_periodic_cb(void *arg)
1676 struct rte_eth_dev *bond_dev = arg;
1677 struct bond_dev_private *internals = bond_dev->data->dev_private;
1678 struct mode8023ad_private *mode4 = &internals->mode4;
1681 uint16_t i, slave_id;
1683 for (i = 0; i < internals->active_slave_count; i++) {
1684 slave_id = internals->active_slaves[i];
1685 port = &bond_mode_8023ad_ports[slave_id];
1687 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1688 struct rte_mbuf *lacp_pkt = pkt;
1689 struct lacpdu_header *lacp;
1691 lacp = rte_pktmbuf_mtod(lacp_pkt,
1692 struct lacpdu_header *);
1693 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1695 /* This is LACP frame so pass it to rx callback.
1696 * Callback is responsible for freeing mbuf.
1698 mode4->slowrx_cb(slave_id, lacp_pkt);
1702 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1703 bond_mode_8023ad_ext_periodic_cb, arg);
1707 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1710 struct rte_eth_dev *dev;
1711 struct bond_dev_private *internals;
1713 if (valid_bonded_port_id(port) != 0)
1716 dev = &rte_eth_devices[port];
1717 internals = dev->data->dev_private;
1719 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1722 /* Device must be stopped to set up slow queue */
1723 if (dev->data->dev_started)
1726 internals->mode4.dedicated_queues.enabled = 1;
1728 bond_ethdev_mode_set(dev, internals->mode);
1733 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1736 struct rte_eth_dev *dev;
1737 struct bond_dev_private *internals;
1739 if (valid_bonded_port_id(port) != 0)
1742 dev = &rte_eth_devices[port];
1743 internals = dev->data->dev_private;
1745 /* Device must be stopped to set up slow queue */
1746 if (dev->data->dev_started)
1749 internals->mode4.dedicated_queues.enabled = 0;
1751 bond_ethdev_mode_set(dev, internals->mode);