/* Location of per-queue reset values for packets/bytes in reset_vals */
uint64_t *reset_rx_pkts;
uint64_t *reset_rx_bytes;
+ uint64_t *reset_tx_pkts;
+ uint64_t *reset_tx_bytes;
rte_spinlock_t queues_bitmap_lock;
void *queues_bitmap_mem;
unsigned int features;
#define SFC_DP_TX_FEAT_MULTI_PROCESS 0x1
+#define SFC_DP_TX_FEAT_STATS 0x2
/**
* Tx offload capabilities supported by the datapath on device
* level only if HW/FW supports it.
}
dma_desc_space -= (added - pkt_start);
+
+ sfc_pkts_bytes_add(&txq->dp.dpq.stats, 1,
+ rte_pktmbuf_pkt_len(*pktp));
}
if (likely(added != txq->added)) {
.type = SFC_DP_TX,
.hw_fw_caps = SFC_DP_HW_FW_CAP_EF100,
},
- .features = SFC_DP_TX_FEAT_MULTI_PROCESS,
+ .features = SFC_DP_TX_FEAT_MULTI_PROCESS |
+ SFC_DP_TX_FEAT_STATS,
.dev_offload_capa = 0,
.queue_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |
*bytes = bytes_sum;
}
+static void
+sfc_stats_get_dp_tx(struct sfc_adapter *sa, uint64_t *pkts, uint64_t *bytes)
+{
+ struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+ uint64_t pkts_sum = 0;
+ uint64_t bytes_sum = 0;
+ unsigned int i;
+
+ for (i = 0; i < sas->ethdev_txq_count; ++i) {
+ struct sfc_txq_info *txq_info;
+
+ txq_info = sfc_txq_info_by_ethdev_qid(sas, i);
+ if (txq_info->state & SFC_TXQ_INITIALIZED) {
+ union sfc_pkts_bytes qstats;
+
+ sfc_pkts_bytes_get(&txq_info->dp->dpq.stats, &qstats);
+ pkts_sum += qstats.pkts -
+ sa->sw_stats.reset_tx_pkts[i];
+ bytes_sum += qstats.bytes -
+ sa->sw_stats.reset_tx_bytes[i];
+ }
+ }
+
+ *pkts = pkts_sum;
+ *bytes = bytes_sum;
+}
+
/*
* Some statistics are computed as A - B where A and B each increase
* monotonically with some hardware counter(s) and the counters are read
{
const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
+ bool have_dp_tx_stats = sap->dp_tx->features & SFC_DP_TX_FEAT_STATS;
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
struct sfc_port *port = &sa->port;
uint64_t *mac_stats;
if (have_dp_rx_stats)
sfc_stats_get_dp_rx(sa, &stats->ipackets, &stats->ibytes);
+ if (have_dp_tx_stats)
+ sfc_stats_get_dp_tx(sa, &stats->opackets, &stats->obytes);
ret = sfc_port_update_mac_stats(sa, B_FALSE);
if (ret != 0)
/* CRC is included in these stats, but shouldn't be */
stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
}
- stats->opackets =
- mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
- mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
- mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
- stats->obytes =
- mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
- mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
- mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
+ if (!have_dp_tx_stats) {
+ stats->opackets =
+ mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
+ stats->obytes =
+ mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
+
+ /* CRC is included in these stats, but shouldn't be */
+ stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
+ }
stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
-
- /* CRC is included in these stats, but shouldn't be */
- stats->obytes -= stats->opackets * RTE_ETHER_CRC_LEN;
} else {
- stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
- stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
-
- /* CRC is included in these stats, but shouldn't be */
- stats->obytes -= mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
+ if (!have_dp_tx_stats) {
+ stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
+ stats->obytes = mac_stats[EFX_MAC_TX_OCTETS] -
+ mac_stats[EFX_MAC_TX_PKTS] * RTE_ETHER_CRC_LEN;
+ }
/*
* Take into account stats which are whenever supported
}
}
+static sfc_get_sw_stat_val_t sfc_sw_stat_get_tx_good_pkts_bytes;
+static void
+sfc_sw_stat_get_tx_good_pkts_bytes(struct sfc_adapter *sa, uint16_t qid,
+ uint64_t *values,
+ unsigned int values_count)
+{
+ struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
+ struct sfc_txq_info *txq_info;
+ union sfc_pkts_bytes qstats;
+
+ RTE_SET_USED(values_count);
+ SFC_ASSERT(values_count == SFX_SW_STATS_GROUP_BASIC_MAX);
+ txq_info = sfc_txq_info_by_ethdev_qid(sas, qid);
+ if (txq_info->state & SFC_TXQ_INITIALIZED) {
+ sfc_pkts_bytes_get(&txq_info->dp->dpq.stats, &qstats);
+ values[SFC_SW_STATS_GROUP_BASIC_PKTS] = qstats.pkts;
+ values[SFC_SW_STATS_GROUP_BASIC_BYTES] = qstats.bytes;
+ } else {
+ values[SFC_SW_STATS_GROUP_BASIC_PKTS] = 0;
+ values[SFC_SW_STATS_GROUP_BASIC_BYTES] = 0;
+ }
+}
+
static sfc_get_sw_stat_val_t sfc_get_sw_stat_val_rx_dbells;
static void
sfc_get_sw_stat_val_rx_dbells(struct sfc_adapter *sa, uint16_t qid,
.get_val = NULL,
.provide_total = false,
},
+ /* Group of Tx packets/bytes stats */
+ {
+ .name = SFC_SW_STAT_GOOD_PACKETS,
+ .type = SFC_SW_STATS_TX,
+ .get_val = sfc_sw_stat_get_tx_good_pkts_bytes,
+ .provide_total = false,
+ },
+ {
+ .name = SFC_SW_STAT_GOOD_BYTES,
+ .type = SFC_SW_STATS_TX,
+ .get_val = NULL,
+ .provide_total = false,
+ },
/* End of basic stats */
{
.name = "dbells",
{
const struct sfc_adapter_priv *sap = &sa->priv;
bool have_dp_rx_stats = sap->dp_rx->features & SFC_DP_RX_FEAT_STATS;
+ bool have_dp_tx_stats = sap->dp_tx->features & SFC_DP_TX_FEAT_STATS;
struct sfc_sw_stats *sw_stats = &sa->sw_stats;
const struct sfc_sw_stat_descr *sw_stat_descr;
unsigned int i;
sw_stat_descr->type == SFC_SW_STATS_RX &&
sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
continue;
+ if (!have_dp_tx_stats &&
+ sw_stat_descr->type == SFC_SW_STATS_TX &&
+ sfc_sw_stats_is_packets_or_bytes(sw_stat_descr->name))
+ continue;
sw_stats->supp[sw_stats->supp_count].descr = sw_stat_descr;
sw_stats->supp_count++;
}
sa->sw_stats.reset_rx_bytes = reset_vals;
break;
case SFC_SW_STATS_TX:
+ if (strcmp(sw_stat->name,
+ SFC_SW_STAT_GOOD_PACKETS) == 0)
+ sa->sw_stats.reset_tx_pkts = reset_vals;
+ else if (strcmp(sw_stat->name,
+ SFC_SW_STAT_GOOD_BYTES) == 0)
+ sa->sw_stats.reset_tx_bytes = reset_vals;
+ break;
default:
SFC_GENERIC_LOG(ERR, "Unknown SW stat type");
return -EINVAL;