/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2014-2018 Broadcom
+ * 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_256b_511b_frames)},
{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
rx_512b_1023b_frames)},
- {"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
- rx_1024b_1518_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_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_256b_511b_frames)},
{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
tx_512b_1023b_frames)},
- {"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
- tx_1024b_1518_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_2047_frames", offsetof(struct tx_port_stats,
- tx_1519b_2047_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_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_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[] = {
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
*/
}
}
+static void bnxt_fill_rte_eth_stats(struct rte_eth_stats *stats,
+ struct bnxt_ring_stats *ring_stats,
+ unsigned int i, bool rx)
+{
+ if (rx) {
+ stats->q_ipackets[i] = ring_stats->rx_ucast_pkts;
+ stats->q_ipackets[i] += ring_stats->rx_mcast_pkts;
+ stats->q_ipackets[i] += ring_stats->rx_bcast_pkts;
+
+ stats->ipackets += stats->q_ipackets[i];
+
+ stats->q_ibytes[i] = ring_stats->rx_ucast_bytes;
+ stats->q_ibytes[i] += ring_stats->rx_mcast_bytes;
+ stats->q_ibytes[i] += ring_stats->rx_bcast_bytes;
+
+ stats->ibytes += stats->q_ibytes[i];
+
+ stats->q_errors[i] = ring_stats->rx_discard_pkts;
+ stats->q_errors[i] += ring_stats->rx_error_pkts;
+
+ stats->imissed += ring_stats->rx_discard_pkts;
+ stats->ierrors += ring_stats->rx_error_pkts;
+ } else {
+ stats->q_opackets[i] = ring_stats->tx_ucast_pkts;
+ stats->q_opackets[i] += ring_stats->tx_mcast_pkts;
+ stats->q_opackets[i] += ring_stats->tx_bcast_pkts;
+
+ stats->opackets += stats->q_opackets[i];
+
+ stats->q_obytes[i] = ring_stats->tx_ucast_bytes;
+ stats->q_obytes[i] += ring_stats->tx_mcast_bytes;
+ stats->q_obytes[i] += ring_stats->tx_bcast_bytes;
+
+ stats->obytes += stats->q_obytes[i];
+
+ stats->oerrors += ring_stats->tx_discard_pkts;
+ }
+}
+
int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
- struct rte_eth_stats *bnxt_stats)
+ 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;
- memset(bnxt_stats, 0, sizeof(*bnxt_stats));
- if (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
- PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
- return -1;
- }
+ rc = is_bnxt_in_error(bp);
+ if (rc)
+ return rc;
- for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ 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;
+ struct bnxt_ring_stats ring_stats = {0};
+
+ if (!rxq->rx_started)
+ continue;
- rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
- bnxt_stats, 1);
+ rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
+ &ring_stats, true);
if (unlikely(rc))
return rc;
+
+ bnxt_fill_rte_eth_stats(bnxt_stats, &ring_stats, i, true);
bnxt_stats->rx_nombuf +=
rte_atomic64_read(&rxq->rx_mbuf_alloc_fail);
}
- for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ 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;
+ struct bnxt_ring_stats ring_stats = {0};
- rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i,
- bnxt_stats, 0);
+ if (!txq->tx_started)
+ continue;
+
+ rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
+ &ring_stats, false);
if (unlikely(rc))
return rc;
+
+ bnxt_fill_rte_eth_stats(bnxt_stats, &ring_stats, i, false);
}
- rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
- if (unlikely(rc))
- return rc;
+
return rc;
}
-void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
+static void bnxt_clear_prev_stat(struct bnxt *bp)
{
- struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ /*
+ * Clear the cached values of stats returned by HW in the previous
+ * get operation.
+ */
+ memset(bp->prev_rx_ring_stats, 0, sizeof(struct bnxt_ring_stats) * bp->rx_cp_nr_rings);
+ memset(bp->prev_tx_ring_stats, 0, sizeof(struct bnxt_ring_stats) * bp->tx_cp_nr_rings);
+}
+
+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 (!(bp->flags & BNXT_FLAG_INIT_DONE)) {
+ if (!eth_dev->data->dev_started) {
PMD_DRV_LOG(ERR, "Device Initialization not complete!\n");
- return;
+ return -EINVAL;
}
- bnxt_clear_all_hwrm_stat_ctxs(bp);
+ 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);
}
+
+ bnxt_clear_prev_stat(bp);
+
+ return ret;
+}
+
+static void bnxt_fill_func_qstats(struct hwrm_func_qstats_output *func_qstats,
+ struct bnxt_ring_stats *ring_stats,
+ bool rx)
+{
+ if (rx) {
+ func_qstats->rx_ucast_pkts += ring_stats->rx_ucast_pkts;
+ func_qstats->rx_mcast_pkts += ring_stats->rx_mcast_pkts;
+ func_qstats->rx_bcast_pkts += ring_stats->rx_bcast_pkts;
+
+ func_qstats->rx_ucast_bytes += ring_stats->rx_ucast_bytes;
+ func_qstats->rx_mcast_bytes += ring_stats->rx_mcast_bytes;
+ func_qstats->rx_bcast_bytes += ring_stats->rx_bcast_bytes;
+
+ func_qstats->rx_discard_pkts += ring_stats->rx_discard_pkts;
+ func_qstats->rx_drop_pkts += ring_stats->rx_error_pkts;
+
+ func_qstats->rx_agg_pkts += ring_stats->rx_agg_pkts;
+ func_qstats->rx_agg_bytes += ring_stats->rx_agg_bytes;
+ func_qstats->rx_agg_events += ring_stats->rx_agg_events;
+ func_qstats->rx_agg_aborts += ring_stats->rx_agg_aborts;
+ } else {
+ func_qstats->tx_ucast_pkts += ring_stats->tx_ucast_pkts;
+ func_qstats->tx_mcast_pkts += ring_stats->tx_mcast_pkts;
+ func_qstats->tx_bcast_pkts += ring_stats->tx_bcast_pkts;
+
+ func_qstats->tx_ucast_bytes += ring_stats->tx_ucast_bytes;
+ func_qstats->tx_mcast_bytes += ring_stats->tx_mcast_bytes;
+ func_qstats->tx_bcast_bytes += ring_stats->tx_bcast_bytes;
+
+ func_qstats->tx_drop_pkts += ring_stats->tx_error_pkts;
+ func_qstats->tx_discard_pkts += ring_stats->tx_discard_pkts;
+ }
}
int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
struct rte_eth_xstat *xstats, unsigned int n)
{
- struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-
+ struct bnxt *bp = eth_dev->data->dev_private;
unsigned int count, i;
- uint64_t tx_drop_pkts;
+ 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;
- bnxt_hwrm_port_qstats(bp);
- bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
+ 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);
- count = RTE_DIM(bnxt_rx_stats_strings) +
- RTE_DIM(bnxt_tx_stats_strings) + 1; /* For tx_drop_pkts */
+ if (n < stat_count || xstats == NULL)
+ return stat_count;
- if (n < count)
- return count;
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+ struct bnxt_ring_stats ring_stats = {0};
+
+ if (!rxq->rx_started)
+ continue;
+
+ rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
+ &ring_stats, true);
+ if (unlikely(rc))
+ return rc;
+
+ bnxt_fill_func_qstats(&func_qstats, &ring_stats, true);
+ }
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+ struct bnxt_ring_stats ring_stats = {0};
+
+ if (!txq->tx_started)
+ continue;
+
+ rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
+ &ring_stats, false);
+ if (unlikely(rc))
+ return rc;
+
+ bnxt_fill_func_qstats(&func_qstats, &ring_stats, false);
+ }
+
+ 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) * n);
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));
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++;
}
- /* The Tx drop pkts aka the Anti spoof coounter */
- xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
- count++;
+ for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
+ xstats[count].id = count;
+ xstats[count].value = *(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 count;
+ return 0;
}
-int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
- struct rte_eth_xstat_name *xstats_names,
- __rte_unused unsigned int limit)
+int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int size)
{
- /* Account for the Tx drop pkts aka the Anti spoof counter */
+ 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) + 1;
- unsigned int i, count;
+ 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 || size < stat_cnt)
+ return stat_cnt;
+
+ 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 (xstats_names != NULL) {
- count = 0;
+ 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];
- for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
- snprintf(xstats_names[count].name,
- sizeof(xstats_names[count].name),
- "%s",
- bnxt_rx_stats_strings[i].name);
+ sprintf(buf, "flow_%d_bytes", i);
+ strlcpy(xstats_names[count].name, buf,
+ sizeof(xstats_names[count].name));
count++;
- }
- for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
- snprintf(xstats_names[count].name,
- sizeof(xstats_names[count].name),
- "%s",
- bnxt_tx_stats_strings[i].name);
+ sprintf(buf, "flow_%d_packets", i);
+ strlcpy(xstats_names[count].name, buf,
+ sizeof(xstats_names[count].name));
+
count++;
}
-
- snprintf(xstats_names[count].name,
- sizeof(xstats_names[count].name),
- "%s",
- bnxt_func_stats_strings[4].name);
- count++;
}
+
return stat_cnt;
}
-void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
+int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
{
- struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt *bp = eth_dev->data->dev_private;
+ int ret;
- if (bp->flags & BNXT_FLAG_PORT_STATS && BNXT_SINGLE_PF(bp))
- bnxt_hwrm_port_clr_stats(bp);
+ ret = is_bnxt_in_error(bp);
+ if (ret)
+ return ret;
- if (BNXT_VF(bp))
- PMD_DRV_LOG(ERR, "Operation not supported on a VF device\n");
- if (!BNXT_SINGLE_PF(bp))
- PMD_DRV_LOG(ERR, "Operation not supported on a MF device\n");
- if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+ 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));
+
+ bnxt_clear_prev_stat(bp);
+
+ return ret;
}
-int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids,
- uint64_t *values, unsigned int limit)
+/* 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)
{
- /* Account for the Tx drop pkts aka the Anti spoof counter */
- const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
- RTE_DIM(bnxt_tx_stats_strings) + 1;
- struct rte_eth_xstat xstats[stat_cnt];
- uint64_t values_copy[stat_cnt];
- uint16_t i;
-
- if (!ids)
- return bnxt_dev_xstats_get_op(dev, xstats, stat_cnt);
-
- bnxt_dev_xstats_get_by_id_op(dev, NULL, values_copy, stat_cnt);
- for (i = 0; i < limit; i++) {
- if (ids[i] >= stat_cnt) {
- PMD_DRV_LOG(ERR, "id value isn't valid");
- return -1;
- }
- values[i] = values_copy[ids[i]];
+ 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);
}
- return stat_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;
}
-int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev,
- struct rte_eth_xstat_name *xstats_names,
- const uint64_t *ids, unsigned int limit)
+/* Walks through the list which has all the flows
+ * requesting for explicit flow counters.
+ */
+int bnxt_flow_stats_req(struct bnxt *bp)
{
- /* Account for the Tx drop pkts aka the Anti spoof counter */
- const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
- RTE_DIM(bnxt_tx_stats_strings) + 1;
- struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
- uint16_t i;
-
- if (!ids)
- return bnxt_dev_xstats_get_names_op(dev, xstats_names,
- stat_cnt);
- bnxt_dev_xstats_get_names_by_id_op(dev, xstats_names_copy, NULL,
- stat_cnt);
-
- for (i = 0; i < limit; i++) {
- if (ids[i] >= stat_cnt) {
- PMD_DRV_LOG(ERR, "id value isn't valid");
- return -1;
+ 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;
+ }
}
- strcpy(xstats_names[i].name,
- xstats_names_copy[ids[i]].name);
}
- return stat_cnt;
+
+ 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;
}