ethdev: fix xstats get by id APIs
[dpdk.git] / lib / librte_ether / rte_ethdev.c
index 9b228ce..8bcd3a2 100644 (file)
@@ -179,11 +179,9 @@ rte_eth_dev_allocated(const char *name)
        unsigned i;
 
        for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-               if (rte_eth_devices[i].state == RTE_ETH_DEV_ATTACHED &&
-                               rte_eth_devices[i].device) {
-                       if (!strcmp(rte_eth_devices[i].device->name, name))
-                               return &rte_eth_devices[i];
-               }
+               if ((rte_eth_devices[i].state == RTE_ETH_DEV_ATTACHED) &&
+                   strcmp(rte_eth_devices[i].data->name, name) == 0)
+                       return &rte_eth_devices[i];
        }
        return NULL;
 }
@@ -303,6 +301,13 @@ rte_eth_dev_socket_id(uint16_t port_id)
        return rte_eth_devices[port_id].data->numa_node;
 }
 
+void *
+rte_eth_dev_get_sec_ctx(uint8_t port_id)
+{
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
+       return rte_eth_devices[port_id].security_ctx;
+}
+
 uint16_t
 rte_eth_dev_count(void)
 {
@@ -320,7 +325,7 @@ rte_eth_dev_count(void)
 int
 rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
 {
-       const char *tmp;
+       char *tmp;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -331,7 +336,7 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
 
        /* shouldn't check 'rte_eth_devices[i].data',
         * because it might be overwritten by VDEV PMD */
-       tmp = rte_eth_devices[port_id].device->name;
+       tmp = rte_eth_dev_data[port_id].name;
        strcpy(name, tmp);
        return 0;
 }
@@ -339,7 +344,6 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
 int
 rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 {
-       int ret;
        int i;
 
        if (name == NULL) {
@@ -348,13 +352,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
        }
 
        RTE_ETH_FOREACH_DEV(i) {
-               if (!rte_eth_devices[i].device)
-                       continue;
+               if (!strncmp(name,
+                       rte_eth_dev_data[i].name, strlen(name))) {
 
-               ret = strncmp(name, rte_eth_devices[i].device->name,
-                               strlen(name));
-               if (ret == 0) {
                        *port_id = i;
+
                        return 0;
                }
        }
@@ -437,8 +439,8 @@ rte_eth_dev_detach(uint16_t port_id, char *name)
        if (rte_eth_dev_is_detachable(port_id))
                goto err;
 
-       snprintf(name, RTE_DEV_NAME_MAX_LEN, "%s",
-                rte_eth_devices[port_id].device->name);
+       snprintf(name, sizeof(rte_eth_devices[port_id].data->name),
+                "%s", rte_eth_devices[port_id].data->name);
 
        ret = rte_eal_dev_detach(rte_eth_devices[port_id].device);
        if (ret < 0)
@@ -717,6 +719,8 @@ rte_eth_convert_rx_offload_bitfield(const struct rte_eth_rxmode *rxmode,
                offloads |= DEV_RX_OFFLOAD_TCP_LRO;
        if (rxmode->hw_timestamp == 1)
                offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
+       if (rxmode->security == 1)
+               offloads |= DEV_RX_OFFLOAD_SECURITY;
 
        *rx_offloads = offloads;
 }
@@ -769,6 +773,10 @@ rte_eth_convert_rx_offloads(const uint64_t rx_offloads,
                rxmode->hw_timestamp = 1;
        else
                rxmode->hw_timestamp = 0;
+       if (rx_offloads & DEV_RX_OFFLOAD_SECURITY)
+               rxmode->security = 1;
+       else
+               rxmode->security = 0;
 }
 
 int
@@ -1555,6 +1563,22 @@ rte_eth_stats_reset(uint16_t port_id)
        return 0;
 }
 
+static inline int
+get_xstats_basic_count(struct rte_eth_dev *dev)
+{
+       uint16_t nb_rxqs, nb_txqs;
+       int count;
+
+       nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+       nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+       count = RTE_NB_STATS;
+       count += nb_rxqs * RTE_NB_RXQ_STATS;
+       count += nb_txqs * RTE_NB_TXQ_STATS;
+
+       return count;
+}
+
 static int
 get_xstats_count(uint16_t port_id)
 {
@@ -1576,11 +1600,9 @@ get_xstats_count(uint16_t port_id)
        } else
                count = 0;
 
-       count += RTE_NB_STATS;
-       count += RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS) *
-                RTE_NB_RXQ_STATS;
-       count += RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS) *
-                RTE_NB_TXQ_STATS;
+
+       count += get_xstats_basic_count(dev);
+
        return count;
 }
 
@@ -1628,121 +1650,88 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
        return -EINVAL;
 }
 
+/* retrieve ethdev extended statistics names */
 int
 rte_eth_xstats_get_names_by_id(uint16_t port_id,
        struct rte_eth_xstat_name *xstats_names, unsigned int size,
        uint64_t *ids)
 {
-       /* Get all xstats */
+       struct rte_eth_xstat_name *xstats_names_copy;
+       unsigned int no_basic_stat_requested = 1;
+       unsigned int expected_entries;
+       struct rte_eth_dev *dev;
+       unsigned int i;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       expected_entries = get_xstats_count(port_id);
+       dev = &rte_eth_devices[port_id];
+
+       /* Return max number of stats if no ids given */
        if (!ids) {
-               struct rte_eth_dev *dev;
-               int cnt_used_entries;
-               int cnt_expected_entries;
-               int cnt_driver_entries;
-               uint32_t idx, id_queue;
-               uint16_t num_q;
-
-               cnt_expected_entries = get_xstats_count(port_id);
-               if (xstats_names == NULL || cnt_expected_entries < 0 ||
-                               (int)size < cnt_expected_entries)
-                       return cnt_expected_entries;
-
-               /* port_id checked in get_xstats_count() */
-               dev = &rte_eth_devices[port_id];
-               cnt_used_entries = 0;
-
-               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);
-                       cnt_used_entries++;
-               }
-               num_q = RTE_MIN(dev->data->nb_rx_queues,
-                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
-               for (id_queue = 0; id_queue < num_q; id_queue++) {
-                       for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
-                               snprintf(xstats_names[cnt_used_entries].name,
-                                       sizeof(xstats_names[0].name),
-                                       "rx_q%u%s",
-                                       id_queue,
-                                       rte_rxq_stats_strings[idx].name);
-                               cnt_used_entries++;
-                       }
+               if (!xstats_names)
+                       return expected_entries;
+               else if (xstats_names && size < expected_entries)
+                       return expected_entries;
+       }
 
-               }
-               num_q = RTE_MIN(dev->data->nb_tx_queues,
-                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
-               for (id_queue = 0; id_queue < num_q; id_queue++) {
-                       for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
-                               snprintf(xstats_names[cnt_used_entries].name,
-                                       sizeof(xstats_names[0].name),
-                                       "tx_q%u%s",
-                                       id_queue,
-                                       rte_txq_stats_strings[idx].name);
-                               cnt_used_entries++;
+       if (ids && !xstats_names)
+               return -EINVAL;
+
+       if (ids && dev->dev_ops->xstats_get_names_by_id != NULL && size > 0) {
+               unsigned int basic_count = get_xstats_basic_count(dev);
+               uint64_t ids_copy[size];
+
+               for (i = 0; i < size; i++) {
+                       if (ids[i] < basic_count) {
+                               no_basic_stat_requested = 0;
+                               break;
                        }
-               }
 
-               if (dev->dev_ops->xstats_get_names_by_id != NULL) {
-                       /* If there are any driver-specific xstats, append them
-                        * to end of list.
-                        */
-                       cnt_driver_entries =
-                               (*dev->dev_ops->xstats_get_names_by_id)(
-                               dev,
-                               xstats_names + cnt_used_entries,
-                               NULL,
-                               size - cnt_used_entries);
-                       if (cnt_driver_entries < 0)
-                               return cnt_driver_entries;
-                       cnt_used_entries += cnt_driver_entries;
-
-               } else if (dev->dev_ops->xstats_get_names != NULL) {
-                       /* If there are any driver-specific xstats, append them
-                        * to end of list.
+                       /*
+                        * Convert ids to xstats ids that PMD knows.
+                        * ids known by user are basic + extended stats.
                         */
-                       cnt_driver_entries = (*dev->dev_ops->xstats_get_names)(
-                               dev,
-                               xstats_names + cnt_used_entries,
-                               size - cnt_used_entries);
-                       if (cnt_driver_entries < 0)
-                               return cnt_driver_entries;
-                       cnt_used_entries += cnt_driver_entries;
+                       ids_copy[i] = ids[i] - basic_count;
                }
 
-               return cnt_used_entries;
+               if (no_basic_stat_requested)
+                       return (*dev->dev_ops->xstats_get_names_by_id)(dev,
+                                       xstats_names, ids_copy, size);
        }
-       /* Get only xstats given by IDS */
-       else {
-               uint16_t len, i;
-               struct rte_eth_xstat_name *xstats_names_copy;
 
-               len = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
+       /* Retrieve all stats */
+       if (!ids) {
+               int num_stats = rte_eth_xstats_get_names(port_id, xstats_names,
+                               expected_entries);
+               if (num_stats < 0 || num_stats > (int)expected_entries)
+                       return num_stats;
+               else
+                       return expected_entries;
+       }
 
-               xstats_names_copy =
-                               malloc(sizeof(struct rte_eth_xstat_name) * len);
-               if (!xstats_names_copy) {
-                       RTE_PMD_DEBUG_TRACE(
-                            "ERROR: can't allocate memory for values_copy\n");
-                       free(xstats_names_copy);
-                       return -1;
-               }
+       xstats_names_copy = calloc(expected_entries,
+               sizeof(struct rte_eth_xstat_name));
 
-               rte_eth_xstats_get_names_by_id(port_id, xstats_names_copy,
-                               len, NULL);
+       if (!xstats_names_copy) {
+               RTE_PMD_DEBUG_TRACE("ERROR: can't allocate memory");
+               return -ENOMEM;
+       }
 
-               for (i = 0; i < size; i++) {
-                       if (ids[i] >= len) {
-                               RTE_PMD_DEBUG_TRACE(
-                                       "ERROR: id value isn't valid\n");
-                               return -1;
-                       }
-                       strcpy(xstats_names[i].name,
-                                       xstats_names_copy[ids[i]].name);
+       /* Fill xstats_names_copy structure */
+       rte_eth_xstats_get_names(port_id, xstats_names_copy, expected_entries);
+
+       /* Filter stats */
+       for (i = 0; i < size; i++) {
+               if (ids[i] >= expected_entries) {
+                       RTE_PMD_DEBUG_TRACE("ERROR: id value isn't valid\n");
+                       free(xstats_names_copy);
+                       return -1;
                }
-               free(xstats_names_copy);
-               return size;
+               xstats_names[i] = xstats_names_copy[ids[i]];
        }
+
+       free(xstats_names_copy);
+       return size;
 }
 
 int
@@ -1813,128 +1802,72 @@ rte_eth_xstats_get_names(uint16_t port_id,
 /* retrieve ethdev extended statistics */
 int
 rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
-                        uint64_t *values, unsigned int n)
+                        uint64_t *values, unsigned int size)
 {
-       /* If need all xstats */
-       if (!ids) {
-               struct rte_eth_stats eth_stats;
-               struct rte_eth_dev *dev;
-               unsigned int count = 0, i, q;
-               signed int xcount = 0;
-               uint64_t val, *stats_ptr;
-               uint16_t nb_rxqs, nb_txqs;
-
-               RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-               dev = &rte_eth_devices[port_id];
-
-               nb_rxqs = RTE_MIN(dev->data->nb_rx_queues,
-                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
-               nb_txqs = RTE_MIN(dev->data->nb_tx_queues,
-                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
-
-               /* Return generic statistics */
-               count = RTE_NB_STATS + (nb_rxqs * RTE_NB_RXQ_STATS) +
-                       (nb_txqs * RTE_NB_TXQ_STATS);
-
-
-               /* implemented by the driver */
-               if (dev->dev_ops->xstats_get_by_id != NULL) {
-                       /* Retrieve the xstats from the driver at the end of the
-                        * xstats struct. Retrieve all xstats.
-                        */
-                       xcount = (*dev->dev_ops->xstats_get_by_id)(dev,
-                                       NULL,
-                                       values ? values + count : NULL,
-                                       (n > count) ? n - count : 0);
-
-                       if (xcount < 0)
-                               return xcount;
-               /* implemented by the driver */
-               } else if (dev->dev_ops->xstats_get != NULL) {
-                       /* Retrieve the xstats from the driver at the end of the
-                        * xstats struct. Retrieve all xstats.
-                        * Compatibility for PMD without xstats_get_by_ids
-                        */
-                       unsigned int size = (n > count) ? n - count : 1;
-                       struct rte_eth_xstat xstats[size];
-
-                       xcount = (*dev->dev_ops->xstats_get)(dev,
-                                       values ? xstats : NULL, size);
-
-                       if (xcount < 0)
-                               return xcount;
+       unsigned int no_basic_stat_requested = 1;
+       unsigned int num_xstats_filled;
+       uint16_t expected_entries;
+       struct rte_eth_dev *dev;
+       unsigned int i;
 
-                       if (values != NULL)
-                               for (i = 0 ; i < (unsigned int)xcount; i++)
-                                       values[i + count] = xstats[i].value;
-               }
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       expected_entries = get_xstats_count(port_id);
+       struct rte_eth_xstat xstats[expected_entries];
+       dev = &rte_eth_devices[port_id];
 
-               if (n < count + xcount || values == NULL)
-                       return count + xcount;
+       /* Return max number of stats if no ids given */
+       if (!ids) {
+               if (!values)
+                       return expected_entries;
+               else if (values && size < expected_entries)
+                       return expected_entries;
+       }
 
-               /* now fill the xstats structure */
-               count = 0;
-               rte_eth_stats_get(port_id, &eth_stats);
+       if (ids && !values)
+               return -EINVAL;
 
-               /* global stats */
-               for (i = 0; i < RTE_NB_STATS; i++) {
-                       stats_ptr = RTE_PTR_ADD(&eth_stats,
-                                               rte_stats_strings[i].offset);
-                       val = *stats_ptr;
-                       values[count++] = val;
-               }
+       if (ids && dev->dev_ops->xstats_get_by_id != NULL && size) {
+               unsigned int basic_count = get_xstats_basic_count(dev);
+               uint64_t ids_copy[size];
 
-               /* per-rxq stats */
-               for (q = 0; q < nb_rxqs; q++) {
-                       for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
-                               stats_ptr = RTE_PTR_ADD(&eth_stats,
-                                           rte_rxq_stats_strings[i].offset +
-                                           q * sizeof(uint64_t));
-                               val = *stats_ptr;
-                               values[count++] = val;
+               for (i = 0; i < size; i++) {
+                       if (ids[i] < basic_count) {
+                               no_basic_stat_requested = 0;
+                               break;
                        }
-               }
 
-               /* per-txq stats */
-               for (q = 0; q < nb_txqs; q++) {
-                       for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
-                               stats_ptr = RTE_PTR_ADD(&eth_stats,
-                                           rte_txq_stats_strings[i].offset +
-                                           q * sizeof(uint64_t));
-                               val = *stats_ptr;
-                               values[count++] = val;
-                       }
+                       /*
+                        * Convert ids to xstats ids that PMD knows.
+                        * ids known by user are basic + extended stats.
+                        */
+                       ids_copy[i] = ids[i] - basic_count;
                }
 
-               return count + xcount;
+               if (no_basic_stat_requested)
+                       return (*dev->dev_ops->xstats_get_by_id)(dev, ids_copy,
+                                       values, size);
        }
-       /* Need only xstats given by IDS array */
-       else {
-               uint16_t i, size;
-               uint64_t *values_copy;
 
-               size = rte_eth_xstats_get_by_id(port_id, NULL, NULL, 0);
-
-               values_copy = malloc(sizeof(*values_copy) * size);
-               if (!values_copy) {
-                       RTE_PMD_DEBUG_TRACE(
-                           "ERROR: can't allocate memory for values_copy\n");
-                       return -1;
-               }
+       /* Fill the xstats structure */
+       num_xstats_filled = rte_eth_xstats_get(port_id, xstats,
+               expected_entries);
 
-               rte_eth_xstats_get_by_id(port_id, NULL, values_copy, size);
+       /* Return all stats */
+       if (!ids) {
+               for (i = 0; i < num_xstats_filled; i++)
+                       values[i] = xstats[i].value;
+               return expected_entries;
+       }
 
-               for (i = 0; i < n; i++) {
-                       if (ids[i] >= size) {
-                               RTE_PMD_DEBUG_TRACE(
-                                       "ERROR: id value isn't valid\n");
-                               return -1;
-                       }
-                       values[i] = values_copy[ids[i]];
+       /* Filter stats */
+       for (i = 0; i < size; i++) {
+               if (ids[i] >= expected_entries) {
+                       RTE_PMD_DEBUG_TRACE("ERROR: id value isn't valid\n");
+                       return -1;
                }
-               free(values_copy);
-               return n;
+               values[i] = xstats[ids[i]].value;
        }
+       return size;
 }
 
 int
@@ -3633,7 +3566,7 @@ rte_eth_dev_adjust_nb_rx_tx_desc(uint16_t port_id,
 }
 
 int
-rte_eth_dev_pool_ops_supported(uint8_t port_id, const char *pool)
+rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 {
        struct rte_eth_dev *dev;