36ec65d634668b357c5b3d2e104ad791459dc3ad
[deb_dpdk.git] / drivers / net / bonding / rte_eth_bond_api.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 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 <string.h>
35
36 #include <rte_mbuf.h>
37 #include <rte_malloc.h>
38 #include <rte_ethdev.h>
39 #include <rte_tcp.h>
40 #include <rte_vdev.h>
41 #include <rte_kvargs.h>
42
43 #include "rte_eth_bond.h"
44 #include "rte_eth_bond_private.h"
45 #include "rte_eth_bond_8023ad_private.h"
46
47 int
48 check_for_bonded_ethdev(const struct rte_eth_dev *eth_dev)
49 {
50         /* Check valid pointer */
51         if (eth_dev->data->drv_name == NULL)
52                 return -1;
53
54         /* return 0 if driver name matches */
55         return eth_dev->data->drv_name != pmd_bond_drv.driver.name;
56 }
57
58 int
59 valid_bonded_port_id(uint8_t port_id)
60 {
61         RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
62         return check_for_bonded_ethdev(&rte_eth_devices[port_id]);
63 }
64
65 int
66 valid_slave_port_id(uint8_t port_id)
67 {
68         RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
69
70         /* Verify that port_id refers to a non bonded port */
71         if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0)
72                 return -1;
73
74         return 0;
75 }
76
77 void
78 activate_slave(struct rte_eth_dev *eth_dev, uint8_t port_id)
79 {
80         struct bond_dev_private *internals = eth_dev->data->dev_private;
81         uint8_t active_count = internals->active_slave_count;
82
83         if (internals->mode == BONDING_MODE_8023AD)
84                 bond_mode_8023ad_activate_slave(eth_dev, port_id);
85
86         if (internals->mode == BONDING_MODE_TLB
87                         || internals->mode == BONDING_MODE_ALB) {
88
89                 internals->tlb_slaves_order[active_count] = port_id;
90         }
91
92         RTE_ASSERT(internals->active_slave_count <
93                         (RTE_DIM(internals->active_slaves) - 1));
94
95         internals->active_slaves[internals->active_slave_count] = port_id;
96         internals->active_slave_count++;
97
98         if (internals->mode == BONDING_MODE_TLB)
99                 bond_tlb_activate_slave(internals);
100         if (internals->mode == BONDING_MODE_ALB)
101                 bond_mode_alb_client_list_upd(eth_dev);
102 }
103
104 void
105 deactivate_slave(struct rte_eth_dev *eth_dev, uint8_t port_id)
106 {
107         uint8_t slave_pos;
108         struct bond_dev_private *internals = eth_dev->data->dev_private;
109         uint8_t active_count = internals->active_slave_count;
110
111         if (internals->mode == BONDING_MODE_8023AD) {
112                 bond_mode_8023ad_stop(eth_dev);
113                 bond_mode_8023ad_deactivate_slave(eth_dev, port_id);
114         } else if (internals->mode == BONDING_MODE_TLB
115                         || internals->mode == BONDING_MODE_ALB)
116                 bond_tlb_disable(internals);
117
118         slave_pos = find_slave_by_id(internals->active_slaves, active_count,
119                         port_id);
120
121         /* If slave was not at the end of the list
122          * shift active slaves up active array list */
123         if (slave_pos < active_count) {
124                 active_count--;
125                 memmove(internals->active_slaves + slave_pos,
126                                 internals->active_slaves + slave_pos + 1,
127                                 (active_count - slave_pos) *
128                                         sizeof(internals->active_slaves[0]));
129         }
130
131         RTE_ASSERT(active_count < RTE_DIM(internals->active_slaves));
132         internals->active_slave_count = active_count;
133
134         if (eth_dev->data->dev_started) {
135                 if (internals->mode == BONDING_MODE_8023AD) {
136                         bond_mode_8023ad_start(eth_dev);
137                 } else if (internals->mode == BONDING_MODE_TLB) {
138                         bond_tlb_enable(internals);
139                 } else if (internals->mode == BONDING_MODE_ALB) {
140                         bond_tlb_enable(internals);
141                         bond_mode_alb_client_list_upd(eth_dev);
142                 }
143         }
144 }
145
146 uint8_t
147 number_of_sockets(void)
148 {
149         int sockets = 0;
150         int i;
151         const struct rte_memseg *ms = rte_eal_get_physmem_layout();
152
153         for (i = 0; ((i < RTE_MAX_MEMSEG) && (ms[i].addr != NULL)); i++) {
154                 if (sockets < ms[i].socket_id)
155                         sockets = ms[i].socket_id;
156         }
157
158         /* Number of sockets = maximum socket_id + 1 */
159         return ++sockets;
160 }
161
162 int
163 rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
164 {
165         struct bond_dev_private *internals;
166         char devargs[52];
167         uint8_t port_id;
168         int ret;
169
170         if (name == NULL) {
171                 RTE_BOND_LOG(ERR, "Invalid name specified");
172                 return -EINVAL;
173         }
174
175         ret = snprintf(devargs, sizeof(devargs),
176                 "driver=net_bonding,mode=%d,socket_id=%d", mode, socket_id);
177         if (ret < 0 || ret >= (int)sizeof(devargs))
178                 return -ENOMEM;
179
180         ret = rte_vdev_init(name, devargs);
181         if (ret)
182                 return -ENOMEM;
183
184         ret = rte_eth_dev_get_port_by_name(name, &port_id);
185         RTE_ASSERT(!ret);
186
187         /*
188          * To make bond_ethdev_configure() happy we need to free the
189          * internals->kvlist here.
190          *
191          * Also see comment in bond_ethdev_configure().
192          */
193         internals = rte_eth_devices[port_id].data->dev_private;
194         rte_kvargs_free(internals->kvlist);
195         internals->kvlist = NULL;
196
197         return port_id;
198 }
199
200 int
201 rte_eth_bond_free(const char *name)
202 {
203         return rte_vdev_uninit(name);
204 }
205
206 static int
207 slave_vlan_filter_set(uint8_t bonded_port_id, uint8_t slave_port_id)
208 {
209         struct rte_eth_dev *bonded_eth_dev;
210         struct bond_dev_private *internals;
211         int found;
212         int res = 0;
213         uint64_t slab = 0;
214         uint32_t pos = 0;
215         uint16_t first;
216
217         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
218         if (bonded_eth_dev->data->dev_conf.rxmode.hw_vlan_filter == 0)
219                 return 0;
220
221         internals = bonded_eth_dev->data->dev_private;
222         found = rte_bitmap_scan(internals->vlan_filter_bmp, &pos, &slab);
223         first = pos;
224
225         if (!found)
226                 return 0;
227
228         do {
229                 uint32_t i;
230                 uint64_t mask;
231
232                 for (i = 0, mask = 1;
233                      i < RTE_BITMAP_SLAB_BIT_SIZE;
234                      i ++, mask <<= 1) {
235                         if (unlikely(slab & mask))
236                                 res = rte_eth_dev_vlan_filter(slave_port_id,
237                                                               (uint16_t)pos, 1);
238                 }
239                 found = rte_bitmap_scan(internals->vlan_filter_bmp,
240                                         &pos, &slab);
241         } while (found && first != pos && res == 0);
242
243         return res;
244 }
245
246 static int
247 __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
248 {
249         struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
250         struct bond_dev_private *internals;
251         struct rte_eth_link link_props;
252         struct rte_eth_dev_info dev_info;
253
254         if (valid_slave_port_id(slave_port_id) != 0)
255                 return -1;
256
257         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
258         internals = bonded_eth_dev->data->dev_private;
259
260         slave_eth_dev = &rte_eth_devices[slave_port_id];
261         if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_BONDED_SLAVE) {
262                 RTE_BOND_LOG(ERR, "Slave device is already a slave of a bonded device");
263                 return -1;
264         }
265
266         /* Add slave details to bonded device */
267         slave_eth_dev->data->dev_flags |= RTE_ETH_DEV_BONDED_SLAVE;
268
269         rte_eth_dev_info_get(slave_port_id, &dev_info);
270         if (dev_info.max_rx_pktlen < internals->max_rx_pktlen) {
271                 RTE_BOND_LOG(ERR, "Slave (port %u) max_rx_pktlen too small",
272                              slave_port_id);
273                 return -1;
274         }
275
276         slave_add(internals, slave_eth_dev);
277
278         /* We need to store slaves reta_size to be able to synchronize RETA for all
279          * slave devices even if its sizes are different.
280          */
281         internals->slaves[internals->slave_count].reta_size = dev_info.reta_size;
282
283         if (internals->slave_count < 1) {
284                 /* if MAC is not user defined then use MAC of first slave add to
285                  * bonded device */
286                 if (!internals->user_defined_mac)
287                         mac_address_set(bonded_eth_dev, slave_eth_dev->data->mac_addrs);
288
289                 /* Inherit eth dev link properties from first slave */
290                 link_properties_set(bonded_eth_dev,
291                                 &(slave_eth_dev->data->dev_link));
292
293                 /* Make primary slave */
294                 internals->primary_port = slave_port_id;
295                 internals->current_primary_port = slave_port_id;
296
297                 /* Inherit queues settings from first slave */
298                 internals->nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
299                 internals->nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
300
301                 internals->reta_size = dev_info.reta_size;
302
303                 /* Take the first dev's offload capabilities */
304                 internals->rx_offload_capa = dev_info.rx_offload_capa;
305                 internals->tx_offload_capa = dev_info.tx_offload_capa;
306                 internals->flow_type_rss_offloads = dev_info.flow_type_rss_offloads;
307
308                 /* Inherit first slave's max rx packet size */
309                 internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen;
310
311         } else {
312                 internals->rx_offload_capa &= dev_info.rx_offload_capa;
313                 internals->tx_offload_capa &= dev_info.tx_offload_capa;
314                 internals->flow_type_rss_offloads &= dev_info.flow_type_rss_offloads;
315
316                 /* RETA size is GCD of all slaves RETA sizes, so, if all sizes will be
317                  * the power of 2, the lower one is GCD
318                  */
319                 if (internals->reta_size > dev_info.reta_size)
320                         internals->reta_size = dev_info.reta_size;
321
322                 if (!internals->max_rx_pktlen &&
323                     dev_info.max_rx_pktlen < internals->candidate_max_rx_pktlen)
324                         internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen;
325         }
326
327         bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &=
328                         internals->flow_type_rss_offloads;
329
330         internals->slave_count++;
331
332         /* Update all slave devices MACs*/
333         mac_address_slaves_update(bonded_eth_dev);
334
335         if (bonded_eth_dev->data->dev_started) {
336                 if (slave_configure(bonded_eth_dev, slave_eth_dev) != 0) {
337                         slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE);
338                         RTE_BOND_LOG(ERR, "rte_bond_slaves_configure: port=%d",
339                                         slave_port_id);
340                         return -1;
341                 }
342         }
343
344         /* Register link status change callback with bonded device pointer as
345          * argument*/
346         rte_eth_dev_callback_register(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
347                         bond_ethdev_lsc_event_callback, &bonded_eth_dev->data->port_id);
348
349         /* If bonded device is started then we can add the slave to our active
350          * slave array */
351         if (bonded_eth_dev->data->dev_started) {
352                 rte_eth_link_get_nowait(slave_port_id, &link_props);
353
354                  if (link_props.link_status == ETH_LINK_UP) {
355                         if (internals->active_slave_count == 0 &&
356                             !internals->user_defined_primary_port)
357                                 bond_ethdev_primary_set(internals,
358                                                         slave_port_id);
359
360                         if (find_slave_by_id(internals->active_slaves,
361                                              internals->active_slave_count,
362                                              slave_port_id) == internals->active_slave_count)
363                                 activate_slave(bonded_eth_dev, slave_port_id);
364                 }
365         }
366
367         slave_vlan_filter_set(bonded_port_id, slave_port_id);
368
369         return 0;
370
371 }
372
373 int
374 rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
375 {
376         struct rte_eth_dev *bonded_eth_dev;
377         struct bond_dev_private *internals;
378
379         int retval;
380
381         /* Verify that port id's are valid bonded and slave ports */
382         if (valid_bonded_port_id(bonded_port_id) != 0)
383                 return -1;
384
385         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
386         internals = bonded_eth_dev->data->dev_private;
387
388         rte_spinlock_lock(&internals->lock);
389
390         retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id);
391
392         rte_spinlock_unlock(&internals->lock);
393
394         return retval;
395 }
396
397 static int
398 __eth_bond_slave_remove_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
399 {
400         struct rte_eth_dev *bonded_eth_dev;
401         struct bond_dev_private *internals;
402         struct rte_eth_dev *slave_eth_dev;
403         int i, slave_idx;
404
405         if (valid_slave_port_id(slave_port_id) != 0)
406                 return -1;
407
408         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
409         internals = bonded_eth_dev->data->dev_private;
410
411         /* first remove from active slave list */
412         slave_idx = find_slave_by_id(internals->active_slaves,
413                 internals->active_slave_count, slave_port_id);
414
415         if (slave_idx < internals->active_slave_count)
416                 deactivate_slave(bonded_eth_dev, slave_port_id);
417
418         slave_idx = -1;
419         /* now find in slave list */
420         for (i = 0; i < internals->slave_count; i++)
421                 if (internals->slaves[i].port_id == slave_port_id) {
422                         slave_idx = i;
423                         break;
424                 }
425
426         if (slave_idx < 0) {
427                 RTE_BOND_LOG(ERR, "Couldn't find slave in port list, slave count %d",
428                                 internals->slave_count);
429                 return -1;
430         }
431
432         /* Un-register link status change callback with bonded device pointer as
433          * argument*/
434         rte_eth_dev_callback_unregister(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
435                         bond_ethdev_lsc_event_callback,
436                         &rte_eth_devices[bonded_port_id].data->port_id);
437
438         /* Restore original MAC address of slave device */
439         mac_address_set(&rte_eth_devices[slave_port_id],
440                         &(internals->slaves[slave_idx].persisted_mac_addr));
441
442         slave_eth_dev = &rte_eth_devices[slave_port_id];
443         slave_remove(internals, slave_eth_dev);
444         slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE);
445
446         /*  first slave in the active list will be the primary by default,
447          *  otherwise use first device in list */
448         if (internals->current_primary_port == slave_port_id) {
449                 if (internals->active_slave_count > 0)
450                         internals->current_primary_port = internals->active_slaves[0];
451                 else if (internals->slave_count > 0)
452                         internals->current_primary_port = internals->slaves[0].port_id;
453                 else
454                         internals->primary_port = 0;
455         }
456
457         if (internals->active_slave_count < 1) {
458                 /* reset device link properties as no slaves are active */
459                 link_properties_reset(&rte_eth_devices[bonded_port_id]);
460
461                 /* if no slaves are any longer attached to bonded device and MAC is not
462                  * user defined then clear MAC of bonded device as it will be reset
463                  * when a new slave is added */
464                 if (internals->slave_count < 1 && !internals->user_defined_mac)
465                         memset(rte_eth_devices[bonded_port_id].data->mac_addrs, 0,
466                                         sizeof(*(rte_eth_devices[bonded_port_id].data->mac_addrs)));
467         }
468         if (internals->slave_count == 0) {
469                 internals->rx_offload_capa = 0;
470                 internals->tx_offload_capa = 0;
471                 internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK;
472                 internals->reta_size = 0;
473                 internals->candidate_max_rx_pktlen = 0;
474                 internals->max_rx_pktlen = 0;
475         }
476         return 0;
477 }
478
479 int
480 rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
481 {
482         struct rte_eth_dev *bonded_eth_dev;
483         struct bond_dev_private *internals;
484         int retval;
485
486         if (valid_bonded_port_id(bonded_port_id) != 0)
487                 return -1;
488
489         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
490         internals = bonded_eth_dev->data->dev_private;
491
492         rte_spinlock_lock(&internals->lock);
493
494         retval = __eth_bond_slave_remove_lock_free(bonded_port_id, slave_port_id);
495
496         rte_spinlock_unlock(&internals->lock);
497
498         return retval;
499 }
500
501 int
502 rte_eth_bond_mode_set(uint8_t bonded_port_id, uint8_t mode)
503 {
504         if (valid_bonded_port_id(bonded_port_id) != 0)
505                 return -1;
506
507         return bond_ethdev_mode_set(&rte_eth_devices[bonded_port_id], mode);
508 }
509
510 int
511 rte_eth_bond_mode_get(uint8_t bonded_port_id)
512 {
513         struct bond_dev_private *internals;
514
515         if (valid_bonded_port_id(bonded_port_id) != 0)
516                 return -1;
517
518         internals = rte_eth_devices[bonded_port_id].data->dev_private;
519
520         return internals->mode;
521 }
522
523 int
524 rte_eth_bond_primary_set(uint8_t bonded_port_id, uint8_t slave_port_id)
525 {
526         struct bond_dev_private *internals;
527
528         if (valid_bonded_port_id(bonded_port_id) != 0)
529                 return -1;
530
531         if (valid_slave_port_id(slave_port_id) != 0)
532                 return -1;
533
534         internals =  rte_eth_devices[bonded_port_id].data->dev_private;
535
536         internals->user_defined_primary_port = 1;
537         internals->primary_port = slave_port_id;
538
539         bond_ethdev_primary_set(internals, slave_port_id);
540
541         return 0;
542 }
543
544 int
545 rte_eth_bond_primary_get(uint8_t bonded_port_id)
546 {
547         struct bond_dev_private *internals;
548
549         if (valid_bonded_port_id(bonded_port_id) != 0)
550                 return -1;
551
552         internals = rte_eth_devices[bonded_port_id].data->dev_private;
553
554         if (internals->slave_count < 1)
555                 return -1;
556
557         return internals->current_primary_port;
558 }
559
560 int
561 rte_eth_bond_slaves_get(uint8_t bonded_port_id, uint8_t slaves[], uint8_t len)
562 {
563         struct bond_dev_private *internals;
564         uint8_t i;
565
566         if (valid_bonded_port_id(bonded_port_id) != 0)
567                 return -1;
568
569         if (slaves == NULL)
570                 return -1;
571
572         internals = rte_eth_devices[bonded_port_id].data->dev_private;
573
574         if (internals->slave_count > len)
575                 return -1;
576
577         for (i = 0; i < internals->slave_count; i++)
578                 slaves[i] = internals->slaves[i].port_id;
579
580         return internals->slave_count;
581 }
582
583 int
584 rte_eth_bond_active_slaves_get(uint8_t bonded_port_id, uint8_t slaves[],
585                 uint8_t len)
586 {
587         struct bond_dev_private *internals;
588
589         if (valid_bonded_port_id(bonded_port_id) != 0)
590                 return -1;
591
592         if (slaves == NULL)
593                 return -1;
594
595         internals = rte_eth_devices[bonded_port_id].data->dev_private;
596
597         if (internals->active_slave_count > len)
598                 return -1;
599
600         memcpy(slaves, internals->active_slaves, internals->active_slave_count);
601
602         return internals->active_slave_count;
603 }
604
605 int
606 rte_eth_bond_mac_address_set(uint8_t bonded_port_id,
607                 struct ether_addr *mac_addr)
608 {
609         struct rte_eth_dev *bonded_eth_dev;
610         struct bond_dev_private *internals;
611
612         if (valid_bonded_port_id(bonded_port_id) != 0)
613                 return -1;
614
615         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
616         internals = bonded_eth_dev->data->dev_private;
617
618         /* Set MAC Address of Bonded Device */
619         if (mac_address_set(bonded_eth_dev, mac_addr))
620                 return -1;
621
622         internals->user_defined_mac = 1;
623
624         /* Update all slave devices MACs*/
625         if (internals->slave_count > 0)
626                 return mac_address_slaves_update(bonded_eth_dev);
627
628         return 0;
629 }
630
631 int
632 rte_eth_bond_mac_address_reset(uint8_t bonded_port_id)
633 {
634         struct rte_eth_dev *bonded_eth_dev;
635         struct bond_dev_private *internals;
636
637         if (valid_bonded_port_id(bonded_port_id) != 0)
638                 return -1;
639
640         bonded_eth_dev = &rte_eth_devices[bonded_port_id];
641         internals = bonded_eth_dev->data->dev_private;
642
643         internals->user_defined_mac = 0;
644
645         if (internals->slave_count > 0) {
646                 /* Set MAC Address of Bonded Device */
647                 if (mac_address_set(bonded_eth_dev,
648                                 &internals->slaves[internals->primary_port].persisted_mac_addr)
649                                 != 0) {
650                         RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device");
651                         return -1;
652                 }
653                 /* Update all slave devices MAC addresses */
654                 return mac_address_slaves_update(bonded_eth_dev);
655         }
656         /* No need to update anything as no slaves present */
657         return 0;
658 }
659
660 int
661 rte_eth_bond_xmit_policy_set(uint8_t bonded_port_id, uint8_t policy)
662 {
663         struct bond_dev_private *internals;
664
665         if (valid_bonded_port_id(bonded_port_id) != 0)
666                 return -1;
667
668         internals = rte_eth_devices[bonded_port_id].data->dev_private;
669
670         switch (policy) {
671         case BALANCE_XMIT_POLICY_LAYER2:
672                 internals->balance_xmit_policy = policy;
673                 internals->xmit_hash = xmit_l2_hash;
674                 break;
675         case BALANCE_XMIT_POLICY_LAYER23:
676                 internals->balance_xmit_policy = policy;
677                 internals->xmit_hash = xmit_l23_hash;
678                 break;
679         case BALANCE_XMIT_POLICY_LAYER34:
680                 internals->balance_xmit_policy = policy;
681                 internals->xmit_hash = xmit_l34_hash;
682                 break;
683
684         default:
685                 return -1;
686         }
687         return 0;
688 }
689
690 int
691 rte_eth_bond_xmit_policy_get(uint8_t bonded_port_id)
692 {
693         struct bond_dev_private *internals;
694
695         if (valid_bonded_port_id(bonded_port_id) != 0)
696                 return -1;
697
698         internals = rte_eth_devices[bonded_port_id].data->dev_private;
699
700         return internals->balance_xmit_policy;
701 }
702
703 int
704 rte_eth_bond_link_monitoring_set(uint8_t bonded_port_id, uint32_t internal_ms)
705 {
706         struct bond_dev_private *internals;
707
708         if (valid_bonded_port_id(bonded_port_id) != 0)
709                 return -1;
710
711         internals = rte_eth_devices[bonded_port_id].data->dev_private;
712         internals->link_status_polling_interval_ms = internal_ms;
713
714         return 0;
715 }
716
717 int
718 rte_eth_bond_link_monitoring_get(uint8_t bonded_port_id)
719 {
720         struct bond_dev_private *internals;
721
722         if (valid_bonded_port_id(bonded_port_id) != 0)
723                 return -1;
724
725         internals = rte_eth_devices[bonded_port_id].data->dev_private;
726
727         return internals->link_status_polling_interval_ms;
728 }
729
730 int
731 rte_eth_bond_link_down_prop_delay_set(uint8_t bonded_port_id, uint32_t delay_ms)
732
733 {
734         struct bond_dev_private *internals;
735
736         if (valid_bonded_port_id(bonded_port_id) != 0)
737                 return -1;
738
739         internals = rte_eth_devices[bonded_port_id].data->dev_private;
740         internals->link_down_delay_ms = delay_ms;
741
742         return 0;
743 }
744
745 int
746 rte_eth_bond_link_down_prop_delay_get(uint8_t bonded_port_id)
747 {
748         struct bond_dev_private *internals;
749
750         if (valid_bonded_port_id(bonded_port_id) != 0)
751                 return -1;
752
753         internals = rte_eth_devices[bonded_port_id].data->dev_private;
754
755         return internals->link_down_delay_ms;
756 }
757
758 int
759 rte_eth_bond_link_up_prop_delay_set(uint8_t bonded_port_id, uint32_t delay_ms)
760
761 {
762         struct bond_dev_private *internals;
763
764         if (valid_bonded_port_id(bonded_port_id) != 0)
765                 return -1;
766
767         internals = rte_eth_devices[bonded_port_id].data->dev_private;
768         internals->link_up_delay_ms = delay_ms;
769
770         return 0;
771 }
772
773 int
774 rte_eth_bond_link_up_prop_delay_get(uint8_t bonded_port_id)
775 {
776         struct bond_dev_private *internals;
777
778         if (valid_bonded_port_id(bonded_port_id) != 0)
779                 return -1;
780
781         internals = rte_eth_devices[bonded_port_id].data->dev_private;
782
783         return internals->link_up_delay_ms;
784 }