ethdev: add siblings iterators
[dpdk.git] / lib / librte_ethdev / rte_ethdev.c
index 85c1794..243beb4 100644 (file)
@@ -330,8 +330,7 @@ uint16_t
 rte_eth_find_next(uint16_t port_id)
 {
        while (port_id < RTE_MAX_ETHPORTS &&
-              rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED &&
-              rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED)
+                       rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)
                port_id++;
 
        if (port_id >= RTE_MAX_ETHPORTS)
@@ -340,6 +339,25 @@ rte_eth_find_next(uint16_t port_id)
        return port_id;
 }
 
+uint16_t
+rte_eth_find_next_of(uint16_t port_id, const struct rte_device *parent)
+{
+       port_id = rte_eth_find_next(port_id);
+       while (port_id < RTE_MAX_ETHPORTS &&
+                       rte_eth_devices[port_id].device != parent)
+               port_id = rte_eth_find_next(port_id + 1);
+
+       return port_id;
+}
+
+uint16_t
+rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref_port_id)
+{
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(ref_port_id, RTE_MAX_ETHPORTS);
+       return rte_eth_find_next_of(port_id,
+                       rte_eth_devices[ref_port_id].device);
+}
+
 static void
 rte_eth_dev_shared_data_prepare(void)
 {
@@ -438,6 +456,18 @@ rte_eth_dev_allocate(const char *name)
 {
        uint16_t port_id;
        struct rte_eth_dev *eth_dev = NULL;
+       size_t name_len;
+
+       name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN);
+       if (name_len == 0) {
+               RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n");
+               return NULL;
+       }
+
+       if (name_len >= RTE_ETH_NAME_MAX_LEN) {
+               RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n");
+               return NULL;
+       }
 
        rte_eth_dev_shared_data_prepare();
 
@@ -459,7 +489,7 @@ rte_eth_dev_allocate(const char *name)
        }
 
        eth_dev = eth_dev_get(port_id);
-       snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
+       strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
        eth_dev->data->port_id = port_id;
        eth_dev->data->mtu = ETHER_MTU;
 
@@ -555,8 +585,7 @@ uint64_t
 rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 {
        while (port_id < RTE_MAX_ETHPORTS &&
-              ((rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED &&
-              rte_eth_devices[port_id].state != RTE_ETH_DEV_REMOVED) ||
+              (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED ||
               rte_eth_devices[port_id].data->owner.id != owner_id))
                port_id++;
 
@@ -585,7 +614,6 @@ _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 {
        struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
        struct rte_eth_dev_owner *port_owner;
-       int sret;
 
        if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) {
                RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
@@ -609,11 +637,8 @@ _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
                return -EPERM;
        }
 
-       sret = snprintf(port_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN, "%s",
-                       new_owner->name);
-       if (sret < 0 || sret >= RTE_ETH_MAX_OWNER_NAME_LEN)
-               RTE_ETHDEV_LOG(ERR, "Port %u owner name was truncated\n",
-                       port_id);
+       /* can not truncate (same structure) */
+       strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN);
 
        port_owner->id = new_owner->id;
 
@@ -1643,7 +1668,7 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
             local_conf.offloads) {
                RTE_ETHDEV_LOG(ERR,
                        "Ethdev port_id=%d rx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
-                       "within pre-queue offload capabilities 0x%"PRIx64" in %s()\n",
+                       "within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
                        port_id, rx_queue_id, local_conf.offloads,
                        dev_info.rx_queue_offload_capa,
                        __func__);
@@ -1747,7 +1772,7 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
             local_conf.offloads) {
                RTE_ETHDEV_LOG(ERR,
                        "Ethdev port_id=%d tx_queue_id=%d, new added offloads 0x%"PRIx64" must be "
-                       "within pre-queue offload capabilities 0x%"PRIx64" in %s()\n",
+                       "within per-queue offload capabilities 0x%"PRIx64" in %s()\n",
                        port_id, tx_queue_id, local_conf.offloads,
                        dev_info.tx_queue_offload_capa,
                        __func__);
@@ -2060,9 +2085,9 @@ rte_eth_basic_stats_get_names(struct rte_eth_dev *dev,
        uint16_t num_q;
 
        for (idx = 0; idx < RTE_NB_STATS; idx++) {
-               snprintf(xstats_names[cnt_used_entries].name,
-                       sizeof(xstats_names[0].name),
-                       "%s", rte_stats_strings[idx].name);
+               strlcpy(xstats_names[cnt_used_entries].name,
+                       rte_stats_strings[idx].name,
+                       sizeof(xstats_names[0].name));
                cnt_used_entries++;
        }
        num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
@@ -2524,6 +2549,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
        dev_info->rx_desc_lim = lim;
        dev_info->tx_desc_lim = lim;
        dev_info->device = dev->device;
+       dev_info->min_mtu = ETHER_MIN_MTU;
+       dev_info->max_mtu = UINT16_MAX;
 
        RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
        (*dev->dev_ops->dev_infos_get)(dev, dev_info);
@@ -2587,12 +2614,25 @@ int
 rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
 {
        int ret;
+       struct rte_eth_dev_info dev_info;
        struct rte_eth_dev *dev;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP);
 
+       /*
+        * Check if the device supports dev_infos_get, if it does not
+        * skip min_mtu/max_mtu validation here as this requires values
+        * that are populated within the call to rte_eth_dev_info_get()
+        * which relies on dev->dev_ops->dev_infos_get.
+        */
+       if (*dev->dev_ops->dev_infos_get != NULL) {
+               rte_eth_dev_info_get(port_id, &dev_info);
+               if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
+                       return -EINVAL;
+       }
+
        ret = (*dev->dev_ops->mtu_set)(dev, mtu);
        if (!ret)
                dev->data->mtu = mtu;