Imported Upstream version 16.04
[deb_dpdk.git] / drivers / net / bonding / rte_eth_bond_8023ad.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
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
16  *       distribution.
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.
20  *
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.
32  */
33
34 #include <stddef.h>
35 #include <string.h>
36 #include <stdbool.h>
37
38 #include <rte_alarm.h>
39 #include <rte_malloc.h>
40 #include <rte_errno.h>
41 #include <rte_cycles.h>
42
43 #include "rte_eth_bond_private.h"
44
45 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
46 #define MODE4_DEBUG(fmt, ...) RTE_LOG(DEBUG, PMD, "%6u [Port %u: %s] " fmt, \
47                         bond_dbg_get_time_diff_ms(), slave_id, \
48                         __func__, ##__VA_ARGS__)
49
50 static uint64_t start_time;
51
52 static unsigned
53 bond_dbg_get_time_diff_ms(void)
54 {
55         uint64_t now;
56
57         now = rte_rdtsc();
58         if (start_time == 0)
59                 start_time = now;
60
61         return ((now - start_time) * 1000) / rte_get_tsc_hz();
62 }
63
64 static void
65 bond_print_lacp(struct lacpdu *l)
66 {
67         char a_address[18];
68         char p_address[18];
69         char a_state[256] = { 0 };
70         char p_state[256] = { 0 };
71
72         static const char * const state_labels[] = {
73                 "ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
74         };
75
76         int a_len = 0;
77         int p_len = 0;
78         uint8_t i;
79         uint8_t *addr;
80
81         addr = l->actor.port_params.system.addr_bytes;
82         snprintf(a_address, sizeof(a_address), "%02X:%02X:%02X:%02X:%02X:%02X",
83                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
84
85         addr = l->partner.port_params.system.addr_bytes;
86         snprintf(p_address, sizeof(p_address), "%02X:%02X:%02X:%02X:%02X:%02X",
87                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
88
89         for (i = 0; i < 8; i++) {
90                 if ((l->actor.state >> i) & 1) {
91                         a_len += snprintf(&a_state[a_len], RTE_DIM(a_state) - a_len, "%s ",
92                                 state_labels[i]);
93                 }
94
95                 if ((l->partner.state >> i) & 1) {
96                         p_len += snprintf(&p_state[p_len], RTE_DIM(p_state) - p_len, "%s ",
97                                 state_labels[i]);
98                 }
99         }
100
101         if (a_len && a_state[a_len-1] == ' ')
102                 a_state[a_len-1] = '\0';
103
104         if (p_len && p_state[p_len-1] == ' ')
105                 p_state[p_len-1] = '\0';
106
107         RTE_LOG(DEBUG, PMD, "LACP: {\n"\
108                         "  subtype= %02X\n"\
109                         "  ver_num=%02X\n"\
110                         "  actor={ tlv=%02X, len=%02X\n"\
111                         "    pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\
112                         "       state={ %s }\n"\
113                         "  }\n"\
114                         "  partner={ tlv=%02X, len=%02X\n"\
115                         "    pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\
116                         "       state={ %s }\n"\
117                         "  }\n"\
118                         "  collector={info=%02X, length=%02X, max_delay=%04X\n, " \
119                                                         "type_term=%02X, terminator_length = %02X}\n",\
120                         l->subtype,\
121                         l->version_number,\
122                         l->actor.tlv_type_info,\
123                         l->actor.info_length,\
124                         l->actor.port_params.system_priority,\
125                         a_address,\
126                         l->actor.port_params.key,\
127                         l->actor.port_params.port_priority,\
128                         l->actor.port_params.port_number,\
129                         a_state,\
130                         l->partner.tlv_type_info,\
131                         l->partner.info_length,\
132                         l->partner.port_params.system_priority,\
133                         p_address,\
134                         l->partner.port_params.key,\
135                         l->partner.port_params.port_priority,\
136                         l->partner.port_params.port_number,\
137                         p_state,\
138                         l->tlv_type_collector_info,\
139                         l->collector_info_length,\
140                         l->collector_max_delay,\
141                         l->tlv_type_terminator,\
142                         l->terminator_length);
143
144 }
145 #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu)
146 #else
147 #define BOND_PRINT_LACP(lacpdu) do { } while (0)
148 #define MODE4_DEBUG(fmt, ...) do { } while (0)
149 #endif
150
151 static const struct ether_addr lacp_mac_addr = {
152         .addr_bytes = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
153 };
154
155 struct port mode_8023ad_ports[RTE_MAX_ETHPORTS];
156
157 static void
158 timer_cancel(uint64_t *timer)
159 {
160         *timer = 0;
161 }
162
163 static void
164 timer_set(uint64_t *timer, uint64_t timeout)
165 {
166         *timer = rte_rdtsc() + timeout;
167 }
168
169 /* Forces given timer to be in expired state. */
170 static void
171 timer_force_expired(uint64_t *timer)
172 {
173         *timer = rte_rdtsc();
174 }
175
176 static bool
177 timer_is_stopped(uint64_t *timer)
178 {
179         return *timer == 0;
180 }
181
182 static bool
183 timer_is_expired(uint64_t *timer)
184 {
185         return *timer < rte_rdtsc();
186 }
187
188 /* Timer is in running state if it is not stopped nor expired */
189 static bool
190 timer_is_running(uint64_t *timer)
191 {
192         return !timer_is_stopped(timer) && !timer_is_expired(timer);
193 }
194
195 static void
196 set_warning_flags(struct port *port, uint16_t flags)
197 {
198         int retval;
199         uint16_t old;
200         uint16_t new_flag = 0;
201
202         do {
203                 old = port->warnings_to_show;
204                 new_flag = old | flags;
205                 retval = rte_atomic16_cmpset(&port->warnings_to_show, old, new_flag);
206         } while (unlikely(retval == 0));
207 }
208
209 static void
210 show_warnings(uint8_t slave_id)
211 {
212         struct port *port = &mode_8023ad_ports[slave_id];
213         uint8_t warnings;
214
215         do {
216                 warnings = port->warnings_to_show;
217         } while (rte_atomic16_cmpset(&port->warnings_to_show, warnings, 0) == 0);
218
219         if (!warnings)
220                 return;
221
222         if (!timer_is_expired(&port->warning_timer))
223                 return;
224
225
226         timer_set(&port->warning_timer, BOND_8023AD_WARNINGS_PERIOD_MS *
227                         rte_get_tsc_hz() / 1000);
228
229         if (warnings & WRN_RX_QUEUE_FULL) {
230                 RTE_LOG(DEBUG, PMD,
231                         "Slave %u: failed to enqueue LACP packet into RX ring.\n"
232                         "Receive and transmit functions must be invoked on bonded\n"
233                         "interface at least 10 times per second or LACP will not\n"
234                         "work correctly\n", slave_id);
235         }
236
237         if (warnings & WRN_TX_QUEUE_FULL) {
238                 RTE_LOG(DEBUG, PMD,
239                         "Slave %u: failed to enqueue LACP packet into TX ring.\n"
240                         "Receive and transmit functions must be invoked on bonded\n"
241                         "interface at least 10 times per second or LACP will not\n"
242                         "work correctly\n", slave_id);
243         }
244
245         if (warnings & WRN_RX_MARKER_TO_FAST)
246                 RTE_LOG(INFO, PMD, "Slave %u: marker to early - ignoring.\n", slave_id);
247
248         if (warnings & WRN_UNKNOWN_SLOW_TYPE) {
249                 RTE_LOG(INFO, PMD,
250                         "Slave %u: ignoring unknown slow protocol frame type", slave_id);
251         }
252
253         if (warnings & WRN_UNKNOWN_MARKER_TYPE)
254                 RTE_LOG(INFO, PMD, "Slave %u: ignoring unknown marker type", slave_id);
255
256         if (warnings & WRN_NOT_LACP_CAPABLE)
257                 MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id);
258 }
259
260 static void
261 record_default(struct port *port)
262 {
263         /* Record default parameters for partner. Partner admin parameters
264          * are not implemented so set them to arbitrary default (last known) and
265          * mark actor that parner is in defaulted state. */
266         port->partner_state = STATE_LACP_ACTIVE;
267         ACTOR_STATE_SET(port, DEFAULTED);
268 }
269
270 /** Function handles rx state machine.
271  *
272  * This function implements Receive State Machine from point 5.4.12 in
273  * 802.1AX documentation. It should be called periodically.
274  *
275  * @param lacpdu                LACPDU received.
276  * @param port                  Port on which LACPDU was received.
277  */
278 static void
279 rx_machine(struct bond_dev_private *internals, uint8_t slave_id,
280                 struct lacpdu *lacp)
281 {
282         struct port *agg, *port = &mode_8023ad_ports[slave_id];
283         uint64_t timeout;
284
285         if (SM_FLAG(port, BEGIN)) {
286                 /* Initialize stuff */
287                 MODE4_DEBUG("-> INITIALIZE\n");
288                 SM_FLAG_CLR(port, MOVED);
289                 port->selected = UNSELECTED;
290
291                 record_default(port);
292
293                 ACTOR_STATE_CLR(port, EXPIRED);
294                 timer_cancel(&port->current_while_timer);
295
296                 /* DISABLED: On initialization partner is out of sync */
297                 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
298
299                 /* LACP DISABLED stuff if LACP not enabled on this port */
300                 if (!SM_FLAG(port, LACP_ENABLED))
301                         PARTNER_STATE_CLR(port, AGGREGATION);
302                 else
303                         PARTNER_STATE_SET(port, AGGREGATION);
304         }
305
306         if (!SM_FLAG(port, LACP_ENABLED)) {
307                 /* Update parameters only if state changed */
308                 if (!timer_is_stopped(&port->current_while_timer)) {
309                         port->selected = UNSELECTED;
310                         record_default(port);
311                         PARTNER_STATE_CLR(port, AGGREGATION);
312                         ACTOR_STATE_CLR(port, EXPIRED);
313                         timer_cancel(&port->current_while_timer);
314                 }
315                 return;
316         }
317
318         if (lacp) {
319                 MODE4_DEBUG("LACP -> CURRENT\n");
320                 BOND_PRINT_LACP(lacp);
321                 /* Update selected flag. If partner parameters are defaulted assume they
322                  * are match. If not defaulted  compare LACP actor with ports parner
323                  * params. */
324                 if (!ACTOR_STATE(port, DEFAULTED) &&
325                         (ACTOR_STATE(port, AGGREGATION) != PARTNER_STATE(port, AGGREGATION)
326                         || memcmp(&port->partner, &lacp->actor.port_params,
327                                 sizeof(port->partner)) != 0)) {
328                         MODE4_DEBUG("selected <- UNSELECTED\n");
329                         port->selected = UNSELECTED;
330                 }
331
332                 /* Record this PDU actor params as partner params */
333                 memcpy(&port->partner, &lacp->actor.port_params,
334                         sizeof(struct port_params));
335                 port->partner_state = lacp->actor.state;
336
337                 /* Partner parameters are not defaulted any more */
338                 ACTOR_STATE_CLR(port, DEFAULTED);
339
340                 /* If LACP partner params match this port actor params */
341                 agg = &mode_8023ad_ports[port->aggregator_port_id];
342                 bool match = port->actor.system_priority ==
343                         lacp->partner.port_params.system_priority &&
344                         is_same_ether_addr(&agg->actor.system,
345                         &lacp->partner.port_params.system) &&
346                         port->actor.port_priority ==
347                         lacp->partner.port_params.port_priority &&
348                         port->actor.port_number ==
349                         lacp->partner.port_params.port_number;
350
351                 /* Update NTT if partners information are outdated (xored and masked
352                  * bits are set)*/
353                 uint8_t state_mask = STATE_LACP_ACTIVE | STATE_LACP_SHORT_TIMEOUT |
354                         STATE_SYNCHRONIZATION | STATE_AGGREGATION;
355
356                 if (((port->actor_state ^ lacp->partner.state) & state_mask) ||
357                                 match == false) {
358                         SM_FLAG_SET(port, NTT);
359                 }
360
361                 /* If LACP partner params match this port actor params */
362                 if (match == true && ACTOR_STATE(port, AGGREGATION) ==
363                                 PARTNER_STATE(port,     AGGREGATION))
364                         PARTNER_STATE_SET(port, SYNCHRONIZATION);
365                 else if (!PARTNER_STATE(port, AGGREGATION) && ACTOR_STATE(port,
366                                 AGGREGATION))
367                         PARTNER_STATE_SET(port, SYNCHRONIZATION);
368                 else
369                         PARTNER_STATE_CLR(port, SYNCHRONIZATION);
370
371                 if (ACTOR_STATE(port, LACP_SHORT_TIMEOUT))
372                         timeout = internals->mode4.short_timeout;
373                 else
374                         timeout = internals->mode4.long_timeout;
375
376                 timer_set(&port->current_while_timer, timeout);
377                 ACTOR_STATE_CLR(port, EXPIRED);
378                 return; /* No state change */
379         }
380
381         /* If CURRENT state timer is not running (stopped or expired)
382          * transit to EXPIRED state from DISABLED or CURRENT */
383         if (!timer_is_running(&port->current_while_timer)) {
384                 ACTOR_STATE_SET(port, EXPIRED);
385                 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
386                 PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
387                 timer_set(&port->current_while_timer, internals->mode4.short_timeout);
388         }
389 }
390
391 /**
392  * Function handles periodic tx state machine.
393  *
394  * Function implements Periodic Transmission state machine from point 5.4.13
395  * in 802.1AX documentation. It should be called periodically.
396  *
397  * @param port                  Port to handle state machine.
398  */
399 static void
400 periodic_machine(struct bond_dev_private *internals, uint8_t slave_id)
401 {
402         struct port *port = &mode_8023ad_ports[slave_id];
403         /* Calculate if either site is LACP enabled */
404         uint64_t timeout;
405         uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
406                 PARTNER_STATE(port, LACP_ACTIVE);
407
408         uint8_t is_partner_fast, was_partner_fast;
409         /* No periodic is on BEGIN, LACP DISABLE or when both sides are pasive */
410         if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
411                 timer_cancel(&port->periodic_timer);
412                 timer_force_expired(&port->tx_machine_timer);
413                 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
414
415                 MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
416                         SM_FLAG(port, BEGIN) ? "begind " : "",
417                         SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
418                         active ? "LACP active " : "LACP pasive ");
419                 return;
420         }
421
422         is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
423         was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
424
425         /* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
426          * Other case: check if timer expire or partners settings changed. */
427         if (!timer_is_stopped(&port->periodic_timer)) {
428                 if (timer_is_expired(&port->periodic_timer)) {
429                         SM_FLAG_SET(port, NTT);
430                 } else if (is_partner_fast != was_partner_fast) {
431                         /* Partners timeout  was slow and now it is fast -> send LACP.
432                          * In other case (was fast and now it is slow) just switch
433                          * timeout to slow without forcing send of LACP (because standard
434                          * say so)*/
435                         if (!is_partner_fast)
436                                 SM_FLAG_SET(port, NTT);
437                 } else
438                         return; /* Nothing changed */
439         }
440
441         /* Handle state transition to FAST/SLOW LACP timeout */
442         if (is_partner_fast) {
443                 timeout = internals->mode4.fast_periodic_timeout;
444                 SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
445         } else {
446                 timeout = internals->mode4.slow_periodic_timeout;
447                 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
448         }
449
450         timer_set(&port->periodic_timer, timeout);
451 }
452
453 /**
454  * Function handles mux state machine.
455  *
456  * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
457  * It should be called periodically.
458  *
459  * @param port                  Port to handle state machine.
460  */
461 static void
462 mux_machine(struct bond_dev_private *internals, uint8_t slave_id)
463 {
464         struct port *port = &mode_8023ad_ports[slave_id];
465
466         /* Save current state for later use */
467         const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
468                 STATE_COLLECTING;
469
470         /* Enter DETACHED state on BEGIN condition or from any other state if
471          * port was unselected */
472         if (SM_FLAG(port, BEGIN) ||
473                         port->selected == UNSELECTED || (port->selected == STANDBY &&
474                                 (port->actor_state & state_mask) != 0)) {
475                 /* detach mux from aggregator */
476                 port->actor_state &= ~state_mask;
477                 /* Set ntt to true if BEGIN condition or transition from any other state
478                  * which is indicated that wait_while_timer was started */
479                 if (SM_FLAG(port, BEGIN) ||
480                                 !timer_is_stopped(&port->wait_while_timer)) {
481                         SM_FLAG_SET(port, NTT);
482                         MODE4_DEBUG("-> DETACHED\n");
483                 }
484                 timer_cancel(&port->wait_while_timer);
485         }
486
487         if (timer_is_stopped(&port->wait_while_timer)) {
488                 if (port->selected == SELECTED || port->selected == STANDBY) {
489                         timer_set(&port->wait_while_timer,
490                                 internals->mode4.aggregate_wait_timeout);
491
492                         MODE4_DEBUG("DETACHED -> WAITING\n");
493                 }
494                 /* Waiting state entered */
495                 return;
496         }
497
498         /* Transit next state if port is ready */
499         if (!timer_is_expired(&port->wait_while_timer))
500                 return;
501
502         if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
503                 !PARTNER_STATE(port, SYNCHRONIZATION)) {
504                 /* If in COLLECTING or DISTRIBUTING state and partner becomes out of
505                  * sync transit to ATACHED state.  */
506                 ACTOR_STATE_CLR(port, DISTRIBUTING);
507                 ACTOR_STATE_CLR(port, COLLECTING);
508                 /* Clear actor sync to activate transit ATACHED in condition bellow */
509                 ACTOR_STATE_CLR(port, SYNCHRONIZATION);
510                 MODE4_DEBUG("Out of sync -> ATTACHED\n");
511         }
512
513         if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
514                 /* attach mux to aggregator */
515                 RTE_VERIFY((port->actor_state & (STATE_COLLECTING |
516                         STATE_DISTRIBUTING)) == 0);
517
518                 ACTOR_STATE_SET(port, SYNCHRONIZATION);
519                 SM_FLAG_SET(port, NTT);
520                 MODE4_DEBUG("ATTACHED Entered\n");
521         } else if (!ACTOR_STATE(port, COLLECTING)) {
522                 /* Start collecting if in sync */
523                 if (PARTNER_STATE(port, SYNCHRONIZATION)) {
524                         MODE4_DEBUG("ATTACHED -> COLLECTING\n");
525                         ACTOR_STATE_SET(port, COLLECTING);
526                         SM_FLAG_SET(port, NTT);
527                 }
528         } else if (ACTOR_STATE(port, COLLECTING)) {
529                 /* Check if partner is in COLLECTING state. If so this port can
530                  * distribute frames to it */
531                 if (!ACTOR_STATE(port, DISTRIBUTING)) {
532                         if (PARTNER_STATE(port, COLLECTING)) {
533                                 /* Enable  DISTRIBUTING if partner is collecting */
534                                 ACTOR_STATE_SET(port, DISTRIBUTING);
535                                 SM_FLAG_SET(port, NTT);
536                                 MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
537                                 RTE_LOG(INFO, PMD,
538                                         "Bond %u: slave id %u distributing started.\n",
539                                         internals->port_id, slave_id);
540                         }
541                 } else {
542                         if (!PARTNER_STATE(port, COLLECTING)) {
543                                 /* Disable DISTRIBUTING (enter COLLECTING state) if partner
544                                  * is not collecting */
545                                 ACTOR_STATE_CLR(port, DISTRIBUTING);
546                                 SM_FLAG_SET(port, NTT);
547                                 MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
548                                 RTE_LOG(INFO, PMD,
549                                         "Bond %u: slave id %u distributing stopped.\n",
550                                         internals->port_id, slave_id);
551                         }
552                 }
553         }
554 }
555
556 /**
557  * Function handles transmit state machine.
558  *
559  * Function implements Transmit Machine from point 5.4.16 in 802.1AX
560  * documentation.
561  *
562  * @param port
563  */
564 static void
565 tx_machine(struct bond_dev_private *internals, uint8_t slave_id)
566 {
567         struct port *agg, *port = &mode_8023ad_ports[slave_id];
568
569         struct rte_mbuf *lacp_pkt = NULL;
570         struct lacpdu_header *hdr;
571         struct lacpdu *lacpdu;
572
573         /* If periodic timer is not running periodic machine is in NO PERIODIC and
574          * according to 802.3ax standard tx machine should not transmit any frames
575          * and set ntt to false. */
576         if (timer_is_stopped(&port->periodic_timer))
577                 SM_FLAG_CLR(port, NTT);
578
579         if (!SM_FLAG(port, NTT))
580                 return;
581
582         if (!timer_is_expired(&port->tx_machine_timer))
583                 return;
584
585         lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
586         if (lacp_pkt == NULL) {
587                 RTE_LOG(ERR, PMD, "Failed to allocate LACP packet from pool\n");
588                 return;
589         }
590
591         lacp_pkt->data_len = sizeof(*hdr);
592         lacp_pkt->pkt_len = sizeof(*hdr);
593
594         hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
595
596         /* Source and destination MAC */
597         ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.d_addr);
598         rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_addr);
599         hdr->eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_SLOW);
600
601         lacpdu = &hdr->lacpdu;
602         memset(lacpdu, 0, sizeof(*lacpdu));
603
604         /* Initialize LACP part */
605         lacpdu->subtype = SLOW_SUBTYPE_LACP;
606         lacpdu->version_number = 1;
607
608         /* ACTOR */
609         lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
610         lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
611         memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
612                         sizeof(port->actor));
613         agg = &mode_8023ad_ports[port->aggregator_port_id];
614         ether_addr_copy(&agg->actor.system, &hdr->lacpdu.actor.port_params.system);
615         lacpdu->actor.state = port->actor_state;
616
617         /* PARTNER */
618         lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
619         lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
620         memcpy(&lacpdu->partner.port_params, &port->partner,
621                         sizeof(struct port_params));
622         lacpdu->partner.state = port->partner_state;
623
624         /* Other fields */
625         lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
626         lacpdu->collector_info_length = 0x10;
627         lacpdu->collector_max_delay = 0;
628
629         lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
630         lacpdu->terminator_length = 0;
631
632         if (rte_ring_enqueue(port->tx_ring, lacp_pkt) == -ENOBUFS) {
633                 /* If TX ring full, drop packet and free message. Retransmission
634                  * will happen in next function call. */
635                 rte_pktmbuf_free(lacp_pkt);
636                 set_warning_flags(port, WRN_TX_QUEUE_FULL);
637                 return;
638         }
639
640         MODE4_DEBUG("sending LACP frame\n");
641         BOND_PRINT_LACP(lacpdu);
642
643         timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
644         SM_FLAG_CLR(port, NTT);
645 }
646
647 /**
648  * Function assigns port to aggregator.
649  *
650  * @param bond_dev_private      Pointer to bond_dev_private structure.
651  * @param port_pos                      Port to assign.
652  */
653 static void
654 selection_logic(struct bond_dev_private *internals, uint8_t slave_id)
655 {
656         struct port *agg, *port;
657         uint8_t slaves_count, new_agg_id, i;
658         uint8_t *slaves;
659
660         slaves = internals->active_slaves;
661         slaves_count = internals->active_slave_count;
662         port = &mode_8023ad_ports[slave_id];
663
664         /* Search for aggregator suitable for this port */
665         for (i = 0; i < slaves_count; ++i) {
666                 agg = &mode_8023ad_ports[slaves[i]];
667                 /* Skip ports that are not aggreagators */
668                 if (agg->aggregator_port_id != slaves[i])
669                         continue;
670
671                 /* Actors system ID is not checked since all slave device have the same
672                  * ID (MAC address). */
673                 if ((agg->actor.key == port->actor.key &&
674                         agg->partner.system_priority == port->partner.system_priority &&
675                         is_same_ether_addr(&agg->partner.system, &port->partner.system) == 1
676                         && (agg->partner.key == port->partner.key)) &&
677                         is_zero_ether_addr(&port->partner.system) != 1 &&
678                         (agg->actor.key &
679                                 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
680
681                         break;
682                 }
683         }
684
685         /* By default, port uses it self as agregator */
686         if (i == slaves_count)
687                 new_agg_id = slave_id;
688         else
689                 new_agg_id = slaves[i];
690
691         if (new_agg_id != port->aggregator_port_id) {
692                 port->aggregator_port_id = new_agg_id;
693
694                 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
695                         "\t%s aggregator ID=%3u\n",
696                         port->aggregator_port_id,
697                         port->aggregator_port_id == slave_id ?
698                                 "aggregator not found, using default" : "aggregator found",
699                         port->aggregator_port_id);
700         }
701
702         port->selected = SELECTED;
703 }
704
705 /* Function maps DPDK speed to bonding speed stored in key field */
706 static uint16_t
707 link_speed_key(uint16_t speed) {
708         uint16_t key_speed;
709
710         switch (speed) {
711         case ETH_SPEED_NUM_NONE:
712                 key_speed = 0x00;
713                 break;
714         case ETH_SPEED_NUM_10M:
715                 key_speed = BOND_LINK_SPEED_KEY_10M;
716                 break;
717         case ETH_SPEED_NUM_100M:
718                 key_speed = BOND_LINK_SPEED_KEY_100M;
719                 break;
720         case ETH_SPEED_NUM_1G:
721                 key_speed = BOND_LINK_SPEED_KEY_1000M;
722                 break;
723         case ETH_SPEED_NUM_10G:
724                 key_speed = BOND_LINK_SPEED_KEY_10G;
725                 break;
726         case ETH_SPEED_NUM_20G:
727                 key_speed = BOND_LINK_SPEED_KEY_20G;
728                 break;
729         case ETH_SPEED_NUM_40G:
730                 key_speed = BOND_LINK_SPEED_KEY_40G;
731                 break;
732         default:
733                 /* Unknown speed*/
734                 key_speed = 0xFFFF;
735         }
736
737         return key_speed;
738 }
739
740 static void
741 bond_mode_8023ad_periodic_cb(void *arg)
742 {
743         struct rte_eth_dev *bond_dev = arg;
744         struct bond_dev_private *internals = bond_dev->data->dev_private;
745         struct port *port;
746         struct rte_eth_link link_info;
747         struct ether_addr slave_addr;
748
749         void *pkt = NULL;
750         uint8_t i, slave_id;
751
752
753         /* Update link status on each port */
754         for (i = 0; i < internals->active_slave_count; i++) {
755                 uint16_t key;
756
757                 slave_id = internals->active_slaves[i];
758                 rte_eth_link_get(slave_id, &link_info);
759                 rte_eth_macaddr_get(slave_id, &slave_addr);
760
761                 if (link_info.link_status != 0) {
762                         key = link_speed_key(link_info.link_speed) << 1;
763                         if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
764                                 key |= BOND_LINK_FULL_DUPLEX_KEY;
765                 } else
766                         key = 0;
767
768                 port = &mode_8023ad_ports[slave_id];
769
770                 key = rte_cpu_to_be_16(key);
771                 if (key != port->actor.key) {
772                         if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
773                                 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
774
775                         port->actor.key = key;
776                         SM_FLAG_SET(port, NTT);
777                 }
778
779                 if (!is_same_ether_addr(&port->actor.system, &slave_addr)) {
780                         ether_addr_copy(&slave_addr, &port->actor.system);
781                         if (port->aggregator_port_id == slave_id)
782                                 SM_FLAG_SET(port, NTT);
783                 }
784         }
785
786         for (i = 0; i < internals->active_slave_count; i++) {
787                 slave_id = internals->active_slaves[i];
788                 port = &mode_8023ad_ports[slave_id];
789
790                 if ((port->actor.key &
791                                 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
792
793                         SM_FLAG_SET(port, BEGIN);
794
795                         /* LACP is disabled on half duples or link is down */
796                         if (SM_FLAG(port, LACP_ENABLED)) {
797                                 /* If port was enabled set it to BEGIN state */
798                                 SM_FLAG_CLR(port, LACP_ENABLED);
799                                 ACTOR_STATE_CLR(port, DISTRIBUTING);
800                                 ACTOR_STATE_CLR(port, COLLECTING);
801                         }
802
803                         /* Skip this port processing */
804                         continue;
805                 }
806
807                 SM_FLAG_SET(port, LACP_ENABLED);
808
809                 /* Find LACP packet to this port. Do not check subtype, it is done in
810                  * function that queued packet */
811                 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
812                         struct rte_mbuf *lacp_pkt = pkt;
813                         struct lacpdu_header *lacp;
814
815                         lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
816                         RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
817
818                         /* This is LACP frame so pass it to rx_machine */
819                         rx_machine(internals, slave_id, &lacp->lacpdu);
820                         rte_pktmbuf_free(lacp_pkt);
821                 } else
822                         rx_machine(internals, slave_id, NULL);
823
824                 periodic_machine(internals, slave_id);
825                 mux_machine(internals, slave_id);
826                 tx_machine(internals, slave_id);
827                 selection_logic(internals, slave_id);
828
829                 SM_FLAG_CLR(port, BEGIN);
830                 show_warnings(slave_id);
831         }
832
833         rte_eal_alarm_set(internals->mode4.update_timeout_us,
834                         bond_mode_8023ad_periodic_cb, arg);
835 }
836
837 void
838 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, uint8_t slave_id)
839 {
840         struct bond_dev_private *internals = bond_dev->data->dev_private;
841
842         struct port *port = &mode_8023ad_ports[slave_id];
843         struct port_params initial = {
844                         .system = { { 0 } },
845                         .system_priority = rte_cpu_to_be_16(0xFFFF),
846                         .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
847                         .port_priority = rte_cpu_to_be_16(0x00FF),
848                         .port_number = 0,
849         };
850
851         char mem_name[RTE_ETH_NAME_MAX_LEN];
852         int socket_id;
853         unsigned element_size;
854         uint32_t total_tx_desc;
855         struct bond_tx_queue *bd_tx_q;
856         uint16_t q_id;
857
858         /* Given slave mus not be in active list */
859         RTE_VERIFY(find_slave_by_id(internals->active_slaves,
860         internals->active_slave_count, slave_id) == internals->active_slave_count);
861
862         memcpy(&port->actor, &initial, sizeof(struct port_params));
863         /* Standard requires that port ID must be grater than 0.
864          * Add 1 do get corresponding port_number */
865         port->actor.port_number = rte_cpu_to_be_16((uint16_t)slave_id + 1);
866
867         memcpy(&port->partner, &initial, sizeof(struct port_params));
868
869         /* default states */
870         port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
871         port->partner_state = STATE_LACP_ACTIVE;
872         port->sm_flags = SM_FLAGS_BEGIN;
873
874         /* use this port as agregator */
875         port->aggregator_port_id = slave_id;
876         rte_eth_promiscuous_enable(slave_id);
877
878         timer_cancel(&port->warning_timer);
879
880         if (port->mbuf_pool != NULL)
881                 return;
882
883         RTE_VERIFY(port->rx_ring == NULL);
884         RTE_VERIFY(port->tx_ring == NULL);
885         socket_id = rte_eth_devices[slave_id].data->numa_node;
886
887         element_size = sizeof(struct slow_protocol_frame) + sizeof(struct rte_mbuf)
888                                 + RTE_PKTMBUF_HEADROOM;
889
890         /* The size of the mempool should be at least:
891          * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
892         total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
893         for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
894                 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
895                 total_tx_desc += bd_tx_q->nb_tx_desc;
896         }
897
898         snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
899         port->mbuf_pool = rte_mempool_create(mem_name,
900                 total_tx_desc, element_size,
901                 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ? 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
902                 sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init,
903                 NULL, rte_pktmbuf_init, NULL, socket_id, MEMPOOL_F_NO_SPREAD);
904
905         /* Any memory allocation failure in initalization is critical because
906          * resources can't be free, so reinitialization is impossible. */
907         if (port->mbuf_pool == NULL) {
908                 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
909                         slave_id, mem_name, rte_strerror(rte_errno));
910         }
911
912         snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
913         port->rx_ring = rte_ring_create(mem_name,
914                         rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
915
916         if (port->rx_ring == NULL) {
917                 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
918                         mem_name, rte_strerror(rte_errno));
919         }
920
921         /* TX ring is at least one pkt longer to make room for marker packet. */
922         snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
923         port->tx_ring = rte_ring_create(mem_name,
924                         rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
925
926         if (port->tx_ring == NULL) {
927                 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
928                         mem_name, rte_strerror(rte_errno));
929         }
930 }
931
932 int
933 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev,
934                 uint8_t slave_id)
935 {
936         struct bond_dev_private *internals = bond_dev->data->dev_private;
937         void *pkt = NULL;
938         struct port *port;
939         uint8_t i;
940
941         /* Given slave must be in active list */
942         RTE_VERIFY(find_slave_by_id(internals->active_slaves,
943         internals->active_slave_count, slave_id) < internals->active_slave_count);
944
945         /* Exclude slave from transmit policy. If this slave is an aggregator
946          * make all aggregated slaves unselected to force selection logic
947          * to select suitable aggregator for this port. */
948         for (i = 0; i < internals->active_slave_count; i++) {
949                 port = &mode_8023ad_ports[internals->active_slaves[i]];
950                 if (port->aggregator_port_id != slave_id)
951                         continue;
952
953                 port->selected = UNSELECTED;
954
955                 /* Use default aggregator */
956                 port->aggregator_port_id = internals->active_slaves[i];
957         }
958
959         port = &mode_8023ad_ports[slave_id];
960         port->selected = UNSELECTED;
961         port->actor_state &= ~(STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
962                         STATE_COLLECTING);
963
964         while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
965                 rte_pktmbuf_free((struct rte_mbuf *)pkt);
966
967         while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
968                         rte_pktmbuf_free((struct rte_mbuf *)pkt);
969         return 0;
970 }
971
972 void
973 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
974 {
975         struct bond_dev_private *internals = bond_dev->data->dev_private;
976         struct ether_addr slave_addr;
977         struct port *slave, *agg_slave;
978         uint8_t slave_id, i, j;
979
980         bond_mode_8023ad_stop(bond_dev);
981
982         for (i = 0; i < internals->active_slave_count; i++) {
983                 slave_id = internals->active_slaves[i];
984                 slave = &mode_8023ad_ports[slave_id];
985                 rte_eth_macaddr_get(slave_id, &slave_addr);
986
987                 if (is_same_ether_addr(&slave_addr, &slave->actor.system))
988                         continue;
989
990                 ether_addr_copy(&slave_addr, &slave->actor.system);
991                 /* Do nothing if this port is not an aggregator. In other case
992                  * Set NTT flag on every port that use this aggregator. */
993                 if (slave->aggregator_port_id != slave_id)
994                         continue;
995
996                 for (j = 0; j < internals->active_slave_count; j++) {
997                         agg_slave = &mode_8023ad_ports[internals->active_slaves[j]];
998                         if (agg_slave->aggregator_port_id == slave_id)
999                                 SM_FLAG_SET(agg_slave, NTT);
1000                 }
1001         }
1002
1003         if (bond_dev->data->dev_started)
1004                 bond_mode_8023ad_start(bond_dev);
1005 }
1006
1007 void
1008 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1009                 struct rte_eth_bond_8023ad_conf *conf)
1010 {
1011         struct bond_dev_private *internals = dev->data->dev_private;
1012         struct mode8023ad_private *mode4 = &internals->mode4;
1013         uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1014
1015         conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1016         conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1017         conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1018         conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1019         conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1020         conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1021         conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1022         conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1023 }
1024
1025 void
1026 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1027                 struct rte_eth_bond_8023ad_conf *conf)
1028 {
1029         struct rte_eth_bond_8023ad_conf def_conf;
1030         struct bond_dev_private *internals = dev->data->dev_private;
1031         struct mode8023ad_private *mode4 = &internals->mode4;
1032         uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1033
1034         if (conf == NULL) {
1035                 conf = &def_conf;
1036                 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1037                 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1038                 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1039                 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1040                 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1041                 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1042                 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1043                 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1044         }
1045
1046         mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1047         mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1048         mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1049         mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1050         mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1051         mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1052         mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1053         mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1054 }
1055
1056 int
1057 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1058 {
1059         struct bond_dev_private *internals = bond_dev->data->dev_private;
1060         uint8_t i;
1061
1062         for (i = 0; i < internals->active_slave_count; i++)
1063                 bond_mode_8023ad_activate_slave(bond_dev, i);
1064
1065         return 0;
1066 }
1067
1068 int
1069 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1070 {
1071         return rte_eal_alarm_set(BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000,
1072                         &bond_mode_8023ad_periodic_cb, bond_dev);
1073 }
1074
1075 void
1076 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1077 {
1078         rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1079 }
1080
1081 void
1082 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1083         uint8_t slave_id, struct rte_mbuf *pkt)
1084 {
1085         struct mode8023ad_private *mode4 = &internals->mode4;
1086         struct port *port = &mode_8023ad_ports[slave_id];
1087         struct marker_header *m_hdr;
1088         uint64_t marker_timer, old_marker_timer;
1089         int retval;
1090         uint8_t wrn, subtype;
1091         /* If packet is a marker, we send response now by reusing given packet
1092          * and update only source MAC, destination MAC is multicast so don't
1093          * update it. Other frames will be handled later by state machines */
1094         subtype = rte_pktmbuf_mtod(pkt,
1095                         struct slow_protocol_frame *)->slow_protocol.subtype;
1096
1097         if (subtype == SLOW_SUBTYPE_MARKER) {
1098                 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1099
1100                 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1101                         wrn = WRN_UNKNOWN_MARKER_TYPE;
1102                         goto free_out;
1103                 }
1104
1105                 /* Setup marker timer. Do it in loop in case concurrent access. */
1106                 do {
1107                         old_marker_timer = port->rx_marker_timer;
1108                         if (!timer_is_expired(&old_marker_timer)) {
1109                                 wrn = WRN_RX_MARKER_TO_FAST;
1110                                 goto free_out;
1111                         }
1112
1113                         timer_set(&marker_timer, mode4->rx_marker_timeout);
1114                         retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1115                                 old_marker_timer, marker_timer);
1116                 } while (unlikely(retval == 0));
1117
1118                 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1119                 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1120
1121                 if (unlikely(rte_ring_enqueue(port->tx_ring, pkt) == -ENOBUFS)) {
1122                         /* reset timer */
1123                         port->rx_marker_timer = 0;
1124                         wrn = WRN_TX_QUEUE_FULL;
1125                         goto free_out;
1126                 }
1127         } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1128                 if (unlikely(rte_ring_enqueue(port->rx_ring, pkt) == -ENOBUFS)) {
1129                         /* If RX fing full free lacpdu message and drop packet */
1130                         wrn = WRN_RX_QUEUE_FULL;
1131                         goto free_out;
1132                 }
1133         } else {
1134                 wrn = WRN_UNKNOWN_SLOW_TYPE;
1135                 goto free_out;
1136         }
1137
1138         return;
1139
1140 free_out:
1141         set_warning_flags(port, wrn);
1142         rte_pktmbuf_free(pkt);
1143 }
1144
1145 int
1146 rte_eth_bond_8023ad_conf_get(uint8_t port_id,
1147                 struct rte_eth_bond_8023ad_conf *conf)
1148 {
1149         struct rte_eth_dev *bond_dev;
1150
1151         if (valid_bonded_port_id(port_id) != 0)
1152                 return -EINVAL;
1153
1154         if (conf == NULL)
1155                 return -EINVAL;
1156
1157         bond_dev = &rte_eth_devices[port_id];
1158         bond_mode_8023ad_conf_get(bond_dev, conf);
1159         return 0;
1160 }
1161
1162 int
1163 rte_eth_bond_8023ad_setup(uint8_t port_id,
1164                 struct rte_eth_bond_8023ad_conf *conf)
1165 {
1166         struct rte_eth_dev *bond_dev;
1167
1168         if (valid_bonded_port_id(port_id) != 0)
1169                 return -EINVAL;
1170
1171         if (conf != NULL) {
1172                 /* Basic sanity check */
1173                 if (conf->slow_periodic_ms == 0 ||
1174                                 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1175                                 conf->long_timeout_ms == 0 ||
1176                                 conf->short_timeout_ms >= conf->long_timeout_ms ||
1177                                 conf->aggregate_wait_timeout_ms == 0 ||
1178                                 conf->tx_period_ms == 0 ||
1179                                 conf->rx_marker_period_ms == 0 ||
1180                                 conf->update_timeout_ms == 0) {
1181                         RTE_LOG(ERR, PMD, "given mode 4 configuration is invalid\n");
1182                         return -EINVAL;
1183                 }
1184         }
1185
1186         bond_dev = &rte_eth_devices[port_id];
1187         bond_mode_8023ad_setup(bond_dev, conf);
1188
1189         return 0;
1190 }
1191
1192 int
1193 rte_eth_bond_8023ad_slave_info(uint8_t port_id, uint8_t slave_id,
1194                 struct rte_eth_bond_8023ad_slave_info *info)
1195 {
1196         struct rte_eth_dev *bond_dev;
1197         struct bond_dev_private *internals;
1198         struct port *port;
1199
1200         if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1201                         rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1202                 return -EINVAL;
1203
1204         bond_dev = &rte_eth_devices[port_id];
1205
1206         internals = bond_dev->data->dev_private;
1207         if (find_slave_by_id(internals->active_slaves,
1208                         internals->active_slave_count, slave_id) ==
1209                                 internals->active_slave_count)
1210                 return -EINVAL;
1211
1212         port = &mode_8023ad_ports[slave_id];
1213         info->selected = port->selected;
1214
1215         info->actor_state = port->actor_state;
1216         rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1217
1218         info->partner_state = port->partner_state;
1219         rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1220
1221         info->agg_port_id = port->aggregator_port_id;
1222         return 0;
1223 }