bond: free mbufs on Tx burst failure
[dpdk.git] / lib / librte_pmd_bond / rte_eth_bond_pmd.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 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 <rte_mbuf.h>
35 #include <rte_malloc.h>
36 #include <rte_ethdev.h>
37 #include <rte_tcp.h>
38 #include <rte_udp.h>
39 #include <rte_ip.h>
40 #include <rte_devargs.h>
41 #include <rte_kvargs.h>
42 #include <rte_dev.h>
43
44 #include "rte_eth_bond.h"
45 #include "rte_eth_bond_private.h"
46
47 static uint16_t
48 bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
49 {
50         struct bond_dev_private *internals;
51
52         uint16_t num_rx_slave = 0;
53         uint16_t num_rx_total = 0;
54
55         int i;
56
57         /* Cast to structure, containing bonded device's port id and queue id */
58         struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue;
59
60         internals = bd_rx_q->dev_private;
61
62
63         for (i = 0; i < internals->active_slave_count && nb_pkts; i++) {
64                 /* Offset of pointer to *bufs increases as packets are received
65                  * from other slaves */
66                 num_rx_slave = rte_eth_rx_burst(internals->active_slaves[i],
67                                 bd_rx_q->queue_id, bufs + num_rx_total, nb_pkts);
68                 if (num_rx_slave) {
69                         num_rx_total += num_rx_slave;
70                         nb_pkts -= num_rx_slave;
71                 }
72         }
73
74         return num_rx_total;
75 }
76
77 static uint16_t
78 bond_ethdev_rx_burst_active_backup(void *queue, struct rte_mbuf **bufs,
79                 uint16_t nb_pkts)
80 {
81         struct bond_dev_private *internals;
82
83         /* Cast to structure, containing bonded device's port id and queue id */
84         struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue;
85
86         internals = bd_rx_q->dev_private;
87
88         return rte_eth_rx_burst(internals->current_primary_port,
89                         bd_rx_q->queue_id, bufs, nb_pkts);
90 }
91
92 static uint16_t
93 bond_ethdev_tx_burst_round_robin(void *queue, struct rte_mbuf **bufs,
94                 uint16_t nb_pkts)
95 {
96         struct bond_dev_private *internals;
97         struct bond_tx_queue *bd_tx_q;
98
99         struct rte_mbuf *slave_bufs[RTE_MAX_ETHPORTS][nb_pkts];
100         uint16_t slave_nb_pkts[RTE_MAX_ETHPORTS] = { 0 };
101
102         uint8_t num_of_slaves;
103         uint8_t slaves[RTE_MAX_ETHPORTS];
104
105         uint16_t num_tx_total = 0, num_tx_slave;
106
107         static int slave_idx = 0;
108         int i, cslave_idx = 0, tx_fail_total = 0;
109
110         bd_tx_q = (struct bond_tx_queue *)queue;
111         internals = bd_tx_q->dev_private;
112
113         /* Copy slave list to protect against slave up/down changes during tx
114          * bursting */
115         num_of_slaves = internals->active_slave_count;
116         memcpy(slaves, internals->active_slaves,
117                         sizeof(internals->active_slaves[0]) * num_of_slaves);
118
119         if (num_of_slaves < 1)
120                 return num_tx_total;
121
122         /* Populate slaves mbuf with which packets are to be sent on it  */
123         for (i = 0; i < nb_pkts; i++) {
124                 cslave_idx = (slave_idx + i) % num_of_slaves;
125                 slave_bufs[cslave_idx][(slave_nb_pkts[cslave_idx])++] = bufs[i];
126         }
127
128         /* increment current slave index so the next call to tx burst starts on the
129          * next slave */
130         slave_idx = ++cslave_idx;
131
132         /* Send packet burst on each slave device */
133         for (i = 0; i < num_of_slaves; i++) {
134                 if (slave_nb_pkts[i] > 0) {
135                         num_tx_slave = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
136                                         slave_bufs[i], slave_nb_pkts[i]);
137
138                         /* if tx burst fails move packets to end of bufs */
139                         if (unlikely(num_tx_slave < slave_nb_pkts[i])) {
140                                 int tx_fail_slave = slave_nb_pkts[i] - num_tx_slave;
141
142                                 tx_fail_total += tx_fail_slave;
143
144                                 memcpy(&bufs[nb_pkts - tx_fail_total],
145                                                 &slave_bufs[i][num_tx_slave], tx_fail_slave * sizeof(bufs[0]));
146                         }
147                         num_tx_total += num_tx_slave;
148                 }
149         }
150
151         return num_tx_total;
152 }
153
154 static uint16_t
155 bond_ethdev_tx_burst_active_backup(void *queue,
156                 struct rte_mbuf **bufs, uint16_t nb_pkts)
157 {
158         struct bond_dev_private *internals;
159         struct bond_tx_queue *bd_tx_q;
160
161         bd_tx_q = (struct bond_tx_queue *)queue;
162         internals = bd_tx_q->dev_private;
163
164         if (internals->active_slave_count < 1)
165                 return 0;
166
167         return rte_eth_tx_burst(internals->current_primary_port, bd_tx_q->queue_id,
168                         bufs, nb_pkts);
169 }
170
171 static inline uint16_t
172 ether_hash(struct ether_hdr *eth_hdr)
173 {
174         uint16_t *word_src_addr = (uint16_t *)eth_hdr->s_addr.addr_bytes;
175         uint16_t *word_dst_addr = (uint16_t *)eth_hdr->d_addr.addr_bytes;
176
177         return (word_src_addr[0] ^ word_dst_addr[0]) ^
178                         (word_src_addr[1] ^ word_dst_addr[1]) ^
179                         (word_src_addr[2] ^ word_dst_addr[2]);
180 }
181
182 static inline uint32_t
183 ipv4_hash(struct ipv4_hdr *ipv4_hdr)
184 {
185         return (ipv4_hdr->src_addr ^ ipv4_hdr->dst_addr);
186 }
187
188 static inline uint32_t
189 ipv6_hash(struct ipv6_hdr *ipv6_hdr)
190 {
191         uint32_t *word_src_addr = (uint32_t *)&(ipv6_hdr->src_addr[0]);
192         uint32_t *word_dst_addr = (uint32_t *)&(ipv6_hdr->dst_addr[0]);
193
194         return (word_src_addr[0] ^ word_dst_addr[0]) ^
195                         (word_src_addr[1] ^ word_dst_addr[1]) ^
196                         (word_src_addr[2] ^ word_dst_addr[2]) ^
197                         (word_src_addr[3] ^ word_dst_addr[3]);
198 }
199
200 static uint32_t
201 udp_hash(struct udp_hdr *hdr)
202 {
203         return hdr->src_port ^ hdr->dst_port;
204 }
205
206 static inline uint16_t
207 xmit_slave_hash(const struct rte_mbuf *buf, uint8_t slave_count, uint8_t policy)
208 {
209         struct ether_hdr *eth_hdr;
210         struct udp_hdr *udp_hdr;
211         size_t eth_offset = 0;
212         uint32_t hash = 0;
213
214         if (slave_count == 1)
215                 return 0;
216
217         switch (policy) {
218         case BALANCE_XMIT_POLICY_LAYER2:
219                 eth_hdr = rte_pktmbuf_mtod(buf, struct ether_hdr *);
220
221                 hash = ether_hash(eth_hdr);
222                 hash ^= hash >> 8;
223                 return hash % slave_count;
224
225         case BALANCE_XMIT_POLICY_LAYER23:
226                 eth_hdr = rte_pktmbuf_mtod(buf, struct ether_hdr *);
227
228                 if (buf->ol_flags & PKT_RX_VLAN_PKT)
229                         eth_offset = sizeof(struct ether_hdr) + sizeof(struct vlan_hdr);
230                 else
231                         eth_offset = sizeof(struct ether_hdr);
232
233                 if (buf->ol_flags & PKT_RX_IPV4_HDR) {
234                         struct ipv4_hdr *ipv4_hdr;
235                         ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(buf,
236                                         unsigned char *) + eth_offset);
237
238                         hash = ether_hash(eth_hdr) ^ ipv4_hash(ipv4_hdr);
239
240                 } else {
241                         struct ipv6_hdr *ipv6_hdr;
242
243                         ipv6_hdr = (struct ipv6_hdr *)(rte_pktmbuf_mtod(buf,
244                                         unsigned char *) + eth_offset);
245
246                         hash = ether_hash(eth_hdr) ^ ipv6_hash(ipv6_hdr);
247                 }
248                 break;
249
250         case BALANCE_XMIT_POLICY_LAYER34:
251                 if (buf->ol_flags & PKT_RX_VLAN_PKT)
252                         eth_offset = sizeof(struct ether_hdr) + sizeof(struct vlan_hdr);
253                 else
254                         eth_offset = sizeof(struct ether_hdr);
255
256                 if (buf->ol_flags & PKT_RX_IPV4_HDR) {
257                         struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)
258                                         (rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset);
259
260                         if (ipv4_hdr->next_proto_id == IPPROTO_UDP) {
261                                 udp_hdr = (struct udp_hdr *)
262                                                 (rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset +
263                                                                 sizeof(struct ipv4_hdr));
264                                 hash = ipv4_hash(ipv4_hdr) ^ udp_hash(udp_hdr);
265                         } else {
266                                 hash = ipv4_hash(ipv4_hdr);
267                         }
268                 } else {
269                         struct ipv6_hdr *ipv6_hdr = (struct ipv6_hdr *)
270                                         (rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset);
271
272                         if (ipv6_hdr->proto == IPPROTO_UDP) {
273                                 udp_hdr = (struct udp_hdr *)
274                                                 (rte_pktmbuf_mtod(buf, unsigned char *) + eth_offset +
275                                                                 sizeof(struct ipv6_hdr));
276                                 hash = ipv6_hash(ipv6_hdr) ^ udp_hash(udp_hdr);
277                         } else {
278                                 hash = ipv6_hash(ipv6_hdr);
279                         }
280                 }
281                 break;
282         }
283
284         hash ^= hash >> 16;
285         hash ^= hash >> 8;
286
287         return hash % slave_count;
288 }
289
290 static uint16_t
291 bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs,
292                 uint16_t nb_pkts)
293 {
294         struct bond_dev_private *internals;
295         struct bond_tx_queue *bd_tx_q;
296
297         uint8_t num_of_slaves;
298         uint8_t slaves[RTE_MAX_ETHPORTS];
299
300         uint16_t num_tx_total = 0, num_tx_slave = 0, tx_fail_total = 0;
301
302         int i, op_slave_id;
303
304         struct rte_mbuf *slave_bufs[RTE_MAX_ETHPORTS][nb_pkts];
305         uint16_t slave_nb_pkts[RTE_MAX_ETHPORTS] = { 0 };
306
307         bd_tx_q = (struct bond_tx_queue *)queue;
308         internals = bd_tx_q->dev_private;
309
310         /* Copy slave list to protect against slave up/down changes during tx
311          * bursting */
312         num_of_slaves = internals->active_slave_count;
313         memcpy(slaves, internals->active_slaves,
314                         sizeof(internals->active_slaves[0]) * num_of_slaves);
315
316         if (num_of_slaves < 1)
317                 return num_tx_total;
318
319         /* Populate slaves mbuf with the packets which are to be sent on it  */
320         for (i = 0; i < nb_pkts; i++) {
321                 /* Select output slave using hash based on xmit policy */
322                 op_slave_id = xmit_slave_hash(bufs[i], num_of_slaves,
323                                 internals->balance_xmit_policy);
324
325                 /* Populate slave mbuf arrays with mbufs for that slave */
326                 slave_bufs[op_slave_id][slave_nb_pkts[op_slave_id]++] = bufs[i];
327         }
328
329         /* Send packet burst on each slave device */
330         for (i = 0; i < num_of_slaves; i++) {
331                 if (slave_nb_pkts[i] > 0) {
332                         num_tx_slave = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
333                                         slave_bufs[i], slave_nb_pkts[i]);
334
335                         /* if tx burst fails move packets to end of bufs */
336                         if (unlikely(num_tx_slave < slave_nb_pkts[i])) {
337                                 int slave_tx_fail_count = slave_nb_pkts[i] - num_tx_slave;
338
339                                 tx_fail_total += slave_tx_fail_count;
340                                 memcpy(bufs[nb_pkts - tx_fail_total],
341                                                 slave_bufs[i][num_tx_slave], slave_tx_fail_count);
342                         }
343
344                         num_tx_total += num_tx_slave;
345                 }
346         }
347
348
349         return num_tx_total;
350 }
351
352 #ifdef RTE_MBUF_REFCNT
353 static uint16_t
354 bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs,
355                 uint16_t nb_pkts)
356 {
357         struct bond_dev_private *internals;
358         struct bond_tx_queue *bd_tx_q;
359
360         uint8_t tx_failed_flag = 0, num_of_slaves;
361         uint8_t slaves[RTE_MAX_ETHPORTS];
362
363         uint16_t max_nb_of_tx_pkts = 0;
364
365         int slave_tx_total[RTE_MAX_ETHPORTS];
366         int i, most_successful_tx_slave = -1;
367
368         bd_tx_q = (struct bond_tx_queue *)queue;
369         internals = bd_tx_q->dev_private;
370
371         /* Copy slave list to protect against slave up/down changes during tx
372          * bursting */
373         num_of_slaves = internals->active_slave_count;
374         memcpy(slaves, internals->active_slaves,
375                         sizeof(internals->active_slaves[0]) * num_of_slaves);
376
377         if (num_of_slaves < 1)
378                 return 0;
379
380         /* Increment reference count on mbufs */
381         for (i = 0; i < nb_pkts; i++)
382                 rte_mbuf_refcnt_update(bufs[i], num_of_slaves - 1);
383
384         /* Transmit burst on each active slave */
385         for (i = 0; i < num_of_slaves; i++) {
386                 slave_tx_total[i] = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
387                                         bufs, nb_pkts);
388
389                 if (unlikely(slave_tx_total[i] < nb_pkts))
390                         tx_failed_flag = 1;
391
392                 /* record the value and slave index for the slave which transmits the
393                  * maximum number of packets */
394                 if (slave_tx_total[i] > max_nb_of_tx_pkts) {
395                         max_nb_of_tx_pkts = slave_tx_total[i];
396                         most_successful_tx_slave = i;
397                 }
398         }
399
400         /* if slaves fail to transmit packets from burst, the calling application
401          * is not expected to know about multiple references to packets so we must
402          * handle failures of all packets except those of the most successful slave
403          */
404         if (unlikely(tx_failed_flag))
405                 for (i = 0; i < num_of_slaves; i++)
406                         if (i != most_successful_tx_slave)
407                                 while (slave_tx_total[i] < nb_pkts)
408                                         rte_pktmbuf_free(bufs[slave_tx_total[i]++]);
409
410         return max_nb_of_tx_pkts;
411 }
412 #endif
413
414 void
415 link_properties_set(struct rte_eth_dev *bonded_eth_dev,
416                 struct rte_eth_link *slave_dev_link)
417 {
418         struct rte_eth_link *bonded_dev_link = &bonded_eth_dev->data->dev_link;
419         struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
420
421         if (slave_dev_link->link_status &&
422                 bonded_eth_dev->data->dev_started) {
423                 bonded_dev_link->link_duplex = slave_dev_link->link_duplex;
424                 bonded_dev_link->link_speed = slave_dev_link->link_speed;
425
426                 internals->link_props_set = 1;
427         }
428 }
429
430 void
431 link_properties_reset(struct rte_eth_dev *bonded_eth_dev)
432 {
433         struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
434
435         memset(&(bonded_eth_dev->data->dev_link), 0,
436                         sizeof(bonded_eth_dev->data->dev_link));
437
438         internals->link_props_set = 0;
439 }
440
441 int
442 link_properties_valid(struct rte_eth_link *bonded_dev_link,
443                 struct rte_eth_link *slave_dev_link)
444 {
445         if (bonded_dev_link->link_duplex != slave_dev_link->link_duplex ||
446                 bonded_dev_link->link_speed !=  slave_dev_link->link_speed)
447                 return -1;
448
449         return 0;
450 }
451
452 int
453 mac_address_set(struct rte_eth_dev *eth_dev, struct ether_addr *new_mac_addr)
454 {
455         struct ether_addr *mac_addr;
456
457         mac_addr = eth_dev->data->mac_addrs;
458
459         if (eth_dev == NULL) {
460                 RTE_LOG(ERR, PMD, "%s: NULL pointer eth_dev specified\n", __func__);
461                 return -1;
462         }
463
464         if (new_mac_addr == NULL) {
465                 RTE_LOG(ERR, PMD, "%s: NULL pointer MAC specified\n", __func__);
466                 return -1;
467         }
468
469         /* if new MAC is different to current MAC then update */
470         if (memcmp(mac_addr, new_mac_addr, sizeof(*mac_addr)) != 0)
471                 memcpy(mac_addr, new_mac_addr, sizeof(*mac_addr));
472
473         return 0;
474 }
475
476 int
477 mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
478 {
479         struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
480         int i;
481
482         /* Update slave devices MAC addresses */
483         if (internals->slave_count < 1)
484                 return -1;
485
486         switch (internals->mode) {
487         case BONDING_MODE_ROUND_ROBIN:
488         case BONDING_MODE_BALANCE:
489 #ifdef RTE_MBUF_REFCNT
490         case BONDING_MODE_BROADCAST:
491 #endif
492                 for (i = 0; i < internals->slave_count; i++) {
493                         if (mac_address_set(&rte_eth_devices[internals->slaves[i]],
494                                         bonded_eth_dev->data->mac_addrs)) {
495                                 RTE_LOG(ERR, PMD,
496                                                 "%s: Failed to update port Id %d MAC address\n",
497                                                 __func__, internals->slaves[i]);
498                                 return -1;
499                         }
500                 }
501                 break;
502         case BONDING_MODE_ACTIVE_BACKUP:
503         default:
504                 for (i = 0; i < internals->slave_count; i++) {
505                         if (internals->slaves[i] == internals->current_primary_port) {
506                                 if (mac_address_set(&rte_eth_devices[internals->primary_port],
507                                                 bonded_eth_dev->data->mac_addrs)) {
508                                         RTE_LOG(ERR, PMD,
509                                                         "%s: Failed to update port Id %d MAC address\n",
510                                                         __func__, internals->current_primary_port);
511                                 }
512                         } else {
513                                 struct slave_conf *conf =
514                                                 slave_config_get(internals, internals->slaves[i]);
515
516                                 if (mac_address_set(&rte_eth_devices[internals->slaves[i]],
517                                                 &conf->mac_addr)) {
518                                         RTE_LOG(ERR, PMD,
519                                                         "%s: Failed to update port Id %d MAC address\n",
520                                                         __func__, internals->slaves[i]);
521
522                                         return -1;
523                                 }
524                         }
525                 }
526         }
527
528         return 0;
529 }
530
531 int
532 bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode)
533 {
534         struct bond_dev_private *internals;
535
536         internals = eth_dev->data->dev_private;
537
538         switch (mode) {
539         case BONDING_MODE_ROUND_ROBIN:
540                 eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_round_robin;
541                 eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
542                 break;
543         case BONDING_MODE_ACTIVE_BACKUP:
544                 eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_active_backup;
545                 eth_dev->rx_pkt_burst = bond_ethdev_rx_burst_active_backup;
546                 break;
547         case BONDING_MODE_BALANCE:
548                 eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_balance;
549                 eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
550                 break;
551 #ifdef RTE_MBUF_REFCNT
552         case BONDING_MODE_BROADCAST:
553                 eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_broadcast;
554                 eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
555                 break;
556 #endif
557         default:
558                 return -1;
559         }
560
561         internals->mode = mode;
562
563         return 0;
564 }
565
566 int
567 slave_configure(struct rte_eth_dev *bonded_eth_dev,
568                 struct rte_eth_dev *slave_eth_dev)
569 {
570         struct bond_rx_queue *bd_rx_q;
571         struct bond_tx_queue *bd_tx_q;
572
573         int q_id;
574
575         /* Stop slave */
576         rte_eth_dev_stop(slave_eth_dev->data->port_id);
577
578         /* Enable interrupts on slave device */
579         slave_eth_dev->data->dev_conf.intr_conf.lsc = 1;
580
581         if (rte_eth_dev_configure(slave_eth_dev->data->port_id,
582                         bonded_eth_dev->data->nb_rx_queues,
583                         bonded_eth_dev->data->nb_tx_queues,
584                         &(slave_eth_dev->data->dev_conf)) != 0) {
585                 RTE_LOG(ERR, PMD, "Cannot configure slave device: port=%u\n",
586                                 slave_eth_dev->data->port_id);
587                 return -1;
588         }
589
590         /* Setup Rx Queues */
591         for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
592                 bd_rx_q = (struct bond_rx_queue *)bonded_eth_dev->data->rx_queues[q_id];
593
594                 if (rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
595                                 bd_rx_q->nb_rx_desc,
596                                 rte_eth_dev_socket_id(slave_eth_dev->data->port_id),
597                                 &(bd_rx_q->rx_conf), bd_rx_q->mb_pool) != 0) {
598                         RTE_LOG(ERR, PMD, "rte_eth_rx_queue_setup: port=%d queue_id %d\n",
599                                         slave_eth_dev->data->port_id, q_id);
600                         return -1;
601                 }
602         }
603
604         /* Setup Tx Queues */
605         for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
606                 bd_tx_q = (struct bond_tx_queue *)bonded_eth_dev->data->tx_queues[q_id];
607
608                 if (rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
609                                 bd_tx_q->nb_tx_desc,
610                                 rte_eth_dev_socket_id(slave_eth_dev->data->port_id),
611                                 &bd_tx_q->tx_conf) != 0) {
612                         RTE_LOG(ERR, PMD, "rte_eth_tx_queue_setup: port=%d queue_id %d\n",
613                                         slave_eth_dev->data->port_id, q_id);
614                         return -1;
615                 }
616         }
617
618         /* Start device */
619         if (rte_eth_dev_start(slave_eth_dev->data->port_id) != 0) {
620                 RTE_LOG(ERR, PMD, "rte_eth_dev_start: port=%u\n",
621                                 slave_eth_dev->data->port_id);
622                 return -1;
623         }
624
625         return 0;
626 }
627
628 struct slave_conf *
629 slave_config_get(struct bond_dev_private *internals, uint8_t slave_port_id)
630 {
631         int i;
632
633         for (i = 0; i < internals->slave_count; i++) {
634                 if (internals->presisted_slaves_conf[i].port_id == slave_port_id)
635                         return &internals->presisted_slaves_conf[i];
636         }
637         return NULL;
638 }
639
640 void
641 slave_config_clear(struct bond_dev_private *internals,
642                 struct rte_eth_dev *slave_eth_dev)
643 {
644         int i, found = 0;
645
646         for (i = 0; i < internals->slave_count; i++) {
647                 if (internals->presisted_slaves_conf[i].port_id ==
648                                 slave_eth_dev->data->port_id) {
649                         found = 1;
650                         memset(&internals->presisted_slaves_conf[i], 0,
651                                         sizeof(internals->presisted_slaves_conf[i]));
652                 }
653                 if (found && i < (internals->slave_count - 1)) {
654                         memcpy(&internals->presisted_slaves_conf[i],
655                                         &internals->presisted_slaves_conf[i+1],
656                                         sizeof(internals->presisted_slaves_conf[i]));
657                 }
658         }
659 }
660
661 void
662 slave_config_store(struct bond_dev_private *internals,
663                 struct rte_eth_dev *slave_eth_dev)
664 {
665         struct slave_conf *presisted_slave_conf =
666                         &internals->presisted_slaves_conf[internals->slave_count];
667
668         presisted_slave_conf->port_id = slave_eth_dev->data->port_id;
669
670         memcpy(&(presisted_slave_conf->mac_addr), slave_eth_dev->data->mac_addrs,
671                         sizeof(struct ether_addr));
672 }
673
674 void
675 bond_ethdev_primary_set(struct bond_dev_private *internals,
676                 uint8_t slave_port_id)
677 {
678         int i;
679
680         if (internals->active_slave_count < 1)
681                 internals->current_primary_port = slave_port_id;
682         else
683                 /* Search bonded device slave ports for new proposed primary port */
684                 for (i = 0; i < internals->active_slave_count; i++) {
685                         if (internals->active_slaves[i] == slave_port_id)
686                                 internals->current_primary_port = slave_port_id;
687                 }
688 }
689
690 static void
691 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev);
692
693 static int
694 bond_ethdev_start(struct rte_eth_dev *eth_dev)
695 {
696         struct bond_dev_private *internals;
697         int i;
698
699         /* slave eth dev will be started by bonded device */
700         if (valid_bonded_ethdev(eth_dev)) {
701                 RTE_LOG(ERR, PMD,
702                                 "%s: user tried to explicitly start a slave eth_dev (%d) of the bonded eth_dev\n",
703                                 __func__, eth_dev->data->port_id);
704                 return -1;
705         }
706
707         eth_dev->data->dev_link.link_status = 1;
708         eth_dev->data->dev_started = 1;
709
710         internals = eth_dev->data->dev_private;
711
712         if (internals->slave_count == 0) {
713                 RTE_LOG(ERR, PMD,
714                                 "%s: Cannot start port since there are no slave devices\n",
715                                 __func__);
716                 return -1;
717         }
718
719         if (internals->user_defined_mac == 0) {
720                 struct slave_conf *conf = slave_config_get(internals,
721                                 internals->primary_port);
722
723                 if (mac_address_set(eth_dev, &(conf->mac_addr)) != 0) {
724                         RTE_LOG(ERR, PMD,
725                                         "bonded port (%d) failed to update mac address",
726                                         eth_dev->data->port_id);
727                         return -1;
728                 }
729         }
730
731         /* Update all slave devices MACs*/
732         if (mac_address_slaves_update(eth_dev) != 0)
733                 return -1;
734
735         /* If bonded device is configure in promiscuous mode then re-apply config */
736         if (internals->promiscuous_en)
737                 bond_ethdev_promiscuous_enable(eth_dev);
738
739         /* Reconfigure each slave device if starting bonded device */
740         for (i = 0; i < internals->slave_count; i++) {
741                 if (slave_configure(eth_dev, &(rte_eth_devices[internals->slaves[i]]))
742                                 != 0) {
743                         RTE_LOG(ERR, PMD, "bonded port "
744                                         "(%d) failed to reconfigure slave device (%d)\n)",
745                                         eth_dev->data->port_id, internals->slaves[i]);
746                         return -1;
747                 }
748         }
749
750         if (internals->user_defined_primary_port)
751                 bond_ethdev_primary_set(internals, internals->primary_port);
752
753         return 0;
754 }
755
756 static void
757 bond_ethdev_stop(struct rte_eth_dev *eth_dev)
758 {
759         struct bond_dev_private *internals = eth_dev->data->dev_private;
760
761         internals->active_slave_count = 0;
762
763         eth_dev->data->dev_link.link_status = 0;
764         eth_dev->data->dev_started = 0;
765 }
766
767 static void
768 bond_ethdev_close(struct rte_eth_dev *dev __rte_unused)
769 {
770 }
771
772 /* forward declaration */
773 static int bond_ethdev_configure(struct rte_eth_dev *dev);
774
775 static void
776 bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
777 {
778         dev_info->driver_name = driver_name;
779         dev_info->max_mac_addrs = 1;
780
781         dev_info->max_rx_pktlen = (uint32_t)2048;
782
783         dev_info->max_rx_queues = (uint16_t)128;
784         dev_info->max_tx_queues = (uint16_t)512;
785
786         dev_info->min_rx_bufsize = 0;
787         dev_info->pci_dev = dev->pci_dev;
788 }
789
790 static int
791 bond_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
792                 uint16_t nb_rx_desc, unsigned int socket_id __rte_unused,
793                 const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mb_pool)
794 {
795         struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)
796                         rte_zmalloc_socket(NULL, sizeof(struct bond_rx_queue),
797                                         0, dev->pci_dev->numa_node);
798         if (bd_rx_q == NULL)
799                 return -1;
800
801         bd_rx_q->queue_id = rx_queue_id;
802         bd_rx_q->dev_private = dev->data->dev_private;
803
804         bd_rx_q->nb_rx_desc = nb_rx_desc;
805
806         memcpy(&(bd_rx_q->rx_conf), rx_conf, sizeof(struct rte_eth_rxconf));
807         bd_rx_q->mb_pool = mb_pool;
808
809         dev->data->rx_queues[rx_queue_id] = bd_rx_q;
810
811         return 0;
812 }
813
814 static int
815 bond_ethdev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
816                 uint16_t nb_tx_desc, unsigned int socket_id __rte_unused,
817                 const struct rte_eth_txconf *tx_conf)
818 {
819         struct bond_tx_queue *bd_tx_q  = (struct bond_tx_queue *)
820                         rte_zmalloc_socket(NULL, sizeof(struct bond_tx_queue),
821                                         0, dev->pci_dev->numa_node);
822
823         if (bd_tx_q == NULL)
824                         return -1;
825
826         bd_tx_q->queue_id = tx_queue_id;
827         bd_tx_q->dev_private = dev->data->dev_private;
828
829         bd_tx_q->nb_tx_desc = nb_tx_desc;
830         memcpy(&(bd_tx_q->tx_conf), tx_conf, sizeof(bd_tx_q->tx_conf));
831
832         dev->data->tx_queues[tx_queue_id] = bd_tx_q;
833
834         return 0;
835 }
836
837 static void
838 bond_ethdev_rx_queue_release(void *queue)
839 {
840         if (queue == NULL)
841                 return;
842
843         rte_free(queue);
844 }
845
846 static void
847 bond_ethdev_tx_queue_release(void *queue)
848 {
849         if (queue == NULL)
850                 return;
851
852         rte_free(queue);
853 }
854
855 static int
856 bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
857                 int wait_to_complete)
858 {
859         struct bond_dev_private *internals = bonded_eth_dev->data->dev_private;
860
861         if (!bonded_eth_dev->data->dev_started ||
862                 internals->active_slave_count == 0) {
863                 bonded_eth_dev->data->dev_link.link_status = 0;
864                 return 0;
865         } else {
866                 struct rte_eth_dev *slave_eth_dev;
867                 int i, link_up = 0;
868
869                 for (i = 0; i < internals->active_slave_count; i++) {
870                         slave_eth_dev = &rte_eth_devices[internals->active_slaves[i]];
871
872                         (*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
873                                         wait_to_complete);
874                         if (slave_eth_dev->data->dev_link.link_status == 1) {
875                                 link_up = 1;
876                                 break;
877                         }
878                 }
879
880                 bonded_eth_dev->data->dev_link.link_status = link_up;
881         }
882
883         return 0;
884 }
885
886 static void
887 bond_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
888 {
889         struct bond_dev_private *internals = dev->data->dev_private;
890         struct rte_eth_stats slave_stats;
891
892         int i;
893
894         /* clear bonded stats before populating from slaves */
895         memset(stats, 0, sizeof(*stats));
896
897         for (i = 0; i < internals->slave_count; i++) {
898                 rte_eth_stats_get(internals->slaves[i], &slave_stats);
899
900                 stats->ipackets += slave_stats.ipackets;
901                 stats->opackets += slave_stats.opackets;
902                 stats->ibytes += slave_stats.ibytes;
903                 stats->obytes += slave_stats.obytes;
904                 stats->ierrors += slave_stats.ierrors;
905                 stats->oerrors += slave_stats.oerrors;
906                 stats->imcasts += slave_stats.imcasts;
907                 stats->rx_nombuf += slave_stats.rx_nombuf;
908                 stats->fdirmatch += slave_stats.fdirmatch;
909                 stats->fdirmiss += slave_stats.fdirmiss;
910                 stats->tx_pause_xon += slave_stats.tx_pause_xon;
911                 stats->rx_pause_xon += slave_stats.rx_pause_xon;
912                 stats->tx_pause_xoff += slave_stats.tx_pause_xoff;
913                 stats->rx_pause_xoff += slave_stats.rx_pause_xoff;
914         }
915 }
916
917 static void
918 bond_ethdev_stats_reset(struct rte_eth_dev *dev)
919 {
920         struct bond_dev_private *internals = dev->data->dev_private;
921         int i;
922
923         for (i = 0; i < internals->slave_count; i++)
924                 rte_eth_stats_reset(internals->slaves[i]);
925 }
926
927 static void
928 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
929 {
930         struct bond_dev_private *internals = eth_dev->data->dev_private;
931         int i;
932
933         internals->promiscuous_en = 1;
934
935         switch (internals->mode) {
936         /* Promiscuous mode is propagated to all slaves */
937         case BONDING_MODE_ROUND_ROBIN:
938         case BONDING_MODE_BALANCE:
939 #ifdef RTE_MBUF_REFCNT
940         case BONDING_MODE_BROADCAST:
941 #endif
942                 for (i = 0; i < internals->slave_count; i++)
943                         rte_eth_promiscuous_enable(internals->slaves[i]);
944                 break;
945         /* Promiscuous mode is propagated only to primary slave */
946         case BONDING_MODE_ACTIVE_BACKUP:
947         default:
948                 rte_eth_promiscuous_enable(internals->current_primary_port);
949
950         }
951 }
952
953 static void
954 bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
955 {
956         struct bond_dev_private *internals = dev->data->dev_private;
957         int i;
958
959         internals->promiscuous_en = 0;
960
961         switch (internals->mode) {
962         /* Promiscuous mode is propagated to all slaves */
963         case BONDING_MODE_ROUND_ROBIN:
964         case BONDING_MODE_BALANCE:
965 #ifdef RTE_MBUF_REFCNT
966         case BONDING_MODE_BROADCAST:
967 #endif
968                 for (i = 0; i < internals->slave_count; i++)
969                         rte_eth_promiscuous_disable(internals->slaves[i]);
970                 break;
971         /* Promiscuous mode is propagated only to primary slave */
972         case BONDING_MODE_ACTIVE_BACKUP:
973         default:
974                 rte_eth_promiscuous_disable(internals->current_primary_port);
975         }
976 }
977
978 void
979 bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
980                 void *param)
981 {
982         struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
983         struct bond_dev_private *internals;
984         struct rte_eth_link link;
985
986         int i, valid_slave = 0, active_pos = -1;
987         uint8_t lsc_flag = 0;
988
989         if (type != RTE_ETH_EVENT_INTR_LSC || param == NULL)
990                 return;
991
992         bonded_eth_dev = &rte_eth_devices[*(uint8_t *)param];
993         slave_eth_dev = &rte_eth_devices[port_id];
994
995         if (valid_bonded_ethdev(bonded_eth_dev))
996                 return;
997
998         internals = bonded_eth_dev->data->dev_private;
999
1000         /* If the device isn't started don't handle interrupts */
1001         if (!bonded_eth_dev->data->dev_started)
1002                 return;
1003
1004         /* verify that port_id is a valid slave of bonded port */
1005         for (i = 0; i < internals->slave_count; i++) {
1006                 if (internals->slaves[i] == port_id) {
1007                         valid_slave = 1;
1008                         break;
1009                 }
1010         }
1011
1012         if (!valid_slave)
1013                 return;
1014
1015         /* Search for port in active port list */
1016         for (i = 0; i < internals->active_slave_count; i++) {
1017                 if (port_id == internals->active_slaves[i]) {
1018                         active_pos = i;
1019                         break;
1020                 }
1021         }
1022
1023         rte_eth_link_get_nowait(port_id, &link);
1024         if (link.link_status) {
1025                 if (active_pos >= 0)
1026                         return;
1027
1028                 /* if no active slave ports then set this port to be primary port */
1029                 if (internals->active_slave_count < 1) {
1030                         /* If first active slave, then change link status */
1031                         bonded_eth_dev->data->dev_link.link_status = 1;
1032                         internals->current_primary_port = port_id;
1033                         lsc_flag = 1;
1034
1035                         /* Inherit eth dev link properties from first active slave */
1036                         link_properties_set(bonded_eth_dev,
1037                                         &(slave_eth_dev->data->dev_link));
1038                 }
1039                 internals->active_slaves[internals->active_slave_count++] = port_id;
1040
1041                 /* If user has defined the primary port then default to using it */
1042                 if (internals->user_defined_primary_port &&
1043                                 internals->primary_port == port_id)
1044                         bond_ethdev_primary_set(internals, port_id);
1045         } else {
1046                 if (active_pos < 0)
1047                         return;
1048
1049                 /* Remove from active slave list */
1050                 for (i = active_pos; i < (internals->active_slave_count - 1); i++)
1051                         internals->active_slaves[i] = internals->active_slaves[i+1];
1052
1053                 internals->active_slave_count--;
1054
1055                 /* No active slaves, change link status to down and reset other
1056                  * link properties */
1057                 if (internals->active_slave_count < 1) {
1058                         lsc_flag = 1;
1059                         bonded_eth_dev->data->dev_link.link_status = 0;
1060
1061                         link_properties_reset(bonded_eth_dev);
1062                 }
1063
1064                 /* Update primary id, take first active slave from list or if none
1065                  * available set to -1 */
1066                 if (port_id == internals->current_primary_port) {
1067                         if (internals->active_slave_count > 0)
1068                                 bond_ethdev_primary_set(internals,
1069                                                 internals->active_slaves[0]);
1070                         else
1071                                 internals->current_primary_port = internals->primary_port;
1072                 }
1073         }
1074
1075         if (lsc_flag)
1076                 _rte_eth_dev_callback_process(bonded_eth_dev, RTE_ETH_EVENT_INTR_LSC);
1077 }
1078
1079 struct eth_dev_ops default_dev_ops = {
1080                 .dev_start = bond_ethdev_start,
1081                 .dev_stop = bond_ethdev_stop,
1082                 .dev_close = bond_ethdev_close,
1083                 .dev_configure = bond_ethdev_configure,
1084                 .dev_infos_get = bond_ethdev_info,
1085                 .rx_queue_setup = bond_ethdev_rx_queue_setup,
1086                 .tx_queue_setup = bond_ethdev_tx_queue_setup,
1087                 .rx_queue_release = bond_ethdev_rx_queue_release,
1088                 .tx_queue_release = bond_ethdev_tx_queue_release,
1089                 .link_update = bond_ethdev_link_update,
1090                 .stats_get = bond_ethdev_stats_get,
1091                 .stats_reset = bond_ethdev_stats_reset,
1092                 .promiscuous_enable = bond_ethdev_promiscuous_enable,
1093                 .promiscuous_disable = bond_ethdev_promiscuous_disable
1094 };
1095
1096 static int
1097 bond_init(const char *name, const char *params)
1098 {
1099         struct bond_dev_private *internals;
1100         struct rte_kvargs *kvlist;
1101         uint8_t bonding_mode, socket_id;
1102         int  arg_count, port_id;
1103
1104         RTE_LOG(INFO, EAL, "Initializing pmd_bond for %s\n", name);
1105
1106         kvlist = rte_kvargs_parse(params, pmd_bond_init_valid_arguments);
1107         if (kvlist == NULL)
1108                 return -1;
1109
1110         /* Parse link bonding mode */
1111         if (rte_kvargs_count(kvlist, PMD_BOND_MODE_KVARG) == 1) {
1112                 if (rte_kvargs_process(kvlist, PMD_BOND_MODE_KVARG,
1113                                 &bond_ethdev_parse_slave_mode_kvarg, &bonding_mode) != 0) {
1114                         RTE_LOG(ERR, EAL, "Invalid mode for bonded device %s\n", name);
1115                         return -1;
1116                 }
1117         } else {
1118                 RTE_LOG(ERR, EAL,
1119                                 "Mode must be specified only once for bonded device %s\n",
1120                                 name);
1121                 return -1;
1122         }
1123
1124         /* Parse socket id to create bonding device on */
1125         arg_count = rte_kvargs_count(kvlist, PMD_BOND_SOCKET_ID_KVARG);
1126         if (arg_count == 1) {
1127                 if (rte_kvargs_process(kvlist, PMD_BOND_SOCKET_ID_KVARG,
1128                                 &bond_ethdev_parse_socket_id_kvarg, &socket_id) != 0) {
1129                         RTE_LOG(ERR, EAL,
1130                                         "Invalid socket Id specified for bonded device %s\n",
1131                                         name);
1132                         return -1;
1133                 }
1134         } else if (arg_count > 1) {
1135                 RTE_LOG(ERR, EAL,
1136                                 "Socket Id can be specified only once for bonded device %s\n",
1137                                 name);
1138                 return -1;
1139         } else {
1140                 socket_id = rte_socket_id();
1141         }
1142
1143         /* Create link bonding eth device */
1144         port_id = rte_eth_bond_create(name, bonding_mode, socket_id);
1145         if (port_id < 0) {
1146                 RTE_LOG(ERR, EAL,
1147                                 "Failed to create socket %s in mode %u on socket %u.\n",
1148                                 name, bonding_mode, socket_id);
1149                 return -1;
1150         }
1151         internals = rte_eth_devices[port_id].data->dev_private;
1152         internals->kvlist = kvlist;
1153
1154         RTE_LOG(INFO, EAL,
1155                         "Create bonded device %s on port %d in mode %u on socket %u.\n",
1156                         name, port_id, bonding_mode, socket_id);
1157         return 0;
1158 }
1159
1160 /* this part will resolve the slave portids after all the other pdev and vdev
1161  * have been allocated */
1162 static int
1163 bond_ethdev_configure(struct rte_eth_dev *dev)
1164 {
1165         char *name = dev->data->name;
1166         struct bond_dev_private *internals = dev->data->dev_private;
1167         struct rte_kvargs *kvlist = internals->kvlist;
1168         int arg_count, port_id = dev - rte_eth_devices;
1169
1170         /*
1171          * if no kvlist, it means that this bonded device has been created
1172          * through the bonding api.
1173          */
1174         if (!kvlist)
1175                 return 0;
1176
1177         /* Parse MAC address for bonded device */
1178         arg_count = rte_kvargs_count(kvlist, PMD_BOND_MAC_ADDR_KVARG);
1179         if (arg_count == 1) {
1180                 struct ether_addr bond_mac;
1181
1182                 if (rte_kvargs_process(kvlist, PMD_BOND_MAC_ADDR_KVARG,
1183                                 &bond_ethdev_parse_bond_mac_addr_kvarg, &bond_mac) < 0) {
1184                         RTE_LOG(INFO, EAL, "Invalid mac address for bonded device %s\n",
1185                                         name);
1186                         return -1;
1187                 }
1188
1189                 /* Set MAC address */
1190                 if (rte_eth_bond_mac_address_set(port_id, &bond_mac) != 0) {
1191                         RTE_LOG(ERR, EAL,
1192                                         "Failed to set mac address on bonded device %s\n",
1193                                         name);
1194                         return -1;
1195                 }
1196         } else if (arg_count > 1) {
1197                 RTE_LOG(ERR, EAL,
1198                                 "MAC address can be specified only once for bonded device %s\n",
1199                                 name);
1200                 return -1;
1201         }
1202
1203         /* Parse/set balance mode transmit policy */
1204         arg_count = rte_kvargs_count(kvlist, PMD_BOND_XMIT_POLICY_KVARG);
1205         if (arg_count == 1) {
1206                 uint8_t xmit_policy;
1207
1208                 if (rte_kvargs_process(kvlist, PMD_BOND_XMIT_POLICY_KVARG,
1209                                 &bond_ethdev_parse_balance_xmit_policy_kvarg, &xmit_policy) !=
1210                                                 0) {
1211                         RTE_LOG(INFO, EAL,
1212                                         "Invalid xmit policy specified for bonded device %s\n",
1213                                         name);
1214                         return -1;
1215                 }
1216
1217                 /* Set balance mode transmit policy*/
1218                 if (rte_eth_bond_xmit_policy_set(port_id, xmit_policy) != 0) {
1219                         RTE_LOG(ERR, EAL,
1220                                         "Failed to set balance xmit policy on bonded device %s\n",
1221                                         name);
1222                         return -1;
1223                 }
1224         } else if (arg_count > 1) {
1225                 RTE_LOG(ERR, EAL,
1226                                 "Transmit policy can be specified only once for bonded device %s\n",
1227                                 name);
1228                 return -1;
1229         }
1230
1231         /* Parse/add slave ports to bonded device */
1232         if (rte_kvargs_count(kvlist, PMD_BOND_SLAVE_PORT_KVARG) > 0) {
1233                 struct bond_ethdev_slave_ports slave_ports;
1234                 unsigned i;
1235
1236                 memset(&slave_ports, 0, sizeof(slave_ports));
1237
1238                 if (rte_kvargs_process(kvlist, PMD_BOND_SLAVE_PORT_KVARG,
1239                                 &bond_ethdev_parse_slave_port_kvarg, &slave_ports) != 0) {
1240                         RTE_LOG(ERR, EAL,
1241                                         "Failed to parse slave ports for bonded device %s\n",
1242                                         name);
1243                         return -1;
1244                 }
1245
1246                 for (i = 0; i < slave_ports.slave_count; i++) {
1247                         if (rte_eth_bond_slave_add(port_id, slave_ports.slaves[i]) != 0) {
1248                                 RTE_LOG(ERR, EAL,
1249                                                 "Failed to add port %d as slave to bonded device %s\n",
1250                                                 slave_ports.slaves[i], name);
1251                         }
1252                 }
1253
1254         } else {
1255                 RTE_LOG(INFO, EAL, "No slaves specified for bonded device %s\n", name);
1256                 return -1;
1257         }
1258
1259         /* Parse/set primary slave port id*/
1260         arg_count = rte_kvargs_count(kvlist, PMD_BOND_PRIMARY_SLAVE_KVARG);
1261         if (arg_count == 1) {
1262                 uint8_t primary_slave_port_id;
1263
1264                 if (rte_kvargs_process(kvlist,
1265                                 PMD_BOND_PRIMARY_SLAVE_KVARG,
1266                                 &bond_ethdev_parse_primary_slave_port_id_kvarg,
1267                                 &primary_slave_port_id) < 0) {
1268                         RTE_LOG(INFO, EAL,
1269                                         "Invalid primary slave port id specified for bonded device %s\n",
1270                                         name);
1271                         return -1;
1272                 }
1273
1274                 /* Set balance mode transmit policy*/
1275                 if (rte_eth_bond_primary_set(port_id, (uint8_t)primary_slave_port_id)
1276                                 != 0) {
1277                         RTE_LOG(ERR, EAL,
1278                                         "Failed to set primary slave port %d on bonded device %s\n",
1279                                         primary_slave_port_id, name);
1280                         return -1;
1281                 }
1282         } else if (arg_count > 1) {
1283                 RTE_LOG(INFO, EAL,
1284                                 "Primary slave can be specified only once for bonded device %s\n",
1285                                 name);
1286                 return -1;
1287         }
1288
1289         return 0;
1290 }
1291
1292 static struct rte_driver bond_drv = {
1293         .name = "eth_bond",
1294         .type = PMD_VDEV,
1295         .init = bond_init,
1296 };
1297
1298 PMD_REGISTER_DRIVER(bond_drv);