@@ -127,7 +127,10 @@ static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
static void i40e_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
+static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
+ struct rte_eth_xstats *xstats, unsigned n);
static void i40e_dev_stats_reset(struct rte_eth_dev *dev);
+static void i40e_dev_xstats_reset(struct rte_eth_dev *dev);
static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
uint16_t queue_id,
uint8_t stat_idx,
@@ -232,6 +235,8 @@ static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
uint32_t flags);
static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
struct timespec *timestamp);
+static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw);
+
static const struct rte_pci_id pci_id_i40e_map[] = {
#define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -252,7 +257,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
.dev_set_link_down = i40e_dev_set_link_down,
.link_update = i40e_dev_link_update,
.stats_get = i40e_dev_stats_get,
+ .xstats_get = i40e_dev_xstats_get,
.stats_reset = i40e_dev_stats_reset,
+ .xstats_reset = i40e_dev_xstats_reset,
.queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set,
.dev_infos_get = i40e_dev_info_get,
.vlan_filter_set = i40e_vlan_filter_set,
@@ -291,6 +298,187 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
.timesync_read_tx_timestamp = i40e_timesync_read_tx_timestamp,
};
+/* store statistics names and its offset in stats structure */
+struct rte_i40e_xstats_name_off {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+ unsigned offset;
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
+ {"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+ {"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+ {"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+ {"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)},
+ {"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+ rx_unknown_protocol)},
+ {"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
+ {"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
+ {"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
+ {"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)},
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = {
+ {"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats,
+ tx_dropped_link_down)},
+ {"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)},
+ {"rx_illegal_bytes", offsetof(struct i40e_hw_port_stats,
+ illegal_bytes)},
+ {"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)},
+ {"mac_local_errors", offsetof(struct i40e_hw_port_stats,
+ mac_local_faults)},
+ {"mac_remote_errors", offsetof(struct i40e_hw_port_stats,
+ mac_remote_faults)},
+ {"rx_length_errors", offsetof(struct i40e_hw_port_stats,
+ rx_length_errors)},
+ {"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)},
+ {"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)},
+ {"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)},
+ {"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)},
+ {"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)},
+ {"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+ rx_size_127)},
+ {"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+ rx_size_255)},
+ {"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+ rx_size_511)},
+ {"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+ rx_size_1023)},
+ {"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+ rx_size_1522)},
+ {"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+ rx_size_big)},
+ {"rx_undersized_packets", offsetof(struct i40e_hw_port_stats,
+ rx_undersize)},
+ {"rx_oversize_packets", offsetof(struct i40e_hw_port_stats,
+ rx_oversize)},
+ {"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats,
+ mac_short_packet_dropped)},
+ {"rx_fragmented_packets", offsetof(struct i40e_hw_port_stats,
+ rx_fragments)},
+ {"rx_jabber_packets", offsetof(struct i40e_hw_port_stats, rx_jabber)},
+ {"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)},
+ {"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+ tx_size_127)},
+ {"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+ tx_size_255)},
+ {"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+ tx_size_511)},
+ {"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+ tx_size_1023)},
+ {"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+ tx_size_1522)},
+ {"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+ tx_size_big)},
+ {"rx_flow_director_atr_match_packets",
+ offsetof(struct i40e_hw_port_stats, fd_atr_match)},
+ {"rx_flow_director_sb_match_packets",
+ offsetof(struct i40e_hw_port_stats, fd_sb_match)},
+ {"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+ tx_lpi_status)},
+ {"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+ rx_lpi_status)},
+ {"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+ tx_lpi_count)},
+ {"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+ rx_lpi_count)},
+
+ /* priority_xon_rx[8] */
+ {"tx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[0])},
+ {"tx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[1])},
+ {"tx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[2])},
+ {"tx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[3])},
+ {"tx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[4])},
+ {"tx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[5])},
+ {"tx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[6])},
+ {"tx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_tx[7])},
+
+ /* priority_xon_rx[8] */
+ {"rx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[0])},
+ {"rx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[1])},
+ {"rx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[2])},
+ {"rx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[3])},
+ {"rx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[4])},
+ {"rx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[5])},
+ {"rx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[6])},
+ {"rx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xon_rx[7])},
+
+ /* priority_xoff_tx[8] */
+ {"tx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[0])},
+ {"tx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[1])},
+ {"tx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[2])},
+ {"tx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[3])},
+ {"tx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[4])},
+ {"tx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[5])},
+ {"tx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[6])},
+ {"tx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_tx[7])},
+
+ /* priority_xoff_rx[8] */
+ {"rx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[0])},
+ {"rx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[1])},
+ {"rx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[2])},
+ {"rx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[3])},
+ {"rx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[4])},
+ {"rx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[5])},
+ {"rx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[6])},
+ {"rx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+ priority_xoff_rx[7])},
+
+ /* priority_xon_2_xoff[8] */
+ {"xx_q0_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[0])},
+ {"xx_q1_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[1])},
+ {"xx_q2_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[2])},
+ {"xx_q3_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[3])},
+ {"xx_q4_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[4])},
+ {"xx_q5_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[5])},
+ {"xx_q6_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[6])},
+ {"xx_q7_xon_to_xoff_priority_packets",
+ offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[7])},
+};
+
+#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
+ sizeof(rte_i40e_stats_strings[0]))
+#define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \
+ sizeof(rte_i40e_hw_port_strings[0]))
+#define I40E_NB_XSTATS (I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS)
+
static struct eth_driver rte_i40e_pmd = {
.pci_drv = {
.name = "rte_i40e_pmd",
@@ -1322,16 +1510,12 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi)
vsi->vsi_id);
}
-/* Get all statistics of a port */
static void
-i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
{
- uint32_t i;
- struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
- struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ unsigned int i;
struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
-
/* Get statistics of struct i40e_eth_stats */
i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
I40E_GLPRT_GORCL(hw->port),
@@ -1508,8 +1692,21 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
pf->offset_loaded = true;
- if (pf->main_vsi)
+ if(pf->main_vsi)
i40e_update_vsi_stats(pf->main_vsi);
+}
+
+/* Get all statistics of a port */
+static void
+i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
+ unsigned i;
+
+ /* call read registers - updates values, now write them to struct */
+ i40e_read_stats_registers(pf, hw);
stats->ipackets = ns->eth.rx_unicast + ns->eth.rx_multicast +
ns->eth.rx_broadcast;
@@ -1599,6 +1796,60 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
}
+static void
+i40e_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+ /* The hw registers are cleared on read */
+ pf->offset_loaded = false;
+ i40e_read_stats_registers(pf, hw);
+
+ /* reset software counters */
+ memset(hw_stats, 0, sizeof(*hw_stats));
+}
+
+static int
+i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+ unsigned n)
+{
+ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ unsigned i, count = 0;
+ struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+ if(n < I40E_NB_XSTATS)
+ return I40E_NB_XSTATS;
+
+ i40e_read_stats_registers(pf, hw);
+
+ /* Reset */
+ if(xstats == NULL)
+ return 0;
+
+ /* copy from i40e_eth_stats struct */
+ for(i = 0; i < I40E_NB_ETH_XSTATS; i++) {
+ snprintf(xstats[count].name, sizeof(xstats[count].name),
+ "%s", rte_i40e_stats_strings[i].name);
+ xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
+ rte_i40e_stats_strings[i].offset);
+ count++;
+ }
+
+ /* copy from i40e_hw_port struct */
+ for(i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
+ snprintf(xstats[count].name, sizeof(xstats[count].name),
+ "%s", rte_i40e_hw_port_strings[i].name);
+ xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+ rte_i40e_hw_port_strings[i].offset);
+ count++;
+ }
+
+ return I40E_NB_XSTATS;
+}
+
/* Reset the statistics */
static void
i40e_dev_stats_reset(struct rte_eth_dev *dev)