ethdev: call Rx and Tx callbacks in the order they were added
[dpdk.git] / lib / librte_ether / rte_ethdev.c
index 4be17f1..ddf3658 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -443,9 +443,6 @@ rte_eth_dev_count(void)
        return nb_ports;
 }
 
-/* So far, DPDK hotplug function only supports linux */
-#ifdef RTE_LIBRTE_EAL_HOTPLUG
-
 static enum rte_eth_dev_type
 rte_eth_dev_get_device_type(uint8_t port_id)
 {
@@ -527,6 +524,7 @@ rte_eth_dev_is_detachable(uint8_t port_id)
                switch (rte_eth_devices[port_id].pci_dev->kdrv) {
                case RTE_KDRV_IGB_UIO:
                case RTE_KDRV_UIO_GENERIC:
+               case RTE_KDRV_NIC_UIO:
                        break;
                case RTE_KDRV_VFIO:
                default:
@@ -719,24 +717,6 @@ rte_eth_dev_detach(uint8_t port_id, char *name)
        } else
                return rte_eth_dev_detach_vdev(port_id, name);
 }
-#else /* RTE_LIBRTE_EAL_HOTPLUG */
-int
-rte_eth_dev_attach(const char *devargs __rte_unused,
-                       uint8_t *port_id __rte_unused)
-{
-       RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
-       return -1;
-}
-
-/* detach the device, then store the name of the device */
-int
-rte_eth_dev_detach(uint8_t port_id __rte_unused,
-                       char *name __rte_unused)
-{
-       RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
-       return -1;
-}
-#endif /* RTE_LIBRTE_EAL_HOTPLUG */
 
 static int
 rte_eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
@@ -2817,7 +2797,7 @@ rte_eth_mirror_rule_set(uint8_t port_id,
        struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 
        VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-       if (mirror_conf->rule_type_mask == 0) {
+       if (mirror_conf->rule_type == 0) {
                PMD_DEBUG_TRACE("mirror rule type can not be 0.\n");
                return -EINVAL;
        }
@@ -2828,12 +2808,19 @@ rte_eth_mirror_rule_set(uint8_t port_id,
                return -EINVAL;
        }
 
-       if ((mirror_conf->rule_type_mask & ETH_VMDQ_POOL_MIRROR) &&
-               (mirror_conf->pool_mask == 0)) {
+       if ((mirror_conf->rule_type & (ETH_MIRROR_VIRTUAL_POOL_UP |
+            ETH_MIRROR_VIRTUAL_POOL_DOWN)) &&
+           (mirror_conf->pool_mask == 0)) {
                PMD_DEBUG_TRACE("Invalid mirror pool, pool mask can not be 0.\n");
                return -EINVAL;
        }
 
+       if ((mirror_conf->rule_type & ETH_MIRROR_VLAN) &&
+           mirror_conf->vlan.vlan_mask == 0) {
+               PMD_DEBUG_TRACE("Invalid vlan mask, vlan mask can not be 0.\n");
+               return -EINVAL;
+       }
+
        dev = &rte_eth_devices[port_id];
        FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
@@ -3192,8 +3179,20 @@ rte_eth_add_rx_callback(uint8_t port_id, uint16_t queue_id,
 
        cb->fn.rx = fn;
        cb->param = user_param;
-       cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
-       rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb;
+
+       /* Add the callbacks in fifo order. */
+       struct rte_eth_rxtx_callback *tail =
+               rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
+
+       if (!tail) {
+               rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb;
+
+       } else {
+               while (tail->next)
+                       tail = tail->next;
+               tail->next = cb;
+       }
+
        return cb;
 }
 
@@ -3221,8 +3220,20 @@ rte_eth_add_tx_callback(uint8_t port_id, uint16_t queue_id,
 
        cb->fn.tx = fn;
        cb->param = user_param;
-       cb->next = rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id];
-       rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id] = cb;
+
+       /* Add the callbacks in fifo order. */
+       struct rte_eth_rxtx_callback *tail =
+               rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id];
+
+       if (!tail) {
+               rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id] = cb;
+
+       } else {
+               while (tail->next)
+                       tail = tail->next;
+               tail->next = cb;
+       }
+
        return cb;
 }
 
@@ -3317,3 +3328,52 @@ rte_eth_dev_set_mc_addr_list(uint8_t port_id,
        FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
        return dev->dev_ops->set_mc_addr_list(dev, mc_addr_set, nb_mc_addr);
 }
+
+int
+rte_eth_timesync_enable(uint8_t port_id)
+{
+       struct rte_eth_dev *dev;
+
+       VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       dev = &rte_eth_devices[port_id];
+
+       FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_enable, -ENOTSUP);
+       return (*dev->dev_ops->timesync_enable)(dev);
+}
+
+int
+rte_eth_timesync_disable(uint8_t port_id)
+{
+       struct rte_eth_dev *dev;
+
+       VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       dev = &rte_eth_devices[port_id];
+
+       FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_disable, -ENOTSUP);
+       return (*dev->dev_ops->timesync_disable)(dev);
+}
+
+int
+rte_eth_timesync_read_rx_timestamp(uint8_t port_id, struct timespec *timestamp,
+                                  uint32_t flags)
+{
+       struct rte_eth_dev *dev;
+
+       VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       dev = &rte_eth_devices[port_id];
+
+       FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
+       return (*dev->dev_ops->timesync_read_rx_timestamp)(dev, timestamp, flags);
+}
+
+int
+rte_eth_timesync_read_tx_timestamp(uint8_t port_id, struct timespec *timestamp)
+{
+       struct rte_eth_dev *dev;
+
+       VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       dev = &rte_eth_devices[port_id];
+
+       FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
+       return (*dev->dev_ops->timesync_read_tx_timestamp)(dev, timestamp);
+}