#include "sfc_flow.h"
#include "sfc_dp.h"
#include "sfc_dp_rx.h"
+#include "sfc_sw_stats.h"
+
+#define SFC_XSTAT_ID_INVALID_VAL UINT64_MAX
+#define SFC_XSTAT_ID_INVALID_NAME '\0'
uint32_t sfc_logtype_driver;
sfc_adapter_lock(sa);
- ret = sfc_port_update_mac_stats(sa);
+ ret = sfc_port_update_mac_stats(sa, B_FALSE);
if (ret != 0)
goto unlock;
if (rc != 0)
sfc_err(sa, "failed to reset statistics (rc = %d)", rc);
+ sfc_sw_xstats_reset(sa);
+
sfc_adapter_unlock(sa);
SFC_ASSERT(rc >= 0);
return -rc;
}
+static unsigned int
+sfc_xstats_get_nb_supported(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ unsigned int nb_supported;
+
+ sfc_adapter_lock(sa);
+ nb_supported = port->mac_stats_nb_supported +
+ sfc_sw_xstats_get_nb_supported(sa);
+ sfc_adapter_unlock(sa);
+
+ return nb_supported;
+}
+
static int
sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
unsigned int xstats_count)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
- struct sfc_port *port = &sa->port;
- uint64_t *mac_stats;
+ unsigned int nb_written = 0;
+ unsigned int nb_supported = 0;
int rc;
- unsigned int i;
- int nstats = 0;
-
- sfc_adapter_lock(sa);
-
- rc = sfc_port_update_mac_stats(sa);
- if (rc != 0) {
- SFC_ASSERT(rc > 0);
- nstats = -rc;
- goto unlock;
- }
- mac_stats = port->mac_stats_buf;
+ if (unlikely(xstats == NULL))
+ return sfc_xstats_get_nb_supported(sa);
- for (i = 0; i < EFX_MAC_NSTATS; ++i) {
- if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
- if (xstats != NULL && nstats < (int)xstats_count) {
- xstats[nstats].id = nstats;
- xstats[nstats].value = mac_stats[i];
- }
- nstats++;
- }
- }
+ rc = sfc_port_get_mac_stats(sa, xstats, xstats_count, &nb_written);
+ if (rc < 0)
+ return rc;
-unlock:
- sfc_adapter_unlock(sa);
+ nb_supported = rc;
+ sfc_sw_xstats_get_vals(sa, xstats, xstats_count, &nb_written,
+ &nb_supported);
- return nstats;
+ return nb_supported;
}
static int
struct sfc_port *port = &sa->port;
unsigned int i;
unsigned int nstats = 0;
+ unsigned int nb_written = 0;
+ int ret;
+
+ if (unlikely(xstats_names == NULL))
+ return sfc_xstats_get_nb_supported(sa);
for (i = 0; i < EFX_MAC_NSTATS; ++i) {
if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
- if (xstats_names != NULL && nstats < xstats_count)
+ if (nstats < xstats_count) {
strlcpy(xstats_names[nstats].name,
efx_mac_stat_name(sa->nic, i),
sizeof(xstats_names[0].name));
+ nb_written++;
+ }
nstats++;
}
}
+ ret = sfc_sw_xstats_get_names(sa, xstats_names, xstats_count,
+ &nb_written, &nstats);
+ if (ret != 0) {
+ SFC_ASSERT(ret < 0);
+ return ret;
+ }
+
return nstats;
}
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
struct sfc_port *port = &sa->port;
- uint64_t *mac_stats;
+ unsigned int nb_supported;
unsigned int i;
- int ret;
int rc;
if (unlikely(ids == NULL || values == NULL))
return -EINVAL;
- sfc_adapter_lock(sa);
-
- rc = sfc_port_update_mac_stats(sa);
- if (rc != 0) {
- SFC_ASSERT(rc > 0);
- ret = -rc;
- goto unlock;
- }
+ /*
+ * Values array could be filled in nonsequential order. Fill values with
+ * constant indicating invalid ID first.
+ */
+ for (i = 0; i < n; i++)
+ values[i] = SFC_XSTAT_ID_INVALID_VAL;
- mac_stats = port->mac_stats_buf;
+ rc = sfc_port_get_mac_stats_by_id(sa, ids, values, n);
+ if (rc != 0)
+ return rc;
- SFC_ASSERT(port->mac_stats_nb_supported <=
- RTE_DIM(port->mac_stats_by_id));
+ nb_supported = port->mac_stats_nb_supported;
+ sfc_sw_xstats_get_vals_by_id(sa, ids, values, n, &nb_supported);
+ /* Return number of written stats before invalid ID is encountered. */
for (i = 0; i < n; i++) {
- if (ids[i] < port->mac_stats_nb_supported) {
- values[i] = mac_stats[port->mac_stats_by_id[ids[i]]];
- } else {
- ret = i;
- goto unlock;
- }
+ if (values[i] == SFC_XSTAT_ID_INVALID_VAL)
+ return i;
}
- ret = n;
-
-unlock:
- sfc_adapter_unlock(sa);
-
- return ret;
+ return n;
}
static int
struct sfc_port *port = &sa->port;
unsigned int nb_supported;
unsigned int i;
+ int ret;
if (unlikely(xstats_names == NULL && ids != NULL) ||
unlikely(xstats_names != NULL && ids == NULL))
return -EINVAL;
- sfc_adapter_lock(sa);
+ if (unlikely(xstats_names == NULL && ids == NULL))
+ return sfc_xstats_get_nb_supported(sa);
- if (unlikely(xstats_names == NULL && ids == NULL)) {
- nb_supported = port->mac_stats_nb_supported;
- sfc_adapter_unlock(sa);
- return nb_supported;
- }
+ /*
+ * Names array could be filled in nonsequential order. Fill names with
+ * string indicating invalid ID first.
+ */
+ for (i = 0; i < size; i++)
+ xstats_names[i].name[0] = SFC_XSTAT_ID_INVALID_NAME;
+
+ sfc_adapter_lock(sa);
SFC_ASSERT(port->mac_stats_nb_supported <=
RTE_DIM(port->mac_stats_by_id));
efx_mac_stat_name(sa->nic,
port->mac_stats_by_id[ids[i]]),
sizeof(xstats_names[0].name));
- } else {
- sfc_adapter_unlock(sa);
- return i;
}
}
+ nb_supported = port->mac_stats_nb_supported;
+
sfc_adapter_unlock(sa);
+ ret = sfc_sw_xstats_get_names_by_id(sa, ids, xstats_names, size,
+ &nb_supported);
+ if (ret != 0) {
+ SFC_ASSERT(ret < 0);
+ return ret;
+ }
+
+ /* Return number of written names before invalid ID is encountered. */
+ for (i = 0; i < size; i++) {
+ if (xstats_names[i].name[0] == SFC_XSTAT_ID_INVALID_NAME)
+ return i;
+ }
+
return size;
}