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 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.d_addr);
591 rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_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;
808 if (lacp_pkt != NULL) {
809 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
810 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
812 partner = &lacp->lacpdu.partner;
813 if (rte_is_zero_ether_addr(&partner->port_params.system) ||
814 rte_is_same_ether_addr(&partner->port_params.system,
815 &internals->mode4.mac_addr)) {
816 /* This LACP frame is sending to the bonding port
817 * so pass it to rx_machine.
819 rx_machine(internals, slave_id, &lacp->lacpdu);
821 rte_pktmbuf_free(lacp_pkt);
823 rx_machine(internals, slave_id, NULL);
827 bond_mode_8023ad_periodic_cb(void *arg)
829 struct rte_eth_dev *bond_dev = arg;
830 struct bond_dev_private *internals = bond_dev->data->dev_private;
832 struct rte_eth_link link_info;
833 struct rte_ether_addr slave_addr;
834 struct rte_mbuf *lacp_pkt = NULL;
839 /* Update link status on each port */
840 for (i = 0; i < internals->active_slave_count; i++) {
844 slave_id = internals->active_slaves[i];
845 ret = rte_eth_link_get_nowait(slave_id, &link_info);
848 "Slave (port %u) link get failed: %s\n",
849 slave_id, rte_strerror(-ret));
852 if (ret >= 0 && link_info.link_status != 0) {
853 key = link_speed_key(link_info.link_speed) << 1;
854 if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
855 key |= BOND_LINK_FULL_DUPLEX_KEY;
860 rte_eth_macaddr_get(slave_id, &slave_addr);
861 port = &bond_mode_8023ad_ports[slave_id];
863 key = rte_cpu_to_be_16(key);
864 if (key != port->actor.key) {
865 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
866 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
868 port->actor.key = key;
869 SM_FLAG_SET(port, NTT);
872 if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
873 rte_ether_addr_copy(&slave_addr, &port->actor.system);
874 if (port->aggregator_port_id == slave_id)
875 SM_FLAG_SET(port, NTT);
879 for (i = 0; i < internals->active_slave_count; i++) {
880 slave_id = internals->active_slaves[i];
881 port = &bond_mode_8023ad_ports[slave_id];
883 if ((port->actor.key &
884 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
886 SM_FLAG_SET(port, BEGIN);
888 /* LACP is disabled on half duples or link is down */
889 if (SM_FLAG(port, LACP_ENABLED)) {
890 /* If port was enabled set it to BEGIN state */
891 SM_FLAG_CLR(port, LACP_ENABLED);
892 ACTOR_STATE_CLR(port, DISTRIBUTING);
893 ACTOR_STATE_CLR(port, COLLECTING);
896 /* Skip this port processing */
900 SM_FLAG_SET(port, LACP_ENABLED);
902 if (internals->mode4.dedicated_queues.enabled == 0) {
903 /* Find LACP packet to this port. Do not check subtype,
904 * it is done in function that queued packet
906 int retval = rte_ring_dequeue(port->rx_ring,
912 rx_machine_update(internals, slave_id, lacp_pkt);
914 uint16_t rx_count = rte_eth_rx_burst(slave_id,
915 internals->mode4.dedicated_queues.rx_qid,
919 bond_mode_8023ad_handle_slow_pkt(internals,
922 rx_machine_update(internals, slave_id, NULL);
925 periodic_machine(internals, slave_id);
926 mux_machine(internals, slave_id);
927 tx_machine(internals, slave_id);
928 selection_logic(internals, slave_id);
930 SM_FLAG_CLR(port, BEGIN);
931 show_warnings(slave_id);
934 rte_eal_alarm_set(internals->mode4.update_timeout_us,
935 bond_mode_8023ad_periodic_cb, arg);
939 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
943 ret = rte_eth_allmulticast_enable(slave_id);
946 "failed to enable allmulti mode for port %u: %s",
947 slave_id, rte_strerror(-ret));
949 if (rte_eth_allmulticast_get(slave_id)) {
950 RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
952 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
953 BOND_8023AD_FORCED_ALLMULTI;
957 ret = rte_eth_promiscuous_enable(slave_id);
960 "failed to enable promiscuous mode for port %u: %s",
961 slave_id, rte_strerror(-ret));
963 if (rte_eth_promiscuous_get(slave_id)) {
964 RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
966 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
967 BOND_8023AD_FORCED_PROMISC;
975 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
979 switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
980 case BOND_8023AD_FORCED_ALLMULTI:
981 RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
982 ret = rte_eth_allmulticast_disable(slave_id);
985 "failed to disable allmulti mode for port %u: %s",
986 slave_id, rte_strerror(-ret));
989 case BOND_8023AD_FORCED_PROMISC:
990 RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
991 ret = rte_eth_promiscuous_disable(slave_id);
994 "failed to disable promiscuous mode for port %u: %s",
995 slave_id, rte_strerror(-ret));
1004 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
1007 struct bond_dev_private *internals = bond_dev->data->dev_private;
1009 struct port *port = &bond_mode_8023ad_ports[slave_id];
1010 struct port_params initial = {
1011 .system = { { 0 } },
1012 .system_priority = rte_cpu_to_be_16(0xFFFF),
1013 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1014 .port_priority = rte_cpu_to_be_16(0x00FF),
1018 char mem_name[RTE_ETH_NAME_MAX_LEN];
1020 unsigned element_size;
1021 uint32_t total_tx_desc;
1022 struct bond_tx_queue *bd_tx_q;
1025 /* Given slave mus not be in active list */
1026 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1027 internals->active_slave_count, slave_id) == internals->active_slave_count);
1028 RTE_SET_USED(internals); /* used only for assert when enabled */
1030 memcpy(&port->actor, &initial, sizeof(struct port_params));
1031 /* Standard requires that port ID must be grater than 0.
1032 * Add 1 do get corresponding port_number */
1033 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1035 memcpy(&port->partner, &initial, sizeof(struct port_params));
1036 memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
1038 /* default states */
1039 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1040 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1041 port->sm_flags = SM_FLAGS_BEGIN;
1043 /* use this port as agregator */
1044 port->aggregator_port_id = slave_id;
1046 if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1047 RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1051 timer_cancel(&port->warning_timer);
1053 if (port->mbuf_pool != NULL)
1056 RTE_ASSERT(port->rx_ring == NULL);
1057 RTE_ASSERT(port->tx_ring == NULL);
1059 socket_id = rte_eth_dev_socket_id(slave_id);
1060 if (socket_id == -1)
1061 socket_id = rte_socket_id();
1063 element_size = sizeof(struct slow_protocol_frame) +
1064 RTE_PKTMBUF_HEADROOM;
1066 /* The size of the mempool should be at least:
1067 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1068 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1069 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1070 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1071 total_tx_desc += bd_tx_q->nb_tx_desc;
1074 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1075 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1076 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1077 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1078 0, element_size, socket_id);
1080 /* Any memory allocation failure in initialization is critical because
1081 * resources can't be free, so reinitialization is impossible. */
1082 if (port->mbuf_pool == NULL) {
1083 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1084 slave_id, mem_name, rte_strerror(rte_errno));
1087 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1088 port->rx_ring = rte_ring_create(mem_name,
1089 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1091 if (port->rx_ring == NULL) {
1092 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1093 mem_name, rte_strerror(rte_errno));
1096 /* TX ring is at least one pkt longer to make room for marker packet. */
1097 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1098 port->tx_ring = rte_ring_create(mem_name,
1099 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1101 if (port->tx_ring == NULL) {
1102 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1103 mem_name, rte_strerror(rte_errno));
1108 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1112 struct port *port = NULL;
1113 uint8_t old_partner_state;
1115 port = &bond_mode_8023ad_ports[slave_id];
1117 ACTOR_STATE_CLR(port, AGGREGATION);
1118 port->selected = UNSELECTED;
1120 old_partner_state = port->partner_state;
1121 record_default(port);
1123 bond_mode_8023ad_unregister_lacp_mac(slave_id);
1125 /* If partner timeout state changes then disable timer */
1126 if (!((old_partner_state ^ port->partner_state) &
1127 STATE_LACP_SHORT_TIMEOUT))
1128 timer_cancel(&port->current_while_timer);
1130 PARTNER_STATE_CLR(port, AGGREGATION);
1131 ACTOR_STATE_CLR(port, EXPIRED);
1133 /* flush rx/tx rings */
1134 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1135 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1137 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1138 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1143 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1145 struct bond_dev_private *internals = bond_dev->data->dev_private;
1146 struct rte_ether_addr slave_addr;
1147 struct port *slave, *agg_slave;
1148 uint16_t slave_id, i, j;
1150 bond_mode_8023ad_stop(bond_dev);
1152 for (i = 0; i < internals->active_slave_count; i++) {
1153 slave_id = internals->active_slaves[i];
1154 slave = &bond_mode_8023ad_ports[slave_id];
1155 rte_eth_macaddr_get(slave_id, &slave_addr);
1157 if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1160 rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1161 /* Do nothing if this port is not an aggregator. In other case
1162 * Set NTT flag on every port that use this aggregator. */
1163 if (slave->aggregator_port_id != slave_id)
1166 for (j = 0; j < internals->active_slave_count; j++) {
1167 agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1168 if (agg_slave->aggregator_port_id == slave_id)
1169 SM_FLAG_SET(agg_slave, NTT);
1173 if (bond_dev->data->dev_started)
1174 bond_mode_8023ad_start(bond_dev);
1178 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1179 struct rte_eth_bond_8023ad_conf *conf)
1181 struct bond_dev_private *internals = dev->data->dev_private;
1182 struct mode8023ad_private *mode4 = &internals->mode4;
1183 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1185 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1186 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1187 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1188 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1189 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1190 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1191 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1192 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1193 conf->slowrx_cb = mode4->slowrx_cb;
1194 conf->agg_selection = mode4->agg_selection;
1198 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1200 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1201 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1202 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1203 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1204 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1205 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1206 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1207 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1208 conf->slowrx_cb = NULL;
1209 conf->agg_selection = AGG_STABLE;
1213 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1214 struct rte_eth_bond_8023ad_conf *conf)
1216 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1218 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1219 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1220 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1221 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1222 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1223 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1224 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1225 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1227 mode4->dedicated_queues.enabled = 0;
1228 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1229 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1233 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1234 struct rte_eth_bond_8023ad_conf *conf)
1236 struct rte_eth_bond_8023ad_conf def_conf;
1237 struct bond_dev_private *internals = dev->data->dev_private;
1238 struct mode8023ad_private *mode4 = &internals->mode4;
1242 bond_mode_8023ad_conf_get_default(conf);
1245 bond_mode_8023ad_stop(dev);
1246 bond_mode_8023ad_conf_assign(mode4, conf);
1247 mode4->slowrx_cb = conf->slowrx_cb;
1248 mode4->agg_selection = AGG_STABLE;
1250 if (dev->data->dev_started)
1251 bond_mode_8023ad_start(dev);
1255 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1257 struct bond_dev_private *internals = bond_dev->data->dev_private;
1260 for (i = 0; i < internals->active_slave_count; i++)
1261 bond_mode_8023ad_activate_slave(bond_dev,
1262 internals->active_slaves[i]);
1268 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1270 struct bond_dev_private *internals = bond_dev->data->dev_private;
1271 struct mode8023ad_private *mode4 = &internals->mode4;
1272 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1274 rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1275 if (mode4->slowrx_cb)
1276 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1279 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1283 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1285 struct bond_dev_private *internals = bond_dev->data->dev_private;
1286 struct mode8023ad_private *mode4 = &internals->mode4;
1288 if (mode4->slowrx_cb) {
1289 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1293 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1297 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1298 uint16_t slave_id, struct rte_mbuf *pkt)
1300 struct mode8023ad_private *mode4 = &internals->mode4;
1301 struct port *port = &bond_mode_8023ad_ports[slave_id];
1302 struct marker_header *m_hdr;
1303 uint64_t marker_timer, old_marker_timer;
1305 uint8_t wrn, subtype;
1306 /* If packet is a marker, we send response now by reusing given packet
1307 * and update only source MAC, destination MAC is multicast so don't
1308 * update it. Other frames will be handled later by state machines */
1309 subtype = rte_pktmbuf_mtod(pkt,
1310 struct slow_protocol_frame *)->slow_protocol.subtype;
1312 if (subtype == SLOW_SUBTYPE_MARKER) {
1313 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1315 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1316 wrn = WRN_UNKNOWN_MARKER_TYPE;
1320 /* Setup marker timer. Do it in loop in case concurrent access. */
1322 old_marker_timer = port->rx_marker_timer;
1323 if (!timer_is_expired(&old_marker_timer)) {
1324 wrn = WRN_RX_MARKER_TO_FAST;
1328 timer_set(&marker_timer, mode4->rx_marker_timeout);
1329 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1330 old_marker_timer, marker_timer);
1331 } while (unlikely(retval == 0));
1333 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1334 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1336 if (internals->mode4.dedicated_queues.enabled == 0) {
1337 if (rte_ring_enqueue(port->tx_ring, pkt) != 0) {
1339 port->rx_marker_timer = 0;
1340 wrn = WRN_TX_QUEUE_FULL;
1344 /* Send packet directly to the slow queue */
1345 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1346 internals->mode4.dedicated_queues.tx_qid,
1348 if (tx_count != 1) {
1350 port->rx_marker_timer = 0;
1351 wrn = WRN_TX_QUEUE_FULL;
1355 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1356 if (internals->mode4.dedicated_queues.enabled == 0) {
1357 if (rte_ring_enqueue(port->rx_ring, pkt) != 0) {
1358 /* If RX fing full free lacpdu message and drop packet */
1359 wrn = WRN_RX_QUEUE_FULL;
1363 rx_machine_update(internals, slave_id, pkt);
1365 wrn = WRN_UNKNOWN_SLOW_TYPE;
1372 set_warning_flags(port, wrn);
1373 rte_pktmbuf_free(pkt);
1377 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1378 struct rte_eth_bond_8023ad_conf *conf)
1380 struct rte_eth_dev *bond_dev;
1382 if (valid_bonded_port_id(port_id) != 0)
1388 bond_dev = &rte_eth_devices[port_id];
1389 bond_mode_8023ad_conf_get(bond_dev, conf);
1394 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1395 enum rte_bond_8023ad_agg_selection agg_selection)
1397 struct rte_eth_dev *bond_dev;
1398 struct bond_dev_private *internals;
1399 struct mode8023ad_private *mode4;
1401 if (valid_bonded_port_id(port_id) != 0)
1404 bond_dev = &rte_eth_devices[port_id];
1405 internals = bond_dev->data->dev_private;
1407 if (internals->mode != 4)
1410 mode4 = &internals->mode4;
1411 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1412 || agg_selection == AGG_STABLE)
1413 mode4->agg_selection = agg_selection;
1417 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1419 struct rte_eth_dev *bond_dev;
1420 struct bond_dev_private *internals;
1421 struct mode8023ad_private *mode4;
1423 if (valid_bonded_port_id(port_id) != 0)
1426 bond_dev = &rte_eth_devices[port_id];
1427 internals = bond_dev->data->dev_private;
1429 if (internals->mode != 4)
1431 mode4 = &internals->mode4;
1433 return mode4->agg_selection;
1439 bond_8023ad_setup_validate(uint16_t port_id,
1440 struct rte_eth_bond_8023ad_conf *conf)
1442 if (valid_bonded_port_id(port_id) != 0)
1446 /* Basic sanity check */
1447 if (conf->slow_periodic_ms == 0 ||
1448 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1449 conf->long_timeout_ms == 0 ||
1450 conf->short_timeout_ms >= conf->long_timeout_ms ||
1451 conf->aggregate_wait_timeout_ms == 0 ||
1452 conf->tx_period_ms == 0 ||
1453 conf->rx_marker_period_ms == 0 ||
1454 conf->update_timeout_ms == 0) {
1455 RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1465 rte_eth_bond_8023ad_setup(uint16_t port_id,
1466 struct rte_eth_bond_8023ad_conf *conf)
1468 struct rte_eth_dev *bond_dev;
1471 err = bond_8023ad_setup_validate(port_id, conf);
1475 bond_dev = &rte_eth_devices[port_id];
1476 bond_mode_8023ad_setup(bond_dev, conf);
1486 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1487 struct rte_eth_bond_8023ad_slave_info *info)
1489 struct rte_eth_dev *bond_dev;
1490 struct bond_dev_private *internals;
1493 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1494 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1497 bond_dev = &rte_eth_devices[port_id];
1499 internals = bond_dev->data->dev_private;
1500 if (find_slave_by_id(internals->active_slaves,
1501 internals->active_slave_count, slave_id) ==
1502 internals->active_slave_count)
1505 port = &bond_mode_8023ad_ports[slave_id];
1506 info->selected = port->selected;
1508 info->actor_state = port->actor_state;
1509 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1511 info->partner_state = port->partner_state;
1512 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1514 info->agg_port_id = port->aggregator_port_id;
1519 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1521 struct rte_eth_dev *bond_dev;
1522 struct bond_dev_private *internals;
1523 struct mode8023ad_private *mode4;
1525 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1528 bond_dev = &rte_eth_devices[port_id];
1530 if (!bond_dev->data->dev_started)
1533 internals = bond_dev->data->dev_private;
1534 if (find_slave_by_id(internals->active_slaves,
1535 internals->active_slave_count, slave_id) ==
1536 internals->active_slave_count)
1539 mode4 = &internals->mode4;
1540 if (mode4->slowrx_cb == NULL)
1547 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1553 res = bond_8023ad_ext_validate(port_id, slave_id);
1557 port = &bond_mode_8023ad_ports[slave_id];
1560 ACTOR_STATE_SET(port, COLLECTING);
1562 ACTOR_STATE_CLR(port, COLLECTING);
1568 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1574 res = bond_8023ad_ext_validate(port_id, slave_id);
1578 port = &bond_mode_8023ad_ports[slave_id];
1581 ACTOR_STATE_SET(port, DISTRIBUTING);
1583 ACTOR_STATE_CLR(port, DISTRIBUTING);
1589 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1594 err = bond_8023ad_ext_validate(port_id, slave_id);
1598 port = &bond_mode_8023ad_ports[slave_id];
1599 return ACTOR_STATE(port, DISTRIBUTING);
1603 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1608 err = bond_8023ad_ext_validate(port_id, slave_id);
1612 port = &bond_mode_8023ad_ports[slave_id];
1613 return ACTOR_STATE(port, COLLECTING);
1617 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1618 struct rte_mbuf *lacp_pkt)
1623 res = bond_8023ad_ext_validate(port_id, slave_id);
1627 port = &bond_mode_8023ad_ports[slave_id];
1629 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1632 struct lacpdu_header *lacp;
1634 /* only enqueue LACPDUs */
1635 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1636 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1639 MODE4_DEBUG("sending LACP frame\n");
1641 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1645 bond_mode_8023ad_ext_periodic_cb(void *arg)
1647 struct rte_eth_dev *bond_dev = arg;
1648 struct bond_dev_private *internals = bond_dev->data->dev_private;
1649 struct mode8023ad_private *mode4 = &internals->mode4;
1652 uint16_t i, slave_id;
1654 for (i = 0; i < internals->active_slave_count; i++) {
1655 slave_id = internals->active_slaves[i];
1656 port = &bond_mode_8023ad_ports[slave_id];
1658 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1659 struct rte_mbuf *lacp_pkt = pkt;
1660 struct lacpdu_header *lacp;
1662 lacp = rte_pktmbuf_mtod(lacp_pkt,
1663 struct lacpdu_header *);
1664 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1666 /* This is LACP frame so pass it to rx callback.
1667 * Callback is responsible for freeing mbuf.
1669 mode4->slowrx_cb(slave_id, lacp_pkt);
1673 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1674 bond_mode_8023ad_ext_periodic_cb, arg);
1678 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1681 struct rte_eth_dev *dev;
1682 struct bond_dev_private *internals;
1684 if (valid_bonded_port_id(port) != 0)
1687 dev = &rte_eth_devices[port];
1688 internals = dev->data->dev_private;
1690 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1693 /* Device must be stopped to set up slow queue */
1694 if (dev->data->dev_started)
1697 internals->mode4.dedicated_queues.enabled = 1;
1699 bond_ethdev_mode_set(dev, internals->mode);
1704 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1707 struct rte_eth_dev *dev;
1708 struct bond_dev_private *internals;
1710 if (valid_bonded_port_id(port) != 0)
1713 dev = &rte_eth_devices[port];
1714 internals = dev->data->dev_private;
1716 /* Device must be stopped to set up slow queue */
1717 if (dev->data->dev_started)
1720 internals->mode4.dedicated_queues.enabled = 0;
1722 bond_ethdev_mode_set(dev, internals->mode);