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