net/bonding: add dedicated HW queues for LACP control
[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 #include <rte_compat.h>
43
44 #include "rte_eth_bond_private.h"
45
46 static void bond_mode_8023ad_ext_periodic_cb(void *arg);
47
48 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
49 #define MODE4_DEBUG(fmt, ...) RTE_LOG(DEBUG, PMD, "%6u [Port %u: %s] " fmt, \
50                         bond_dbg_get_time_diff_ms(), slave_id, \
51                         __func__, ##__VA_ARGS__)
52
53 static uint64_t start_time;
54
55 static unsigned
56 bond_dbg_get_time_diff_ms(void)
57 {
58         uint64_t now;
59
60         now = rte_rdtsc();
61         if (start_time == 0)
62                 start_time = now;
63
64         return ((now - start_time) * 1000) / rte_get_tsc_hz();
65 }
66
67 static void
68 bond_print_lacp(struct lacpdu *l)
69 {
70         char a_address[18];
71         char p_address[18];
72         char a_state[256] = { 0 };
73         char p_state[256] = { 0 };
74
75         static const char * const state_labels[] = {
76                 "ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
77         };
78
79         int a_len = 0;
80         int p_len = 0;
81         uint8_t i;
82         uint8_t *addr;
83
84         addr = l->actor.port_params.system.addr_bytes;
85         snprintf(a_address, sizeof(a_address), "%02X:%02X:%02X:%02X:%02X:%02X",
86                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
87
88         addr = l->partner.port_params.system.addr_bytes;
89         snprintf(p_address, sizeof(p_address), "%02X:%02X:%02X:%02X:%02X:%02X",
90                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
91
92         for (i = 0; i < 8; i++) {
93                 if ((l->actor.state >> i) & 1) {
94                         a_len += snprintf(&a_state[a_len], RTE_DIM(a_state) - a_len, "%s ",
95                                 state_labels[i]);
96                 }
97
98                 if ((l->partner.state >> i) & 1) {
99                         p_len += snprintf(&p_state[p_len], RTE_DIM(p_state) - p_len, "%s ",
100                                 state_labels[i]);
101                 }
102         }
103
104         if (a_len && a_state[a_len-1] == ' ')
105                 a_state[a_len-1] = '\0';
106
107         if (p_len && p_state[p_len-1] == ' ')
108                 p_state[p_len-1] = '\0';
109
110         RTE_LOG(DEBUG, PMD, "LACP: {\n"\
111                         "  subtype= %02X\n"\
112                         "  ver_num=%02X\n"\
113                         "  actor={ tlv=%02X, len=%02X\n"\
114                         "    pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\
115                         "       state={ %s }\n"\
116                         "  }\n"\
117                         "  partner={ tlv=%02X, len=%02X\n"\
118                         "    pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"\
119                         "       state={ %s }\n"\
120                         "  }\n"\
121                         "  collector={info=%02X, length=%02X, max_delay=%04X\n, " \
122                                                         "type_term=%02X, terminator_length = %02X}\n",\
123                         l->subtype,\
124                         l->version_number,\
125                         l->actor.tlv_type_info,\
126                         l->actor.info_length,\
127                         l->actor.port_params.system_priority,\
128                         a_address,\
129                         l->actor.port_params.key,\
130                         l->actor.port_params.port_priority,\
131                         l->actor.port_params.port_number,\
132                         a_state,\
133                         l->partner.tlv_type_info,\
134                         l->partner.info_length,\
135                         l->partner.port_params.system_priority,\
136                         p_address,\
137                         l->partner.port_params.key,\
138                         l->partner.port_params.port_priority,\
139                         l->partner.port_params.port_number,\
140                         p_state,\
141                         l->tlv_type_collector_info,\
142                         l->collector_info_length,\
143                         l->collector_max_delay,\
144                         l->tlv_type_terminator,\
145                         l->terminator_length);
146
147 }
148 #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu)
149 #else
150 #define BOND_PRINT_LACP(lacpdu) do { } while (0)
151 #define MODE4_DEBUG(fmt, ...) do { } while (0)
152 #endif
153
154 static const struct ether_addr lacp_mac_addr = {
155         .addr_bytes = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
156 };
157
158 struct port mode_8023ad_ports[RTE_MAX_ETHPORTS];
159
160 static void
161 timer_cancel(uint64_t *timer)
162 {
163         *timer = 0;
164 }
165
166 static void
167 timer_set(uint64_t *timer, uint64_t timeout)
168 {
169         *timer = rte_rdtsc() + timeout;
170 }
171
172 /* Forces given timer to be in expired state. */
173 static void
174 timer_force_expired(uint64_t *timer)
175 {
176         *timer = rte_rdtsc();
177 }
178
179 static bool
180 timer_is_stopped(uint64_t *timer)
181 {
182         return *timer == 0;
183 }
184
185 static bool
186 timer_is_expired(uint64_t *timer)
187 {
188         return *timer < rte_rdtsc();
189 }
190
191 /* Timer is in running state if it is not stopped nor expired */
192 static bool
193 timer_is_running(uint64_t *timer)
194 {
195         return !timer_is_stopped(timer) && !timer_is_expired(timer);
196 }
197
198 static void
199 set_warning_flags(struct port *port, uint16_t flags)
200 {
201         int retval;
202         uint16_t old;
203         uint16_t new_flag = 0;
204
205         do {
206                 old = port->warnings_to_show;
207                 new_flag = old | flags;
208                 retval = rte_atomic16_cmpset(&port->warnings_to_show, old, new_flag);
209         } while (unlikely(retval == 0));
210 }
211
212 static void
213 show_warnings(uint8_t slave_id)
214 {
215         struct port *port = &mode_8023ad_ports[slave_id];
216         uint8_t warnings;
217
218         do {
219                 warnings = port->warnings_to_show;
220         } while (rte_atomic16_cmpset(&port->warnings_to_show, warnings, 0) == 0);
221
222         if (!warnings)
223                 return;
224
225         if (!timer_is_expired(&port->warning_timer))
226                 return;
227
228
229         timer_set(&port->warning_timer, BOND_8023AD_WARNINGS_PERIOD_MS *
230                         rte_get_tsc_hz() / 1000);
231
232         if (warnings & WRN_RX_QUEUE_FULL) {
233                 RTE_LOG(DEBUG, PMD,
234                         "Slave %u: failed to enqueue LACP packet into RX ring.\n"
235                         "Receive and transmit functions must be invoked on bonded\n"
236                         "interface at least 10 times per second or LACP will not\n"
237                         "work correctly\n", slave_id);
238         }
239
240         if (warnings & WRN_TX_QUEUE_FULL) {
241                 RTE_LOG(DEBUG, PMD,
242                         "Slave %u: failed to enqueue LACP packet into TX ring.\n"
243                         "Receive and transmit functions must be invoked on bonded\n"
244                         "interface at least 10 times per second or LACP will not\n"
245                         "work correctly\n", slave_id);
246         }
247
248         if (warnings & WRN_RX_MARKER_TO_FAST)
249                 RTE_LOG(INFO, PMD, "Slave %u: marker to early - ignoring.\n", slave_id);
250
251         if (warnings & WRN_UNKNOWN_SLOW_TYPE) {
252                 RTE_LOG(INFO, PMD,
253                         "Slave %u: ignoring unknown slow protocol frame type", slave_id);
254         }
255
256         if (warnings & WRN_UNKNOWN_MARKER_TYPE)
257                 RTE_LOG(INFO, PMD, "Slave %u: ignoring unknown marker type", slave_id);
258
259         if (warnings & WRN_NOT_LACP_CAPABLE)
260                 MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id);
261 }
262
263 static void
264 record_default(struct port *port)
265 {
266         /* Record default parameters for partner. Partner admin parameters
267          * are not implemented so set them to arbitrary default (last known) and
268          * mark actor that parner is in defaulted state. */
269         port->partner_state = STATE_LACP_ACTIVE;
270         ACTOR_STATE_SET(port, DEFAULTED);
271 }
272
273 /** Function handles rx state machine.
274  *
275  * This function implements Receive State Machine from point 5.4.12 in
276  * 802.1AX documentation. It should be called periodically.
277  *
278  * @param lacpdu                LACPDU received.
279  * @param port                  Port on which LACPDU was received.
280  */
281 static void
282 rx_machine(struct bond_dev_private *internals, uint8_t slave_id,
283                 struct lacpdu *lacp)
284 {
285         struct port *agg, *port = &mode_8023ad_ports[slave_id];
286         uint64_t timeout;
287
288         if (SM_FLAG(port, BEGIN)) {
289                 /* Initialize stuff */
290                 MODE4_DEBUG("-> INITIALIZE\n");
291                 SM_FLAG_CLR(port, MOVED);
292                 port->selected = UNSELECTED;
293
294                 record_default(port);
295
296                 ACTOR_STATE_CLR(port, EXPIRED);
297                 timer_cancel(&port->current_while_timer);
298
299                 /* DISABLED: On initialization partner is out of sync */
300                 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
301
302                 /* LACP DISABLED stuff if LACP not enabled on this port */
303                 if (!SM_FLAG(port, LACP_ENABLED))
304                         PARTNER_STATE_CLR(port, AGGREGATION);
305                 else
306                         PARTNER_STATE_SET(port, AGGREGATION);
307         }
308
309         if (!SM_FLAG(port, LACP_ENABLED)) {
310                 /* Update parameters only if state changed */
311                 if (!timer_is_stopped(&port->current_while_timer)) {
312                         port->selected = UNSELECTED;
313                         record_default(port);
314                         PARTNER_STATE_CLR(port, AGGREGATION);
315                         ACTOR_STATE_CLR(port, EXPIRED);
316                         timer_cancel(&port->current_while_timer);
317                 }
318                 return;
319         }
320
321         if (lacp) {
322                 MODE4_DEBUG("LACP -> CURRENT\n");
323                 BOND_PRINT_LACP(lacp);
324                 /* Update selected flag. If partner parameters are defaulted assume they
325                  * are match. If not defaulted  compare LACP actor with ports parner
326                  * params. */
327                 if (!ACTOR_STATE(port, DEFAULTED) &&
328                         (ACTOR_STATE(port, AGGREGATION) != PARTNER_STATE(port, AGGREGATION)
329                         || memcmp(&port->partner, &lacp->actor.port_params,
330                                 sizeof(port->partner)) != 0)) {
331                         MODE4_DEBUG("selected <- UNSELECTED\n");
332                         port->selected = UNSELECTED;
333                 }
334
335                 /* Record this PDU actor params as partner params */
336                 memcpy(&port->partner, &lacp->actor.port_params,
337                         sizeof(struct port_params));
338                 port->partner_state = lacp->actor.state;
339
340                 /* Partner parameters are not defaulted any more */
341                 ACTOR_STATE_CLR(port, DEFAULTED);
342
343                 /* If LACP partner params match this port actor params */
344                 agg = &mode_8023ad_ports[port->aggregator_port_id];
345                 bool match = port->actor.system_priority ==
346                         lacp->partner.port_params.system_priority &&
347                         is_same_ether_addr(&agg->actor.system,
348                         &lacp->partner.port_params.system) &&
349                         port->actor.port_priority ==
350                         lacp->partner.port_params.port_priority &&
351                         port->actor.port_number ==
352                         lacp->partner.port_params.port_number;
353
354                 /* Update NTT if partners information are outdated (xored and masked
355                  * bits are set)*/
356                 uint8_t state_mask = STATE_LACP_ACTIVE | STATE_LACP_SHORT_TIMEOUT |
357                         STATE_SYNCHRONIZATION | STATE_AGGREGATION;
358
359                 if (((port->actor_state ^ lacp->partner.state) & state_mask) ||
360                                 match == false) {
361                         SM_FLAG_SET(port, NTT);
362                 }
363
364                 /* If LACP partner params match this port actor params */
365                 if (match == true && ACTOR_STATE(port, AGGREGATION) ==
366                                 PARTNER_STATE(port,     AGGREGATION))
367                         PARTNER_STATE_SET(port, SYNCHRONIZATION);
368                 else if (!PARTNER_STATE(port, AGGREGATION) && ACTOR_STATE(port,
369                                 AGGREGATION))
370                         PARTNER_STATE_SET(port, SYNCHRONIZATION);
371                 else
372                         PARTNER_STATE_CLR(port, SYNCHRONIZATION);
373
374                 if (ACTOR_STATE(port, LACP_SHORT_TIMEOUT))
375                         timeout = internals->mode4.short_timeout;
376                 else
377                         timeout = internals->mode4.long_timeout;
378
379                 timer_set(&port->current_while_timer, timeout);
380                 ACTOR_STATE_CLR(port, EXPIRED);
381                 return; /* No state change */
382         }
383
384         /* If CURRENT state timer is not running (stopped or expired)
385          * transit to EXPIRED state from DISABLED or CURRENT */
386         if (!timer_is_running(&port->current_while_timer)) {
387                 ACTOR_STATE_SET(port, EXPIRED);
388                 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
389                 PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
390                 timer_set(&port->current_while_timer, internals->mode4.short_timeout);
391         }
392 }
393
394 /**
395  * Function handles periodic tx state machine.
396  *
397  * Function implements Periodic Transmission state machine from point 5.4.13
398  * in 802.1AX documentation. It should be called periodically.
399  *
400  * @param port                  Port to handle state machine.
401  */
402 static void
403 periodic_machine(struct bond_dev_private *internals, uint8_t slave_id)
404 {
405         struct port *port = &mode_8023ad_ports[slave_id];
406         /* Calculate if either site is LACP enabled */
407         uint64_t timeout;
408         uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
409                 PARTNER_STATE(port, LACP_ACTIVE);
410
411         uint8_t is_partner_fast, was_partner_fast;
412         /* No periodic is on BEGIN, LACP DISABLE or when both sides are pasive */
413         if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
414                 timer_cancel(&port->periodic_timer);
415                 timer_force_expired(&port->tx_machine_timer);
416                 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
417
418                 MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
419                         SM_FLAG(port, BEGIN) ? "begind " : "",
420                         SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
421                         active ? "LACP active " : "LACP pasive ");
422                 return;
423         }
424
425         is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
426         was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
427
428         /* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
429          * Other case: check if timer expire or partners settings changed. */
430         if (!timer_is_stopped(&port->periodic_timer)) {
431                 if (timer_is_expired(&port->periodic_timer)) {
432                         SM_FLAG_SET(port, NTT);
433                 } else if (is_partner_fast != was_partner_fast) {
434                         /* Partners timeout  was slow and now it is fast -> send LACP.
435                          * In other case (was fast and now it is slow) just switch
436                          * timeout to slow without forcing send of LACP (because standard
437                          * say so)*/
438                         if (is_partner_fast)
439                                 SM_FLAG_SET(port, NTT);
440                 } else
441                         return; /* Nothing changed */
442         }
443
444         /* Handle state transition to FAST/SLOW LACP timeout */
445         if (is_partner_fast) {
446                 timeout = internals->mode4.fast_periodic_timeout;
447                 SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
448         } else {
449                 timeout = internals->mode4.slow_periodic_timeout;
450                 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
451         }
452
453         timer_set(&port->periodic_timer, timeout);
454 }
455
456 /**
457  * Function handles mux state machine.
458  *
459  * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
460  * It should be called periodically.
461  *
462  * @param port                  Port to handle state machine.
463  */
464 static void
465 mux_machine(struct bond_dev_private *internals, uint8_t slave_id)
466 {
467         struct port *port = &mode_8023ad_ports[slave_id];
468
469         /* Save current state for later use */
470         const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
471                 STATE_COLLECTING;
472
473         /* Enter DETACHED state on BEGIN condition or from any other state if
474          * port was unselected */
475         if (SM_FLAG(port, BEGIN) ||
476                         port->selected == UNSELECTED || (port->selected == STANDBY &&
477                                 (port->actor_state & state_mask) != 0)) {
478                 /* detach mux from aggregator */
479                 port->actor_state &= ~state_mask;
480                 /* Set ntt to true if BEGIN condition or transition from any other state
481                  * which is indicated that wait_while_timer was started */
482                 if (SM_FLAG(port, BEGIN) ||
483                                 !timer_is_stopped(&port->wait_while_timer)) {
484                         SM_FLAG_SET(port, NTT);
485                         MODE4_DEBUG("-> DETACHED\n");
486                 }
487                 timer_cancel(&port->wait_while_timer);
488         }
489
490         if (timer_is_stopped(&port->wait_while_timer)) {
491                 if (port->selected == SELECTED || port->selected == STANDBY) {
492                         timer_set(&port->wait_while_timer,
493                                 internals->mode4.aggregate_wait_timeout);
494
495                         MODE4_DEBUG("DETACHED -> WAITING\n");
496                 }
497                 /* Waiting state entered */
498                 return;
499         }
500
501         /* Transit next state if port is ready */
502         if (!timer_is_expired(&port->wait_while_timer))
503                 return;
504
505         if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
506                 !PARTNER_STATE(port, SYNCHRONIZATION)) {
507                 /* If in COLLECTING or DISTRIBUTING state and partner becomes out of
508                  * sync transit to ATACHED state.  */
509                 ACTOR_STATE_CLR(port, DISTRIBUTING);
510                 ACTOR_STATE_CLR(port, COLLECTING);
511                 /* Clear actor sync to activate transit ATACHED in condition bellow */
512                 ACTOR_STATE_CLR(port, SYNCHRONIZATION);
513                 MODE4_DEBUG("Out of sync -> ATTACHED\n");
514         }
515
516         if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
517                 /* attach mux to aggregator */
518                 RTE_ASSERT((port->actor_state & (STATE_COLLECTING |
519                         STATE_DISTRIBUTING)) == 0);
520
521                 ACTOR_STATE_SET(port, SYNCHRONIZATION);
522                 SM_FLAG_SET(port, NTT);
523                 MODE4_DEBUG("ATTACHED Entered\n");
524         } else if (!ACTOR_STATE(port, COLLECTING)) {
525                 /* Start collecting if in sync */
526                 if (PARTNER_STATE(port, SYNCHRONIZATION)) {
527                         MODE4_DEBUG("ATTACHED -> COLLECTING\n");
528                         ACTOR_STATE_SET(port, COLLECTING);
529                         SM_FLAG_SET(port, NTT);
530                 }
531         } else if (ACTOR_STATE(port, COLLECTING)) {
532                 /* Check if partner is in COLLECTING state. If so this port can
533                  * distribute frames to it */
534                 if (!ACTOR_STATE(port, DISTRIBUTING)) {
535                         if (PARTNER_STATE(port, COLLECTING)) {
536                                 /* Enable  DISTRIBUTING if partner is collecting */
537                                 ACTOR_STATE_SET(port, DISTRIBUTING);
538                                 SM_FLAG_SET(port, NTT);
539                                 MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
540                                 RTE_LOG(INFO, PMD,
541                                         "Bond %u: slave id %u distributing started.\n",
542                                         internals->port_id, slave_id);
543                         }
544                 } else {
545                         if (!PARTNER_STATE(port, COLLECTING)) {
546                                 /* Disable DISTRIBUTING (enter COLLECTING state) if partner
547                                  * is not collecting */
548                                 ACTOR_STATE_CLR(port, DISTRIBUTING);
549                                 SM_FLAG_SET(port, NTT);
550                                 MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
551                                 RTE_LOG(INFO, PMD,
552                                         "Bond %u: slave id %u distributing stopped.\n",
553                                         internals->port_id, slave_id);
554                         }
555                 }
556         }
557 }
558
559 /**
560  * Function handles transmit state machine.
561  *
562  * Function implements Transmit Machine from point 5.4.16 in 802.1AX
563  * documentation.
564  *
565  * @param port
566  */
567 static void
568 tx_machine(struct bond_dev_private *internals, uint8_t slave_id)
569 {
570         struct port *agg, *port = &mode_8023ad_ports[slave_id];
571
572         struct rte_mbuf *lacp_pkt = NULL;
573         struct lacpdu_header *hdr;
574         struct lacpdu *lacpdu;
575
576         /* If periodic timer is not running periodic machine is in NO PERIODIC and
577          * according to 802.3ax standard tx machine should not transmit any frames
578          * and set ntt to false. */
579         if (timer_is_stopped(&port->periodic_timer))
580                 SM_FLAG_CLR(port, NTT);
581
582         if (!SM_FLAG(port, NTT))
583                 return;
584
585         if (!timer_is_expired(&port->tx_machine_timer))
586                 return;
587
588         lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
589         if (lacp_pkt == NULL) {
590                 RTE_LOG(ERR, PMD, "Failed to allocate LACP packet from pool\n");
591                 return;
592         }
593
594         lacp_pkt->data_len = sizeof(*hdr);
595         lacp_pkt->pkt_len = sizeof(*hdr);
596
597         hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
598
599         /* Source and destination MAC */
600         ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.d_addr);
601         rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_addr);
602         hdr->eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_SLOW);
603
604         lacpdu = &hdr->lacpdu;
605         memset(lacpdu, 0, sizeof(*lacpdu));
606
607         /* Initialize LACP part */
608         lacpdu->subtype = SLOW_SUBTYPE_LACP;
609         lacpdu->version_number = 1;
610
611         /* ACTOR */
612         lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
613         lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
614         memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
615                         sizeof(port->actor));
616         agg = &mode_8023ad_ports[port->aggregator_port_id];
617         ether_addr_copy(&agg->actor.system, &hdr->lacpdu.actor.port_params.system);
618         lacpdu->actor.state = port->actor_state;
619
620         /* PARTNER */
621         lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
622         lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
623         memcpy(&lacpdu->partner.port_params, &port->partner,
624                         sizeof(struct port_params));
625         lacpdu->partner.state = port->partner_state;
626
627         /* Other fields */
628         lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
629         lacpdu->collector_info_length = 0x10;
630         lacpdu->collector_max_delay = 0;
631
632         lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
633         lacpdu->terminator_length = 0;
634
635         MODE4_DEBUG("Sending LACP frame\n");
636         BOND_PRINT_LACP(lacpdu);
637
638         if (internals->mode4.dedicated_queues.enabled == 0) {
639                 int retval = rte_ring_enqueue(port->tx_ring, lacp_pkt);
640                 if (retval != 0) {
641                         /* If TX ring full, drop packet and free message.
642                            Retransmission will happen in next function call. */
643                         rte_pktmbuf_free(lacp_pkt);
644                         set_warning_flags(port, WRN_TX_QUEUE_FULL);
645                         return;
646                 }
647         } else {
648                 uint16_t pkts_sent = rte_eth_tx_burst(slave_id,
649                                 internals->mode4.dedicated_queues.tx_qid,
650                                 &lacp_pkt, 1);
651                 if (pkts_sent != 1) {
652                         rte_pktmbuf_free(lacp_pkt);
653                         set_warning_flags(port, WRN_TX_QUEUE_FULL);
654                         return;
655                 }
656         }
657
658
659         timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
660         SM_FLAG_CLR(port, NTT);
661 }
662
663 /**
664  * Function assigns port to aggregator.
665  *
666  * @param bond_dev_private      Pointer to bond_dev_private structure.
667  * @param port_pos                      Port to assign.
668  */
669 static void
670 selection_logic(struct bond_dev_private *internals, uint8_t slave_id)
671 {
672         struct port *agg, *port;
673         uint8_t slaves_count, new_agg_id, i;
674         uint8_t *slaves;
675
676         slaves = internals->active_slaves;
677         slaves_count = internals->active_slave_count;
678         port = &mode_8023ad_ports[slave_id];
679
680         /* Search for aggregator suitable for this port */
681         for (i = 0; i < slaves_count; ++i) {
682                 agg = &mode_8023ad_ports[slaves[i]];
683                 /* Skip ports that are not aggreagators */
684                 if (agg->aggregator_port_id != slaves[i])
685                         continue;
686
687                 /* Actors system ID is not checked since all slave device have the same
688                  * ID (MAC address). */
689                 if ((agg->actor.key == port->actor.key &&
690                         agg->partner.system_priority == port->partner.system_priority &&
691                         is_same_ether_addr(&agg->partner.system, &port->partner.system) == 1
692                         && (agg->partner.key == port->partner.key)) &&
693                         is_zero_ether_addr(&port->partner.system) != 1 &&
694                         (agg->actor.key &
695                                 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
696
697                         break;
698                 }
699         }
700
701         /* By default, port uses it self as agregator */
702         if (i == slaves_count)
703                 new_agg_id = slave_id;
704         else
705                 new_agg_id = slaves[i];
706
707         if (new_agg_id != port->aggregator_port_id) {
708                 port->aggregator_port_id = new_agg_id;
709
710                 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
711                         "\t%s aggregator ID=%3u\n",
712                         port->aggregator_port_id,
713                         port->aggregator_port_id == slave_id ?
714                                 "aggregator not found, using default" : "aggregator found",
715                         port->aggregator_port_id);
716         }
717
718         port->selected = SELECTED;
719 }
720
721 /* Function maps DPDK speed to bonding speed stored in key field */
722 static uint16_t
723 link_speed_key(uint16_t speed) {
724         uint16_t key_speed;
725
726         switch (speed) {
727         case ETH_SPEED_NUM_NONE:
728                 key_speed = 0x00;
729                 break;
730         case ETH_SPEED_NUM_10M:
731                 key_speed = BOND_LINK_SPEED_KEY_10M;
732                 break;
733         case ETH_SPEED_NUM_100M:
734                 key_speed = BOND_LINK_SPEED_KEY_100M;
735                 break;
736         case ETH_SPEED_NUM_1G:
737                 key_speed = BOND_LINK_SPEED_KEY_1000M;
738                 break;
739         case ETH_SPEED_NUM_10G:
740                 key_speed = BOND_LINK_SPEED_KEY_10G;
741                 break;
742         case ETH_SPEED_NUM_20G:
743                 key_speed = BOND_LINK_SPEED_KEY_20G;
744                 break;
745         case ETH_SPEED_NUM_40G:
746                 key_speed = BOND_LINK_SPEED_KEY_40G;
747                 break;
748         default:
749                 /* Unknown speed*/
750                 key_speed = 0xFFFF;
751         }
752
753         return key_speed;
754 }
755
756 static void
757 rx_machine_update(struct bond_dev_private *internals, uint8_t slave_id,
758                 struct rte_mbuf *lacp_pkt) {
759         struct lacpdu_header *lacp;
760
761         if (lacp_pkt != NULL) {
762                 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
763                 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
764
765                 /* This is LACP frame so pass it to rx_machine */
766                 rx_machine(internals, slave_id, &lacp->lacpdu);
767                 rte_pktmbuf_free(lacp_pkt);
768         } else
769                 rx_machine(internals, slave_id, NULL);
770 }
771
772 static void
773 bond_mode_8023ad_periodic_cb(void *arg)
774 {
775         struct rte_eth_dev *bond_dev = arg;
776         struct bond_dev_private *internals = bond_dev->data->dev_private;
777         struct port *port;
778         struct rte_eth_link link_info;
779         struct ether_addr slave_addr;
780         struct rte_mbuf *lacp_pkt = NULL;
781
782         uint8_t i, slave_id;
783
784
785         /* Update link status on each port */
786         for (i = 0; i < internals->active_slave_count; i++) {
787                 uint16_t key;
788
789                 slave_id = internals->active_slaves[i];
790                 rte_eth_link_get_nowait(slave_id, &link_info);
791                 rte_eth_macaddr_get(slave_id, &slave_addr);
792
793                 if (link_info.link_status != 0) {
794                         key = link_speed_key(link_info.link_speed) << 1;
795                         if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
796                                 key |= BOND_LINK_FULL_DUPLEX_KEY;
797                 } else
798                         key = 0;
799
800                 port = &mode_8023ad_ports[slave_id];
801
802                 key = rte_cpu_to_be_16(key);
803                 if (key != port->actor.key) {
804                         if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
805                                 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
806
807                         port->actor.key = key;
808                         SM_FLAG_SET(port, NTT);
809                 }
810
811                 if (!is_same_ether_addr(&port->actor.system, &slave_addr)) {
812                         ether_addr_copy(&slave_addr, &port->actor.system);
813                         if (port->aggregator_port_id == slave_id)
814                                 SM_FLAG_SET(port, NTT);
815                 }
816         }
817
818         for (i = 0; i < internals->active_slave_count; i++) {
819                 slave_id = internals->active_slaves[i];
820                 port = &mode_8023ad_ports[slave_id];
821
822                 if ((port->actor.key &
823                                 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
824
825                         SM_FLAG_SET(port, BEGIN);
826
827                         /* LACP is disabled on half duples or link is down */
828                         if (SM_FLAG(port, LACP_ENABLED)) {
829                                 /* If port was enabled set it to BEGIN state */
830                                 SM_FLAG_CLR(port, LACP_ENABLED);
831                                 ACTOR_STATE_CLR(port, DISTRIBUTING);
832                                 ACTOR_STATE_CLR(port, COLLECTING);
833                         }
834
835                         /* Skip this port processing */
836                         continue;
837                 }
838
839                 SM_FLAG_SET(port, LACP_ENABLED);
840
841                 if (internals->mode4.dedicated_queues.enabled == 0) {
842                         /* Find LACP packet to this port. Do not check subtype,
843                          * it is done in function that queued packet
844                          */
845                         int retval = rte_ring_dequeue(port->rx_ring,
846                                         (void **)&lacp_pkt);
847
848                         if (retval != 0)
849                                 lacp_pkt = NULL;
850
851                         rx_machine_update(internals, slave_id, lacp_pkt);
852                 } else {
853                         uint16_t rx_count = rte_eth_rx_burst(slave_id,
854                                         internals->mode4.dedicated_queues.rx_qid,
855                                         &lacp_pkt, 1);
856
857                         if (rx_count == 1)
858                                 bond_mode_8023ad_handle_slow_pkt(internals,
859                                                 slave_id, lacp_pkt);
860                         else
861                                 rx_machine_update(internals, slave_id, NULL);
862                 }
863
864                 periodic_machine(internals, slave_id);
865                 mux_machine(internals, slave_id);
866                 tx_machine(internals, slave_id);
867                 selection_logic(internals, slave_id);
868
869                 SM_FLAG_CLR(port, BEGIN);
870                 show_warnings(slave_id);
871         }
872
873         rte_eal_alarm_set(internals->mode4.update_timeout_us,
874                         bond_mode_8023ad_periodic_cb, arg);
875 }
876
877 void
878 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, uint8_t slave_id)
879 {
880         struct bond_dev_private *internals = bond_dev->data->dev_private;
881
882         struct port *port = &mode_8023ad_ports[slave_id];
883         struct port_params initial = {
884                         .system = { { 0 } },
885                         .system_priority = rte_cpu_to_be_16(0xFFFF),
886                         .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
887                         .port_priority = rte_cpu_to_be_16(0x00FF),
888                         .port_number = 0,
889         };
890
891         char mem_name[RTE_ETH_NAME_MAX_LEN];
892         int socket_id;
893         unsigned element_size;
894         uint32_t total_tx_desc;
895         struct bond_tx_queue *bd_tx_q;
896         uint16_t q_id;
897
898         /* Given slave mus not be in active list */
899         RTE_ASSERT(find_slave_by_id(internals->active_slaves,
900         internals->active_slave_count, slave_id) == internals->active_slave_count);
901         RTE_SET_USED(internals); /* used only for assert when enabled */
902
903         memcpy(&port->actor, &initial, sizeof(struct port_params));
904         /* Standard requires that port ID must be grater than 0.
905          * Add 1 do get corresponding port_number */
906         port->actor.port_number = rte_cpu_to_be_16((uint16_t)slave_id + 1);
907
908         memcpy(&port->partner, &initial, sizeof(struct port_params));
909
910         /* default states */
911         port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
912         port->partner_state = STATE_LACP_ACTIVE;
913         port->sm_flags = SM_FLAGS_BEGIN;
914
915         /* use this port as agregator */
916         port->aggregator_port_id = slave_id;
917         rte_eth_promiscuous_enable(slave_id);
918
919         timer_cancel(&port->warning_timer);
920
921         if (port->mbuf_pool != NULL)
922                 return;
923
924         RTE_ASSERT(port->rx_ring == NULL);
925         RTE_ASSERT(port->tx_ring == NULL);
926
927         socket_id = rte_eth_dev_socket_id(slave_id);
928         if (socket_id == (int)LCORE_ID_ANY)
929                 socket_id = rte_socket_id();
930
931         element_size = sizeof(struct slow_protocol_frame) +
932                                 RTE_PKTMBUF_HEADROOM;
933
934         /* The size of the mempool should be at least:
935          * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
936         total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
937         for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
938                 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
939                 total_tx_desc += bd_tx_q->nb_tx_desc;
940         }
941
942         snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
943         port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
944                 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
945                         32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
946                 0, element_size, socket_id);
947
948         /* Any memory allocation failure in initialization is critical because
949          * resources can't be free, so reinitialization is impossible. */
950         if (port->mbuf_pool == NULL) {
951                 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
952                         slave_id, mem_name, rte_strerror(rte_errno));
953         }
954
955         snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
956         port->rx_ring = rte_ring_create(mem_name,
957                         rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
958
959         if (port->rx_ring == NULL) {
960                 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
961                         mem_name, rte_strerror(rte_errno));
962         }
963
964         /* TX ring is at least one pkt longer to make room for marker packet. */
965         snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
966         port->tx_ring = rte_ring_create(mem_name,
967                         rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
968
969         if (port->tx_ring == NULL) {
970                 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
971                         mem_name, rte_strerror(rte_errno));
972         }
973 }
974
975 int
976 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev,
977                 uint8_t slave_id)
978 {
979         struct bond_dev_private *internals = bond_dev->data->dev_private;
980         void *pkt = NULL;
981         struct port *port;
982         uint8_t i;
983
984         /* Given slave must be in active list */
985         RTE_ASSERT(find_slave_by_id(internals->active_slaves,
986         internals->active_slave_count, slave_id) < internals->active_slave_count);
987
988         /* Exclude slave from transmit policy. If this slave is an aggregator
989          * make all aggregated slaves unselected to force selection logic
990          * to select suitable aggregator for this port. */
991         for (i = 0; i < internals->active_slave_count; i++) {
992                 port = &mode_8023ad_ports[internals->active_slaves[i]];
993                 if (port->aggregator_port_id != slave_id)
994                         continue;
995
996                 port->selected = UNSELECTED;
997
998                 /* Use default aggregator */
999                 port->aggregator_port_id = internals->active_slaves[i];
1000         }
1001
1002         port = &mode_8023ad_ports[slave_id];
1003         port->selected = UNSELECTED;
1004         port->actor_state &= ~(STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
1005                         STATE_COLLECTING);
1006
1007         while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1008                 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1009
1010         while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1011                         rte_pktmbuf_free((struct rte_mbuf *)pkt);
1012         return 0;
1013 }
1014
1015 void
1016 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1017 {
1018         struct bond_dev_private *internals = bond_dev->data->dev_private;
1019         struct ether_addr slave_addr;
1020         struct port *slave, *agg_slave;
1021         uint8_t slave_id, i, j;
1022
1023         bond_mode_8023ad_stop(bond_dev);
1024
1025         for (i = 0; i < internals->active_slave_count; i++) {
1026                 slave_id = internals->active_slaves[i];
1027                 slave = &mode_8023ad_ports[slave_id];
1028                 rte_eth_macaddr_get(slave_id, &slave_addr);
1029
1030                 if (is_same_ether_addr(&slave_addr, &slave->actor.system))
1031                         continue;
1032
1033                 ether_addr_copy(&slave_addr, &slave->actor.system);
1034                 /* Do nothing if this port is not an aggregator. In other case
1035                  * Set NTT flag on every port that use this aggregator. */
1036                 if (slave->aggregator_port_id != slave_id)
1037                         continue;
1038
1039                 for (j = 0; j < internals->active_slave_count; j++) {
1040                         agg_slave = &mode_8023ad_ports[internals->active_slaves[j]];
1041                         if (agg_slave->aggregator_port_id == slave_id)
1042                                 SM_FLAG_SET(agg_slave, NTT);
1043                 }
1044         }
1045
1046         if (bond_dev->data->dev_started)
1047                 bond_mode_8023ad_start(bond_dev);
1048 }
1049
1050 static void
1051 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1052                 struct rte_eth_bond_8023ad_conf *conf)
1053 {
1054         struct bond_dev_private *internals = dev->data->dev_private;
1055         struct mode8023ad_private *mode4 = &internals->mode4;
1056         uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1057
1058         conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1059         conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1060         conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1061         conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1062         conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1063         conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1064         conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1065         conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1066 }
1067
1068 static void
1069 bond_mode_8023ad_conf_get_v1607(struct rte_eth_dev *dev,
1070                 struct rte_eth_bond_8023ad_conf *conf)
1071 {
1072         struct bond_dev_private *internals = dev->data->dev_private;
1073         struct mode8023ad_private *mode4 = &internals->mode4;
1074
1075         bond_mode_8023ad_conf_get(dev, conf);
1076         conf->slowrx_cb = mode4->slowrx_cb;
1077 }
1078
1079 static void
1080 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1081 {
1082         conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1083         conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1084         conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1085         conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1086         conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1087         conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1088         conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1089         conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1090         conf->slowrx_cb = NULL;
1091 }
1092
1093 static void
1094 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1095                 struct rte_eth_bond_8023ad_conf *conf)
1096 {
1097         uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1098
1099         mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1100         mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1101         mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1102         mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1103         mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1104         mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1105         mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1106         mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1107
1108         mode4->dedicated_queues.enabled = 0;
1109         mode4->dedicated_queues.rx_qid = UINT16_MAX;
1110         mode4->dedicated_queues.tx_qid = UINT16_MAX;
1111 }
1112
1113 static void
1114 bond_mode_8023ad_setup_v20(struct rte_eth_dev *dev,
1115                 struct rte_eth_bond_8023ad_conf *conf)
1116 {
1117         struct rte_eth_bond_8023ad_conf def_conf;
1118         struct bond_dev_private *internals = dev->data->dev_private;
1119         struct mode8023ad_private *mode4 = &internals->mode4;
1120
1121         if (conf == NULL) {
1122                 conf = &def_conf;
1123                 bond_mode_8023ad_conf_get_default(conf);
1124         }
1125
1126         bond_mode_8023ad_stop(dev);
1127         bond_mode_8023ad_conf_assign(mode4, conf);
1128
1129         if (dev->data->dev_started)
1130                 bond_mode_8023ad_start(dev);
1131 }
1132
1133
1134 void
1135 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1136                 struct rte_eth_bond_8023ad_conf *conf)
1137 {
1138         struct rte_eth_bond_8023ad_conf def_conf;
1139         struct bond_dev_private *internals = dev->data->dev_private;
1140         struct mode8023ad_private *mode4 = &internals->mode4;
1141
1142         if (conf == NULL) {
1143                 conf = &def_conf;
1144                 bond_mode_8023ad_conf_get_default(conf);
1145         }
1146
1147         bond_mode_8023ad_stop(dev);
1148         bond_mode_8023ad_conf_assign(mode4, conf);
1149         mode4->slowrx_cb = conf->slowrx_cb;
1150
1151         if (dev->data->dev_started)
1152                 bond_mode_8023ad_start(dev);
1153 }
1154
1155 int
1156 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1157 {
1158         struct bond_dev_private *internals = bond_dev->data->dev_private;
1159         uint8_t i;
1160
1161         for (i = 0; i < internals->active_slave_count; i++)
1162                 bond_mode_8023ad_activate_slave(bond_dev, i);
1163
1164         return 0;
1165 }
1166
1167 int
1168 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1169 {
1170         struct bond_dev_private *internals = bond_dev->data->dev_private;
1171         struct mode8023ad_private *mode4 = &internals->mode4;
1172         static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1173
1174         if (mode4->slowrx_cb)
1175                 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1176                                          bond_dev);
1177
1178         return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1179 }
1180
1181 void
1182 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1183 {
1184         struct bond_dev_private *internals = bond_dev->data->dev_private;
1185         struct mode8023ad_private *mode4 = &internals->mode4;
1186
1187         if (mode4->slowrx_cb) {
1188                 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1189                                      bond_dev);
1190                 return;
1191         }
1192         rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1193 }
1194
1195 void
1196 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1197         uint8_t slave_id, struct rte_mbuf *pkt)
1198 {
1199         struct mode8023ad_private *mode4 = &internals->mode4;
1200         struct port *port = &mode_8023ad_ports[slave_id];
1201         struct marker_header *m_hdr;
1202         uint64_t marker_timer, old_marker_timer;
1203         int retval;
1204         uint8_t wrn, subtype;
1205         /* If packet is a marker, we send response now by reusing given packet
1206          * and update only source MAC, destination MAC is multicast so don't
1207          * update it. Other frames will be handled later by state machines */
1208         subtype = rte_pktmbuf_mtod(pkt,
1209                         struct slow_protocol_frame *)->slow_protocol.subtype;
1210
1211         if (subtype == SLOW_SUBTYPE_MARKER) {
1212                 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1213
1214                 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1215                         wrn = WRN_UNKNOWN_MARKER_TYPE;
1216                         goto free_out;
1217                 }
1218
1219                 /* Setup marker timer. Do it in loop in case concurrent access. */
1220                 do {
1221                         old_marker_timer = port->rx_marker_timer;
1222                         if (!timer_is_expired(&old_marker_timer)) {
1223                                 wrn = WRN_RX_MARKER_TO_FAST;
1224                                 goto free_out;
1225                         }
1226
1227                         timer_set(&marker_timer, mode4->rx_marker_timeout);
1228                         retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1229                                 old_marker_timer, marker_timer);
1230                 } while (unlikely(retval == 0));
1231
1232                 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1233                 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1234
1235                 if (internals->mode4.dedicated_queues.enabled == 0) {
1236                         int retval = rte_ring_enqueue(port->tx_ring, pkt);
1237                         if (retval != 0) {
1238                                 /* reset timer */
1239                                 port->rx_marker_timer = 0;
1240                                 wrn = WRN_TX_QUEUE_FULL;
1241                                 goto free_out;
1242                         }
1243                 } else {
1244                         /* Send packet directly to the slow queue */
1245                         uint16_t tx_count = rte_eth_tx_burst(slave_id,
1246                                         internals->mode4.dedicated_queues.tx_qid,
1247                                         &pkt, 1);
1248                         if (tx_count != 1) {
1249                                 /* reset timer */
1250                                 port->rx_marker_timer = 0;
1251                                 wrn = WRN_TX_QUEUE_FULL;
1252                                 goto free_out;
1253                         }
1254                 }
1255         } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1256                 if (internals->mode4.dedicated_queues.enabled == 0) {
1257                         int retval = rte_ring_enqueue(port->rx_ring, pkt);
1258                         if (retval != 0) {
1259                                 /* If RX fing full free lacpdu message and drop packet */
1260                                 wrn = WRN_RX_QUEUE_FULL;
1261                                 goto free_out;
1262                         }
1263                 } else
1264                         rx_machine_update(internals, slave_id, pkt);
1265         } else {
1266                 wrn = WRN_UNKNOWN_SLOW_TYPE;
1267                 goto free_out;
1268         }
1269
1270         return;
1271
1272 free_out:
1273         set_warning_flags(port, wrn);
1274         rte_pktmbuf_free(pkt);
1275 }
1276
1277 int
1278 rte_eth_bond_8023ad_conf_get_v20(uint8_t port_id,
1279                 struct rte_eth_bond_8023ad_conf *conf)
1280 {
1281         struct rte_eth_dev *bond_dev;
1282
1283         if (valid_bonded_port_id(port_id) != 0)
1284                 return -EINVAL;
1285
1286         if (conf == NULL)
1287                 return -EINVAL;
1288
1289         bond_dev = &rte_eth_devices[port_id];
1290         bond_mode_8023ad_conf_get(bond_dev, conf);
1291         return 0;
1292 }
1293 VERSION_SYMBOL(rte_eth_bond_8023ad_conf_get, _v20, 2.0);
1294
1295 int
1296 rte_eth_bond_8023ad_conf_get_v1607(uint8_t port_id,
1297                 struct rte_eth_bond_8023ad_conf *conf)
1298 {
1299         struct rte_eth_dev *bond_dev;
1300
1301         if (valid_bonded_port_id(port_id) != 0)
1302                 return -EINVAL;
1303
1304         if (conf == NULL)
1305                 return -EINVAL;
1306
1307         bond_dev = &rte_eth_devices[port_id];
1308         bond_mode_8023ad_conf_get_v1607(bond_dev, conf);
1309         return 0;
1310 }
1311 BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_conf_get, _v1607, 16.07);
1312 MAP_STATIC_SYMBOL(int rte_eth_bond_8023ad_conf_get(uint8_t port_id,
1313                 struct rte_eth_bond_8023ad_conf *conf),
1314                 rte_eth_bond_8023ad_conf_get_v1607);
1315
1316 static int
1317 bond_8023ad_setup_validate(uint8_t port_id,
1318                 struct rte_eth_bond_8023ad_conf *conf)
1319 {
1320         if (valid_bonded_port_id(port_id) != 0)
1321                 return -EINVAL;
1322
1323         if (conf != NULL) {
1324                 /* Basic sanity check */
1325                 if (conf->slow_periodic_ms == 0 ||
1326                                 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1327                                 conf->long_timeout_ms == 0 ||
1328                                 conf->short_timeout_ms >= conf->long_timeout_ms ||
1329                                 conf->aggregate_wait_timeout_ms == 0 ||
1330                                 conf->tx_period_ms == 0 ||
1331                                 conf->rx_marker_period_ms == 0 ||
1332                                 conf->update_timeout_ms == 0) {
1333                         RTE_LOG(ERR, PMD, "given mode 4 configuration is invalid\n");
1334                         return -EINVAL;
1335                 }
1336         }
1337
1338         return 0;
1339 }
1340
1341 int
1342 rte_eth_bond_8023ad_setup_v20(uint8_t port_id,
1343                 struct rte_eth_bond_8023ad_conf *conf)
1344 {
1345         struct rte_eth_dev *bond_dev;
1346         int err;
1347
1348         err = bond_8023ad_setup_validate(port_id, conf);
1349         if (err != 0)
1350                 return err;
1351
1352         bond_dev = &rte_eth_devices[port_id];
1353         bond_mode_8023ad_setup_v20(bond_dev, conf);
1354
1355         return 0;
1356 }
1357 VERSION_SYMBOL(rte_eth_bond_8023ad_setup, _v20, 2.0);
1358
1359 int
1360 rte_eth_bond_8023ad_setup_v1607(uint8_t port_id,
1361                 struct rte_eth_bond_8023ad_conf *conf)
1362 {
1363         struct rte_eth_dev *bond_dev;
1364         int err;
1365
1366         err = bond_8023ad_setup_validate(port_id, conf);
1367         if (err != 0)
1368                 return err;
1369
1370         bond_dev = &rte_eth_devices[port_id];
1371         bond_mode_8023ad_setup(bond_dev, conf);
1372
1373         return 0;
1374 }
1375 BIND_DEFAULT_SYMBOL(rte_eth_bond_8023ad_setup, _v1607, 16.07);
1376 MAP_STATIC_SYMBOL(int rte_eth_bond_8023ad_setup(uint8_t port_id,
1377                 struct rte_eth_bond_8023ad_conf *conf),
1378                 rte_eth_bond_8023ad_setup_v1607);
1379
1380 int
1381 rte_eth_bond_8023ad_slave_info(uint8_t port_id, uint8_t slave_id,
1382                 struct rte_eth_bond_8023ad_slave_info *info)
1383 {
1384         struct rte_eth_dev *bond_dev;
1385         struct bond_dev_private *internals;
1386         struct port *port;
1387
1388         if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1389                         rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1390                 return -EINVAL;
1391
1392         bond_dev = &rte_eth_devices[port_id];
1393
1394         internals = bond_dev->data->dev_private;
1395         if (find_slave_by_id(internals->active_slaves,
1396                         internals->active_slave_count, slave_id) ==
1397                                 internals->active_slave_count)
1398                 return -EINVAL;
1399
1400         port = &mode_8023ad_ports[slave_id];
1401         info->selected = port->selected;
1402
1403         info->actor_state = port->actor_state;
1404         rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1405
1406         info->partner_state = port->partner_state;
1407         rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1408
1409         info->agg_port_id = port->aggregator_port_id;
1410         return 0;
1411 }
1412
1413 static int
1414 bond_8023ad_ext_validate(uint8_t port_id, uint8_t slave_id)
1415 {
1416         struct rte_eth_dev *bond_dev;
1417         struct bond_dev_private *internals;
1418         struct mode8023ad_private *mode4;
1419
1420         if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1421                 return -EINVAL;
1422
1423         bond_dev = &rte_eth_devices[port_id];
1424
1425         if (!bond_dev->data->dev_started)
1426                 return -EINVAL;
1427
1428         internals = bond_dev->data->dev_private;
1429         if (find_slave_by_id(internals->active_slaves,
1430                         internals->active_slave_count, slave_id) ==
1431                                 internals->active_slave_count)
1432                 return -EINVAL;
1433
1434         mode4 = &internals->mode4;
1435         if (mode4->slowrx_cb == NULL)
1436                 return -EINVAL;
1437
1438         return 0;
1439 }
1440
1441 int
1442 rte_eth_bond_8023ad_ext_collect(uint8_t port_id, uint8_t slave_id, int enabled)
1443 {
1444         struct port *port;
1445         int res;
1446
1447         res = bond_8023ad_ext_validate(port_id, slave_id);
1448         if (res != 0)
1449                 return res;
1450
1451         port = &mode_8023ad_ports[slave_id];
1452
1453         if (enabled)
1454                 ACTOR_STATE_SET(port, COLLECTING);
1455         else
1456                 ACTOR_STATE_CLR(port, COLLECTING);
1457
1458         return 0;
1459 }
1460
1461 int
1462 rte_eth_bond_8023ad_ext_distrib(uint8_t port_id, uint8_t slave_id, int enabled)
1463 {
1464         struct port *port;
1465         int res;
1466
1467         res = bond_8023ad_ext_validate(port_id, slave_id);
1468         if (res != 0)
1469                 return res;
1470
1471         port = &mode_8023ad_ports[slave_id];
1472
1473         if (enabled)
1474                 ACTOR_STATE_SET(port, DISTRIBUTING);
1475         else
1476                 ACTOR_STATE_CLR(port, DISTRIBUTING);
1477
1478         return 0;
1479 }
1480
1481 int
1482 rte_eth_bond_8023ad_ext_distrib_get(uint8_t port_id, uint8_t slave_id)
1483 {
1484         struct port *port;
1485         int err;
1486
1487         err = bond_8023ad_ext_validate(port_id, slave_id);
1488         if (err != 0)
1489                 return err;
1490
1491         port = &mode_8023ad_ports[slave_id];
1492         return ACTOR_STATE(port, DISTRIBUTING);
1493 }
1494
1495 int
1496 rte_eth_bond_8023ad_ext_collect_get(uint8_t port_id, uint8_t slave_id)
1497 {
1498         struct port *port;
1499         int err;
1500
1501         err = bond_8023ad_ext_validate(port_id, slave_id);
1502         if (err != 0)
1503                 return err;
1504
1505         port = &mode_8023ad_ports[slave_id];
1506         return ACTOR_STATE(port, COLLECTING);
1507 }
1508
1509 int
1510 rte_eth_bond_8023ad_ext_slowtx(uint8_t port_id, uint8_t slave_id,
1511                 struct rte_mbuf *lacp_pkt)
1512 {
1513         struct port *port;
1514         int res;
1515
1516         res = bond_8023ad_ext_validate(port_id, slave_id);
1517         if (res != 0)
1518                 return res;
1519
1520         port = &mode_8023ad_ports[slave_id];
1521
1522         if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1523                 return -EINVAL;
1524
1525         struct lacpdu_header *lacp;
1526
1527         /* only enqueue LACPDUs */
1528         lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1529         if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1530                 return -EINVAL;
1531
1532         MODE4_DEBUG("sending LACP frame\n");
1533
1534         return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1535 }
1536
1537 static void
1538 bond_mode_8023ad_ext_periodic_cb(void *arg)
1539 {
1540         struct rte_eth_dev *bond_dev = arg;
1541         struct bond_dev_private *internals = bond_dev->data->dev_private;
1542         struct mode8023ad_private *mode4 = &internals->mode4;
1543         struct port *port;
1544         void *pkt = NULL;
1545         uint16_t i, slave_id;
1546
1547         for (i = 0; i < internals->active_slave_count; i++) {
1548                 slave_id = internals->active_slaves[i];
1549                 port = &mode_8023ad_ports[slave_id];
1550
1551                 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1552                         struct rte_mbuf *lacp_pkt = pkt;
1553                         struct lacpdu_header *lacp;
1554
1555                         lacp = rte_pktmbuf_mtod(lacp_pkt,
1556                                                 struct lacpdu_header *);
1557                         RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1558
1559                         /* This is LACP frame so pass it to rx callback.
1560                          * Callback is responsible for freeing mbuf.
1561                          */
1562                         mode4->slowrx_cb(slave_id, lacp_pkt);
1563                 }
1564         }
1565
1566         rte_eal_alarm_set(internals->mode4.update_timeout_us,
1567                         bond_mode_8023ad_ext_periodic_cb, arg);
1568 }
1569
1570 int
1571 rte_eth_bond_8023ad_dedicated_queues_enable(uint8_t port)
1572 {
1573         int retval = 0;
1574         struct rte_eth_dev *dev = &rte_eth_devices[port];
1575         struct bond_dev_private *internals = (struct bond_dev_private *)
1576                 dev->data->dev_private;
1577
1578         if (check_for_bonded_ethdev(dev) != 0)
1579                 return -1;
1580
1581         if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1582                 return -1;
1583
1584         /* Device must be stopped to set up slow queue */
1585         if (dev->data->dev_started)
1586                 return -1;
1587
1588         internals->mode4.dedicated_queues.enabled = 1;
1589
1590         bond_ethdev_mode_set(dev, internals->mode);
1591         return retval;
1592 }
1593
1594 int
1595 rte_eth_bond_8023ad_dedicated_queues_disable(uint8_t port)
1596 {
1597         int retval = 0;
1598         struct rte_eth_dev *dev = &rte_eth_devices[port];
1599         struct bond_dev_private *internals = (struct bond_dev_private *)
1600                 dev->data->dev_private;
1601
1602         if (check_for_bonded_ethdev(dev) != 0)
1603                 return -1;
1604
1605         /* Device must be stopped to set up slow queue */
1606         if (dev->data->dev_started)
1607                 return -1;
1608
1609         internals->mode4.dedicated_queues.enabled = 0;
1610
1611         bond_ethdev_mode_set(dev, internals->mode);
1612
1613         return retval;
1614 }