4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <rte_alarm.h>
39 #include <rte_malloc.h>
40 #include <rte_errno.h>
41 #include <rte_cycles.h>
42 #include <rte_compat.h>
44 #include "rte_eth_bond_private.h"
46 static void bond_mode_8023ad_ext_periodic_cb(void *arg);
47 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
48 #define MODE4_DEBUG(fmt, ...) RTE_LOG(DEBUG, PMD, "%6u [Port %u: %s] " fmt, \
49 bond_dbg_get_time_diff_ms(), slave_id, \
50 __func__, ##__VA_ARGS__)
52 static uint64_t start_time;
55 bond_dbg_get_time_diff_ms(void)
63 return ((now - start_time) * 1000) / rte_get_tsc_hz();
67 bond_print_lacp(struct lacpdu *l)
71 char a_state[256] = { 0 };
72 char p_state[256] = { 0 };
74 static const char * const state_labels[] = {
75 "ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
83 addr = l->actor.port_params.system.addr_bytes;
84 snprintf(a_address, sizeof(a_address), "%02X:%02X:%02X:%02X:%02X:%02X",
85 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
87 addr = l->partner.port_params.system.addr_bytes;
88 snprintf(p_address, sizeof(p_address), "%02X:%02X:%02X:%02X:%02X:%02X",
89 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
91 for (i = 0; i < 8; i++) {
92 if ((l->actor.state >> i) & 1) {
93 a_len += snprintf(&a_state[a_len], RTE_DIM(a_state) - a_len, "%s ",
97 if ((l->partner.state >> i) & 1) {
98 p_len += snprintf(&p_state[p_len], RTE_DIM(p_state) - p_len, "%s ",
103 if (a_len && a_state[a_len-1] == ' ')
104 a_state[a_len-1] = '\0';
106 if (p_len && p_state[p_len-1] == ' ')
107 p_state[p_len-1] = '\0';
109 RTE_LOG(DEBUG, PMD, "LACP: {\n"\
112 " actor={ tlv=%02X, len=%02X\n"\
113 " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\
116 " partner={ tlv=%02X, len=%02X\n"\
117 " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\
120 " collector={info=%02X, length=%02X, max_delay=%04X\n, " \
121 "type_term=%02X, terminator_length = %02X}\n",\
124 l->actor.tlv_type_info,\
125 l->actor.info_length,\
126 l->actor.port_params.system_priority,\
128 l->actor.port_params.key,\
129 l->actor.port_params.port_priority,\
130 l->actor.port_params.port_number,\
132 l->partner.tlv_type_info,\
133 l->partner.info_length,\
134 l->partner.port_params.system_priority,\
136 l->partner.port_params.key,\
137 l->partner.port_params.port_priority,\
138 l->partner.port_params.port_number,\
140 l->tlv_type_collector_info,\
141 l->collector_info_length,\
142 l->collector_max_delay,\
143 l->tlv_type_terminator,\
144 l->terminator_length);
147 #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu)
149 #define BOND_PRINT_LACP(lacpdu) do { } while (0)
150 #define MODE4_DEBUG(fmt, ...) do { } while (0)
153 static const struct ether_addr lacp_mac_addr = {
154 .addr_bytes = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
157 struct port mode_8023ad_ports[RTE_MAX_ETHPORTS];
160 timer_cancel(uint64_t *timer)
166 timer_set(uint64_t *timer, uint64_t timeout)
168 *timer = rte_rdtsc() + timeout;
171 /* Forces given timer to be in expired state. */
173 timer_force_expired(uint64_t *timer)
175 *timer = rte_rdtsc();
179 timer_is_stopped(uint64_t *timer)
185 timer_is_expired(uint64_t *timer)
187 return *timer < rte_rdtsc();
190 /* Timer is in running state if it is not stopped nor expired */
192 timer_is_running(uint64_t *timer)
194 return !timer_is_stopped(timer) && !timer_is_expired(timer);
198 set_warning_flags(struct port *port, uint16_t flags)
202 uint16_t new_flag = 0;
205 old = port->warnings_to_show;
206 new_flag = old | flags;
207 retval = rte_atomic16_cmpset(&port->warnings_to_show, old, new_flag);
208 } while (unlikely(retval == 0));
212 show_warnings(uint8_t slave_id)
214 struct port *port = &mode_8023ad_ports[slave_id];
218 warnings = port->warnings_to_show;
219 } while (rte_atomic16_cmpset(&port->warnings_to_show, warnings, 0) == 0);
224 if (!timer_is_expired(&port->warning_timer))
228 timer_set(&port->warning_timer, BOND_8023AD_WARNINGS_PERIOD_MS *
229 rte_get_tsc_hz() / 1000);
231 if (warnings & WRN_RX_QUEUE_FULL) {
233 "Slave %u: failed to enqueue LACP packet into RX ring.\n"
234 "Receive and transmit functions must be invoked on bonded\n"
235 "interface at least 10 times per second or LACP will not\n"
236 "work correctly\n", slave_id);
239 if (warnings & WRN_TX_QUEUE_FULL) {
241 "Slave %u: failed to enqueue LACP packet into TX ring.\n"
242 "Receive and transmit functions must be invoked on bonded\n"
243 "interface at least 10 times per second or LACP will not\n"
244 "work correctly\n", slave_id);
247 if (warnings & WRN_RX_MARKER_TO_FAST)
248 RTE_LOG(INFO, PMD, "Slave %u: marker to early - ignoring.\n", slave_id);
250 if (warnings & WRN_UNKNOWN_SLOW_TYPE) {
252 "Slave %u: ignoring unknown slow protocol frame type", slave_id);
255 if (warnings & WRN_UNKNOWN_MARKER_TYPE)
256 RTE_LOG(INFO, PMD, "Slave %u: ignoring unknown marker type", slave_id);
258 if (warnings & WRN_NOT_LACP_CAPABLE)
259 MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id);
263 record_default(struct port *port)
265 /* Record default parameters for partner. Partner admin parameters
266 * are not implemented so set them to arbitrary default (last known) and
267 * mark actor that parner is in defaulted state. */
268 port->partner_state = STATE_LACP_ACTIVE;
269 ACTOR_STATE_SET(port, DEFAULTED);
272 /** Function handles rx state machine.
274 * This function implements Receive State Machine from point 5.4.12 in
275 * 802.1AX documentation. It should be called periodically.
277 * @param lacpdu LACPDU received.
278 * @param port Port on which LACPDU was received.
281 rx_machine(struct bond_dev_private *internals, uint8_t slave_id,
284 struct port *agg, *port = &mode_8023ad_ports[slave_id];
287 if (SM_FLAG(port, BEGIN)) {
288 /* Initialize stuff */
289 MODE4_DEBUG("-> INITIALIZE\n");
290 SM_FLAG_CLR(port, MOVED);
291 port->selected = UNSELECTED;
293 record_default(port);
295 ACTOR_STATE_CLR(port, EXPIRED);
296 timer_cancel(&port->current_while_timer);
298 /* DISABLED: On initialization partner is out of sync */
299 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
301 /* LACP DISABLED stuff if LACP not enabled on this port */
302 if (!SM_FLAG(port, LACP_ENABLED))
303 PARTNER_STATE_CLR(port, AGGREGATION);
305 PARTNER_STATE_SET(port, AGGREGATION);
308 if (!SM_FLAG(port, LACP_ENABLED)) {
309 /* Update parameters only if state changed */
310 if (!timer_is_stopped(&port->current_while_timer)) {
311 port->selected = UNSELECTED;
312 record_default(port);
313 PARTNER_STATE_CLR(port, AGGREGATION);
314 ACTOR_STATE_CLR(port, EXPIRED);
315 timer_cancel(&port->current_while_timer);
321 MODE4_DEBUG("LACP -> CURRENT\n");
322 BOND_PRINT_LACP(lacp);
323 /* Update selected flag. If partner parameters are defaulted assume they
324 * are match. If not defaulted compare LACP actor with ports parner
326 if (!ACTOR_STATE(port, DEFAULTED) &&
327 (ACTOR_STATE(port, AGGREGATION) != PARTNER_STATE(port, AGGREGATION)
328 || memcmp(&port->partner, &lacp->actor.port_params,
329 sizeof(port->partner)) != 0)) {
330 MODE4_DEBUG("selected <- UNSELECTED\n");
331 port->selected = UNSELECTED;
334 /* Record this PDU actor params as partner params */
335 memcpy(&port->partner, &lacp->actor.port_params,
336 sizeof(struct port_params));
337 port->partner_state = lacp->actor.state;
339 /* Partner parameters are not defaulted any more */
340 ACTOR_STATE_CLR(port, DEFAULTED);
342 /* If LACP partner params match this port actor params */
343 agg = &mode_8023ad_ports[port->aggregator_port_id];
344 bool match = port->actor.system_priority ==
345 lacp->partner.port_params.system_priority &&
346 is_same_ether_addr(&agg->actor.system,
347 &lacp->partner.port_params.system) &&
348 port->actor.port_priority ==
349 lacp->partner.port_params.port_priority &&
350 port->actor.port_number ==
351 lacp->partner.port_params.port_number;
353 /* Update NTT if partners information are outdated (xored and masked
355 uint8_t state_mask = STATE_LACP_ACTIVE | STATE_LACP_SHORT_TIMEOUT |
356 STATE_SYNCHRONIZATION | STATE_AGGREGATION;
358 if (((port->actor_state ^ lacp->partner.state) & state_mask) ||
360 SM_FLAG_SET(port, NTT);
363 /* If LACP partner params match this port actor params */
364 if (match == true && ACTOR_STATE(port, AGGREGATION) ==
365 PARTNER_STATE(port, AGGREGATION))
366 PARTNER_STATE_SET(port, SYNCHRONIZATION);
367 else if (!PARTNER_STATE(port, AGGREGATION) && ACTOR_STATE(port,
369 PARTNER_STATE_SET(port, SYNCHRONIZATION);
371 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
373 if (ACTOR_STATE(port, LACP_SHORT_TIMEOUT))
374 timeout = internals->mode4.short_timeout;
376 timeout = internals->mode4.long_timeout;
378 timer_set(&port->current_while_timer, timeout);
379 ACTOR_STATE_CLR(port, EXPIRED);
380 return; /* No state change */
383 /* If CURRENT state timer is not running (stopped or expired)
384 * transit to EXPIRED state from DISABLED or CURRENT */
385 if (!timer_is_running(&port->current_while_timer)) {
386 ACTOR_STATE_SET(port, EXPIRED);
387 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
388 PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
389 timer_set(&port->current_while_timer, internals->mode4.short_timeout);
394 * Function handles periodic tx state machine.
396 * Function implements Periodic Transmission state machine from point 5.4.13
397 * in 802.1AX documentation. It should be called periodically.
399 * @param port Port to handle state machine.
402 periodic_machine(struct bond_dev_private *internals, uint8_t slave_id)
404 struct port *port = &mode_8023ad_ports[slave_id];
405 /* Calculate if either site is LACP enabled */
407 uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
408 PARTNER_STATE(port, LACP_ACTIVE);
410 uint8_t is_partner_fast, was_partner_fast;
411 /* No periodic is on BEGIN, LACP DISABLE or when both sides are pasive */
412 if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
413 timer_cancel(&port->periodic_timer);
414 timer_force_expired(&port->tx_machine_timer);
415 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
417 MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
418 SM_FLAG(port, BEGIN) ? "begind " : "",
419 SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
420 active ? "LACP active " : "LACP pasive ");
424 is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
425 was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
427 /* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
428 * Other case: check if timer expire or partners settings changed. */
429 if (!timer_is_stopped(&port->periodic_timer)) {
430 if (timer_is_expired(&port->periodic_timer)) {
431 SM_FLAG_SET(port, NTT);
432 } else if (is_partner_fast != was_partner_fast) {
433 /* Partners timeout was slow and now it is fast -> send LACP.
434 * In other case (was fast and now it is slow) just switch
435 * timeout to slow without forcing send of LACP (because standard
438 SM_FLAG_SET(port, NTT);
440 return; /* Nothing changed */
443 /* Handle state transition to FAST/SLOW LACP timeout */
444 if (is_partner_fast) {
445 timeout = internals->mode4.fast_periodic_timeout;
446 SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
448 timeout = internals->mode4.slow_periodic_timeout;
449 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
452 timer_set(&port->periodic_timer, timeout);
456 * Function handles mux state machine.
458 * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
459 * It should be called periodically.
461 * @param port Port to handle state machine.
464 mux_machine(struct bond_dev_private *internals, uint8_t slave_id)
466 struct port *port = &mode_8023ad_ports[slave_id];
468 /* Save current state for later use */
469 const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
472 /* Enter DETACHED state on BEGIN condition or from any other state if
473 * port was unselected */
474 if (SM_FLAG(port, BEGIN) ||
475 port->selected == UNSELECTED || (port->selected == STANDBY &&
476 (port->actor_state & state_mask) != 0)) {
477 /* detach mux from aggregator */
478 port->actor_state &= ~state_mask;
479 /* Set ntt to true if BEGIN condition or transition from any other state
480 * which is indicated that wait_while_timer was started */
481 if (SM_FLAG(port, BEGIN) ||
482 !timer_is_stopped(&port->wait_while_timer)) {
483 SM_FLAG_SET(port, NTT);
484 MODE4_DEBUG("-> DETACHED\n");
486 timer_cancel(&port->wait_while_timer);
489 if (timer_is_stopped(&port->wait_while_timer)) {
490 if (port->selected == SELECTED || port->selected == STANDBY) {
491 timer_set(&port->wait_while_timer,
492 internals->mode4.aggregate_wait_timeout);
494 MODE4_DEBUG("DETACHED -> WAITING\n");
496 /* Waiting state entered */
500 /* Transit next state if port is ready */
501 if (!timer_is_expired(&port->wait_while_timer))
504 if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
505 !PARTNER_STATE(port, SYNCHRONIZATION)) {
506 /* If in COLLECTING or DISTRIBUTING state and partner becomes out of
507 * sync transit to ATACHED state. */
508 ACTOR_STATE_CLR(port, DISTRIBUTING);
509 ACTOR_STATE_CLR(port, COLLECTING);
510 /* Clear actor sync to activate transit ATACHED in condition bellow */
511 ACTOR_STATE_CLR(port, SYNCHRONIZATION);
512 MODE4_DEBUG("Out of sync -> ATTACHED\n");
515 if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
516 /* attach mux to aggregator */
517 RTE_ASSERT((port->actor_state & (STATE_COLLECTING |
518 STATE_DISTRIBUTING)) == 0);
520 ACTOR_STATE_SET(port, SYNCHRONIZATION);
521 SM_FLAG_SET(port, NTT);
522 MODE4_DEBUG("ATTACHED Entered\n");
523 } else if (!ACTOR_STATE(port, COLLECTING)) {
524 /* Start collecting if in sync */
525 if (PARTNER_STATE(port, SYNCHRONIZATION)) {
526 MODE4_DEBUG("ATTACHED -> COLLECTING\n");
527 ACTOR_STATE_SET(port, COLLECTING);
528 SM_FLAG_SET(port, NTT);
530 } else if (ACTOR_STATE(port, COLLECTING)) {
531 /* Check if partner is in COLLECTING state. If so this port can
532 * distribute frames to it */
533 if (!ACTOR_STATE(port, DISTRIBUTING)) {
534 if (PARTNER_STATE(port, COLLECTING)) {
535 /* Enable DISTRIBUTING if partner is collecting */
536 ACTOR_STATE_SET(port, DISTRIBUTING);
537 SM_FLAG_SET(port, NTT);
538 MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
540 "Bond %u: slave id %u distributing started.\n",
541 internals->port_id, slave_id);
544 if (!PARTNER_STATE(port, COLLECTING)) {
545 /* Disable DISTRIBUTING (enter COLLECTING state) if partner
546 * is not collecting */
547 ACTOR_STATE_CLR(port, DISTRIBUTING);
548 SM_FLAG_SET(port, NTT);
549 MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
551 "Bond %u: slave id %u distributing stopped.\n",
552 internals->port_id, slave_id);
559 * Function handles transmit state machine.
561 * Function implements Transmit Machine from point 5.4.16 in 802.1AX
567 tx_machine(struct bond_dev_private *internals, uint8_t slave_id)
569 struct port *agg, *port = &mode_8023ad_ports[slave_id];
571 struct rte_mbuf *lacp_pkt = NULL;
572 struct lacpdu_header *hdr;
573 struct lacpdu *lacpdu;
575 /* If periodic timer is not running periodic machine is in NO PERIODIC and
576 * according to 802.3ax standard tx machine should not transmit any frames
577 * and set ntt to false. */
578 if (timer_is_stopped(&port->periodic_timer))
579 SM_FLAG_CLR(port, NTT);
581 if (!SM_FLAG(port, NTT))
584 if (!timer_is_expired(&port->tx_machine_timer))
587 lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
588 if (lacp_pkt == NULL) {
589 RTE_LOG(ERR, PMD, "Failed to allocate LACP packet from pool\n");
593 lacp_pkt->data_len = sizeof(*hdr);
594 lacp_pkt->pkt_len = sizeof(*hdr);
596 hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
598 /* Source and destination MAC */
599 ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.d_addr);
600 rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_addr);
601 hdr->eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_SLOW);
603 lacpdu = &hdr->lacpdu;
604 memset(lacpdu, 0, sizeof(*lacpdu));
606 /* Initialize LACP part */
607 lacpdu->subtype = SLOW_SUBTYPE_LACP;
608 lacpdu->version_number = 1;
611 lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
612 lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
613 memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
614 sizeof(port->actor));
615 agg = &mode_8023ad_ports[port->aggregator_port_id];
616 ether_addr_copy(&agg->actor.system, &hdr->lacpdu.actor.port_params.system);
617 lacpdu->actor.state = port->actor_state;
620 lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
621 lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
622 memcpy(&lacpdu->partner.port_params, &port->partner,
623 sizeof(struct port_params));
624 lacpdu->partner.state = port->partner_state;
627 lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
628 lacpdu->collector_info_length = 0x10;
629 lacpdu->collector_max_delay = 0;
631 lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
632 lacpdu->terminator_length = 0;
634 MODE4_DEBUG("Sending LACP frame\n");
635 BOND_PRINT_LACP(lacpdu);
637 if (internals->mode4.dedicated_queues.enabled == 0) {
638 int retval = rte_ring_enqueue(port->tx_ring, lacp_pkt);
640 /* If TX ring full, drop packet and free message.
641 Retransmission will happen in next function call. */
642 rte_pktmbuf_free(lacp_pkt);
643 set_warning_flags(port, WRN_TX_QUEUE_FULL);
647 uint16_t pkts_sent = rte_eth_tx_burst(slave_id,
648 internals->mode4.dedicated_queues.tx_qid,
650 if (pkts_sent != 1) {
651 rte_pktmbuf_free(lacp_pkt);
652 set_warning_flags(port, WRN_TX_QUEUE_FULL);
658 timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
659 SM_FLAG_CLR(port, NTT);
663 max_index(uint64_t *a, int n)
671 for (i = 1; i < n; ++i) {
682 * Function assigns port to aggregator.
684 * @param bond_dev_private Pointer to bond_dev_private structure.
685 * @param port_pos Port to assign.
688 selection_logic(struct bond_dev_private *internals, uint8_t slave_id)
690 struct port *agg, *port;
691 uint8_t slaves_count, new_agg_id, i, j = 0;
693 uint64_t agg_bandwidth[8] = {0};
694 uint64_t agg_count[8] = {0};
695 uint8_t default_slave = 0;
696 uint8_t mode_count_id, mode_band_id;
697 struct rte_eth_link link_info;
699 slaves = internals->active_slaves;
700 slaves_count = internals->active_slave_count;
701 port = &mode_8023ad_ports[slave_id];
703 /* Search for aggregator suitable for this port */
704 for (i = 0; i < slaves_count; ++i) {
705 agg = &mode_8023ad_ports[slaves[i]];
706 /* Skip ports that are not aggreagators */
707 if (agg->aggregator_port_id != slaves[i])
710 agg_count[agg->aggregator_port_id] += 1;
711 rte_eth_link_get_nowait(slaves[i], &link_info);
712 agg_bandwidth[agg->aggregator_port_id] += link_info.link_speed;
714 /* Actors system ID is not checked since all slave device have the same
715 * ID (MAC address). */
716 if ((agg->actor.key == port->actor.key &&
717 agg->partner.system_priority == port->partner.system_priority &&
718 is_same_ether_addr(&agg->partner.system, &port->partner.system) == 1
719 && (agg->partner.key == port->partner.key)) &&
720 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 mode_count_id = max_index(
733 (uint64_t *)agg_count, slaves_count);
734 new_agg_id = mode_count_id;
737 mode_band_id = max_index(
738 (uint64_t *)agg_bandwidth, slaves_count);
739 new_agg_id = mode_band_id;
742 if (default_slave == slaves_count)
743 new_agg_id = slave_id;
745 new_agg_id = slaves[default_slave];
748 if (default_slave == slaves_count)
749 new_agg_id = slave_id;
751 new_agg_id = slaves[default_slave];
755 if (new_agg_id != port->aggregator_port_id) {
756 port->aggregator_port_id = new_agg_id;
758 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
759 "\t%s aggregator ID=%3u\n",
760 port->aggregator_port_id,
761 port->aggregator_port_id == slave_id ?
762 "aggregator not found, using default" : "aggregator found",
763 port->aggregator_port_id);
766 port->selected = SELECTED;
769 /* Function maps DPDK speed to bonding speed stored in key field */
771 link_speed_key(uint16_t speed) {
775 case ETH_SPEED_NUM_NONE:
778 case ETH_SPEED_NUM_10M:
779 key_speed = BOND_LINK_SPEED_KEY_10M;
781 case ETH_SPEED_NUM_100M:
782 key_speed = BOND_LINK_SPEED_KEY_100M;
784 case ETH_SPEED_NUM_1G:
785 key_speed = BOND_LINK_SPEED_KEY_1000M;
787 case ETH_SPEED_NUM_10G:
788 key_speed = BOND_LINK_SPEED_KEY_10G;
790 case ETH_SPEED_NUM_20G:
791 key_speed = BOND_LINK_SPEED_KEY_20G;
793 case ETH_SPEED_NUM_40G:
794 key_speed = BOND_LINK_SPEED_KEY_40G;
805 rx_machine_update(struct bond_dev_private *internals, uint8_t slave_id,
806 struct rte_mbuf *lacp_pkt) {
807 struct lacpdu_header *lacp;
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 /* This is LACP frame so pass it to rx_machine */
814 rx_machine(internals, slave_id, &lacp->lacpdu);
815 rte_pktmbuf_free(lacp_pkt);
817 rx_machine(internals, slave_id, NULL);
821 bond_mode_8023ad_periodic_cb(void *arg)
823 struct rte_eth_dev *bond_dev = arg;
824 struct bond_dev_private *internals = bond_dev->data->dev_private;
826 struct rte_eth_link link_info;
827 struct ether_addr slave_addr;
828 struct rte_mbuf *lacp_pkt = NULL;
833 /* Update link status on each port */
834 for (i = 0; i < internals->active_slave_count; i++) {
837 slave_id = internals->active_slaves[i];
838 rte_eth_link_get_nowait(slave_id, &link_info);
839 rte_eth_macaddr_get(slave_id, &slave_addr);
841 if (link_info.link_status != 0) {
842 key = link_speed_key(link_info.link_speed) << 1;
843 if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
844 key |= BOND_LINK_FULL_DUPLEX_KEY;
848 port = &mode_8023ad_ports[slave_id];
850 key = rte_cpu_to_be_16(key);
851 if (key != port->actor.key) {
852 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
853 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
855 port->actor.key = key;
856 SM_FLAG_SET(port, NTT);
859 if (!is_same_ether_addr(&port->actor.system, &slave_addr)) {
860 ether_addr_copy(&slave_addr, &port->actor.system);
861 if (port->aggregator_port_id == slave_id)
862 SM_FLAG_SET(port, NTT);
866 for (i = 0; i < internals->active_slave_count; i++) {
867 slave_id = internals->active_slaves[i];
868 port = &mode_8023ad_ports[slave_id];
870 if ((port->actor.key &
871 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
873 SM_FLAG_SET(port, BEGIN);
875 /* LACP is disabled on half duples or link is down */
876 if (SM_FLAG(port, LACP_ENABLED)) {
877 /* If port was enabled set it to BEGIN state */
878 SM_FLAG_CLR(port, LACP_ENABLED);
879 ACTOR_STATE_CLR(port, DISTRIBUTING);
880 ACTOR_STATE_CLR(port, COLLECTING);
883 /* Skip this port processing */
887 SM_FLAG_SET(port, LACP_ENABLED);
889 if (internals->mode4.dedicated_queues.enabled == 0) {
890 /* Find LACP packet to this port. Do not check subtype,
891 * it is done in function that queued packet
893 int retval = rte_ring_dequeue(port->rx_ring,
899 rx_machine_update(internals, slave_id, lacp_pkt);
901 uint16_t rx_count = rte_eth_rx_burst(slave_id,
902 internals->mode4.dedicated_queues.rx_qid,
906 bond_mode_8023ad_handle_slow_pkt(internals,
909 rx_machine_update(internals, slave_id, NULL);
912 periodic_machine(internals, slave_id);
913 mux_machine(internals, slave_id);
914 tx_machine(internals, slave_id);
915 selection_logic(internals, slave_id);
917 SM_FLAG_CLR(port, BEGIN);
918 show_warnings(slave_id);
921 rte_eal_alarm_set(internals->mode4.update_timeout_us,
922 bond_mode_8023ad_periodic_cb, arg);
926 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, uint8_t slave_id)
928 struct bond_dev_private *internals = bond_dev->data->dev_private;
930 struct port *port = &mode_8023ad_ports[slave_id];
931 struct port_params initial = {
933 .system_priority = rte_cpu_to_be_16(0xFFFF),
934 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
935 .port_priority = rte_cpu_to_be_16(0x00FF),
939 char mem_name[RTE_ETH_NAME_MAX_LEN];
941 unsigned element_size;
942 uint32_t total_tx_desc;
943 struct bond_tx_queue *bd_tx_q;
946 /* Given slave mus not be in active list */
947 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
948 internals->active_slave_count, slave_id) == internals->active_slave_count);
949 RTE_SET_USED(internals); /* used only for assert when enabled */
951 memcpy(&port->actor, &initial, sizeof(struct port_params));
952 /* Standard requires that port ID must be grater than 0.
953 * Add 1 do get corresponding port_number */
954 port->actor.port_number = rte_cpu_to_be_16((uint16_t)slave_id + 1);
956 memcpy(&port->partner, &initial, sizeof(struct port_params));
959 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
960 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
961 port->sm_flags = SM_FLAGS_BEGIN;
963 /* use this port as agregator */
964 port->aggregator_port_id = slave_id;
965 rte_eth_promiscuous_enable(slave_id);
967 timer_cancel(&port->warning_timer);
969 if (port->mbuf_pool != NULL)
972 RTE_ASSERT(port->rx_ring == NULL);
973 RTE_ASSERT(port->tx_ring == NULL);
975 socket_id = rte_eth_dev_socket_id(slave_id);
976 if (socket_id == (int)LCORE_ID_ANY)
977 socket_id = rte_socket_id();
979 element_size = sizeof(struct slow_protocol_frame) +
980 RTE_PKTMBUF_HEADROOM;
982 /* The size of the mempool should be at least:
983 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
984 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
985 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
986 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
987 total_tx_desc += bd_tx_q->nb_tx_desc;
990 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
991 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
992 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
993 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
994 0, element_size, socket_id);
996 /* Any memory allocation failure in initialization is critical because
997 * resources can't be free, so reinitialization is impossible. */
998 if (port->mbuf_pool == NULL) {
999 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1000 slave_id, mem_name, rte_strerror(rte_errno));
1003 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1004 port->rx_ring = rte_ring_create(mem_name,
1005 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1007 if (port->rx_ring == NULL) {
1008 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1009 mem_name, rte_strerror(rte_errno));
1012 /* TX ring is at least one pkt longer to make room for marker packet. */
1013 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1014 port->tx_ring = rte_ring_create(mem_name,
1015 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1017 if (port->tx_ring == NULL) {
1018 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1019 mem_name, rte_strerror(rte_errno));
1024 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev,
1027 struct bond_dev_private *internals = bond_dev->data->dev_private;
1032 /* Given slave must be in active list */
1033 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1034 internals->active_slave_count, slave_id) < internals->active_slave_count);
1036 /* Exclude slave from transmit policy. If this slave is an aggregator
1037 * make all aggregated slaves unselected to force selection logic
1038 * to select suitable aggregator for this port. */
1039 for (i = 0; i < internals->active_slave_count; i++) {
1040 port = &mode_8023ad_ports[internals->active_slaves[i]];
1041 if (port->aggregator_port_id != slave_id)
1044 port->selected = UNSELECTED;
1046 /* Use default aggregator */
1047 port->aggregator_port_id = internals->active_slaves[i];
1050 port = &mode_8023ad_ports[slave_id];
1051 port->selected = UNSELECTED;
1052 port->actor_state &= ~(STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
1055 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1056 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1058 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1059 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1064 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1066 struct bond_dev_private *internals = bond_dev->data->dev_private;
1067 struct ether_addr slave_addr;
1068 struct port *slave, *agg_slave;
1069 uint8_t slave_id, i, j;
1071 bond_mode_8023ad_stop(bond_dev);
1073 for (i = 0; i < internals->active_slave_count; i++) {
1074 slave_id = internals->active_slaves[i];
1075 slave = &mode_8023ad_ports[slave_id];
1076 rte_eth_macaddr_get(slave_id, &slave_addr);
1078 if (is_same_ether_addr(&slave_addr, &slave->actor.system))
1081 ether_addr_copy(&slave_addr, &slave->actor.system);
1082 /* Do nothing if this port is not an aggregator. In other case
1083 * Set NTT flag on every port that use this aggregator. */
1084 if (slave->aggregator_port_id != slave_id)
1087 for (j = 0; j < internals->active_slave_count; j++) {
1088 agg_slave = &mode_8023ad_ports[internals->active_slaves[j]];
1089 if (agg_slave->aggregator_port_id == slave_id)
1090 SM_FLAG_SET(agg_slave, NTT);
1094 if (bond_dev->data->dev_started)
1095 bond_mode_8023ad_start(bond_dev);
1099 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1100 struct rte_eth_bond_8023ad_conf *conf)
1102 struct bond_dev_private *internals = dev->data->dev_private;
1103 struct mode8023ad_private *mode4 = &internals->mode4;
1104 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1106 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1107 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1108 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1109 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1110 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1111 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1112 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1113 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1117 bond_mode_8023ad_conf_get_v1607(struct rte_eth_dev *dev,
1118 struct rte_eth_bond_8023ad_conf *conf)
1120 struct bond_dev_private *internals = dev->data->dev_private;
1121 struct mode8023ad_private *mode4 = &internals->mode4;
1123 bond_mode_8023ad_conf_get(dev, conf);
1124 conf->slowrx_cb = mode4->slowrx_cb;
1128 bond_mode_8023ad_conf_get_v1708(struct rte_eth_dev *dev,
1129 struct rte_eth_bond_8023ad_conf *conf)
1131 struct bond_dev_private *internals = dev->data->dev_private;
1132 struct mode8023ad_private *mode4 = &internals->mode4;
1134 bond_mode_8023ad_conf_get(dev, conf);
1135 conf->slowrx_cb = mode4->slowrx_cb;
1136 conf->agg_selection = mode4->agg_selection;
1140 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1142 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1143 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1144 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1145 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1146 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1147 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1148 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1149 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1150 conf->slowrx_cb = NULL;
1151 conf->agg_selection = AGG_STABLE;
1155 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1156 struct rte_eth_bond_8023ad_conf *conf)
1158 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1160 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1161 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1162 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1163 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1164 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1165 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1166 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1167 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1169 mode4->dedicated_queues.enabled = 0;
1170 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1171 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1175 bond_mode_8023ad_setup_v20(struct rte_eth_dev *dev,
1176 struct rte_eth_bond_8023ad_conf *conf)
1178 struct rte_eth_bond_8023ad_conf def_conf;
1179 struct bond_dev_private *internals = dev->data->dev_private;
1180 struct mode8023ad_private *mode4 = &internals->mode4;
1184 bond_mode_8023ad_conf_get_default(conf);
1187 bond_mode_8023ad_stop(dev);
1188 bond_mode_8023ad_conf_assign(mode4, conf);
1190 if (dev->data->dev_started)
1191 bond_mode_8023ad_start(dev);
1196 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1197 struct rte_eth_bond_8023ad_conf *conf)
1199 struct rte_eth_bond_8023ad_conf def_conf;
1200 struct bond_dev_private *internals = dev->data->dev_private;
1201 struct mode8023ad_private *mode4 = &internals->mode4;
1205 bond_mode_8023ad_conf_get_default(conf);
1208 bond_mode_8023ad_stop(dev);
1209 bond_mode_8023ad_conf_assign(mode4, conf);
1212 if (dev->data->dev_started)
1213 bond_mode_8023ad_start(dev);
1217 bond_mode_8023ad_setup_v1708(struct rte_eth_dev *dev,
1218 struct rte_eth_bond_8023ad_conf *conf)
1220 struct rte_eth_bond_8023ad_conf def_conf;
1221 struct bond_dev_private *internals = dev->data->dev_private;
1222 struct mode8023ad_private *mode4 = &internals->mode4;
1226 bond_mode_8023ad_conf_get_default(conf);
1229 bond_mode_8023ad_stop(dev);
1230 bond_mode_8023ad_conf_assign(mode4, conf);
1231 mode4->slowrx_cb = conf->slowrx_cb;
1232 mode4->agg_selection = AGG_STABLE;
1234 if (dev->data->dev_started)
1235 bond_mode_8023ad_start(dev);
1239 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1241 struct bond_dev_private *internals = bond_dev->data->dev_private;
1244 for (i = 0; i < internals->active_slave_count; i++)
1245 bond_mode_8023ad_activate_slave(bond_dev, i);
1251 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1253 struct bond_dev_private *internals = bond_dev->data->dev_private;
1254 struct mode8023ad_private *mode4 = &internals->mode4;
1255 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1257 if (mode4->slowrx_cb)
1258 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1261 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1265 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1267 struct bond_dev_private *internals = bond_dev->data->dev_private;
1268 struct mode8023ad_private *mode4 = &internals->mode4;
1270 if (mode4->slowrx_cb) {
1271 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1275 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1279 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1280 uint8_t slave_id, struct rte_mbuf *pkt)
1282 struct mode8023ad_private *mode4 = &internals->mode4;
1283 struct port *port = &mode_8023ad_ports[slave_id];
1284 struct marker_header *m_hdr;
1285 uint64_t marker_timer, old_marker_timer;
1287 uint8_t wrn, subtype;
1288 /* If packet is a marker, we send response now by reusing given packet
1289 * and update only source MAC, destination MAC is multicast so don't
1290 * update it. Other frames will be handled later by state machines */
1291 subtype = rte_pktmbuf_mtod(pkt,
1292 struct slow_protocol_frame *)->slow_protocol.subtype;
1294 if (subtype == SLOW_SUBTYPE_MARKER) {
1295 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1297 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1298 wrn = WRN_UNKNOWN_MARKER_TYPE;
1302 /* Setup marker timer. Do it in loop in case concurrent access. */
1304 old_marker_timer = port->rx_marker_timer;
1305 if (!timer_is_expired(&old_marker_timer)) {
1306 wrn = WRN_RX_MARKER_TO_FAST;
1310 timer_set(&marker_timer, mode4->rx_marker_timeout);
1311 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1312 old_marker_timer, marker_timer);
1313 } while (unlikely(retval == 0));
1315 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1316 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1318 if (internals->mode4.dedicated_queues.enabled == 0) {
1319 int retval = rte_ring_enqueue(port->tx_ring, pkt);
1322 port->rx_marker_timer = 0;
1323 wrn = WRN_TX_QUEUE_FULL;
1327 /* Send packet directly to the slow queue */
1328 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1329 internals->mode4.dedicated_queues.tx_qid,
1331 if (tx_count != 1) {
1333 port->rx_marker_timer = 0;
1334 wrn = WRN_TX_QUEUE_FULL;
1338 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1339 if (internals->mode4.dedicated_queues.enabled == 0) {
1340 int retval = rte_ring_enqueue(port->rx_ring, pkt);
1342 /* If RX fing full free lacpdu message and drop packet */
1343 wrn = WRN_RX_QUEUE_FULL;
1347 rx_machine_update(internals, slave_id, pkt);
1349 wrn = WRN_UNKNOWN_SLOW_TYPE;
1356 set_warning_flags(port, wrn);
1357 rte_pktmbuf_free(pkt);
1361 rte_eth_bond_8023ad_conf_get_v20(uint8_t port_id,
1362 struct rte_eth_bond_8023ad_conf *conf)
1364 struct rte_eth_dev *bond_dev;
1366 if (valid_bonded_port_id(port_id) != 0)
1372 bond_dev = &rte_eth_devices[port_id];
1373 bond_mode_8023ad_conf_get(bond_dev, conf);
1376 VERSION_SYMBOL(rte_eth_bond_8023ad_conf_get, _v20, 2.0);
1379 rte_eth_bond_8023ad_conf_get_v1607(uint8_t port_id,
1380 struct rte_eth_bond_8023ad_conf *conf)
1382 struct rte_eth_dev *bond_dev;
1384 if (valid_bonded_port_id(port_id) != 0)
1390 bond_dev = &rte_eth_devices[port_id];
1391 bond_mode_8023ad_conf_get_v1607(bond_dev, conf);
1394 VERSION_SYMBOL(rte_eth_bond_8023ad_conf_get, _v1607, 16.07);
1397 rte_eth_bond_8023ad_conf_get_v1708(uint8_t port_id,
1398 struct rte_eth_bond_8023ad_conf *conf)
1400 struct rte_eth_dev *bond_dev;
1402 if (valid_bonded_port_id(port_id) != 0)
1408 bond_dev = &rte_eth_devices[port_id];
1409 bond_mode_8023ad_conf_get_v1708(bond_dev, conf);
1412 MAP_STATIC_SYMBOL(int rte_eth_bond_8023ad_conf_get(uint8_t port_id,
1413 struct rte_eth_bond_8023ad_conf *conf),
1414 rte_eth_bond_8023ad_conf_get_v1708);
1415 BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_conf_get, _v1708, 17.08);
1418 rte_eth_bond_8023ad_agg_selection_set(uint8_t port_id,
1419 enum rte_bond_8023ad_agg_selection agg_selection)
1421 struct rte_eth_dev *bond_dev;
1422 struct bond_dev_private *internals;
1423 struct mode8023ad_private *mode4;
1425 bond_dev = &rte_eth_devices[port_id];
1426 internals = bond_dev->data->dev_private;
1428 if (valid_bonded_port_id(port_id) != 0)
1430 if (internals->mode != 4)
1433 mode4 = &internals->mode4;
1434 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1435 || agg_selection == AGG_STABLE)
1436 mode4->agg_selection = agg_selection;
1440 int rte_eth_bond_8023ad_agg_selection_get(uint8_t port_id)
1442 struct rte_eth_dev *bond_dev;
1443 struct bond_dev_private *internals;
1444 struct mode8023ad_private *mode4;
1446 bond_dev = &rte_eth_devices[port_id];
1447 internals = bond_dev->data->dev_private;
1449 if (valid_bonded_port_id(port_id) != 0)
1451 if (internals->mode != 4)
1453 mode4 = &internals->mode4;
1455 return mode4->agg_selection;
1461 bond_8023ad_setup_validate(uint8_t port_id,
1462 struct rte_eth_bond_8023ad_conf *conf)
1464 if (valid_bonded_port_id(port_id) != 0)
1468 /* Basic sanity check */
1469 if (conf->slow_periodic_ms == 0 ||
1470 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1471 conf->long_timeout_ms == 0 ||
1472 conf->short_timeout_ms >= conf->long_timeout_ms ||
1473 conf->aggregate_wait_timeout_ms == 0 ||
1474 conf->tx_period_ms == 0 ||
1475 conf->rx_marker_period_ms == 0 ||
1476 conf->update_timeout_ms == 0) {
1477 RTE_LOG(ERR, PMD, "given mode 4 configuration is invalid\n");
1486 rte_eth_bond_8023ad_setup_v20(uint8_t port_id,
1487 struct rte_eth_bond_8023ad_conf *conf)
1489 struct rte_eth_dev *bond_dev;
1492 err = bond_8023ad_setup_validate(port_id, conf);
1496 bond_dev = &rte_eth_devices[port_id];
1497 bond_mode_8023ad_setup_v20(bond_dev, conf);
1501 VERSION_SYMBOL(rte_eth_bond_8023ad_setup, _v20, 2.0);
1504 rte_eth_bond_8023ad_setup_v1607(uint8_t port_id,
1505 struct rte_eth_bond_8023ad_conf *conf)
1507 struct rte_eth_dev *bond_dev;
1510 err = bond_8023ad_setup_validate(port_id, conf);
1514 bond_dev = &rte_eth_devices[port_id];
1515 bond_mode_8023ad_setup(bond_dev, conf);
1519 VERSION_SYMBOL(rte_eth_bond_8023ad_setup, _v1607, 16.07);
1523 rte_eth_bond_8023ad_setup_v1708(uint8_t port_id,
1524 struct rte_eth_bond_8023ad_conf *conf)
1526 struct rte_eth_dev *bond_dev;
1529 err = bond_8023ad_setup_validate(port_id, conf);
1533 bond_dev = &rte_eth_devices[port_id];
1534 bond_mode_8023ad_setup_v1708(bond_dev, conf);
1538 BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_setup, _v1708, 17.08);
1539 MAP_STATIC_SYMBOL(int rte_eth_bond_8023ad_setup(uint8_t port_id,
1540 struct rte_eth_bond_8023ad_conf *conf),
1541 rte_eth_bond_8023ad_setup_v1708);
1549 rte_eth_bond_8023ad_slave_info(uint8_t port_id, uint8_t slave_id,
1550 struct rte_eth_bond_8023ad_slave_info *info)
1552 struct rte_eth_dev *bond_dev;
1553 struct bond_dev_private *internals;
1556 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1557 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1560 bond_dev = &rte_eth_devices[port_id];
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 port = &mode_8023ad_ports[slave_id];
1569 info->selected = port->selected;
1571 info->actor_state = port->actor_state;
1572 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1574 info->partner_state = port->partner_state;
1575 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1577 info->agg_port_id = port->aggregator_port_id;
1582 bond_8023ad_ext_validate(uint8_t port_id, uint8_t slave_id)
1584 struct rte_eth_dev *bond_dev;
1585 struct bond_dev_private *internals;
1586 struct mode8023ad_private *mode4;
1588 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1591 bond_dev = &rte_eth_devices[port_id];
1593 if (!bond_dev->data->dev_started)
1596 internals = bond_dev->data->dev_private;
1597 if (find_slave_by_id(internals->active_slaves,
1598 internals->active_slave_count, slave_id) ==
1599 internals->active_slave_count)
1602 mode4 = &internals->mode4;
1603 if (mode4->slowrx_cb == NULL)
1610 rte_eth_bond_8023ad_ext_collect(uint8_t port_id, uint8_t slave_id, int enabled)
1615 res = bond_8023ad_ext_validate(port_id, slave_id);
1619 port = &mode_8023ad_ports[slave_id];
1622 ACTOR_STATE_SET(port, COLLECTING);
1624 ACTOR_STATE_CLR(port, COLLECTING);
1630 rte_eth_bond_8023ad_ext_distrib(uint8_t port_id, uint8_t slave_id, int enabled)
1635 res = bond_8023ad_ext_validate(port_id, slave_id);
1639 port = &mode_8023ad_ports[slave_id];
1642 ACTOR_STATE_SET(port, DISTRIBUTING);
1644 ACTOR_STATE_CLR(port, DISTRIBUTING);
1650 rte_eth_bond_8023ad_ext_distrib_get(uint8_t port_id, uint8_t slave_id)
1655 err = bond_8023ad_ext_validate(port_id, slave_id);
1659 port = &mode_8023ad_ports[slave_id];
1660 return ACTOR_STATE(port, DISTRIBUTING);
1664 rte_eth_bond_8023ad_ext_collect_get(uint8_t port_id, uint8_t slave_id)
1669 err = bond_8023ad_ext_validate(port_id, slave_id);
1673 port = &mode_8023ad_ports[slave_id];
1674 return ACTOR_STATE(port, COLLECTING);
1678 rte_eth_bond_8023ad_ext_slowtx(uint8_t port_id, uint8_t slave_id,
1679 struct rte_mbuf *lacp_pkt)
1684 res = bond_8023ad_ext_validate(port_id, slave_id);
1688 port = &mode_8023ad_ports[slave_id];
1690 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1693 struct lacpdu_header *lacp;
1695 /* only enqueue LACPDUs */
1696 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1697 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1700 MODE4_DEBUG("sending LACP frame\n");
1702 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1706 bond_mode_8023ad_ext_periodic_cb(void *arg)
1708 struct rte_eth_dev *bond_dev = arg;
1709 struct bond_dev_private *internals = bond_dev->data->dev_private;
1710 struct mode8023ad_private *mode4 = &internals->mode4;
1713 uint16_t i, slave_id;
1715 for (i = 0; i < internals->active_slave_count; i++) {
1716 slave_id = internals->active_slaves[i];
1717 port = &mode_8023ad_ports[slave_id];
1719 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1720 struct rte_mbuf *lacp_pkt = pkt;
1721 struct lacpdu_header *lacp;
1723 lacp = rte_pktmbuf_mtod(lacp_pkt,
1724 struct lacpdu_header *);
1725 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1727 /* This is LACP frame so pass it to rx callback.
1728 * Callback is responsible for freeing mbuf.
1730 mode4->slowrx_cb(slave_id, lacp_pkt);
1734 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1735 bond_mode_8023ad_ext_periodic_cb, arg);
1739 rte_eth_bond_8023ad_dedicated_queues_enable(uint8_t port)
1742 struct rte_eth_dev *dev = &rte_eth_devices[port];
1743 struct bond_dev_private *internals = (struct bond_dev_private *)
1744 dev->data->dev_private;
1746 if (check_for_bonded_ethdev(dev) != 0)
1749 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1752 /* Device must be stopped to set up slow queue */
1753 if (dev->data->dev_started)
1756 internals->mode4.dedicated_queues.enabled = 1;
1758 bond_ethdev_mode_set(dev, internals->mode);
1763 rte_eth_bond_8023ad_dedicated_queues_disable(uint8_t port)
1766 struct rte_eth_dev *dev = &rte_eth_devices[port];
1767 struct bond_dev_private *internals = (struct bond_dev_private *)
1768 dev->data->dev_private;
1770 if (check_for_bonded_ethdev(dev) != 0)
1773 /* Device must be stopped to set up slow queue */
1774 if (dev->data->dev_started)
1777 internals->mode4.dedicated_queues.enabled = 0;
1779 bond_ethdev_mode_set(dev, internals->mode);