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(uint16_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, uint16_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, uint16_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, uint16_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, uint16_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 uint16_t slaves_count, new_agg_id, i, j = 0;
693 uint64_t agg_bandwidth[8] = {0};
694 uint64_t agg_count[8] = {0};
695 uint16_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,
929 struct bond_dev_private *internals = bond_dev->data->dev_private;
931 struct port *port = &mode_8023ad_ports[slave_id];
932 struct port_params initial = {
934 .system_priority = rte_cpu_to_be_16(0xFFFF),
935 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
936 .port_priority = rte_cpu_to_be_16(0x00FF),
940 char mem_name[RTE_ETH_NAME_MAX_LEN];
942 unsigned element_size;
943 uint32_t total_tx_desc;
944 struct bond_tx_queue *bd_tx_q;
947 /* Given slave mus not be in active list */
948 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
949 internals->active_slave_count, slave_id) == internals->active_slave_count);
950 RTE_SET_USED(internals); /* used only for assert when enabled */
952 memcpy(&port->actor, &initial, sizeof(struct port_params));
953 /* Standard requires that port ID must be grater than 0.
954 * Add 1 do get corresponding port_number */
955 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
957 memcpy(&port->partner, &initial, sizeof(struct port_params));
960 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
961 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
962 port->sm_flags = SM_FLAGS_BEGIN;
964 /* use this port as agregator */
965 port->aggregator_port_id = slave_id;
966 rte_eth_promiscuous_enable(slave_id);
968 timer_cancel(&port->warning_timer);
970 if (port->mbuf_pool != NULL)
973 RTE_ASSERT(port->rx_ring == NULL);
974 RTE_ASSERT(port->tx_ring == NULL);
976 socket_id = rte_eth_dev_socket_id(slave_id);
977 if (socket_id == (int)LCORE_ID_ANY)
978 socket_id = rte_socket_id();
980 element_size = sizeof(struct slow_protocol_frame) +
981 RTE_PKTMBUF_HEADROOM;
983 /* The size of the mempool should be at least:
984 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
985 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
986 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
987 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
988 total_tx_desc += bd_tx_q->nb_tx_desc;
991 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
992 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
993 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
994 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
995 0, element_size, socket_id);
997 /* Any memory allocation failure in initialization is critical because
998 * resources can't be free, so reinitialization is impossible. */
999 if (port->mbuf_pool == NULL) {
1000 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1001 slave_id, mem_name, rte_strerror(rte_errno));
1004 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1005 port->rx_ring = rte_ring_create(mem_name,
1006 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1008 if (port->rx_ring == NULL) {
1009 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1010 mem_name, rte_strerror(rte_errno));
1013 /* TX ring is at least one pkt longer to make room for marker packet. */
1014 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1015 port->tx_ring = rte_ring_create(mem_name,
1016 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1018 if (port->tx_ring == NULL) {
1019 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1020 mem_name, rte_strerror(rte_errno));
1025 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev,
1028 struct bond_dev_private *internals = bond_dev->data->dev_private;
1033 /* Given slave must be in active list */
1034 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1035 internals->active_slave_count, slave_id) < internals->active_slave_count);
1037 /* Exclude slave from transmit policy. If this slave is an aggregator
1038 * make all aggregated slaves unselected to force selection logic
1039 * to select suitable aggregator for this port. */
1040 for (i = 0; i < internals->active_slave_count; i++) {
1041 port = &mode_8023ad_ports[internals->active_slaves[i]];
1042 if (port->aggregator_port_id != slave_id)
1045 port->selected = UNSELECTED;
1047 /* Use default aggregator */
1048 port->aggregator_port_id = internals->active_slaves[i];
1051 port = &mode_8023ad_ports[slave_id];
1052 port->selected = UNSELECTED;
1053 port->actor_state &= ~(STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
1056 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1057 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1059 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1060 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1065 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1067 struct bond_dev_private *internals = bond_dev->data->dev_private;
1068 struct ether_addr slave_addr;
1069 struct port *slave, *agg_slave;
1070 uint16_t slave_id, i, j;
1072 bond_mode_8023ad_stop(bond_dev);
1074 for (i = 0; i < internals->active_slave_count; i++) {
1075 slave_id = internals->active_slaves[i];
1076 slave = &mode_8023ad_ports[slave_id];
1077 rte_eth_macaddr_get(slave_id, &slave_addr);
1079 if (is_same_ether_addr(&slave_addr, &slave->actor.system))
1082 ether_addr_copy(&slave_addr, &slave->actor.system);
1083 /* Do nothing if this port is not an aggregator. In other case
1084 * Set NTT flag on every port that use this aggregator. */
1085 if (slave->aggregator_port_id != slave_id)
1088 for (j = 0; j < internals->active_slave_count; j++) {
1089 agg_slave = &mode_8023ad_ports[internals->active_slaves[j]];
1090 if (agg_slave->aggregator_port_id == slave_id)
1091 SM_FLAG_SET(agg_slave, NTT);
1095 if (bond_dev->data->dev_started)
1096 bond_mode_8023ad_start(bond_dev);
1100 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1101 struct rte_eth_bond_8023ad_conf *conf)
1103 struct bond_dev_private *internals = dev->data->dev_private;
1104 struct mode8023ad_private *mode4 = &internals->mode4;
1105 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1107 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1108 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1109 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1110 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1111 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1112 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1113 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1114 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1115 conf->slowrx_cb = mode4->slowrx_cb;
1116 conf->agg_selection = mode4->agg_selection;
1120 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1122 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1123 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1124 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1125 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1126 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1127 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1128 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1129 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1130 conf->slowrx_cb = NULL;
1131 conf->agg_selection = AGG_STABLE;
1135 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1136 struct rte_eth_bond_8023ad_conf *conf)
1138 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1140 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1141 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1142 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1143 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1144 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1145 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1146 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1147 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1149 mode4->dedicated_queues.enabled = 0;
1150 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1151 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1155 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1156 struct rte_eth_bond_8023ad_conf *conf)
1158 struct rte_eth_bond_8023ad_conf def_conf;
1159 struct bond_dev_private *internals = dev->data->dev_private;
1160 struct mode8023ad_private *mode4 = &internals->mode4;
1164 bond_mode_8023ad_conf_get_default(conf);
1167 bond_mode_8023ad_stop(dev);
1168 bond_mode_8023ad_conf_assign(mode4, conf);
1169 mode4->slowrx_cb = conf->slowrx_cb;
1170 mode4->agg_selection = AGG_STABLE;
1172 if (dev->data->dev_started)
1173 bond_mode_8023ad_start(dev);
1177 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1179 struct bond_dev_private *internals = bond_dev->data->dev_private;
1182 for (i = 0; i < internals->active_slave_count; i++)
1183 bond_mode_8023ad_activate_slave(bond_dev, i);
1189 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1191 struct bond_dev_private *internals = bond_dev->data->dev_private;
1192 struct mode8023ad_private *mode4 = &internals->mode4;
1193 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1195 if (mode4->slowrx_cb)
1196 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1199 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1203 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1205 struct bond_dev_private *internals = bond_dev->data->dev_private;
1206 struct mode8023ad_private *mode4 = &internals->mode4;
1208 if (mode4->slowrx_cb) {
1209 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1213 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1217 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1218 uint16_t slave_id, struct rte_mbuf *pkt)
1220 struct mode8023ad_private *mode4 = &internals->mode4;
1221 struct port *port = &mode_8023ad_ports[slave_id];
1222 struct marker_header *m_hdr;
1223 uint64_t marker_timer, old_marker_timer;
1225 uint8_t wrn, subtype;
1226 /* If packet is a marker, we send response now by reusing given packet
1227 * and update only source MAC, destination MAC is multicast so don't
1228 * update it. Other frames will be handled later by state machines */
1229 subtype = rte_pktmbuf_mtod(pkt,
1230 struct slow_protocol_frame *)->slow_protocol.subtype;
1232 if (subtype == SLOW_SUBTYPE_MARKER) {
1233 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1235 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1236 wrn = WRN_UNKNOWN_MARKER_TYPE;
1240 /* Setup marker timer. Do it in loop in case concurrent access. */
1242 old_marker_timer = port->rx_marker_timer;
1243 if (!timer_is_expired(&old_marker_timer)) {
1244 wrn = WRN_RX_MARKER_TO_FAST;
1248 timer_set(&marker_timer, mode4->rx_marker_timeout);
1249 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1250 old_marker_timer, marker_timer);
1251 } while (unlikely(retval == 0));
1253 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1254 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1256 if (internals->mode4.dedicated_queues.enabled == 0) {
1257 int retval = rte_ring_enqueue(port->tx_ring, pkt);
1260 port->rx_marker_timer = 0;
1261 wrn = WRN_TX_QUEUE_FULL;
1265 /* Send packet directly to the slow queue */
1266 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1267 internals->mode4.dedicated_queues.tx_qid,
1269 if (tx_count != 1) {
1271 port->rx_marker_timer = 0;
1272 wrn = WRN_TX_QUEUE_FULL;
1276 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1277 if (internals->mode4.dedicated_queues.enabled == 0) {
1278 int retval = rte_ring_enqueue(port->rx_ring, pkt);
1280 /* If RX fing full free lacpdu message and drop packet */
1281 wrn = WRN_RX_QUEUE_FULL;
1285 rx_machine_update(internals, slave_id, pkt);
1287 wrn = WRN_UNKNOWN_SLOW_TYPE;
1294 set_warning_flags(port, wrn);
1295 rte_pktmbuf_free(pkt);
1299 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1300 struct rte_eth_bond_8023ad_conf *conf)
1302 struct rte_eth_dev *bond_dev;
1304 if (valid_bonded_port_id(port_id) != 0)
1310 bond_dev = &rte_eth_devices[port_id];
1311 bond_mode_8023ad_conf_get(bond_dev, conf);
1316 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1317 enum rte_bond_8023ad_agg_selection agg_selection)
1319 struct rte_eth_dev *bond_dev;
1320 struct bond_dev_private *internals;
1321 struct mode8023ad_private *mode4;
1323 bond_dev = &rte_eth_devices[port_id];
1324 internals = bond_dev->data->dev_private;
1326 if (valid_bonded_port_id(port_id) != 0)
1328 if (internals->mode != 4)
1331 mode4 = &internals->mode4;
1332 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1333 || agg_selection == AGG_STABLE)
1334 mode4->agg_selection = agg_selection;
1338 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1340 struct rte_eth_dev *bond_dev;
1341 struct bond_dev_private *internals;
1342 struct mode8023ad_private *mode4;
1344 bond_dev = &rte_eth_devices[port_id];
1345 internals = bond_dev->data->dev_private;
1347 if (valid_bonded_port_id(port_id) != 0)
1349 if (internals->mode != 4)
1351 mode4 = &internals->mode4;
1353 return mode4->agg_selection;
1359 bond_8023ad_setup_validate(uint16_t port_id,
1360 struct rte_eth_bond_8023ad_conf *conf)
1362 if (valid_bonded_port_id(port_id) != 0)
1366 /* Basic sanity check */
1367 if (conf->slow_periodic_ms == 0 ||
1368 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1369 conf->long_timeout_ms == 0 ||
1370 conf->short_timeout_ms >= conf->long_timeout_ms ||
1371 conf->aggregate_wait_timeout_ms == 0 ||
1372 conf->tx_period_ms == 0 ||
1373 conf->rx_marker_period_ms == 0 ||
1374 conf->update_timeout_ms == 0) {
1375 RTE_LOG(ERR, PMD, "given mode 4 configuration is invalid\n");
1385 rte_eth_bond_8023ad_setup(uint16_t port_id,
1386 struct rte_eth_bond_8023ad_conf *conf)
1388 struct rte_eth_dev *bond_dev;
1391 err = bond_8023ad_setup_validate(port_id, conf);
1395 bond_dev = &rte_eth_devices[port_id];
1396 bond_mode_8023ad_setup(bond_dev, conf);
1406 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1407 struct rte_eth_bond_8023ad_slave_info *info)
1409 struct rte_eth_dev *bond_dev;
1410 struct bond_dev_private *internals;
1413 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1414 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1417 bond_dev = &rte_eth_devices[port_id];
1419 internals = bond_dev->data->dev_private;
1420 if (find_slave_by_id(internals->active_slaves,
1421 internals->active_slave_count, slave_id) ==
1422 internals->active_slave_count)
1425 port = &mode_8023ad_ports[slave_id];
1426 info->selected = port->selected;
1428 info->actor_state = port->actor_state;
1429 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1431 info->partner_state = port->partner_state;
1432 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1434 info->agg_port_id = port->aggregator_port_id;
1439 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1441 struct rte_eth_dev *bond_dev;
1442 struct bond_dev_private *internals;
1443 struct mode8023ad_private *mode4;
1445 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1448 bond_dev = &rte_eth_devices[port_id];
1450 if (!bond_dev->data->dev_started)
1453 internals = bond_dev->data->dev_private;
1454 if (find_slave_by_id(internals->active_slaves,
1455 internals->active_slave_count, slave_id) ==
1456 internals->active_slave_count)
1459 mode4 = &internals->mode4;
1460 if (mode4->slowrx_cb == NULL)
1467 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1473 res = bond_8023ad_ext_validate(port_id, slave_id);
1477 port = &mode_8023ad_ports[slave_id];
1480 ACTOR_STATE_SET(port, COLLECTING);
1482 ACTOR_STATE_CLR(port, COLLECTING);
1488 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1494 res = bond_8023ad_ext_validate(port_id, slave_id);
1498 port = &mode_8023ad_ports[slave_id];
1501 ACTOR_STATE_SET(port, DISTRIBUTING);
1503 ACTOR_STATE_CLR(port, DISTRIBUTING);
1509 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1514 err = bond_8023ad_ext_validate(port_id, slave_id);
1518 port = &mode_8023ad_ports[slave_id];
1519 return ACTOR_STATE(port, DISTRIBUTING);
1523 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1528 err = bond_8023ad_ext_validate(port_id, slave_id);
1532 port = &mode_8023ad_ports[slave_id];
1533 return ACTOR_STATE(port, COLLECTING);
1537 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1538 struct rte_mbuf *lacp_pkt)
1543 res = bond_8023ad_ext_validate(port_id, slave_id);
1547 port = &mode_8023ad_ports[slave_id];
1549 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1552 struct lacpdu_header *lacp;
1554 /* only enqueue LACPDUs */
1555 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1556 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1559 MODE4_DEBUG("sending LACP frame\n");
1561 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1565 bond_mode_8023ad_ext_periodic_cb(void *arg)
1567 struct rte_eth_dev *bond_dev = arg;
1568 struct bond_dev_private *internals = bond_dev->data->dev_private;
1569 struct mode8023ad_private *mode4 = &internals->mode4;
1572 uint16_t i, slave_id;
1574 for (i = 0; i < internals->active_slave_count; i++) {
1575 slave_id = internals->active_slaves[i];
1576 port = &mode_8023ad_ports[slave_id];
1578 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1579 struct rte_mbuf *lacp_pkt = pkt;
1580 struct lacpdu_header *lacp;
1582 lacp = rte_pktmbuf_mtod(lacp_pkt,
1583 struct lacpdu_header *);
1584 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1586 /* This is LACP frame so pass it to rx callback.
1587 * Callback is responsible for freeing mbuf.
1589 mode4->slowrx_cb(slave_id, lacp_pkt);
1593 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1594 bond_mode_8023ad_ext_periodic_cb, arg);
1598 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1601 struct rte_eth_dev *dev = &rte_eth_devices[port];
1602 struct bond_dev_private *internals = (struct bond_dev_private *)
1603 dev->data->dev_private;
1605 if (check_for_bonded_ethdev(dev) != 0)
1608 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1611 /* Device must be stopped to set up slow queue */
1612 if (dev->data->dev_started)
1615 internals->mode4.dedicated_queues.enabled = 1;
1617 bond_ethdev_mode_set(dev, internals->mode);
1622 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1625 struct rte_eth_dev *dev = &rte_eth_devices[port];
1626 struct bond_dev_private *internals = (struct bond_dev_private *)
1627 dev->data->dev_private;
1629 if (check_for_bonded_ethdev(dev) != 0)
1632 /* Device must be stopped to set up slow queue */
1633 if (dev->data->dev_started)
1636 internals->mode4.dedicated_queues.enabled = 0;
1638 bond_ethdev_mode_set(dev, internals->mode);