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