first public release
[dpdk.git] / lib / librte_ether / rte_ethdev.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 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  *  version: DPDK.L.1.2.3-3
34  */
35
36 #include <sys/types.h>
37 #include <sys/queue.h>
38 #include <ctype.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include <errno.h>
44 #include <stdint.h>
45 #include <inttypes.h>
46
47 #include <rte_byteorder.h>
48 #include <rte_log.h>
49 #include <rte_debug.h>
50 #include <rte_interrupts.h>
51 #include <rte_pci.h>
52 #include <rte_memory.h>
53 #include <rte_memcpy.h>
54 #include <rte_memzone.h>
55 #include <rte_launch.h>
56 #include <rte_tailq.h>
57 #include <rte_eal.h>
58 #include <rte_per_lcore.h>
59 #include <rte_lcore.h>
60 #include <rte_atomic.h>
61 #include <rte_branch_prediction.h>
62 #include <rte_common.h>
63 #include <rte_ring.h>
64 #include <rte_mempool.h>
65 #include <rte_malloc.h>
66 #include <rte_mbuf.h>
67 #include <rte_errno.h>
68 #include <rte_spinlock.h>
69
70 #include "rte_ether.h"
71 #include "rte_ethdev.h"
72
73 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
74 #define PMD_DEBUG_TRACE(fmt, args...) do {                        \
75                 RTE_LOG(ERR, PMD, "%s: " fmt, __func__, ## args); \
76         } while (0)
77 #else
78 #define PMD_DEBUG_TRACE(fmt, args...)
79 #endif
80
81 /* define two macros for quick checking for restricting functions to primary
82  * instance only. First macro is for functions returning an int - and therefore
83  * an error code, second macro is for functions returning null.
84  */
85 #define PROC_PRIMARY_OR_ERR() do { \
86         if (rte_eal_process_type() != RTE_PROC_PRIMARY) { \
87                 PMD_DEBUG_TRACE("Cannot run %s in secondary processes\n", \
88                                                         __func__); \
89                         return (-E_RTE_SECONDARY); \
90                 } \
91 } while(0)
92
93 #define PROC_PRIMARY_OR_RET() do { \
94         if (rte_eal_process_type() != RTE_PROC_PRIMARY) { \
95                 PMD_DEBUG_TRACE("Cannot run %s in secondary processes\n", \
96                                                         __func__); \
97                 return; \
98         } \
99 } while(0)
100
101 /* Macros to check for invlaid function pointers in dev_ops structure */
102 #define FUNC_PTR_OR_ERR_RET(func, retval) do { \
103         if ((func) == NULL) { \
104                 PMD_DEBUG_TRACE("Function not supported\n"); \
105                 return (retval); \
106         } \
107 } while(0)
108 #define FUNC_PTR_OR_RET(func) do { \
109         if ((func) == NULL) { \
110                 PMD_DEBUG_TRACE("Function not supported\n"); \
111                 return; \
112         } \
113 } while(0)
114
115 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
116 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
117 static struct rte_eth_dev_data *rte_eth_dev_data = NULL;
118 static uint8_t nb_ports = 0;
119
120 /* spinlock for eth device callbacks */
121 static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
122
123 /**
124  * The user application callback description.
125  *
126  * It contains callback address to be registered by user application,
127  * the pointer to the parameters for callback, and the event type.
128  */
129 struct rte_eth_dev_callback {
130         TAILQ_ENTRY(rte_eth_dev_callback) next; /**< Callbacks list */
131         rte_eth_dev_cb_fn cb_fn;                /**< Callback address */
132         void *cb_arg;                           /**< Parameter for callback */
133         enum rte_eth_event_type event;          /**< Interrupt event type */
134 };
135
136 static inline void
137 rte_eth_dev_data_alloc(void)
138 {
139         const unsigned flags = 0;
140         const struct rte_memzone *mz;
141
142         if (rte_eal_process_type() == RTE_PROC_PRIMARY){
143                 mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA,
144                                 RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data),
145                                 rte_socket_id(), flags);
146         } else
147                 mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
148         if (mz == NULL)
149                 rte_panic("Cannot allocate memzone for ethernet port data\n");
150
151         rte_eth_dev_data = mz->addr;
152         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
153                 memset(rte_eth_dev_data, 0,
154                                 RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
155 }
156
157 static inline struct rte_eth_dev *
158 rte_eth_dev_allocate(void)
159 {
160         struct rte_eth_dev *eth_dev;
161
162         if (nb_ports == RTE_MAX_ETHPORTS)
163                 return NULL;
164
165         if (rte_eth_dev_data == NULL)
166                 rte_eth_dev_data_alloc();
167
168         eth_dev = &rte_eth_devices[nb_ports];
169         eth_dev->data = &rte_eth_dev_data[nb_ports];
170         eth_dev->data->port_id = nb_ports++;
171         return eth_dev;
172 }
173
174 static int
175 rte_eth_dev_init(struct rte_pci_driver *pci_drv,
176                  struct rte_pci_device *pci_dev)
177 {
178         struct eth_driver    *eth_drv;
179         struct rte_eth_dev *eth_dev;
180         int diag;
181
182         eth_drv = (struct eth_driver *)pci_drv;
183
184         eth_dev = rte_eth_dev_allocate();
185         if (eth_dev == NULL)
186                 return -ENOMEM;
187
188
189         if (rte_eal_process_type() == RTE_PROC_PRIMARY){
190                 eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
191                                   eth_drv->dev_private_size,
192                                   CACHE_LINE_SIZE);
193                 if (eth_dev->data->dev_private == NULL)
194                         return -ENOMEM;
195         }
196         eth_dev->pci_dev = pci_dev;
197         eth_dev->driver = eth_drv;
198         eth_dev->data->rx_mbuf_alloc_failed = 0;
199
200         /* init user callbacks */
201         TAILQ_INIT(&(eth_dev->callbacks));
202
203         /*
204          * Set the default maximum frame size.
205          */
206         eth_dev->data->max_frame_size = ETHER_MAX_LEN;
207
208         /* Invoke PMD device initialization function */
209         diag = (*eth_drv->eth_dev_init)(eth_drv, eth_dev);
210         if (diag == 0)
211                 return (0);
212
213         PMD_DEBUG_TRACE("driver %s: eth_dev_init(vendor_id=0x%u device_id=0x%x)"
214                         " failed\n", pci_drv->name,
215                         (unsigned) pci_dev->id.vendor_id,
216                         (unsigned) pci_dev->id.device_id);
217         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
218                 rte_free(eth_dev->data->dev_private);
219         nb_ports--;
220         return diag;
221 }
222
223 /**
224  * Register an Ethernet [Poll Mode] driver.
225  *
226  * Function invoked by the initialization function of an Ethernet driver
227  * to simultaneously register itself as a PCI driver and as an Ethernet
228  * Poll Mode Driver.
229  * Invokes the rte_eal_pci_register() function to register the *pci_drv*
230  * structure embedded in the *eth_drv* structure, after having stored the
231  * address of the rte_eth_dev_init() function in the *devinit* field of
232  * the *pci_drv* structure.
233  * During the PCI probing phase, the rte_eth_dev_init() function is
234  * invoked for each PCI [Ethernet device] matching the embedded PCI
235  * identifiers provided by the driver.
236  */
237 void
238 rte_eth_driver_register(struct eth_driver *eth_drv)
239 {
240         eth_drv->pci_drv.devinit = rte_eth_dev_init;
241         rte_eal_pci_register(&eth_drv->pci_drv);
242 }
243
244 uint8_t
245 rte_eth_dev_count(void)
246 {
247         return (nb_ports);
248 }
249
250 int
251 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
252                       const struct rte_eth_conf *dev_conf)
253 {
254         struct rte_eth_dev *dev;
255         struct rte_eth_dev_info dev_info;
256         int diag;
257
258         /* This function is only safe when called from the primary process
259          * in a multi-process setup*/
260         PROC_PRIMARY_OR_ERR();
261
262         if (port_id >= nb_ports || port_id >= RTE_MAX_ETHPORTS) {
263                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
264                 return (-EINVAL);
265         }
266         dev = &rte_eth_devices[port_id];
267
268         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
269         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
270
271         if (dev->data->dev_started) {
272                 PMD_DEBUG_TRACE(
273                     "port %d must be stopped to allow configuration", port_id);
274                 return -EBUSY;
275         }
276
277         /*
278          * Check that the numbers of RX and TX queues are not greater
279          * than the maximum number of RX and TX queues supported by the
280          * configured device.
281          */
282         (*dev->dev_ops->dev_infos_get)(dev, &dev_info);
283         if (nb_rx_q > dev_info.max_rx_queues) {
284                 PMD_DEBUG_TRACE("ethdev port_id=%d nb_rx_queues=%d > %d",
285                                 port_id, nb_rx_q, dev_info.max_rx_queues);
286                 return (-EINVAL);
287         }
288         if (nb_rx_q == 0) {
289                 PMD_DEBUG_TRACE("ethdev port_id=%d nb_rx_q == 0", port_id);
290                 return (-EINVAL);
291         }
292
293         if (nb_tx_q > dev_info.max_tx_queues) {
294                 PMD_DEBUG_TRACE("ethdev port_id=%d nb_tx_queues=%d > %d",
295                                 port_id, nb_tx_q, dev_info.max_tx_queues);
296                 return (-EINVAL);
297         }
298         if (nb_tx_q == 0) {
299                 PMD_DEBUG_TRACE("ethdev port_id=%d nb_tx_q == 0", port_id);
300                 return (-EINVAL);
301         }
302
303         /* Copy the dev_conf parameter into the dev structure */
304         memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
305
306         /*
307          * If jumbo frames are enabled, check that the maximum RX packet
308          * length is supported by the configured device.
309          */
310         if (dev_conf->rxmode.jumbo_frame == 1) {
311                 if (dev_conf->rxmode.max_rx_pkt_len >
312                     dev_info.max_rx_pktlen) {
313                         PMD_DEBUG_TRACE("ethdev port_id=%d max_rx_pkt_len %u"
314                                 " > max valid value %u",
315                                 port_id,
316                                 (unsigned)dev_conf->rxmode.max_rx_pkt_len,
317                                 (unsigned)dev_info.max_rx_pktlen);
318                         return (-EINVAL);
319                 }
320         } else
321                 /* Use default value */
322                 dev->data->dev_conf.rxmode.max_rx_pkt_len = ETHER_MAX_LEN;
323
324         /* For vmdb+dcb mode check our configuration before we go further */
325         if (dev_conf->rxmode.mq_mode == ETH_VMDQ_DCB) {
326                 const struct rte_eth_vmdq_dcb_conf *conf;
327
328                 if (nb_rx_q != ETH_VMDQ_DCB_NUM_QUEUES) {
329                         PMD_DEBUG_TRACE("ethdev port_id=%d VMDQ+DCB, nb_rx_q "
330                                         "!= %d",
331                                         port_id, ETH_VMDQ_DCB_NUM_QUEUES);
332                         return (-EINVAL);
333                 }
334                 conf = &(dev_conf->rx_adv_conf.vmdq_dcb_conf);
335                 if (! (conf->nb_queue_pools == ETH_16_POOLS ||
336                        conf->nb_queue_pools == ETH_32_POOLS)) {
337                     PMD_DEBUG_TRACE("ethdev port_id=%d VMDQ+DCB selected, "
338                                     "nb_queue_pools != %d or nb_queue_pools "
339                                     "!= %d",
340                                     port_id, ETH_16_POOLS, ETH_32_POOLS);
341                     return (-EINVAL);
342                 }
343         }
344
345         diag = (*dev->dev_ops->dev_configure)(dev, nb_rx_q, nb_tx_q);
346         if (diag != 0) {
347                 rte_free(dev->data->rx_queues);
348                 rte_free(dev->data->tx_queues);
349         }
350         return diag;
351 }
352
353 static void
354 rte_eth_dev_config_restore(uint8_t port_id)
355 {
356         struct rte_eth_dev *dev;
357         struct rte_eth_dev_info dev_info;
358         struct ether_addr addr;
359         uint16_t i;
360
361         dev = &rte_eth_devices[port_id];
362
363         rte_eth_dev_info_get(port_id, &dev_info);
364
365         /* replay MAC address configuration */
366         for (i = 0; i < dev_info.max_mac_addrs; i++) {
367                 addr = dev->data->mac_addrs[i];
368
369                 /* skip zero address */
370                 if (is_zero_ether_addr(&addr))
371                         continue;
372
373                 /* add address to the hardware */
374                 if  (*dev->dev_ops->mac_addr_add)
375                         (*dev->dev_ops->mac_addr_add)(dev, &addr, i, 0);
376                 else {
377                         PMD_DEBUG_TRACE("port %d: MAC address array not supported\n",
378                                         port_id);
379                         /* exit the loop but not return an error */
380                         break;
381                 }
382         }
383
384         /* replay promiscuous configuration */
385         if (rte_eth_promiscuous_get(port_id) == 1)
386                 rte_eth_promiscuous_enable(port_id);
387         else if (rte_eth_promiscuous_get(port_id) == 0)
388                 rte_eth_promiscuous_disable(port_id);
389
390         /* replay allmulticast configuration */
391         if (rte_eth_allmulticast_get(port_id) == 1)
392                 rte_eth_allmulticast_enable(port_id);
393         else if (rte_eth_allmulticast_get(port_id) == 0)
394                 rte_eth_allmulticast_disable(port_id);
395 }
396
397 int
398 rte_eth_dev_start(uint8_t port_id)
399 {
400         struct rte_eth_dev *dev;
401         int diag;
402
403         /* This function is only safe when called from the primary process
404          * in a multi-process setup*/
405         PROC_PRIMARY_OR_ERR();
406
407         if (port_id >= nb_ports) {
408                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
409                 return (-EINVAL);
410         }
411         dev = &rte_eth_devices[port_id];
412
413         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
414         diag = (*dev->dev_ops->dev_start)(dev);
415         if (diag == 0)
416                 dev->data->dev_started = 1;
417         else
418                 return diag;
419
420         rte_eth_dev_config_restore(port_id);
421
422         return 0;
423 }
424
425 void
426 rte_eth_dev_stop(uint8_t port_id)
427 {
428         struct rte_eth_dev *dev;
429
430         /* This function is only safe when called from the primary process
431          * in a multi-process setup*/
432         PROC_PRIMARY_OR_RET();
433
434         if (port_id >= nb_ports) {
435                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
436                 return;
437         }
438         dev = &rte_eth_devices[port_id];
439
440         FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
441         dev->data->dev_started = 0;
442         (*dev->dev_ops->dev_stop)(dev);
443 }
444
445 void
446 rte_eth_dev_close(uint8_t port_id)
447 {
448         struct rte_eth_dev *dev;
449
450         /* This function is only safe when called from the primary process
451          * in a multi-process setup*/
452         PROC_PRIMARY_OR_RET();
453
454         if (port_id >= nb_ports) {
455                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
456                 return;
457         }
458
459         dev = &rte_eth_devices[port_id];
460         FUNC_PTR_OR_RET(*dev->dev_ops->dev_close);
461         dev->data->dev_started = 0;
462         (*dev->dev_ops->dev_close)(dev);
463 }
464
465 int
466 rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
467                        uint16_t nb_rx_desc, unsigned int socket_id,
468                        const struct rte_eth_rxconf *rx_conf,
469                        struct rte_mempool *mp)
470 {
471         struct rte_eth_dev *dev;
472         struct rte_pktmbuf_pool_private *mbp_priv;
473         struct rte_eth_dev_info dev_info;
474
475         /* This function is only safe when called from the primary process
476          * in a multi-process setup*/
477         PROC_PRIMARY_OR_ERR();
478
479         if (port_id >= nb_ports) {
480                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
481                 return (-EINVAL);
482         }
483         dev = &rte_eth_devices[port_id];
484         if (rx_queue_id >= dev->data->nb_rx_queues) {
485                 PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", rx_queue_id);
486                 return (-EINVAL);
487         }
488
489         if (dev->data->dev_started) {
490                 PMD_DEBUG_TRACE(
491                     "port %d must be stopped to allow configuration", port_id);
492                 return -EBUSY;
493         }
494
495         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
496         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_setup, -ENOTSUP);
497
498         /*
499          * Check the size of the mbuf data buffer.
500          * This value must be provided in the private data of the memory pool.
501          * First check that the memory pool has a valid private data.
502          */
503         (*dev->dev_ops->dev_infos_get)(dev, &dev_info);
504         if (mp->private_data_size < sizeof(struct rte_pktmbuf_pool_private)) {
505                 PMD_DEBUG_TRACE("%s private_data_size %d < %d\n",
506                                 mp->name, (int) mp->private_data_size,
507                                 (int) sizeof(struct rte_pktmbuf_pool_private));
508                 return (-ENOSPC);
509         }
510         mbp_priv = (struct rte_pktmbuf_pool_private *)
511                 ((char *)mp + sizeof(struct rte_mempool));
512         if ((uint32_t) (mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM) <
513             dev_info.min_rx_bufsize) {
514                 PMD_DEBUG_TRACE("%s mbuf_data_room_size %d < %d "
515                                 "(RTE_PKTMBUF_HEADROOM=%d + min_rx_bufsize(dev)"
516                                 "=%d)\n",
517                                 mp->name,
518                                 (int)mbp_priv->mbuf_data_room_size,
519                                 (int)(RTE_PKTMBUF_HEADROOM +
520                                       dev_info.min_rx_bufsize),
521                                 (int)RTE_PKTMBUF_HEADROOM,
522                                 (int)dev_info.min_rx_bufsize);
523                 return (-EINVAL);
524         }
525
526         return (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc,
527                                                socket_id, rx_conf, mp);
528 }
529
530 int
531 rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id,
532                        uint16_t nb_tx_desc, unsigned int socket_id,
533                        const struct rte_eth_txconf *tx_conf)
534 {
535         struct rte_eth_dev *dev;
536
537         /* This function is only safe when called from the primary process
538          * in a multi-process setup*/
539         PROC_PRIMARY_OR_ERR();
540
541         if (port_id >= nb_ports) {
542                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
543                 return (-EINVAL);
544         }
545         dev = &rte_eth_devices[port_id];
546         if (tx_queue_id >= dev->data->nb_tx_queues) {
547                 PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", tx_queue_id);
548                 return (-EINVAL);
549         }
550
551         if (dev->data->dev_started) {
552                 PMD_DEBUG_TRACE(
553                     "port %d must be stopped to allow configuration", port_id);
554                 return -EBUSY;
555         }
556
557         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_setup, -ENOTSUP);
558         return (*dev->dev_ops->tx_queue_setup)(dev, tx_queue_id, nb_tx_desc,
559                                                socket_id, tx_conf);
560 }
561
562 void
563 rte_eth_promiscuous_enable(uint8_t port_id)
564 {
565         struct rte_eth_dev *dev;
566
567         if (port_id >= nb_ports) {
568                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
569                 return;
570         }
571         dev = &rte_eth_devices[port_id];
572
573         FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable);
574         (*dev->dev_ops->promiscuous_enable)(dev);
575         dev->data->promiscuous = 1;
576 }
577
578 void
579 rte_eth_promiscuous_disable(uint8_t port_id)
580 {
581         struct rte_eth_dev *dev;
582
583         if (port_id >= nb_ports) {
584                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
585                 return;
586         }
587         dev = &rte_eth_devices[port_id];
588
589         FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable);
590         dev->data->promiscuous = 0;
591         (*dev->dev_ops->promiscuous_disable)(dev);
592 }
593
594 int
595 rte_eth_promiscuous_get(uint8_t port_id)
596 {
597         struct rte_eth_dev *dev;
598
599         if (port_id >= nb_ports) {
600                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
601                 return -1;
602         }
603
604         dev = &rte_eth_devices[port_id];
605         return dev->data->promiscuous;
606 }
607
608 void
609 rte_eth_allmulticast_enable(uint8_t port_id)
610 {
611         struct rte_eth_dev *dev;
612
613         if (port_id >= nb_ports) {
614                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
615                 return;
616         }
617         dev = &rte_eth_devices[port_id];
618
619         FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_enable);
620         (*dev->dev_ops->allmulticast_enable)(dev);
621         dev->data->all_multicast = 1;
622 }
623
624 void
625 rte_eth_allmulticast_disable(uint8_t port_id)
626 {
627         struct rte_eth_dev *dev;
628
629         if (port_id >= nb_ports) {
630                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
631                 return;
632         }
633         dev = &rte_eth_devices[port_id];
634
635         FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_disable);
636         dev->data->all_multicast = 0;
637         (*dev->dev_ops->allmulticast_disable)(dev);
638 }
639
640 int
641 rte_eth_allmulticast_get(uint8_t port_id)
642 {
643         struct rte_eth_dev *dev;
644
645         if (port_id >= nb_ports) {
646                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
647                 return -1;
648         }
649
650         dev = &rte_eth_devices[port_id];
651         return dev->data->all_multicast;
652 }
653
654 static inline int
655 rte_eth_dev_atomic_read_link_status(struct rte_eth_dev *dev,
656                                 struct rte_eth_link *link)
657 {
658         struct rte_eth_link *dst = link;
659         struct rte_eth_link *src = &(dev->data->dev_link);
660
661         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
662                                         *(uint64_t *)src) == 0)
663                 return -1;
664
665         return 0;
666 }
667
668 void
669 rte_eth_link_get(uint8_t port_id, struct rte_eth_link *eth_link)
670 {
671         struct rte_eth_dev *dev;
672
673         if (port_id >= nb_ports) {
674                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
675                 return;
676         }
677         dev = &rte_eth_devices[port_id];
678         FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
679
680         if (dev->data->dev_conf.intr_conf.lsc != 0)
681                 rte_eth_dev_atomic_read_link_status(dev, eth_link);
682         else {
683                 (*dev->dev_ops->link_update)(dev, 1);
684                 *eth_link = dev->data->dev_link;
685         }
686 }
687
688 void
689 rte_eth_link_get_nowait(uint8_t port_id, struct rte_eth_link *eth_link)
690 {
691         struct rte_eth_dev *dev;
692
693         if (port_id >= nb_ports) {
694                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
695                 return;
696         }
697         dev = &rte_eth_devices[port_id];
698         FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
699
700         if (dev->data->dev_conf.intr_conf.lsc != 0)
701                 rte_eth_dev_atomic_read_link_status(dev, eth_link);
702         else {
703                 (*dev->dev_ops->link_update)(dev, 0);
704                 *eth_link = dev->data->dev_link;
705         }
706 }
707
708 void
709 rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats)
710 {
711         struct rte_eth_dev *dev;
712
713         if (port_id >= nb_ports) {
714                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
715                 return;
716         }
717         dev = &rte_eth_devices[port_id];
718
719         FUNC_PTR_OR_RET(*dev->dev_ops->stats_get);
720         (*dev->dev_ops->stats_get)(dev, stats);
721         stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
722 }
723
724 void
725 rte_eth_stats_reset(uint8_t port_id)
726 {
727         struct rte_eth_dev *dev;
728
729         if (port_id >= nb_ports) {
730                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
731                 return;
732         }
733         dev = &rte_eth_devices[port_id];
734
735         FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset);
736         (*dev->dev_ops->stats_reset)(dev);
737 }
738
739 void
740 rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
741 {
742         struct rte_eth_dev *dev;
743
744         if (port_id >= nb_ports) {
745                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
746                 return;
747         }
748         dev = &rte_eth_devices[port_id];
749
750         FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
751         (*dev->dev_ops->dev_infos_get)(dev, dev_info);
752         dev_info->pci_dev = dev->pci_dev;
753         dev_info->driver_name = dev->driver->pci_drv.name;
754 }
755
756 void
757 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
758 {
759         struct rte_eth_dev *dev;
760
761         if (port_id >= nb_ports) {
762                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
763                 return;
764         }
765         dev = &rte_eth_devices[port_id];
766         ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
767 }
768
769 int
770 rte_eth_dev_vlan_filter(uint8_t port_id, uint16_t vlan_id, int on)
771 {
772         struct rte_eth_dev *dev;
773
774         if (port_id >= nb_ports) {
775                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
776                 return (-ENODEV);
777         }
778         dev = &rte_eth_devices[port_id];
779         if (! (dev->data->dev_conf.rxmode.hw_vlan_filter)) {
780                 PMD_DEBUG_TRACE("port %d: vlan-filtering disabled\n", port_id);
781                 return (-ENOSYS);
782         }
783         if (vlan_id > 4095) {
784                 PMD_DEBUG_TRACE("(port_id=%d) invalid vlan_id=%u > 4095\n",
785                                 port_id, (unsigned) vlan_id);
786                 return (-EINVAL);
787         }
788
789         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_filter_set, -ENOTSUP);
790         (*dev->dev_ops->vlan_filter_set)(dev, vlan_id, on);
791         return (0);
792 }
793
794 int
795 rte_eth_dev_fdir_add_signature_filter(uint8_t port_id,
796                                       struct rte_fdir_filter *fdir_filter,
797                                       uint8_t queue)
798 {
799         struct rte_eth_dev *dev;
800
801         if (port_id >= nb_ports) {
802                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
803                 return (-ENODEV);
804         }
805
806         dev = &rte_eth_devices[port_id];
807
808         if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_SIGNATURE) {
809                 PMD_DEBUG_TRACE("port %d: invalid FDIR mode=%u\n",
810                                 port_id, dev->data->dev_conf.fdir_conf.mode);
811                 return (-ENOSYS);
812         }
813
814         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP
815              || fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE)
816             && (fdir_filter->port_src || fdir_filter->port_dst)) {
817                 PMD_DEBUG_TRACE(" Port are meaningless for SCTP and " \
818                                 "None l4type source & destinations ports " \
819                                 "should be null!");
820                 return (-EINVAL);
821         }
822
823         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_add_signature_filter, -ENOTSUP);
824         if (*dev->dev_ops->fdir_add_signature_filter)
825                 return (*dev->dev_ops->fdir_add_signature_filter)(dev,
826                                                                   fdir_filter,
827                                                                   queue);
828
829         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
830         return (-ENOTSUP);
831 }
832
833 int
834 rte_eth_dev_fdir_update_signature_filter(uint8_t port_id,
835                                          struct rte_fdir_filter *fdir_filter,
836                                          uint8_t queue)
837 {
838         struct rte_eth_dev *dev;
839
840         if (port_id >= nb_ports) {
841                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
842                 return (-ENODEV);
843         }
844
845         dev = &rte_eth_devices[port_id];
846
847         if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_SIGNATURE) {
848                 PMD_DEBUG_TRACE("port %d: invalid FDIR mode=%u\n",
849                                 port_id, dev->data->dev_conf.fdir_conf.mode);
850                 return (-ENOSYS);
851         }
852
853         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP
854              || fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE)
855             && (fdir_filter->port_src || fdir_filter->port_dst)) {
856                 PMD_DEBUG_TRACE(" Port are meaningless for SCTP and " \
857                                 "None l4type source & destinations ports " \
858                                 "should be null!");
859                 return (-EINVAL);
860         }
861
862         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_update_signature_filter, -ENOTSUP);
863         if (*dev->dev_ops->fdir_update_signature_filter)
864                 return (*dev->dev_ops->fdir_update_signature_filter)(dev,
865                                                                      fdir_filter,
866                                                                      queue);
867
868
869         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
870         return (-ENOTSUP);
871 }
872
873 int
874 rte_eth_dev_fdir_remove_signature_filter(uint8_t port_id,
875                                          struct rte_fdir_filter *fdir_filter)
876 {
877         struct rte_eth_dev *dev;
878
879         if (port_id >= nb_ports) {
880                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
881                 return (-ENODEV);
882         }
883
884         dev = &rte_eth_devices[port_id];
885
886         if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_SIGNATURE) {
887                 PMD_DEBUG_TRACE("port %d: invalid FDIR mode=%u\n",
888                                 port_id, dev->data->dev_conf.fdir_conf.mode);
889                 return (-ENOSYS);
890         }
891
892         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP
893              || fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE)
894             && (fdir_filter->port_src || fdir_filter->port_dst)) {
895                 PMD_DEBUG_TRACE(" Port are meaningless for SCTP and " \
896                                 "None l4type source & destinations ports " \
897                                 "should be null!");
898                 return (-EINVAL);
899         }
900
901         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_remove_signature_filter, -ENOTSUP);
902         if (*dev->dev_ops->fdir_remove_signature_filter)
903                 return (*dev->dev_ops->fdir_remove_signature_filter)(dev,
904                                                                      fdir_filter);
905
906         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
907         return (-ENOTSUP);
908 }
909
910 int
911 rte_eth_dev_fdir_get_infos(uint8_t port_id, struct rte_eth_fdir *fdir)
912 {
913         struct rte_eth_dev *dev;
914
915         if (port_id >= nb_ports) {
916                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
917                 return (-ENODEV);
918         }
919
920         dev = &rte_eth_devices[port_id];
921         if (! (dev->data->dev_conf.fdir_conf.mode)) {
922                 PMD_DEBUG_TRACE("port %d: pkt-filter disabled\n", port_id);
923                 return (-ENOSYS);
924         }
925
926         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_infos_get, -ENOTSUP);
927         if (*dev->dev_ops->fdir_infos_get) {
928                 (*dev->dev_ops->fdir_infos_get)(dev, fdir);
929                 return (0);
930         }
931
932         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
933         return (-ENOTSUP);
934 }
935
936 int
937 rte_eth_dev_fdir_add_perfect_filter(uint8_t port_id,
938                                     struct rte_fdir_filter *fdir_filter,
939                                     uint16_t soft_id, uint8_t queue,
940                                     uint8_t drop)
941 {
942         struct rte_eth_dev *dev;
943
944         if (port_id >= nb_ports) {
945                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
946                 return (-ENODEV);
947         }
948
949         dev = &rte_eth_devices[port_id];
950
951         if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) {
952                 PMD_DEBUG_TRACE("port %d: invalid FDIR mode=%u\n",
953                                 port_id, dev->data->dev_conf.fdir_conf.mode);
954                 return (-ENOSYS);
955         }
956
957         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP
958              || fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE)
959             && (fdir_filter->port_src || fdir_filter->port_dst)) {
960                 PMD_DEBUG_TRACE(" Port are meaningless for SCTP and " \
961                                 "None l4type source & destinations ports " \
962                                 "should be null!");
963                 return (-EINVAL);
964         }
965
966         /* For now IPv6 is not supported with perfect filter */
967         if (fdir_filter->iptype == RTE_FDIR_IPTYPE_IPV6)
968                 return (-ENOTSUP);
969
970         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_add_perfect_filter, -ENOTSUP);
971         if  (*dev->dev_ops->fdir_add_perfect_filter)
972                 return (*dev->dev_ops->fdir_add_perfect_filter)(dev, fdir_filter,
973                                                                 soft_id, queue,
974                                                                 drop);
975
976         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
977         return (-ENOTSUP);
978 }
979
980 int
981 rte_eth_dev_fdir_update_perfect_filter(uint8_t port_id,
982                                        struct rte_fdir_filter *fdir_filter,
983                                        uint16_t soft_id, uint8_t queue,
984                                        uint8_t drop)
985 {
986         struct rte_eth_dev *dev;
987
988         if (port_id >= nb_ports) {
989                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
990                 return (-ENODEV);
991         }
992
993         dev = &rte_eth_devices[port_id];
994
995         if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) {
996                 PMD_DEBUG_TRACE("port %d: invalid FDIR mode=%u\n",
997                                 port_id, dev->data->dev_conf.fdir_conf.mode);
998                 return (-ENOSYS);
999         }
1000
1001         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP
1002              || fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE)
1003             && (fdir_filter->port_src || fdir_filter->port_dst)) {
1004                 PMD_DEBUG_TRACE(" Port are meaningless for SCTP and " \
1005                                 "None l4type source & destinations ports " \
1006                                 "should be null!");
1007                 return (-EINVAL);
1008         }
1009
1010         /* For now IPv6 is not supported with perfect filter */
1011         if (fdir_filter->iptype == RTE_FDIR_IPTYPE_IPV6)
1012                 return (-ENOTSUP);
1013
1014         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_update_perfect_filter, -ENOTSUP);
1015         if  (*dev->dev_ops->fdir_update_perfect_filter)
1016                 return (*dev->dev_ops->fdir_update_perfect_filter)(dev,
1017                                                                    fdir_filter,
1018                                                                    soft_id,
1019                                                                    queue,
1020                                                                    drop);
1021
1022         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
1023         return (-ENOTSUP);
1024 }
1025
1026 int
1027 rte_eth_dev_fdir_remove_perfect_filter(uint8_t port_id,
1028                                        struct rte_fdir_filter *fdir_filter,
1029                                        uint16_t soft_id)
1030 {
1031         struct rte_eth_dev *dev;
1032
1033         if (port_id >= nb_ports) {
1034                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1035                 return (-ENODEV);
1036         }
1037
1038         dev = &rte_eth_devices[port_id];
1039
1040         if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) {
1041                 PMD_DEBUG_TRACE("port %d: invalid FDIR mode=%u\n",
1042                                 port_id, dev->data->dev_conf.fdir_conf.mode);
1043                 return (-ENOSYS);
1044         }
1045
1046         if ((fdir_filter->l4type == RTE_FDIR_L4TYPE_SCTP
1047              || fdir_filter->l4type == RTE_FDIR_L4TYPE_NONE)
1048             && (fdir_filter->port_src || fdir_filter->port_dst)) {
1049                 PMD_DEBUG_TRACE(" Port are meaningless for SCTP and " \
1050                                 "None l4type source & destinations ports " \
1051                                 "should be null!");
1052                 return (-EINVAL);
1053         }
1054
1055         /* For now IPv6 is not supported with perfect filter */
1056         if (fdir_filter->iptype == RTE_FDIR_IPTYPE_IPV6)
1057                 return (-ENOTSUP);
1058
1059         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_remove_perfect_filter, -ENOTSUP);
1060         if  (*dev->dev_ops->fdir_remove_perfect_filter)
1061                 return (*dev->dev_ops->fdir_remove_perfect_filter)(dev,
1062                                                                    fdir_filter,
1063                                                                    soft_id);
1064
1065         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n", port_id);
1066         return -ENOTSUP;
1067 }
1068
1069 int
1070 rte_eth_dev_fdir_set_masks(uint8_t port_id, struct rte_fdir_masks *fdir_mask)
1071 {
1072         struct rte_eth_dev *dev;
1073
1074         if (port_id >= nb_ports) {
1075                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1076                 return (-ENODEV);
1077         }
1078
1079         dev = &rte_eth_devices[port_id];
1080         if (! (dev->data->dev_conf.fdir_conf.mode)) {
1081                 PMD_DEBUG_TRACE("port %d: pkt-filter disabled\n", port_id);
1082                 return (-ENOSYS);
1083         }
1084
1085         /* IPv6 mask are not supported */
1086         if (fdir_mask->src_ipv6_mask)
1087                 return (-ENOTSUP);
1088
1089         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fdir_set_masks, -ENOTSUP);
1090         if  (*dev->dev_ops->fdir_set_masks)
1091                 return (*dev->dev_ops->fdir_set_masks)(dev, fdir_mask);
1092
1093         PMD_DEBUG_TRACE("port %d: FDIR feature not supported\n",
1094                         port_id);
1095         return -ENOTSUP;
1096 }
1097
1098 int
1099 rte_eth_dev_flow_ctrl_set(uint8_t port_id, struct rte_eth_fc_conf *fc_conf)
1100 {
1101         struct rte_eth_dev *dev;
1102
1103         if (port_id >= nb_ports) {
1104                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1105                 return (-ENODEV);
1106         }
1107
1108         if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
1109                 PMD_DEBUG_TRACE("Invalid send_xon, only 0/1 allowed\n");
1110                 return (-EINVAL);
1111         }
1112
1113         dev = &rte_eth_devices[port_id];
1114
1115         /* High water, low water validation are device specific */
1116         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
1117         if  (*dev->dev_ops->flow_ctrl_set)
1118                 return (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf);
1119
1120         return -ENOTSUP;
1121 }
1122
1123 int
1124 rte_eth_led_on(uint8_t port_id)
1125 {
1126         struct rte_eth_dev *dev;
1127
1128         if (port_id >= nb_ports) {
1129                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1130                 return (-ENODEV);
1131         }
1132
1133         dev = &rte_eth_devices[port_id];
1134
1135         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP);
1136         return ((*dev->dev_ops->dev_led_on)(dev));
1137 }
1138
1139 int
1140 rte_eth_led_off(uint8_t port_id)
1141 {
1142         struct rte_eth_dev *dev;
1143
1144         if (port_id >= nb_ports) {
1145                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1146                 return (-ENODEV);
1147         }
1148
1149         dev = &rte_eth_devices[port_id];
1150
1151         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP);
1152         return ((*dev->dev_ops->dev_led_off)(dev));
1153 }
1154
1155 /*
1156  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
1157  * an empty spot.
1158  */
1159 static inline int
1160 get_mac_addr_index(uint8_t port_id, struct ether_addr *addr)
1161 {
1162         struct rte_eth_dev_info dev_info;
1163         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
1164         unsigned i;
1165
1166         rte_eth_dev_info_get(port_id, &dev_info);
1167
1168         for (i = 0; i < dev_info.max_mac_addrs; i++)
1169                 if (memcmp(addr, &dev->data->mac_addrs[i], ETHER_ADDR_LEN) == 0)
1170                         return i;
1171
1172         return -1;
1173 }
1174
1175 static struct ether_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
1176
1177 int
1178 rte_eth_dev_mac_addr_add(uint8_t port_id, struct ether_addr *addr,
1179                 uint32_t pool)
1180 {
1181         struct rte_eth_dev *dev;
1182         int index;
1183
1184         if (port_id >= nb_ports) {
1185                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1186                 return (-ENODEV);
1187         }
1188         dev = &rte_eth_devices[port_id];
1189
1190         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
1191         if (is_zero_ether_addr(addr)) {
1192                 PMD_DEBUG_TRACE("port %d: Cannot add NULL MAC address\n", port_id);
1193                 return (-EINVAL);
1194         }
1195
1196         /* Check if it's already there, and do nothing */
1197         index = get_mac_addr_index(port_id, addr);
1198         if (index >= 0)
1199                 return 0;
1200
1201         index = get_mac_addr_index(port_id, &null_mac_addr);
1202         if (index < 0) {
1203                 PMD_DEBUG_TRACE("port %d: MAC address array full\n", port_id);
1204                 return (-ENOSPC);
1205         }
1206
1207         /* Update NIC */
1208         (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
1209
1210         /* Update address in NIC data structure */
1211         ether_addr_copy(addr, &dev->data->mac_addrs[index]);
1212
1213         return 0;
1214 }
1215
1216 int
1217 rte_eth_dev_mac_addr_remove(uint8_t port_id, struct ether_addr *addr)
1218 {
1219         struct rte_eth_dev *dev;
1220         int index;
1221
1222         if (port_id >= nb_ports) {
1223                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1224                 return (-ENODEV);
1225         }
1226         dev = &rte_eth_devices[port_id];
1227
1228         FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
1229         index = get_mac_addr_index(port_id, addr);
1230         if (index == 0) {
1231                 PMD_DEBUG_TRACE("port %d: Cannot remove default MAC address\n", port_id);
1232                 return (-EADDRINUSE);
1233         } else if (index < 0)
1234                 return 0;  /* Do nothing if address wasn't found */
1235
1236         /* Update NIC */
1237         (*dev->dev_ops->mac_addr_remove)(dev, index);
1238
1239         /* Update address in NIC data structure */
1240         ether_addr_copy(&null_mac_addr, &dev->data->mac_addrs[index]);
1241
1242         return 0;
1243 }
1244
1245 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
1246 uint16_t
1247 rte_eth_rx_burst(uint8_t port_id, uint16_t queue_id,
1248                  struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
1249 {
1250         struct rte_eth_dev *dev;
1251
1252         if (port_id >= nb_ports) {
1253                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1254                 return 0;
1255         }
1256         dev = &rte_eth_devices[port_id];
1257
1258         FUNC_PTR_OR_ERR_RET(*dev->rx_pkt_burst, -ENOTSUP);
1259         if (queue_id >= dev->data->nb_rx_queues) {
1260                 PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", queue_id);
1261                 return 0;
1262         }
1263         return (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id],
1264                                                 rx_pkts, nb_pkts);
1265 }
1266
1267 uint16_t
1268 rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
1269                  struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1270 {
1271         struct rte_eth_dev *dev;
1272
1273         if (port_id >= nb_ports) {
1274                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1275                 return 0;
1276         }
1277         dev = &rte_eth_devices[port_id];
1278
1279         FUNC_PTR_OR_ERR_RET(*dev->tx_pkt_burst, -ENOTSUP);
1280         if (queue_id >= dev->data->nb_tx_queues) {
1281                 PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", queue_id);
1282                 return 0;
1283         }
1284         return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id],
1285                                                 tx_pkts, nb_pkts);
1286 }
1287 #endif
1288
1289 int
1290 rte_eth_dev_callback_register(uint8_t port_id,
1291                         enum rte_eth_event_type event,
1292                         rte_eth_dev_cb_fn cb_fn, void *cb_arg)
1293 {
1294         int ret = -1;
1295         struct rte_eth_dev *dev;
1296         struct rte_eth_dev_callback *user_cb = NULL;
1297
1298         if (!cb_fn)
1299                 return -1;
1300         if (port_id >= nb_ports) {
1301                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1302                 return -1;
1303         }
1304         dev = &rte_eth_devices[port_id];
1305         rte_spinlock_lock(&rte_eth_dev_cb_lock);
1306         TAILQ_FOREACH(user_cb, &(dev->callbacks), next) {
1307                 if (user_cb->cb_fn == cb_fn &&
1308                         user_cb->cb_arg == cb_arg &&
1309                         user_cb->event == event) {
1310                         ret = 0;
1311                         goto out;
1312                 }
1313         }
1314         user_cb = rte_malloc("INTR_USER_CALLBACK",
1315                 sizeof(struct rte_eth_dev_callback), 0);
1316         if (!user_cb)
1317                 goto out;
1318         user_cb->cb_fn = cb_fn;
1319         user_cb->cb_arg = cb_arg;
1320         user_cb->event = event;
1321         TAILQ_INSERT_TAIL(&(dev->callbacks), user_cb, next);
1322         ret = 0;
1323
1324 out:
1325         rte_spinlock_unlock(&rte_eth_dev_cb_lock);
1326
1327         return ret;
1328 }
1329
1330 int
1331 rte_eth_dev_callback_unregister(uint8_t port_id,
1332                         enum rte_eth_event_type event,
1333                         rte_eth_dev_cb_fn cb_fn, void *cb_arg)
1334 {
1335         int ret = -1;
1336         struct rte_eth_dev *dev;
1337         struct rte_eth_dev_callback *cb_lst = NULL;
1338
1339         if (!cb_fn)
1340                 return -1;
1341         if (port_id >= nb_ports) {
1342                 PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
1343                 return -1;
1344         }
1345         dev = &rte_eth_devices[port_id];
1346         rte_spinlock_lock(&rte_eth_dev_cb_lock);
1347         TAILQ_FOREACH(cb_lst, &(dev->callbacks), next) {
1348                 if (cb_lst->cb_fn != cb_fn || cb_lst->event != event)
1349                         continue;
1350                 if (cb_lst->cb_arg == (void *)-1 ||
1351                                 cb_lst->cb_arg == cb_arg) {
1352                         TAILQ_REMOVE(&(dev->callbacks), cb_lst, next);
1353                         rte_free(cb_lst);
1354                         ret = 0;
1355                 }
1356         }
1357
1358         rte_spinlock_unlock(&rte_eth_dev_cb_lock);
1359
1360         return ret;
1361 }
1362
1363 void
1364 _rte_eth_dev_callback_process(struct rte_eth_dev *dev, enum rte_eth_event_type event)
1365 {
1366         struct rte_eth_dev_callback *cb_lst = NULL;
1367         struct rte_eth_dev_callback dev_cb;
1368
1369         rte_spinlock_lock(&rte_eth_dev_cb_lock);
1370         TAILQ_FOREACH(cb_lst, &(dev->callbacks), next) {
1371                 if (cb_lst->cb_fn == NULL || cb_lst->event != event)
1372                         continue;
1373                 dev_cb = *cb_lst;
1374                 rte_spinlock_unlock(&rte_eth_dev_cb_lock);
1375                 dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
1376                                                 dev_cb.cb_arg);
1377                 rte_spinlock_lock(&rte_eth_dev_cb_lock);
1378         }
1379         rte_spinlock_unlock(&rte_eth_dev_cb_lock);
1380 }
1381