numam-dpdk/drivers/net/bnxt/bnxt_stats.c
Stephen Hemminger 6aba4a036e net/bnxt: skip get statistics for stopped queues
An application using rte_flow may define a large number of queues
but only use a small subset of them at any one time.

Since querying the status of each queue requires a request/spin/reply
with the firmware, optimize by skipping the request for queues not
running.
For those queues the statistics will be 0.

This cuts the cost of single xstats query in half and has even
bigger gain for simple stats query.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
2021-04-24 20:53:45 +02:00

963 lines
31 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2014-2021 Broadcom
* All rights reserved.
*/
#include <inttypes.h>
#include <rte_string_fns.h>
#include <rte_byteorder.h>
#include "bnxt.h"
#include "bnxt_cpr.h"
#include "bnxt_filter.h"
#include "bnxt_hwrm.h"
#include "bnxt_rxq.h"
#include "bnxt_stats.h"
#include "bnxt_txq.h"
#include "bnxt_vnic.h"
#include "hsi_struct_def_dpdk.h"
static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
{"rx_64b_frames", offsetof(struct rx_port_stats,
rx_64b_frames)},
{"rx_65b_127b_frames", offsetof(struct rx_port_stats,
rx_65b_127b_frames)},
{"rx_128b_255b_frames", offsetof(struct rx_port_stats,
rx_128b_255b_frames)},
{"rx_256b_511b_frames", offsetof(struct rx_port_stats,
rx_256b_511b_frames)},
{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
rx_512b_1023b_frames)},
{"rx_1024b_1518b_frames", offsetof(struct rx_port_stats,
rx_1024b_1518b_frames)},
{"rx_good_vlan_frames", offsetof(struct rx_port_stats,
rx_good_vlan_frames)},
{"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
rx_1519b_2047b_frames)},
{"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
rx_2048b_4095b_frames)},
{"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
rx_4096b_9216b_frames)},
{"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
rx_9217b_16383b_frames)},
{"rx_total_frames", offsetof(struct rx_port_stats,
rx_total_frames)},
{"rx_ucast_frames", offsetof(struct rx_port_stats,
rx_ucast_frames)},
{"rx_mcast_frames", offsetof(struct rx_port_stats,
rx_mcast_frames)},
{"rx_bcast_frames", offsetof(struct rx_port_stats,
rx_bcast_frames)},
{"rx_fcs_err_frames", offsetof(struct rx_port_stats,
rx_fcs_err_frames)},
{"rx_ctrl_frames", offsetof(struct rx_port_stats,
rx_ctrl_frames)},
{"rx_pause_frames", offsetof(struct rx_port_stats,
rx_pause_frames)},
{"rx_pfc_frames", offsetof(struct rx_port_stats,
rx_pfc_frames)},
{"rx_unsupported_opcode_frames", offsetof(struct rx_port_stats,
rx_unsupported_opcode_frames)},
{"rx_unsupported_da_pausepfc_frames", offsetof(struct rx_port_stats,
rx_unsupported_da_pausepfc_frames)},
{"rx_wrong_sa_frames", offsetof(struct rx_port_stats,
rx_wrong_sa_frames)},
{"rx_align_err_frames", offsetof(struct rx_port_stats,
rx_align_err_frames)},
{"rx_oor_len_frames", offsetof(struct rx_port_stats,
rx_oor_len_frames)},
{"rx_code_err_frames", offsetof(struct rx_port_stats,
rx_code_err_frames)},
{"rx_false_carrier_frames", offsetof(struct rx_port_stats,
rx_false_carrier_frames)},
{"rx_ovrsz_frames", offsetof(struct rx_port_stats,
rx_ovrsz_frames)},
{"rx_jbr_frames", offsetof(struct rx_port_stats,
rx_jbr_frames)},
{"rx_mtu_err_frames", offsetof(struct rx_port_stats,
rx_mtu_err_frames)},
{"rx_match_crc_frames", offsetof(struct rx_port_stats,
rx_match_crc_frames)},
{"rx_promiscuous_frames", offsetof(struct rx_port_stats,
rx_promiscuous_frames)},
{"rx_tagged_frames", offsetof(struct rx_port_stats,
rx_tagged_frames)},
{"rx_double_tagged_frames", offsetof(struct rx_port_stats,
rx_double_tagged_frames)},
{"rx_trunc_frames", offsetof(struct rx_port_stats,
rx_trunc_frames)},
{"rx_good_frames", offsetof(struct rx_port_stats,
rx_good_frames)},
{"rx_sch_crc_err_frames", offsetof(struct rx_port_stats,
rx_sch_crc_err_frames)},
{"rx_undrsz_frames", offsetof(struct rx_port_stats,
rx_undrsz_frames)},
{"rx_frag_frames", offsetof(struct rx_port_stats,
rx_frag_frames)},
{"rx_eee_lpi_events", offsetof(struct rx_port_stats,
rx_eee_lpi_events)},
{"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
rx_eee_lpi_duration)},
{"rx_llfc_physical_msgs", offsetof(struct rx_port_stats,
rx_llfc_physical_msgs)},
{"rx_llfc_logical_msgs", offsetof(struct rx_port_stats,
rx_llfc_logical_msgs)},
{"rx_llfc_msgs_with_crc_err", offsetof(struct rx_port_stats,
rx_llfc_msgs_with_crc_err)},
{"rx_hcfc_msgs", offsetof(struct rx_port_stats,
rx_hcfc_msgs)},
{"rx_hcfc_msgs_with_crc_err", offsetof(struct rx_port_stats,
rx_hcfc_msgs_with_crc_err)},
{"rx_bytes", offsetof(struct rx_port_stats,
rx_bytes)},
{"rx_runt_bytes", offsetof(struct rx_port_stats,
rx_runt_bytes)},
{"rx_runt_frames", offsetof(struct rx_port_stats,
rx_runt_frames)},
{"rx_pfc_xon2xoff_frames_pri0", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri0)},
{"rx_pfc_xon2xoff_frames_pri1", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri1)},
{"rx_pfc_xon2xoff_frames_pri2", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri2)},
{"rx_pfc_xon2xoff_frames_pri3", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri3)},
{"rx_pfc_xon2xoff_frames_pri4", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri4)},
{"rx_pfc_xon2xoff_frames_pri5", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri5)},
{"rx_pfc_xon2xoff_frames_pri6", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri6)},
{"rx_pfc_xon2xoff_frames_pri7", offsetof(struct rx_port_stats,
rx_pfc_xon2xoff_frames_pri7)},
{"rx_pfc_ena_frames_pri0", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri0)},
{"rx_pfc_ena_frames_pri1", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri1)},
{"rx_pfc_ena_frames_pri2", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri2)},
{"rx_pfc_ena_frames_pri3", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri3)},
{"rx_pfc_ena_frames_pri4", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri4)},
{"rx_pfc_ena_frames_pri5", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri5)},
{"rx_pfc_ena_frames_pri6", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri6)},
{"rx_pfc_ena_frames_pri7", offsetof(struct rx_port_stats,
rx_pfc_ena_frames_pri7)},
{"rx_stat_discard", offsetof(struct rx_port_stats,
rx_stat_discard)},
{"rx_stat_err", offsetof(struct rx_port_stats,
rx_stat_err)},
};
static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
{"tx_64b_frames", offsetof(struct tx_port_stats,
tx_64b_frames)},
{"tx_65b_127b_frames", offsetof(struct tx_port_stats,
tx_65b_127b_frames)},
{"tx_128b_255b_frames", offsetof(struct tx_port_stats,
tx_128b_255b_frames)},
{"tx_256b_511b_frames", offsetof(struct tx_port_stats,
tx_256b_511b_frames)},
{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
tx_512b_1023b_frames)},
{"tx_1024b_1518b_frames", offsetof(struct tx_port_stats,
tx_1024b_1518b_frames)},
{"tx_good_vlan_frames", offsetof(struct tx_port_stats,
tx_good_vlan_frames)},
{"tx_1519b_2047b_frames", offsetof(struct tx_port_stats,
tx_1519b_2047b_frames)},
{"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
tx_2048b_4095b_frames)},
{"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
tx_4096b_9216b_frames)},
{"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
tx_9217b_16383b_frames)},
{"tx_good_frames", offsetof(struct tx_port_stats,
tx_good_frames)},
{"tx_total_frames", offsetof(struct tx_port_stats,
tx_total_frames)},
{"tx_ucast_frames", offsetof(struct tx_port_stats,
tx_ucast_frames)},
{"tx_mcast_frames", offsetof(struct tx_port_stats,
tx_mcast_frames)},
{"tx_bcast_frames", offsetof(struct tx_port_stats,
tx_bcast_frames)},
{"tx_pause_frames", offsetof(struct tx_port_stats,
tx_pause_frames)},
{"tx_pfc_frames", offsetof(struct tx_port_stats,
tx_pfc_frames)},
{"tx_jabber_frames", offsetof(struct tx_port_stats,
tx_jabber_frames)},
{"tx_fcs_err_frames", offsetof(struct tx_port_stats,
tx_fcs_err_frames)},
{"tx_control_frames", offsetof(struct tx_port_stats,
tx_control_frames)},
{"tx_oversz_frames", offsetof(struct tx_port_stats,
tx_oversz_frames)},
{"tx_single_dfrl_frames", offsetof(struct tx_port_stats,
tx_single_dfrl_frames)},
{"tx_multi_dfrl_frames", offsetof(struct tx_port_stats,
tx_multi_dfrl_frames)},
{"tx_single_coll_frames", offsetof(struct tx_port_stats,
tx_single_coll_frames)},
{"tx_multi_coll_frames", offsetof(struct tx_port_stats,
tx_multi_coll_frames)},
{"tx_late_coll_frames", offsetof(struct tx_port_stats,
tx_late_coll_frames)},
{"tx_excessive_coll_frames", offsetof(struct tx_port_stats,
tx_excessive_coll_frames)},
{"tx_frag_frames", offsetof(struct tx_port_stats,
tx_frag_frames)},
{"tx_err", offsetof(struct tx_port_stats,
tx_err)},
{"tx_tagged_frames", offsetof(struct tx_port_stats,
tx_tagged_frames)},
{"tx_dbl_tagged_frames", offsetof(struct tx_port_stats,
tx_dbl_tagged_frames)},
{"tx_runt_frames", offsetof(struct tx_port_stats,
tx_runt_frames)},
{"tx_fifo_underruns", offsetof(struct tx_port_stats,
tx_fifo_underruns)},
{"tx_eee_lpi_events", offsetof(struct tx_port_stats,
tx_eee_lpi_events)},
{"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
tx_eee_lpi_duration)},
{"tx_total_collisions", offsetof(struct tx_port_stats,
tx_total_collisions)},
{"tx_bytes", offsetof(struct tx_port_stats,
tx_bytes)},
{"tx_pfc_ena_frames_pri0", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri0)},
{"tx_pfc_ena_frames_pri1", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri1)},
{"tx_pfc_ena_frames_pri2", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri2)},
{"tx_pfc_ena_frames_pri3", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri3)},
{"tx_pfc_ena_frames_pri4", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri4)},
{"tx_pfc_ena_frames_pri5", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri5)},
{"tx_pfc_ena_frames_pri6", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri6)},
{"tx_pfc_ena_frames_pri7", offsetof(struct tx_port_stats,
tx_pfc_ena_frames_pri7)},
{"tx_llfc_logical_msgs", offsetof(struct tx_port_stats,
tx_llfc_logical_msgs)},
{"tx_hcfc_msgs", offsetof(struct tx_port_stats,
tx_hcfc_msgs)},
{"tx_xthol_frames", offsetof(struct tx_port_stats,
tx_xthol_frames)},
{"tx_stat_discard", offsetof(struct tx_port_stats,
tx_stat_discard)},
{"tx_stat_error", offsetof(struct tx_port_stats,
tx_stat_error)},
};
static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
tx_ucast_pkts)},
{"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
tx_mcast_pkts)},
{"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
tx_bcast_pkts)},
{"tx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
tx_discard_pkts)},
{"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
tx_drop_pkts)},
{"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
tx_ucast_bytes)},
{"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
tx_mcast_bytes)},
{"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
tx_bcast_bytes)},
{"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
rx_ucast_pkts)},
{"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
rx_mcast_pkts)},
{"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
rx_bcast_pkts)},
{"rx_discard_pkts", offsetof(struct hwrm_func_qstats_output,
rx_discard_pkts)},
{"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
rx_drop_pkts)},
{"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
rx_ucast_bytes)},
{"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
rx_mcast_bytes)},
{"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
rx_bcast_bytes)},
{"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
rx_agg_pkts)},
{"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
rx_agg_bytes)},
{"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
rx_agg_events)},
{"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
rx_agg_aborts)},
};
static const struct bnxt_xstats_name_off bnxt_rx_ext_stats_strings[] = {
{"link_down_events", offsetof(struct rx_port_stats_ext,
link_down_events)},
{"continuous_pause_events", offsetof(struct rx_port_stats_ext,
continuous_pause_events)},
{"resume_pause_events", offsetof(struct rx_port_stats_ext,
resume_pause_events)},
{"continuous_roce_pause_events", offsetof(struct rx_port_stats_ext,
continuous_roce_pause_events)},
{"resume_roce_pause_events", offsetof(struct rx_port_stats_ext,
resume_roce_pause_events)},
{"rx_bytes_cos0", offsetof(struct rx_port_stats_ext,
rx_bytes_cos0)},
{"rx_bytes_cos1", offsetof(struct rx_port_stats_ext,
rx_bytes_cos1)},
{"rx_bytes_cos2", offsetof(struct rx_port_stats_ext,
rx_bytes_cos2)},
{"rx_bytes_cos3", offsetof(struct rx_port_stats_ext,
rx_bytes_cos3)},
{"rx_bytes_cos4", offsetof(struct rx_port_stats_ext,
rx_bytes_cos4)},
{"rx_bytes_cos5", offsetof(struct rx_port_stats_ext,
rx_bytes_cos5)},
{"rx_bytes_cos6", offsetof(struct rx_port_stats_ext,
rx_bytes_cos6)},
{"rx_bytes_cos7", offsetof(struct rx_port_stats_ext,
rx_bytes_cos7)},
{"rx_packets_cos0", offsetof(struct rx_port_stats_ext,
rx_packets_cos0)},
{"rx_packets_cos1", offsetof(struct rx_port_stats_ext,
rx_packets_cos1)},
{"rx_packets_cos2", offsetof(struct rx_port_stats_ext,
rx_packets_cos2)},
{"rx_packets_cos3", offsetof(struct rx_port_stats_ext,
rx_packets_cos3)},
{"rx_packets_cos4", offsetof(struct rx_port_stats_ext,
rx_packets_cos4)},
{"rx_packets_cos5", offsetof(struct rx_port_stats_ext,
rx_packets_cos5)},
{"rx_packets_cos6", offsetof(struct rx_port_stats_ext,
rx_packets_cos6)},
{"rx_packets_cos7", offsetof(struct rx_port_stats_ext,
rx_packets_cos7)},
{"pfc_pri0_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri0_rx_duration_us)},
{"pfc_pri0_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri0_rx_transitions)},
{"pfc_pri1_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri1_rx_duration_us)},
{"pfc_pri1_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri1_rx_transitions)},
{"pfc_pri2_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri2_rx_duration_us)},
{"pfc_pri2_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri2_rx_transitions)},
{"pfc_pri3_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri3_rx_duration_us)},
{"pfc_pri3_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri3_rx_transitions)},
{"pfc_pri4_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri4_rx_duration_us)},
{"pfc_pri4_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri4_rx_transitions)},
{"pfc_pri5_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri5_rx_duration_us)},
{"pfc_pri5_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri5_rx_transitions)},
{"pfc_pri6_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri6_rx_duration_us)},
{"pfc_pri6_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri6_rx_transitions)},
{"pfc_pri7_rx_duration_us", offsetof(struct rx_port_stats_ext,
pfc_pri7_rx_duration_us)},
{"pfc_pri7_rx_transitions", offsetof(struct rx_port_stats_ext,
pfc_pri7_rx_transitions)},
{"rx_bits", offsetof(struct rx_port_stats_ext,
rx_bits)},
{"rx_buffer_passed_threshold", offsetof(struct rx_port_stats_ext,
rx_buffer_passed_threshold)},
{"rx_pcs_symbol_err", offsetof(struct rx_port_stats_ext,
rx_pcs_symbol_err)},
{"rx_corrected_bits", offsetof(struct rx_port_stats_ext,
rx_corrected_bits)},
{"rx_discard_bytes_cos0", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos0)},
{"rx_discard_bytes_cos1", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos1)},
{"rx_discard_bytes_cos2", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos2)},
{"rx_discard_bytes_cos3", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos3)},
{"rx_discard_bytes_cos4", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos4)},
{"rx_discard_bytes_cos5", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos5)},
{"rx_discard_bytes_cos6", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos6)},
{"rx_discard_bytes_cos7", offsetof(struct rx_port_stats_ext,
rx_discard_bytes_cos7)},
{"rx_discard_packets_cos0", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos0)},
{"rx_discard_packets_cos1", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos1)},
{"rx_discard_packets_cos2", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos2)},
{"rx_discard_packets_cos3", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos3)},
{"rx_discard_packets_cos4", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos4)},
{"rx_discard_packets_cos5", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos5)},
{"rx_discard_packets_cos6", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos6)},
{"rx_discard_packets_cos7", offsetof(struct rx_port_stats_ext,
rx_discard_packets_cos7)},
};
static const struct bnxt_xstats_name_off bnxt_tx_ext_stats_strings[] = {
{"tx_bytes_cos0", offsetof(struct tx_port_stats_ext,
tx_bytes_cos0)},
{"tx_bytes_cos1", offsetof(struct tx_port_stats_ext,
tx_bytes_cos1)},
{"tx_bytes_cos2", offsetof(struct tx_port_stats_ext,
tx_bytes_cos2)},
{"tx_bytes_cos3", offsetof(struct tx_port_stats_ext,
tx_bytes_cos3)},
{"tx_bytes_cos4", offsetof(struct tx_port_stats_ext,
tx_bytes_cos4)},
{"tx_bytes_cos5", offsetof(struct tx_port_stats_ext,
tx_bytes_cos5)},
{"tx_bytes_cos6", offsetof(struct tx_port_stats_ext,
tx_bytes_cos6)},
{"tx_bytes_cos7", offsetof(struct tx_port_stats_ext,
tx_bytes_cos7)},
{"tx_packets_cos0", offsetof(struct tx_port_stats_ext,
tx_packets_cos0)},
{"tx_packets_cos1", offsetof(struct tx_port_stats_ext,
tx_packets_cos1)},
{"tx_packets_cos2", offsetof(struct tx_port_stats_ext,
tx_packets_cos2)},
{"tx_packets_cos3", offsetof(struct tx_port_stats_ext,
tx_packets_cos3)},
{"tx_packets_cos4", offsetof(struct tx_port_stats_ext,
tx_packets_cos4)},
{"tx_packets_cos5", offsetof(struct tx_port_stats_ext,
tx_packets_cos5)},
{"tx_packets_cos6", offsetof(struct tx_port_stats_ext,
tx_packets_cos6)},
{"tx_packets_cos7", offsetof(struct tx_port_stats_ext,
tx_packets_cos7)},
{"pfc_pri0_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri0_tx_duration_us)},
{"pfc_pri0_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri0_tx_transitions)},
{"pfc_pri1_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri1_tx_duration_us)},
{"pfc_pri1_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri1_tx_transitions)},
{"pfc_pri2_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri2_tx_duration_us)},
{"pfc_pri2_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri2_tx_transitions)},
{"pfc_pri3_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri3_tx_duration_us)},
{"pfc_pri3_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri3_tx_transitions)},
{"pfc_pri4_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri4_tx_duration_us)},
{"pfc_pri4_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri4_tx_transitions)},
{"pfc_pri5_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri5_tx_duration_us)},
{"pfc_pri5_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri5_tx_transitions)},
{"pfc_pri6_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri6_tx_duration_us)},
{"pfc_pri6_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri6_tx_transitions)},
{"pfc_pri7_tx_duration_us", offsetof(struct tx_port_stats_ext,
pfc_pri7_tx_duration_us)},
{"pfc_pri7_tx_transitions", offsetof(struct tx_port_stats_ext,
pfc_pri7_tx_transitions)},
};
/*
* Statistics functions
*/
void bnxt_free_stats(struct bnxt *bp)
{
int i;
for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
struct bnxt_tx_queue *txq = bp->tx_queues[i];
bnxt_free_txq_stats(txq);
}
for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
struct bnxt_rx_queue *rxq = bp->rx_queues[i];
bnxt_free_rxq_stats(rxq);
}
}
int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
struct rte_eth_stats *bnxt_stats)
{
int rc = 0;
unsigned int i;
struct bnxt *bp = eth_dev->data->dev_private;
unsigned int num_q_stats;
rc = is_bnxt_in_error(bp);
if (rc)
return rc;
if (!eth_dev->data->dev_started)
return -EIO;
num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
(unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
for (i = 0; i < num_q_stats; i++) {
struct bnxt_rx_queue *rxq = bp->rx_queues[i];
struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
if (!rxq->rx_started)
continue;
rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
bnxt_stats, 1);
if (unlikely(rc))
return rc;
bnxt_stats->rx_nombuf +=
rte_atomic64_read(&rxq->rx_mbuf_alloc_fail);
}
num_q_stats = RTE_MIN(bp->tx_cp_nr_rings,
(unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
for (i = 0; i < num_q_stats; i++) {
struct bnxt_tx_queue *txq = bp->tx_queues[i];
struct bnxt_cp_ring_info *cpr = txq->cp_ring;
if (!txq->tx_started)
continue;
rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
bnxt_stats, 0);
if (unlikely(rc))
return rc;
}
rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats, NULL);
return rc;
}
int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
unsigned int i;
int ret;
ret = is_bnxt_in_error(bp);
if (ret)
return ret;
if (!eth_dev->data->dev_started) {
PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
return -EINVAL;
}
ret = bnxt_clear_all_hwrm_stat_ctxs(bp);
for (i = 0; i < bp->rx_cp_nr_rings; i++) {
struct bnxt_rx_queue *rxq = bp->rx_queues[i];
rte_atomic64_clear(&rxq->rx_mbuf_alloc_fail);
}
return ret;
}
int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
struct rte_eth_xstat *xstats, unsigned int n)
{
struct bnxt *bp = eth_dev->data->dev_private;
unsigned int count, i;
unsigned int rx_port_stats_ext_cnt;
unsigned int tx_port_stats_ext_cnt;
unsigned int stat_size = sizeof(uint64_t);
struct hwrm_func_qstats_output func_qstats = {0};
unsigned int stat_count;
int rc;
rc = is_bnxt_in_error(bp);
if (rc)
return rc;
stat_count = RTE_DIM(bnxt_rx_stats_strings) +
RTE_DIM(bnxt_tx_stats_strings) +
RTE_DIM(bnxt_func_stats_strings) +
RTE_DIM(bnxt_rx_ext_stats_strings) +
RTE_DIM(bnxt_tx_ext_stats_strings) +
bnxt_flow_stats_cnt(bp);
if (n < stat_count || xstats == NULL)
return stat_count;
bnxt_hwrm_func_qstats(bp, 0xffff, NULL, &func_qstats);
bnxt_hwrm_port_qstats(bp);
bnxt_hwrm_ext_port_qstats(bp);
rx_port_stats_ext_cnt = RTE_MIN(RTE_DIM(bnxt_rx_ext_stats_strings),
(bp->fw_rx_port_stats_ext_size /
stat_size));
tx_port_stats_ext_cnt = RTE_MIN(RTE_DIM(bnxt_tx_ext_stats_strings),
(bp->fw_tx_port_stats_ext_size /
stat_size));
memset(xstats, 0, sizeof(*xstats));
count = 0;
for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
xstats[count].id = count;
xstats[count].value = rte_le_to_cpu_64(
*(uint64_t *)((char *)rx_stats +
bnxt_rx_stats_strings[i].offset));
count++;
}
for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
xstats[count].id = count;
xstats[count].value = rte_le_to_cpu_64(
*(uint64_t *)((char *)tx_stats +
bnxt_tx_stats_strings[i].offset));
count++;
}
for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
xstats[count].id = count;
xstats[count].value =
rte_le_to_cpu_64(*(uint64_t *)((char *)&func_qstats +
bnxt_func_stats_strings[i].offset));
count++;
}
for (i = 0; i < rx_port_stats_ext_cnt; i++) {
uint64_t *rx_stats_ext = (uint64_t *)bp->hw_rx_port_stats_ext;
xstats[count].value = rte_le_to_cpu_64
(*(uint64_t *)((char *)rx_stats_ext +
bnxt_rx_ext_stats_strings[i].offset));
count++;
}
for (i = 0; i < tx_port_stats_ext_cnt; i++) {
uint64_t *tx_stats_ext = (uint64_t *)bp->hw_tx_port_stats_ext;
xstats[count].value = rte_le_to_cpu_64
(*(uint64_t *)((char *)tx_stats_ext +
bnxt_tx_ext_stats_strings[i].offset));
count++;
}
if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
BNXT_FLOW_XSTATS_EN(bp)) {
int j;
i = 0;
for (j = 0; j < bp->max_vnics; j++) {
struct bnxt_filter_info *filter;
struct bnxt_vnic_info *vnic;
struct rte_flow *flow;
vnic = &bp->vnic_info[j];
if (vnic && vnic->fw_vnic_id == INVALID_VNIC_ID)
continue;
if (STAILQ_EMPTY(&vnic->flow_list))
continue;
STAILQ_FOREACH(flow, &vnic->flow_list, next) {
if (!flow || !flow->filter)
continue;
filter = flow->filter;
xstats[count].id = count;
xstats[count].value =
filter->hw_stats.bytes;
count++;
xstats[count].id = count;
xstats[count].value =
filter->hw_stats.packets;
count++;
if (++i > bp->max_l2_ctx)
break;
}
if (i > bp->max_l2_ctx)
break;
}
}
return stat_count;
}
int bnxt_flow_stats_cnt(struct bnxt *bp)
{
if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
BNXT_FLOW_XSTATS_EN(bp)) {
struct bnxt_xstats_name_off flow_bytes[bp->max_l2_ctx];
struct bnxt_xstats_name_off flow_pkts[bp->max_l2_ctx];
return RTE_DIM(flow_bytes) + RTE_DIM(flow_pkts);
}
return 0;
}
int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev,
struct rte_eth_xstat_name *xstats_names,
__rte_unused unsigned int limit)
{
struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
RTE_DIM(bnxt_tx_stats_strings) +
RTE_DIM(bnxt_func_stats_strings) +
RTE_DIM(bnxt_rx_ext_stats_strings) +
RTE_DIM(bnxt_tx_ext_stats_strings) +
bnxt_flow_stats_cnt(bp);
unsigned int i, count = 0;
int rc;
rc = is_bnxt_in_error(bp);
if (rc)
return rc;
if (xstats_names != NULL) {
count = 0;
for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
strlcpy(xstats_names[count].name,
bnxt_rx_stats_strings[i].name,
sizeof(xstats_names[count].name));
count++;
}
for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
strlcpy(xstats_names[count].name,
bnxt_tx_stats_strings[i].name,
sizeof(xstats_names[count].name));
count++;
}
for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
strlcpy(xstats_names[count].name,
bnxt_func_stats_strings[i].name,
sizeof(xstats_names[count].name));
count++;
}
for (i = 0; i < RTE_DIM(bnxt_rx_ext_stats_strings); i++) {
strlcpy(xstats_names[count].name,
bnxt_rx_ext_stats_strings[i].name,
sizeof(xstats_names[count].name));
count++;
}
for (i = 0; i < RTE_DIM(bnxt_tx_ext_stats_strings); i++) {
strlcpy(xstats_names[count].name,
bnxt_tx_ext_stats_strings[i].name,
sizeof(xstats_names[count].name));
count++;
}
if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
BNXT_FLOW_XSTATS_EN(bp)) {
for (i = 0; i < bp->max_l2_ctx; i++) {
char buf[RTE_ETH_XSTATS_NAME_SIZE];
sprintf(buf, "flow_%d_bytes", i);
strlcpy(xstats_names[count].name, buf,
sizeof(xstats_names[count].name));
count++;
sprintf(buf, "flow_%d_packets", i);
strlcpy(xstats_names[count].name, buf,
sizeof(xstats_names[count].name));
count++;
}
}
}
return stat_cnt;
}
int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
int ret;
ret = is_bnxt_in_error(bp);
if (ret)
return ret;
if (BNXT_VF(bp) || !BNXT_SINGLE_PF(bp) ||
!(bp->flags & BNXT_FLAG_PORT_STATS)) {
PMD_DRV_LOG(ERR, "Operation not supported\n");
return -ENOTSUP;
}
ret = bnxt_hwrm_port_clr_stats(bp);
if (ret != 0)
PMD_DRV_LOG(ERR, "Failed to reset xstats: %s\n",
strerror(-ret));
return ret;
}
/* Update the input context memory with the flow counter IDs
* of the flows that we are interested in.
* Also, update the output tables with the current local values
* since that is what will be used by FW to accumulate
*/
static void bnxt_update_fc_pre_qstat(uint32_t *in_tbl,
uint64_t *out_tbl,
struct bnxt_filter_info *filter,
uint32_t *ptbl_cnt)
{
uint32_t in_tbl_cnt = *ptbl_cnt;
in_tbl[in_tbl_cnt] = filter->flow_id;
out_tbl[2 * in_tbl_cnt] = filter->hw_stats.packets;
out_tbl[2 * in_tbl_cnt + 1] = filter->hw_stats.bytes;
in_tbl_cnt++;
*ptbl_cnt = in_tbl_cnt;
}
/* Post issuing counter_qstats cmd, update the driver's local stat
* entries with the values DMA-ed by FW in the output table
*/
static void bnxt_update_fc_post_qstat(struct bnxt_filter_info *filter,
uint64_t *out_tbl,
uint32_t out_tbl_idx)
{
filter->hw_stats.packets = out_tbl[2 * out_tbl_idx];
filter->hw_stats.bytes = out_tbl[(2 * out_tbl_idx) + 1];
}
static int bnxt_update_fc_tbl(struct bnxt *bp, uint16_t ctr,
struct bnxt_filter_info *en_tbl[],
uint16_t in_flow_cnt)
{
uint32_t *in_rx_tbl;
uint64_t *out_rx_tbl;
uint32_t in_rx_tbl_cnt = 0;
uint32_t out_rx_tbl_cnt = 0;
int i, rc = 0;
in_rx_tbl = (uint32_t *)bp->flow_stat->rx_fc_in_tbl.va;
out_rx_tbl = (uint64_t *)bp->flow_stat->rx_fc_out_tbl.va;
for (i = 0; i < in_flow_cnt; i++) {
if (!en_tbl[i])
continue;
/* Currently only ingress/Rx flows are supported anyway. */
bnxt_update_fc_pre_qstat(in_rx_tbl, out_rx_tbl,
en_tbl[i], &in_rx_tbl_cnt);
}
/* Currently only ingress/Rx flows are supported */
if (in_rx_tbl_cnt) {
rc = bnxt_hwrm_cfa_counter_qstats(bp, BNXT_DIR_RX, ctr,
in_rx_tbl_cnt);
if (rc)
return rc;
}
for (i = 0; i < in_flow_cnt; i++) {
if (!en_tbl[i])
continue;
/* Currently only ingress/Rx flows are supported */
bnxt_update_fc_post_qstat(en_tbl[i], out_rx_tbl,
out_rx_tbl_cnt);
out_rx_tbl_cnt++;
}
return rc;
}
/* Walks through the list which has all the flows
* requesting for explicit flow counters.
*/
int bnxt_flow_stats_req(struct bnxt *bp)
{
int i;
int rc = 0;
struct rte_flow *flow;
uint16_t in_flow_tbl_cnt = 0;
struct bnxt_vnic_info *vnic = NULL;
struct bnxt_filter_info *valid_en_tbl[bp->flow_stat->max_fc];
uint16_t counter_type = CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC;
bnxt_acquire_flow_lock(bp);
for (i = 0; i < bp->max_vnics; i++) {
vnic = &bp->vnic_info[i];
if (vnic && vnic->fw_vnic_id == INVALID_VNIC_ID)
continue;
if (STAILQ_EMPTY(&vnic->flow_list))
continue;
STAILQ_FOREACH(flow, &vnic->flow_list, next) {
if (!flow || !flow->filter)
continue;
valid_en_tbl[in_flow_tbl_cnt++] = flow->filter;
if (in_flow_tbl_cnt >= bp->flow_stat->max_fc) {
rc = bnxt_update_fc_tbl(bp, counter_type,
valid_en_tbl,
in_flow_tbl_cnt);
if (rc)
goto err;
in_flow_tbl_cnt = 0;
continue;
}
}
}
if (!in_flow_tbl_cnt) {
bnxt_release_flow_lock(bp);
goto out;
}
rc = bnxt_update_fc_tbl(bp, counter_type, valid_en_tbl,
in_flow_tbl_cnt);
if (!rc) {
bnxt_release_flow_lock(bp);
return 0;
}
err:
/* If cmd fails once, no need of
* invoking again every second
*/
bnxt_release_flow_lock(bp);
bnxt_cancel_fc_thread(bp);
out:
return rc;
}