root/drivers/net/ethernet/pensando/ionic/ionic_stats.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ionic_get_lif_stats
  2. ionic_sw_stats_get_count
  3. ionic_sw_stats_get_strings
  4. ionic_sw_stats_get_values

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
   3 
   4 #include <linux/kernel.h>
   5 #include <linux/mutex.h>
   6 #include <linux/netdevice.h>
   7 
   8 #include "ionic.h"
   9 #include "ionic_lif.h"
  10 #include "ionic_stats.h"
  11 
  12 static const struct ionic_stat_desc ionic_lif_stats_desc[] = {
  13         IONIC_LIF_STAT_DESC(tx_packets),
  14         IONIC_LIF_STAT_DESC(tx_bytes),
  15         IONIC_LIF_STAT_DESC(rx_packets),
  16         IONIC_LIF_STAT_DESC(rx_bytes),
  17         IONIC_LIF_STAT_DESC(tx_tso),
  18         IONIC_LIF_STAT_DESC(tx_no_csum),
  19         IONIC_LIF_STAT_DESC(tx_csum),
  20         IONIC_LIF_STAT_DESC(rx_csum_none),
  21         IONIC_LIF_STAT_DESC(rx_csum_complete),
  22         IONIC_LIF_STAT_DESC(rx_csum_error),
  23 };
  24 
  25 static const struct ionic_stat_desc ionic_tx_stats_desc[] = {
  26         IONIC_TX_STAT_DESC(pkts),
  27         IONIC_TX_STAT_DESC(bytes),
  28         IONIC_TX_STAT_DESC(clean),
  29         IONIC_TX_STAT_DESC(dma_map_err),
  30         IONIC_TX_STAT_DESC(linearize),
  31         IONIC_TX_STAT_DESC(frags),
  32 };
  33 
  34 static const struct ionic_stat_desc ionic_rx_stats_desc[] = {
  35         IONIC_RX_STAT_DESC(pkts),
  36         IONIC_RX_STAT_DESC(bytes),
  37         IONIC_RX_STAT_DESC(dma_map_err),
  38         IONIC_RX_STAT_DESC(alloc_err),
  39         IONIC_RX_STAT_DESC(csum_none),
  40         IONIC_RX_STAT_DESC(csum_complete),
  41         IONIC_RX_STAT_DESC(csum_error),
  42 };
  43 
  44 static const struct ionic_stat_desc ionic_txq_stats_desc[] = {
  45         IONIC_TX_Q_STAT_DESC(stop),
  46         IONIC_TX_Q_STAT_DESC(wake),
  47         IONIC_TX_Q_STAT_DESC(drop),
  48         IONIC_TX_Q_STAT_DESC(dbell_count),
  49 };
  50 
  51 static const struct ionic_stat_desc ionic_dbg_cq_stats_desc[] = {
  52         IONIC_CQ_STAT_DESC(compl_count),
  53 };
  54 
  55 static const struct ionic_stat_desc ionic_dbg_intr_stats_desc[] = {
  56         IONIC_INTR_STAT_DESC(rearm_count),
  57 };
  58 
  59 static const struct ionic_stat_desc ionic_dbg_napi_stats_desc[] = {
  60         IONIC_NAPI_STAT_DESC(poll_count),
  61 };
  62 
  63 #define IONIC_NUM_LIF_STATS ARRAY_SIZE(ionic_lif_stats_desc)
  64 #define IONIC_NUM_TX_STATS ARRAY_SIZE(ionic_tx_stats_desc)
  65 #define IONIC_NUM_RX_STATS ARRAY_SIZE(ionic_rx_stats_desc)
  66 #define IONIC_NUM_TX_Q_STATS ARRAY_SIZE(ionic_txq_stats_desc)
  67 #define IONIC_NUM_DBG_CQ_STATS ARRAY_SIZE(ionic_dbg_cq_stats_desc)
  68 #define IONIC_NUM_DBG_INTR_STATS ARRAY_SIZE(ionic_dbg_intr_stats_desc)
  69 #define IONIC_NUM_DBG_NAPI_STATS ARRAY_SIZE(ionic_dbg_napi_stats_desc)
  70 
  71 #define MAX_Q(lif)   ((lif)->netdev->real_num_tx_queues)
  72 
  73 static void ionic_get_lif_stats(struct ionic_lif *lif,
  74                                 struct ionic_lif_sw_stats *stats)
  75 {
  76         struct ionic_tx_stats *tstats;
  77         struct ionic_rx_stats *rstats;
  78         struct ionic_qcq *txqcq;
  79         struct ionic_qcq *rxqcq;
  80         int q_num;
  81 
  82         memset(stats, 0, sizeof(*stats));
  83 
  84         for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
  85                 txqcq = lif_to_txqcq(lif, q_num);
  86                 if (txqcq && txqcq->stats) {
  87                         tstats = &txqcq->stats->tx;
  88                         stats->tx_packets += tstats->pkts;
  89                         stats->tx_bytes += tstats->bytes;
  90                         stats->tx_tso += tstats->tso;
  91                         stats->tx_no_csum += tstats->no_csum;
  92                         stats->tx_csum += tstats->csum;
  93                 }
  94 
  95                 rxqcq = lif_to_rxqcq(lif, q_num);
  96                 if (rxqcq && rxqcq->stats) {
  97                         rstats = &rxqcq->stats->rx;
  98                         stats->rx_packets += rstats->pkts;
  99                         stats->rx_bytes += rstats->bytes;
 100                         stats->rx_csum_none += rstats->csum_none;
 101                         stats->rx_csum_complete += rstats->csum_complete;
 102                         stats->rx_csum_error += rstats->csum_error;
 103                 }
 104         }
 105 }
 106 
 107 static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
 108 {
 109         u64 total = 0;
 110 
 111         /* lif stats */
 112         total += IONIC_NUM_LIF_STATS;
 113 
 114         /* tx stats */
 115         total += MAX_Q(lif) * IONIC_NUM_TX_STATS;
 116 
 117         /* rx stats */
 118         total += MAX_Q(lif) * IONIC_NUM_RX_STATS;
 119 
 120         if (test_bit(IONIC_LIF_UP, lif->state) &&
 121             test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
 122                 /* tx debug stats */
 123                 total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS +
 124                                       IONIC_NUM_TX_Q_STATS +
 125                                       IONIC_NUM_DBG_INTR_STATS +
 126                                       IONIC_MAX_NUM_SG_CNTR);
 127 
 128                 /* rx debug stats */
 129                 total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS +
 130                                       IONIC_NUM_DBG_INTR_STATS +
 131                                       IONIC_NUM_DBG_NAPI_STATS +
 132                                       IONIC_MAX_NUM_NAPI_CNTR);
 133         }
 134 
 135         return total;
 136 }
 137 
 138 static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf)
 139 {
 140         int i, q_num;
 141 
 142         for (i = 0; i < IONIC_NUM_LIF_STATS; i++) {
 143                 snprintf(*buf, ETH_GSTRING_LEN, ionic_lif_stats_desc[i].name);
 144                 *buf += ETH_GSTRING_LEN;
 145         }
 146         for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
 147                 for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
 148                         snprintf(*buf, ETH_GSTRING_LEN, "tx_%d_%s",
 149                                  q_num, ionic_tx_stats_desc[i].name);
 150                         *buf += ETH_GSTRING_LEN;
 151                 }
 152 
 153                 if (test_bit(IONIC_LIF_UP, lif->state) &&
 154                     test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
 155                         for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
 156                                 snprintf(*buf, ETH_GSTRING_LEN,
 157                                          "txq_%d_%s",
 158                                          q_num,
 159                                          ionic_txq_stats_desc[i].name);
 160                                 *buf += ETH_GSTRING_LEN;
 161                         }
 162                         for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
 163                                 snprintf(*buf, ETH_GSTRING_LEN,
 164                                          "txq_%d_cq_%s",
 165                                          q_num,
 166                                          ionic_dbg_cq_stats_desc[i].name);
 167                                 *buf += ETH_GSTRING_LEN;
 168                         }
 169                         for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
 170                                 snprintf(*buf, ETH_GSTRING_LEN,
 171                                          "txq_%d_intr_%s",
 172                                          q_num,
 173                                          ionic_dbg_intr_stats_desc[i].name);
 174                                 *buf += ETH_GSTRING_LEN;
 175                         }
 176                         for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) {
 177                                 snprintf(*buf, ETH_GSTRING_LEN,
 178                                          "txq_%d_sg_cntr_%d",
 179                                          q_num, i);
 180                                 *buf += ETH_GSTRING_LEN;
 181                         }
 182                 }
 183         }
 184         for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
 185                 for (i = 0; i < IONIC_NUM_RX_STATS; i++) {
 186                         snprintf(*buf, ETH_GSTRING_LEN,
 187                                  "rx_%d_%s",
 188                                  q_num, ionic_rx_stats_desc[i].name);
 189                         *buf += ETH_GSTRING_LEN;
 190                 }
 191 
 192                 if (test_bit(IONIC_LIF_UP, lif->state) &&
 193                     test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
 194                         for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
 195                                 snprintf(*buf, ETH_GSTRING_LEN,
 196                                          "rxq_%d_cq_%s",
 197                                          q_num,
 198                                          ionic_dbg_cq_stats_desc[i].name);
 199                                 *buf += ETH_GSTRING_LEN;
 200                         }
 201                         for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
 202                                 snprintf(*buf, ETH_GSTRING_LEN,
 203                                          "rxq_%d_intr_%s",
 204                                          q_num,
 205                                          ionic_dbg_intr_stats_desc[i].name);
 206                                 *buf += ETH_GSTRING_LEN;
 207                         }
 208                         for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
 209                                 snprintf(*buf, ETH_GSTRING_LEN,
 210                                          "rxq_%d_napi_%s",
 211                                          q_num,
 212                                          ionic_dbg_napi_stats_desc[i].name);
 213                                 *buf += ETH_GSTRING_LEN;
 214                         }
 215                         for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
 216                                 snprintf(*buf, ETH_GSTRING_LEN,
 217                                          "rxq_%d_napi_work_done_%d",
 218                                          q_num, i);
 219                                 *buf += ETH_GSTRING_LEN;
 220                         }
 221                 }
 222         }
 223 }
 224 
 225 static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf)
 226 {
 227         struct ionic_lif_sw_stats lif_stats;
 228         struct ionic_qcq *txqcq, *rxqcq;
 229         struct ionic_tx_stats *txstats;
 230         struct ionic_rx_stats *rxstats;
 231         int i, q_num;
 232 
 233         ionic_get_lif_stats(lif, &lif_stats);
 234 
 235         for (i = 0; i < IONIC_NUM_LIF_STATS; i++) {
 236                 **buf = IONIC_READ_STAT64(&lif_stats, &ionic_lif_stats_desc[i]);
 237                 (*buf)++;
 238         }
 239 
 240         for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
 241                 txstats = &lif_to_txstats(lif, q_num);
 242 
 243                 for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
 244                         **buf = IONIC_READ_STAT64(txstats,
 245                                                   &ionic_tx_stats_desc[i]);
 246                         (*buf)++;
 247                 }
 248 
 249                 if (test_bit(IONIC_LIF_UP, lif->state) &&
 250                     test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
 251                         txqcq = lif_to_txqcq(lif, q_num);
 252                         for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
 253                                 **buf = IONIC_READ_STAT64(&txqcq->q,
 254                                                       &ionic_txq_stats_desc[i]);
 255                                 (*buf)++;
 256                         }
 257                         for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
 258                                 **buf = IONIC_READ_STAT64(&txqcq->cq,
 259                                                    &ionic_dbg_cq_stats_desc[i]);
 260                                 (*buf)++;
 261                         }
 262                         for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
 263                                 **buf = IONIC_READ_STAT64(&txqcq->intr,
 264                                                  &ionic_dbg_intr_stats_desc[i]);
 265                                 (*buf)++;
 266                         }
 267                         for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) {
 268                                 **buf = txstats->sg_cntr[i];
 269                                 (*buf)++;
 270                         }
 271                 }
 272         }
 273 
 274         for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
 275                 rxstats = &lif_to_rxstats(lif, q_num);
 276 
 277                 for (i = 0; i < IONIC_NUM_RX_STATS; i++) {
 278                         **buf = IONIC_READ_STAT64(rxstats,
 279                                                   &ionic_rx_stats_desc[i]);
 280                         (*buf)++;
 281                 }
 282 
 283                 if (test_bit(IONIC_LIF_UP, lif->state) &&
 284                     test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
 285                         rxqcq = lif_to_rxqcq(lif, q_num);
 286                         for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
 287                                 **buf = IONIC_READ_STAT64(&rxqcq->cq,
 288                                                    &ionic_dbg_cq_stats_desc[i]);
 289                                 (*buf)++;
 290                         }
 291                         for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
 292                                 **buf = IONIC_READ_STAT64(&rxqcq->intr,
 293                                                  &ionic_dbg_intr_stats_desc[i]);
 294                                 (*buf)++;
 295                         }
 296                         for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
 297                                 **buf = IONIC_READ_STAT64(&rxqcq->napi_stats,
 298                                                  &ionic_dbg_napi_stats_desc[i]);
 299                                 (*buf)++;
 300                         }
 301                         for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
 302                                 **buf = rxqcq->napi_stats.work_done_cntr[i];
 303                                 (*buf)++;
 304                         }
 305                 }
 306         }
 307 }
 308 
 309 const struct ionic_stats_group_intf ionic_stats_groups[] = {
 310         /* SW Stats group */
 311         {
 312                 .get_strings = ionic_sw_stats_get_strings,
 313                 .get_values = ionic_sw_stats_get_values,
 314                 .get_count = ionic_sw_stats_get_count,
 315         },
 316         /* Add more stat groups here */
 317 };
 318 
 319 const int ionic_num_stats_grps = ARRAY_SIZE(ionic_stats_groups);

/* [<][>][^][v][top][bottom][index][help] */