1139823Simp// SPDX-License-Identifier: GPL-2.0 21541Srgrimes/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ 3185791Srwatson 4222213Srwatson#include <linux/ethtool.h> 5185791Srwatson#include <linux/kernel.h> 61541Srgrimes#include <linux/mutex.h> 7222213Srwatson#include <linux/netdevice.h> 8222213Srwatson 9222213Srwatson#include "ionic.h" 101541Srgrimes#include "ionic_lif.h" 111541Srgrimes#include "ionic_stats.h" 121541Srgrimes 131541Srgrimesstatic const struct ionic_stat_desc ionic_lif_stats_desc[] = { 141541Srgrimes IONIC_LIF_STAT_DESC(tx_packets), 151541Srgrimes IONIC_LIF_STAT_DESC(tx_bytes), 161541Srgrimes IONIC_LIF_STAT_DESC(rx_packets), 171541Srgrimes IONIC_LIF_STAT_DESC(rx_bytes), 181541Srgrimes IONIC_LIF_STAT_DESC(tx_tso), 191541Srgrimes IONIC_LIF_STAT_DESC(tx_tso_bytes), 201541Srgrimes IONIC_LIF_STAT_DESC(tx_csum_none), 211541Srgrimes IONIC_LIF_STAT_DESC(tx_csum), 221541Srgrimes IONIC_LIF_STAT_DESC(rx_csum_none), 231541Srgrimes IONIC_LIF_STAT_DESC(rx_csum_complete), 241541Srgrimes IONIC_LIF_STAT_DESC(rx_csum_error), 251541Srgrimes IONIC_LIF_STAT_DESC(hw_tx_dropped), 261541Srgrimes IONIC_LIF_STAT_DESC(hw_rx_dropped), 271541Srgrimes IONIC_LIF_STAT_DESC(hw_rx_over_errors), 281541Srgrimes IONIC_LIF_STAT_DESC(hw_rx_missed_errors), 291541Srgrimes IONIC_LIF_STAT_DESC(hw_tx_aborted_errors), 301541Srgrimes IONIC_LIF_STAT_DESC(xdp_drop), 311541Srgrimes IONIC_LIF_STAT_DESC(xdp_aborted), 321541Srgrimes IONIC_LIF_STAT_DESC(xdp_pass), 331541Srgrimes IONIC_LIF_STAT_DESC(xdp_tx), 341541Srgrimes IONIC_LIF_STAT_DESC(xdp_redirect), 3550477Speter IONIC_LIF_STAT_DESC(xdp_frames), 361541Srgrimes}; 371541Srgrimes 382169Spaulstatic const struct ionic_stat_desc ionic_port_stats_desc[] = { 392169Spaul IONIC_PORT_STAT_DESC(frames_rx_ok), 402169Spaul IONIC_PORT_STAT_DESC(frames_rx_all), 4112644Sbde IONIC_PORT_STAT_DESC(frames_rx_bad_fcs), 42102981Sbde IONIC_PORT_STAT_DESC(frames_rx_bad_all), 43102981Sbde IONIC_PORT_STAT_DESC(octets_rx_ok), 44178285Srwatson IONIC_PORT_STAT_DESC(octets_rx_all), 45297225Sgnn IONIC_PORT_STAT_DESC(frames_rx_unicast), 4612644Sbde IONIC_PORT_STAT_DESC(frames_rx_multicast), 47178285Srwatson IONIC_PORT_STAT_DESC(frames_rx_broadcast), 48222787Sbz IONIC_PORT_STAT_DESC(frames_rx_pause), 49178285Srwatson IONIC_PORT_STAT_DESC(frames_rx_bad_length), 50195699Srwatson IONIC_PORT_STAT_DESC(frames_rx_undersized), 51205157Srwatson IONIC_PORT_STAT_DESC(frames_rx_oversized), 52178285Srwatson IONIC_PORT_STAT_DESC(frames_rx_fragments), 53178285Srwatson IONIC_PORT_STAT_DESC(frames_rx_jabber), 5453541Sshin IONIC_PORT_STAT_DESC(frames_rx_pripause), 5553541Sshin IONIC_PORT_STAT_DESC(frames_rx_stomped_crc), 56105199Ssam IONIC_PORT_STAT_DESC(frames_rx_too_long), 5753541Sshin IONIC_PORT_STAT_DESC(frames_rx_vlan_good), 581541Srgrimes IONIC_PORT_STAT_DESC(frames_rx_dropped), 59183460Srwatson IONIC_PORT_STAT_DESC(frames_rx_less_than_64b), 60183460Srwatson IONIC_PORT_STAT_DESC(frames_rx_64b), 61169154Srwatson IONIC_PORT_STAT_DESC(frames_rx_65b_127b), 62169154Srwatson IONIC_PORT_STAT_DESC(frames_rx_128b_255b), 63169154Srwatson IONIC_PORT_STAT_DESC(frames_rx_256b_511b), 64169154Srwatson IONIC_PORT_STAT_DESC(frames_rx_512b_1023b), 651541Srgrimes IONIC_PORT_STAT_DESC(frames_rx_1024b_1518b), 6660938Sjake IONIC_PORT_STAT_DESC(frames_rx_1519b_2047b), 6760938Sjake IONIC_PORT_STAT_DESC(frames_rx_2048b_4095b), 6836079Swollman IONIC_PORT_STAT_DESC(frames_rx_4096b_8191b), 697684Sdg IONIC_PORT_STAT_DESC(frames_rx_8192b_9215b), 7034881Swollman IONIC_PORT_STAT_DESC(frames_rx_other), 7153541Sshin IONIC_PORT_STAT_DESC(frames_tx_ok), 72169154Srwatson IONIC_PORT_STAT_DESC(frames_tx_all), 73169154Srwatson IONIC_PORT_STAT_DESC(frames_tx_bad), 7453541Sshin IONIC_PORT_STAT_DESC(octets_tx_ok), 7553541Sshin IONIC_PORT_STAT_DESC(octets_tx_total), 7653541Sshin IONIC_PORT_STAT_DESC(frames_tx_unicast), 7753541Sshin IONIC_PORT_STAT_DESC(frames_tx_multicast), 7853541Sshin IONIC_PORT_STAT_DESC(frames_tx_broadcast), 7953541Sshin IONIC_PORT_STAT_DESC(frames_tx_pause), 8053541Sshin IONIC_PORT_STAT_DESC(frames_tx_pripause), 81169154Srwatson IONIC_PORT_STAT_DESC(frames_tx_vlan), 82169154Srwatson IONIC_PORT_STAT_DESC(frames_tx_less_than_64b), 83287481Sglebius IONIC_PORT_STAT_DESC(frames_tx_64b), 84287481Sglebius IONIC_PORT_STAT_DESC(frames_tx_65b_127b), 8586764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_128b_255b), 8686764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_256b_511b), 8786764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_512b_1023b), 8886764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_1024b_1518b), 8986764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_1519b_2047b), 9086764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_2048b_4095b), 9186764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_4096b_8191b), 9286764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_8192b_9215b), 9386764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_other), 9486764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_pri_0), 9586764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_pri_1), 9686764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_pri_2), 9786764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_pri_3), 9886764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_pri_4), 9986764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_pri_5), 100271400Sae IONIC_PORT_STAT_DESC(frames_tx_pri_6), 101185791Srwatson IONIC_PORT_STAT_DESC(frames_tx_pri_7), 10286764Sjlemon IONIC_PORT_STAT_DESC(frames_rx_pri_0), 10386764Sjlemon IONIC_PORT_STAT_DESC(frames_rx_pri_1), 10486764Sjlemon IONIC_PORT_STAT_DESC(frames_rx_pri_2), 10586764Sjlemon IONIC_PORT_STAT_DESC(frames_rx_pri_3), 10686764Sjlemon IONIC_PORT_STAT_DESC(frames_rx_pri_4), 10786764Sjlemon IONIC_PORT_STAT_DESC(frames_rx_pri_5), 108169154Srwatson IONIC_PORT_STAT_DESC(frames_rx_pri_6), 109169154Srwatson IONIC_PORT_STAT_DESC(frames_rx_pri_7), 11086764Sjlemon IONIC_PORT_STAT_DESC(tx_pripause_0_1us_count), 11186764Sjlemon IONIC_PORT_STAT_DESC(tx_pripause_1_1us_count), 11286764Sjlemon IONIC_PORT_STAT_DESC(tx_pripause_2_1us_count), 11386764Sjlemon IONIC_PORT_STAT_DESC(tx_pripause_3_1us_count), 114178888Sjulian IONIC_PORT_STAT_DESC(tx_pripause_4_1us_count), 115122922Sandre IONIC_PORT_STAT_DESC(tx_pripause_5_1us_count), 11686764Sjlemon IONIC_PORT_STAT_DESC(tx_pripause_6_1us_count), 11786764Sjlemon IONIC_PORT_STAT_DESC(tx_pripause_7_1us_count), 118186222Sbz IONIC_PORT_STAT_DESC(rx_pripause_0_1us_count), 119186222Sbz IONIC_PORT_STAT_DESC(rx_pripause_1_1us_count), 120186222Sbz IONIC_PORT_STAT_DESC(rx_pripause_2_1us_count), 121186222Sbz IONIC_PORT_STAT_DESC(rx_pripause_3_1us_count), 122186222Sbz IONIC_PORT_STAT_DESC(rx_pripause_4_1us_count), 123343432Stuexen IONIC_PORT_STAT_DESC(rx_pripause_5_1us_count), 124186222Sbz IONIC_PORT_STAT_DESC(rx_pripause_6_1us_count), 125298995Spfg IONIC_PORT_STAT_DESC(rx_pripause_7_1us_count), 12686764Sjlemon IONIC_PORT_STAT_DESC(rx_pause_1us_count), 12786764Sjlemon IONIC_PORT_STAT_DESC(frames_tx_truncated), 12886764Sjlemon}; 12986764Sjlemon 13086764Sjlemonstatic const struct ionic_stat_desc ionic_tx_stats_desc[] = { 13186764Sjlemon IONIC_TX_STAT_DESC(pkts), 132271400Sae IONIC_TX_STAT_DESC(bytes), 13386764Sjlemon IONIC_TX_STAT_DESC(clean), 13453541Sshin IONIC_TX_STAT_DESC(dma_map_err), 13553541Sshin IONIC_TX_STAT_DESC(linearize), 136180368Srwatson IONIC_TX_STAT_DESC(frags), 137286227Sjch IONIC_TX_STAT_DESC(tso), 138286227Sjch IONIC_TX_STAT_DESC(tso_bytes), 139180368Srwatson IONIC_TX_STAT_DESC(hwstamp_valid), 140180368Srwatson IONIC_TX_STAT_DESC(hwstamp_invalid), 141286227Sjch IONIC_TX_STAT_DESC(csum_none), 142286227Sjch IONIC_TX_STAT_DESC(csum), 143286227Sjch IONIC_TX_STAT_DESC(vlan_inserted), 144286227Sjch IONIC_TX_STAT_DESC(xdp_frames), 145286227Sjch}; 146286227Sjch 147286227Sjchstatic const struct ionic_stat_desc ionic_rx_stats_desc[] = { 148286227Sjch IONIC_RX_STAT_DESC(pkts), 149180368Srwatson IONIC_RX_STAT_DESC(bytes), 150286227Sjch IONIC_RX_STAT_DESC(dma_map_err), 151286227Sjch IONIC_RX_STAT_DESC(alloc_err), 152286227Sjch IONIC_RX_STAT_DESC(csum_none), 153286227Sjch IONIC_RX_STAT_DESC(csum_complete), 154286227Sjch IONIC_RX_STAT_DESC(csum_error), 155286227Sjch IONIC_RX_STAT_DESC(hwstamp_valid), 156286227Sjch IONIC_RX_STAT_DESC(hwstamp_invalid), 157286227Sjch IONIC_RX_STAT_DESC(dropped), 158286227Sjch IONIC_RX_STAT_DESC(vlan_stripped), 159180368Srwatson IONIC_RX_STAT_DESC(xdp_drop), 160180368Srwatson IONIC_RX_STAT_DESC(xdp_aborted), 161222748Srwatson IONIC_RX_STAT_DESC(xdp_pass), 162180368Srwatson IONIC_RX_STAT_DESC(xdp_tx), 163180368Srwatson IONIC_RX_STAT_DESC(xdp_redirect), 164286227Sjch}; 165286227Sjch 166180368Srwatson#define IONIC_NUM_LIF_STATS ARRAY_SIZE(ionic_lif_stats_desc) 167180368Srwatson#define IONIC_NUM_PORT_STATS ARRAY_SIZE(ionic_port_stats_desc) 168180368Srwatson#define IONIC_NUM_TX_STATS ARRAY_SIZE(ionic_tx_stats_desc) 169180368Srwatson#define IONIC_NUM_RX_STATS ARRAY_SIZE(ionic_rx_stats_desc) 170180368Srwatson 171180368Srwatson#define MAX_Q(lif) ((lif)->netdev->real_num_tx_queues) 172180368Srwatson 173180368Srwatsonstatic void ionic_add_lif_txq_stats(struct ionic_lif *lif, int q_num, 174180368Srwatson struct ionic_lif_sw_stats *stats) 175180368Srwatson{ 176180368Srwatson struct ionic_tx_stats *txstats = &lif->txqstats[q_num]; 177180368Srwatson 178180368Srwatson stats->tx_packets += txstats->pkts; 179180368Srwatson stats->tx_bytes += txstats->bytes; 180286227Sjch stats->tx_tso += txstats->tso; 181286227Sjch stats->tx_tso_bytes += txstats->tso_bytes; 182286227Sjch stats->tx_csum_none += txstats->csum_none; 183286227Sjch stats->tx_csum += txstats->csum; 184180368Srwatson stats->tx_hwstamp_valid += txstats->hwstamp_valid; 1851541Srgrimes stats->tx_hwstamp_invalid += txstats->hwstamp_invalid; 186286227Sjch stats->xdp_frames += txstats->xdp_frames; 187222748Srwatson} 188286227Sjch 189286227Sjchstatic void ionic_add_lif_rxq_stats(struct ionic_lif *lif, int q_num, 190286227Sjch struct ionic_lif_sw_stats *stats) 191180368Srwatson{ 192180368Srwatson struct ionic_rx_stats *rxstats = &lif->rxqstats[q_num]; 193222748Srwatson 194286227Sjch stats->rx_packets += rxstats->pkts; 195185791Srwatson stats->rx_bytes += rxstats->bytes; 196183606Sbz stats->rx_csum_none += rxstats->csum_none; 197185791Srwatson stats->rx_csum_complete += rxstats->csum_complete; 198180368Srwatson stats->rx_csum_error += rxstats->csum_error; 199191126Skmacy stats->rx_hwstamp_valid += rxstats->hwstamp_valid; 200180368Srwatson stats->rx_hwstamp_invalid += rxstats->hwstamp_invalid; 201180368Srwatson stats->xdp_drop += rxstats->xdp_drop; 202180368Srwatson stats->xdp_aborted += rxstats->xdp_aborted; 203180368Srwatson stats->xdp_pass += rxstats->xdp_pass; 204190880Skmacy stats->xdp_tx += rxstats->xdp_tx; 205185773Srwatson stats->xdp_redirect += rxstats->xdp_redirect; 206302153Snp} 207266418Sadrian 208268479Sadrianstatic void ionic_get_lif_stats(struct ionic_lif *lif, 209302153Snp struct ionic_lif_sw_stats *stats) 210224151Sbz{ 21153541Sshin struct rtnl_link_stats64 ns; 212174388Skmacy int q_num; 213286227Sjch 214174388Skmacy memset(stats, 0, sizeof(*stats)); 215185791Srwatson 216180368Srwatson for (q_num = 0; q_num < MAX_Q(lif); q_num++) { 217180368Srwatson ionic_add_lif_txq_stats(lif, q_num, stats); 218174388Skmacy ionic_add_lif_rxq_stats(lif, q_num, stats); 219169154Srwatson } 22053541Sshin 221180368Srwatson if (lif->hwstamp_txq) 222180368Srwatson ionic_add_lif_txq_stats(lif, lif->hwstamp_txq->q.index, stats); 223185791Srwatson 22453541Sshin if (lif->hwstamp_rxq) 22553541Sshin ionic_add_lif_rxq_stats(lif, lif->hwstamp_rxq->q.index, stats); 226180368Srwatson 22753541Sshin ionic_get_stats64(lif->netdev, &ns); 228180368Srwatson stats->hw_tx_dropped = ns.tx_dropped; 22953541Sshin stats->hw_rx_dropped = ns.rx_dropped; 230180368Srwatson stats->hw_rx_over_errors = ns.rx_over_errors; 23153541Sshin stats->hw_rx_missed_errors = ns.rx_missed_errors; 232180368Srwatson stats->hw_tx_aborted_errors = ns.tx_aborted_errors; 23353541Sshin} 234180368Srwatson 23553541Sshinstatic u64 ionic_sw_stats_get_count(struct ionic_lif *lif) 23653541Sshin{ 23753541Sshin u64 total = 0, tx_queues = MAX_Q(lif), rx_queues = MAX_Q(lif); 238286227Sjch 239286227Sjch if (lif->hwstamp_txq) 240160491Sups tx_queues += 1; 241185791Srwatson 242191158Skmacy if (lif->hwstamp_rxq) 243178285Srwatson rx_queues += 1; 244297225Sgnn 245297225Sgnn total += IONIC_NUM_LIF_STATS; 246297225Sgnn total += IONIC_NUM_PORT_STATS; 247297225Sgnn 248297225Sgnn total += tx_queues * IONIC_NUM_TX_STATS; 249297225Sgnn total += rx_queues * IONIC_NUM_RX_STATS; 250297225Sgnn 251185791Srwatson return total; 252185791Srwatson} 253185791Srwatson 254185791Srwatsonstatic void ionic_sw_stats_get_tx_strings(struct ionic_lif *lif, u8 **buf, 255185791Srwatson int q_num) 256185791Srwatson{ 257185791Srwatson int i; 258185791Srwatson 25998102Shsu for (i = 0; i < IONIC_NUM_TX_STATS; i++) 26086764Sjlemon ethtool_sprintf(buf, "tx_%d_%s", q_num, 26186764Sjlemon ionic_tx_stats_desc[i].name); 262271400Sae} 26353541Sshin 26453541Sshinstatic void ionic_sw_stats_get_rx_strings(struct ionic_lif *lif, u8 **buf, 26553541Sshin int q_num) 26653541Sshin{ 26753541Sshin int i; 26853541Sshin 26953541Sshin for (i = 0; i < IONIC_NUM_RX_STATS; i++) 270185791Srwatson ethtool_sprintf(buf, "rx_%d_%s", q_num, 271191688Szec ionic_rx_stats_desc[i].name); 272191688Szec} 27334881Swollman 274169154Srwatsonstatic void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf) 275169154Srwatson{ 276169154Srwatson int i, q_num; 277169154Srwatson 27834881Swollman for (i = 0; i < IONIC_NUM_LIF_STATS; i++) 2791541Srgrimes ethtool_puts(buf, ionic_lif_stats_desc[i].name); 28036079Swollman 281169154Srwatson for (i = 0; i < IONIC_NUM_PORT_STATS; i++) 282169154Srwatson ethtool_puts(buf, ionic_port_stats_desc[i].name); 28336079Swollman 28436079Swollman for (q_num = 0; q_num < MAX_Q(lif); q_num++) 28536079Swollman ionic_sw_stats_get_tx_strings(lif, buf, q_num); 28636079Swollman 28736079Swollman if (lif->hwstamp_txq) 28836079Swollman ionic_sw_stats_get_tx_strings(lif, buf, lif->hwstamp_txq->q.index); 28936079Swollman 29036079Swollman for (q_num = 0; q_num < MAX_Q(lif); q_num++) 29136079Swollman ionic_sw_stats_get_rx_strings(lif, buf, q_num); 29236079Swollman 29336079Swollman if (lif->hwstamp_rxq) 29436079Swollman ionic_sw_stats_get_rx_strings(lif, buf, lif->hwstamp_rxq->q.index); 29536079Swollman} 29636079Swollman 29736079Swollmanstatic void ionic_sw_stats_get_txq_values(struct ionic_lif *lif, u64 **buf, 29836079Swollman int q_num) 29936079Swollman{ 30032821Sdg struct ionic_tx_stats *txstats; 30160938Sjake int i; 30232821Sdg 30332821Sdg txstats = &lif->txqstats[q_num]; 30432821Sdg 30532821Sdg for (i = 0; i < IONIC_NUM_TX_STATS; i++) { 306222213Srwatson **buf = IONIC_READ_STAT64(txstats, &ionic_tx_stats_desc[i]); 307169154Srwatson (*buf)++; 308169154Srwatson } 309222213Srwatson} 310286227Sjch 311286227Sjchstatic void ionic_sw_stats_get_rxq_values(struct ionic_lif *lif, u64 **buf, 312286227Sjch int q_num) 313286227Sjch{ 314286227Sjch struct ionic_rx_stats *rxstats; 315286227Sjch int i; 316222213Srwatson 317286227Sjch rxstats = &lif->rxqstats[q_num]; 318222213Srwatson 319286227Sjch for (i = 0; i < IONIC_NUM_RX_STATS; i++) { 320286227Sjch **buf = IONIC_READ_STAT64(rxstats, &ionic_rx_stats_desc[i]); 321286227Sjch (*buf)++; 322286227Sjch } 323286227Sjch} 324222213Srwatson 325222213Srwatsonstatic void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) 326222213Srwatson{ 327222213Srwatson struct ionic_port_stats *port_stats; 328286227Sjch struct ionic_lif_sw_stats lif_stats; 329222748Srwatson int i, q_num; 330222748Srwatson 331222213Srwatson ionic_get_lif_stats(lif, &lif_stats); 332169154Srwatson 333169154Srwatson for (i = 0; i < IONIC_NUM_LIF_STATS; i++) { 334169154Srwatson **buf = IONIC_READ_STAT64(&lif_stats, &ionic_lif_stats_desc[i]); 335286227Sjch (*buf)++; 336169154Srwatson } 337222213Srwatson 338169154Srwatson port_stats = &lif->ionic->idev.port_info->stats; 339169154Srwatson for (i = 0; i < IONIC_NUM_PORT_STATS; i++) { 340222213Srwatson **buf = IONIC_READ_STAT_LE64(port_stats, 341169154Srwatson &ionic_port_stats_desc[i]); 342286227Sjch (*buf)++; 343286227Sjch } 344169154Srwatson 345169154Srwatson for (q_num = 0; q_num < MAX_Q(lif); q_num++) 346222213Srwatson ionic_sw_stats_get_txq_values(lif, buf, q_num); 347222213Srwatson 348169154Srwatson if (lif->hwstamp_txq) 349286227Sjch ionic_sw_stats_get_txq_values(lif, buf, lif->hwstamp_txq->q.index); 350169154Srwatson 351169154Srwatson for (q_num = 0; q_num < MAX_Q(lif); q_num++) 352169154Srwatson ionic_sw_stats_get_rxq_values(lif, buf, q_num); 353169154Srwatson 354222213Srwatson if (lif->hwstamp_rxq) 355222213Srwatson ionic_sw_stats_get_rxq_values(lif, buf, lif->hwstamp_rxq->q.index); 356222213Srwatson} 357169154Srwatson 358169154Srwatsonconst struct ionic_stats_group_intf ionic_stats_groups[] = { 359169154Srwatson /* SW Stats group */ 360169154Srwatson { 361222213Srwatson .get_strings = ionic_sw_stats_get_strings, 362169154Srwatson .get_values = ionic_sw_stats_get_values, 363169154Srwatson .get_count = ionic_sw_stats_get_count, 364222748Srwatson }, 365222748Srwatson /* Add more stat groups here */ 366222748Srwatson}; 367222488Srwatson 368222748Srwatsonconst int ionic_num_stats_grps = ARRAY_SIZE(ionic_stats_groups); 369222748Srwatson