linux/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/* Microchip Sparx5 Switch driver
   3 *
   4 * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
   5 */
   6
   7#include <linux/ethtool.h>
   8
   9#include "sparx5_main_regs.h"
  10#include "sparx5_main.h"
  11#include "sparx5_port.h"
  12
  13/* Index of ANA_AC port counters */
  14#define SPX5_PORT_POLICER_DROPS 0
  15
  16/* Add a potentially wrapping 32 bit value to a 64 bit counter */
  17static void sparx5_update_counter(u64 *cnt, u32 val)
  18{
  19        if (val < (*cnt & U32_MAX))
  20                *cnt += (u64)1 << 32; /* value has wrapped */
  21        *cnt = (*cnt & ~(u64)U32_MAX) + val;
  22}
  23
  24enum sparx5_stats_entry {
  25        spx5_stats_rx_symbol_err_cnt = 0,
  26        spx5_stats_pmac_rx_symbol_err_cnt = 1,
  27        spx5_stats_tx_uc_cnt = 2,
  28        spx5_stats_pmac_tx_uc_cnt = 3,
  29        spx5_stats_tx_mc_cnt = 4,
  30        spx5_stats_tx_bc_cnt = 5,
  31        spx5_stats_tx_backoff1_cnt = 6,
  32        spx5_stats_tx_multi_coll_cnt = 7,
  33        spx5_stats_rx_uc_cnt = 8,
  34        spx5_stats_pmac_rx_uc_cnt = 9,
  35        spx5_stats_rx_mc_cnt = 10,
  36        spx5_stats_rx_bc_cnt = 11,
  37        spx5_stats_rx_crc_err_cnt = 12,
  38        spx5_stats_pmac_rx_crc_err_cnt = 13,
  39        spx5_stats_rx_alignment_lost_cnt = 14,
  40        spx5_stats_pmac_rx_alignment_lost_cnt = 15,
  41        spx5_stats_tx_ok_bytes_cnt = 16,
  42        spx5_stats_pmac_tx_ok_bytes_cnt = 17,
  43        spx5_stats_tx_defer_cnt = 18,
  44        spx5_stats_tx_late_coll_cnt = 19,
  45        spx5_stats_tx_xcoll_cnt = 20,
  46        spx5_stats_tx_csense_cnt = 21,
  47        spx5_stats_rx_ok_bytes_cnt = 22,
  48        spx5_stats_pmac_rx_ok_bytes_cnt = 23,
  49        spx5_stats_pmac_tx_mc_cnt = 24,
  50        spx5_stats_pmac_tx_bc_cnt = 25,
  51        spx5_stats_tx_xdefer_cnt = 26,
  52        spx5_stats_pmac_rx_mc_cnt = 27,
  53        spx5_stats_pmac_rx_bc_cnt = 28,
  54        spx5_stats_rx_in_range_len_err_cnt = 29,
  55        spx5_stats_pmac_rx_in_range_len_err_cnt = 30,
  56        spx5_stats_rx_out_of_range_len_err_cnt = 31,
  57        spx5_stats_pmac_rx_out_of_range_len_err_cnt = 32,
  58        spx5_stats_rx_oversize_cnt = 33,
  59        spx5_stats_pmac_rx_oversize_cnt = 34,
  60        spx5_stats_tx_pause_cnt = 35,
  61        spx5_stats_pmac_tx_pause_cnt = 36,
  62        spx5_stats_rx_pause_cnt = 37,
  63        spx5_stats_pmac_rx_pause_cnt = 38,
  64        spx5_stats_rx_unsup_opcode_cnt = 39,
  65        spx5_stats_pmac_rx_unsup_opcode_cnt = 40,
  66        spx5_stats_rx_undersize_cnt = 41,
  67        spx5_stats_pmac_rx_undersize_cnt = 42,
  68        spx5_stats_rx_fragments_cnt = 43,
  69        spx5_stats_pmac_rx_fragments_cnt = 44,
  70        spx5_stats_rx_jabbers_cnt = 45,
  71        spx5_stats_pmac_rx_jabbers_cnt = 46,
  72        spx5_stats_rx_size64_cnt = 47,
  73        spx5_stats_pmac_rx_size64_cnt = 48,
  74        spx5_stats_rx_size65to127_cnt = 49,
  75        spx5_stats_pmac_rx_size65to127_cnt = 50,
  76        spx5_stats_rx_size128to255_cnt = 51,
  77        spx5_stats_pmac_rx_size128to255_cnt = 52,
  78        spx5_stats_rx_size256to511_cnt = 53,
  79        spx5_stats_pmac_rx_size256to511_cnt = 54,
  80        spx5_stats_rx_size512to1023_cnt = 55,
  81        spx5_stats_pmac_rx_size512to1023_cnt = 56,
  82        spx5_stats_rx_size1024to1518_cnt = 57,
  83        spx5_stats_pmac_rx_size1024to1518_cnt = 58,
  84        spx5_stats_rx_size1519tomax_cnt = 59,
  85        spx5_stats_pmac_rx_size1519tomax_cnt = 60,
  86        spx5_stats_tx_size64_cnt = 61,
  87        spx5_stats_pmac_tx_size64_cnt = 62,
  88        spx5_stats_tx_size65to127_cnt = 63,
  89        spx5_stats_pmac_tx_size65to127_cnt = 64,
  90        spx5_stats_tx_size128to255_cnt = 65,
  91        spx5_stats_pmac_tx_size128to255_cnt = 66,
  92        spx5_stats_tx_size256to511_cnt = 67,
  93        spx5_stats_pmac_tx_size256to511_cnt = 68,
  94        spx5_stats_tx_size512to1023_cnt = 69,
  95        spx5_stats_pmac_tx_size512to1023_cnt = 70,
  96        spx5_stats_tx_size1024to1518_cnt = 71,
  97        spx5_stats_pmac_tx_size1024to1518_cnt = 72,
  98        spx5_stats_tx_size1519tomax_cnt = 73,
  99        spx5_stats_pmac_tx_size1519tomax_cnt = 74,
 100        spx5_stats_mm_rx_assembly_err_cnt = 75,
 101        spx5_stats_mm_rx_assembly_ok_cnt = 76,
 102        spx5_stats_mm_rx_merge_frag_cnt = 77,
 103        spx5_stats_mm_rx_smd_err_cnt = 78,
 104        spx5_stats_mm_tx_pfragment_cnt = 79,
 105        spx5_stats_rx_bad_bytes_cnt = 80,
 106        spx5_stats_pmac_rx_bad_bytes_cnt = 81,
 107        spx5_stats_rx_in_bytes_cnt = 82,
 108        spx5_stats_rx_ipg_shrink_cnt = 83,
 109        spx5_stats_rx_sync_lost_err_cnt = 84,
 110        spx5_stats_rx_tagged_frms_cnt = 85,
 111        spx5_stats_rx_untagged_frms_cnt = 86,
 112        spx5_stats_tx_out_bytes_cnt = 87,
 113        spx5_stats_tx_tagged_frms_cnt = 88,
 114        spx5_stats_tx_untagged_frms_cnt = 89,
 115        spx5_stats_rx_hih_cksm_err_cnt = 90,
 116        spx5_stats_pmac_rx_hih_cksm_err_cnt = 91,
 117        spx5_stats_rx_xgmii_prot_err_cnt = 92,
 118        spx5_stats_pmac_rx_xgmii_prot_err_cnt = 93,
 119        spx5_stats_ana_ac_port_stat_lsb_cnt = 94,
 120        spx5_stats_green_p0_rx_fwd = 95,
 121        spx5_stats_green_p0_rx_port_drop = 111,
 122        spx5_stats_green_p0_tx_port = 127,
 123        spx5_stats_rx_local_drop = 143,
 124        spx5_stats_tx_local_drop = 144,
 125        spx5_stats_count = 145,
 126};
 127
 128static const char *const sparx5_stats_layout[] = {
 129        "mm_rx_assembly_err_cnt",
 130        "mm_rx_assembly_ok_cnt",
 131        "mm_rx_merge_frag_cnt",
 132        "mm_rx_smd_err_cnt",
 133        "mm_tx_pfragment_cnt",
 134        "rx_bad_bytes_cnt",
 135        "pmac_rx_bad_bytes_cnt",
 136        "rx_in_bytes_cnt",
 137        "rx_ipg_shrink_cnt",
 138        "rx_sync_lost_err_cnt",
 139        "rx_tagged_frms_cnt",
 140        "rx_untagged_frms_cnt",
 141        "tx_out_bytes_cnt",
 142        "tx_tagged_frms_cnt",
 143        "tx_untagged_frms_cnt",
 144        "rx_hih_cksm_err_cnt",
 145        "pmac_rx_hih_cksm_err_cnt",
 146        "rx_xgmii_prot_err_cnt",
 147        "pmac_rx_xgmii_prot_err_cnt",
 148        "rx_port_policer_drop",
 149        "rx_fwd_green_p0",
 150        "rx_fwd_green_p1",
 151        "rx_fwd_green_p2",
 152        "rx_fwd_green_p3",
 153        "rx_fwd_green_p4",
 154        "rx_fwd_green_p5",
 155        "rx_fwd_green_p6",
 156        "rx_fwd_green_p7",
 157        "rx_fwd_yellow_p0",
 158        "rx_fwd_yellow_p1",
 159        "rx_fwd_yellow_p2",
 160        "rx_fwd_yellow_p3",
 161        "rx_fwd_yellow_p4",
 162        "rx_fwd_yellow_p5",
 163        "rx_fwd_yellow_p6",
 164        "rx_fwd_yellow_p7",
 165        "rx_port_drop_green_p0",
 166        "rx_port_drop_green_p1",
 167        "rx_port_drop_green_p2",
 168        "rx_port_drop_green_p3",
 169        "rx_port_drop_green_p4",
 170        "rx_port_drop_green_p5",
 171        "rx_port_drop_green_p6",
 172        "rx_port_drop_green_p7",
 173        "rx_port_drop_yellow_p0",
 174        "rx_port_drop_yellow_p1",
 175        "rx_port_drop_yellow_p2",
 176        "rx_port_drop_yellow_p3",
 177        "rx_port_drop_yellow_p4",
 178        "rx_port_drop_yellow_p5",
 179        "rx_port_drop_yellow_p6",
 180        "rx_port_drop_yellow_p7",
 181        "tx_port_green_p0",
 182        "tx_port_green_p1",
 183        "tx_port_green_p2",
 184        "tx_port_green_p3",
 185        "tx_port_green_p4",
 186        "tx_port_green_p5",
 187        "tx_port_green_p6",
 188        "tx_port_green_p7",
 189        "tx_port_yellow_p0",
 190        "tx_port_yellow_p1",
 191        "tx_port_yellow_p2",
 192        "tx_port_yellow_p3",
 193        "tx_port_yellow_p4",
 194        "tx_port_yellow_p5",
 195        "tx_port_yellow_p6",
 196        "tx_port_yellow_p7",
 197        "rx_local_drop",
 198        "tx_local_drop",
 199};
 200
 201static void sparx5_get_queue_sys_stats(struct sparx5 *sparx5, int portno)
 202{
 203        u64 *portstats;
 204        u64 *stats;
 205        u32 addr;
 206        int idx;
 207
 208        portstats = &sparx5->stats[portno * sparx5->num_stats];
 209        mutex_lock(&sparx5->queue_stats_lock);
 210        spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno), sparx5, XQS_STAT_CFG);
 211        addr = 0;
 212        stats = &portstats[spx5_stats_green_p0_rx_fwd];
 213        for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
 214                sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
 215        addr = 16;
 216        stats = &portstats[spx5_stats_green_p0_rx_port_drop];
 217        for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
 218                sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
 219        addr = 256;
 220        stats = &portstats[spx5_stats_green_p0_tx_port];
 221        for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
 222                sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
 223        sparx5_update_counter(&portstats[spx5_stats_rx_local_drop],
 224                              spx5_rd(sparx5, XQS_CNT(32)));
 225        sparx5_update_counter(&portstats[spx5_stats_tx_local_drop],
 226                              spx5_rd(sparx5, XQS_CNT(272)));
 227        mutex_unlock(&sparx5->queue_stats_lock);
 228}
 229
 230static void sparx5_get_ana_ac_stats_stats(struct sparx5 *sparx5, int portno)
 231{
 232        u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
 233
 234        sparx5_update_counter(&portstats[spx5_stats_ana_ac_port_stat_lsb_cnt],
 235                              spx5_rd(sparx5, ANA_AC_PORT_STAT_LSB_CNT(portno,
 236                                                                       SPX5_PORT_POLICER_DROPS)));
 237}
 238
 239static void sparx5_get_dev_phy_stats(u64 *portstats, void __iomem *inst, u32
 240                                     tinst)
 241{
 242        sparx5_update_counter(&portstats[spx5_stats_rx_symbol_err_cnt],
 243                              spx5_inst_rd(inst,
 244                                           DEV5G_RX_SYMBOL_ERR_CNT(tinst)));
 245        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_symbol_err_cnt],
 246                              spx5_inst_rd(inst,
 247                                           DEV5G_PMAC_RX_SYMBOL_ERR_CNT(tinst)));
 248}
 249
 250static void sparx5_get_dev_mac_stats(u64 *portstats, void __iomem *inst, u32
 251                                     tinst)
 252{
 253        sparx5_update_counter(&portstats[spx5_stats_tx_uc_cnt],
 254                              spx5_inst_rd(inst, DEV5G_TX_UC_CNT(tinst)));
 255        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_uc_cnt],
 256                              spx5_inst_rd(inst, DEV5G_PMAC_TX_UC_CNT(tinst)));
 257        sparx5_update_counter(&portstats[spx5_stats_tx_mc_cnt],
 258                              spx5_inst_rd(inst, DEV5G_TX_MC_CNT(tinst)));
 259        sparx5_update_counter(&portstats[spx5_stats_tx_bc_cnt],
 260                              spx5_inst_rd(inst, DEV5G_TX_BC_CNT(tinst)));
 261        sparx5_update_counter(&portstats[spx5_stats_rx_uc_cnt],
 262                              spx5_inst_rd(inst, DEV5G_RX_UC_CNT(tinst)));
 263        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_uc_cnt],
 264                              spx5_inst_rd(inst, DEV5G_PMAC_RX_UC_CNT(tinst)));
 265        sparx5_update_counter(&portstats[spx5_stats_rx_mc_cnt],
 266                              spx5_inst_rd(inst, DEV5G_RX_MC_CNT(tinst)));
 267        sparx5_update_counter(&portstats[spx5_stats_rx_bc_cnt],
 268                              spx5_inst_rd(inst, DEV5G_RX_BC_CNT(tinst)));
 269        sparx5_update_counter(&portstats[spx5_stats_rx_crc_err_cnt],
 270                              spx5_inst_rd(inst, DEV5G_RX_CRC_ERR_CNT(tinst)));
 271        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_crc_err_cnt],
 272                              spx5_inst_rd(inst,
 273                                           DEV5G_PMAC_RX_CRC_ERR_CNT(tinst)));
 274        sparx5_update_counter(&portstats[spx5_stats_rx_alignment_lost_cnt],
 275                              spx5_inst_rd(inst,
 276                                           DEV5G_RX_ALIGNMENT_LOST_CNT(tinst)));
 277        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
 278                              spx5_inst_rd(inst,
 279                                           DEV5G_PMAC_RX_ALIGNMENT_LOST_CNT(tinst)));
 280        sparx5_update_counter(&portstats[spx5_stats_tx_ok_bytes_cnt],
 281                              spx5_inst_rd(inst, DEV5G_TX_OK_BYTES_CNT(tinst)));
 282        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
 283                              spx5_inst_rd(inst,
 284                                           DEV5G_PMAC_TX_OK_BYTES_CNT(tinst)));
 285        sparx5_update_counter(&portstats[spx5_stats_rx_ok_bytes_cnt],
 286                              spx5_inst_rd(inst, DEV5G_RX_OK_BYTES_CNT(tinst)));
 287        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
 288                              spx5_inst_rd(inst,
 289                                           DEV5G_PMAC_RX_OK_BYTES_CNT(tinst)));
 290        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_mc_cnt],
 291                              spx5_inst_rd(inst, DEV5G_PMAC_TX_MC_CNT(tinst)));
 292        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_bc_cnt],
 293                              spx5_inst_rd(inst, DEV5G_PMAC_TX_BC_CNT(tinst)));
 294        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_mc_cnt],
 295                              spx5_inst_rd(inst, DEV5G_PMAC_RX_MC_CNT(tinst)));
 296        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bc_cnt],
 297                              spx5_inst_rd(inst, DEV5G_PMAC_RX_BC_CNT(tinst)));
 298        sparx5_update_counter(&portstats[spx5_stats_rx_in_range_len_err_cnt],
 299                              spx5_inst_rd(inst,
 300                                           DEV5G_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
 301        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
 302                              spx5_inst_rd(inst,
 303                                           DEV5G_PMAC_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
 304        sparx5_update_counter(&portstats[spx5_stats_rx_out_of_range_len_err_cnt],
 305                              spx5_inst_rd(inst,
 306                                           DEV5G_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
 307        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
 308                              spx5_inst_rd(inst,
 309                                           DEV5G_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
 310        sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
 311                              spx5_inst_rd(inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
 312        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
 313                              spx5_inst_rd(inst,
 314                                           DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
 315}
 316
 317static void sparx5_get_dev_mac_ctrl_stats(u64 *portstats, void __iomem *inst,
 318                                          u32 tinst)
 319{
 320        sparx5_update_counter(&portstats[spx5_stats_tx_pause_cnt],
 321                              spx5_inst_rd(inst, DEV5G_TX_PAUSE_CNT(tinst)));
 322        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_pause_cnt],
 323                              spx5_inst_rd(inst,
 324                                           DEV5G_PMAC_TX_PAUSE_CNT(tinst)));
 325        sparx5_update_counter(&portstats[spx5_stats_rx_pause_cnt],
 326                              spx5_inst_rd(inst, DEV5G_RX_PAUSE_CNT(tinst)));
 327        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_pause_cnt],
 328                              spx5_inst_rd(inst,
 329                                           DEV5G_PMAC_RX_PAUSE_CNT(tinst)));
 330        sparx5_update_counter(&portstats[spx5_stats_rx_unsup_opcode_cnt],
 331                              spx5_inst_rd(inst,
 332                                           DEV5G_RX_UNSUP_OPCODE_CNT(tinst)));
 333        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
 334                              spx5_inst_rd(inst,
 335                                           DEV5G_PMAC_RX_UNSUP_OPCODE_CNT(tinst)));
 336}
 337
 338static void sparx5_get_dev_rmon_stats(u64 *portstats, void __iomem *inst, u32
 339                                      tinst)
 340{
 341        sparx5_update_counter(&portstats[spx5_stats_rx_undersize_cnt],
 342                              spx5_inst_rd(inst,
 343                                           DEV5G_RX_UNDERSIZE_CNT(tinst)));
 344        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_undersize_cnt],
 345                              spx5_inst_rd(inst,
 346                                           DEV5G_PMAC_RX_UNDERSIZE_CNT(tinst)));
 347        sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
 348                              spx5_inst_rd(inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
 349        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
 350                              spx5_inst_rd(inst,
 351                                           DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
 352        sparx5_update_counter(&portstats[spx5_stats_rx_fragments_cnt],
 353                              spx5_inst_rd(inst,
 354                                           DEV5G_RX_FRAGMENTS_CNT(tinst)));
 355        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_fragments_cnt],
 356                              spx5_inst_rd(inst,
 357                                           DEV5G_PMAC_RX_FRAGMENTS_CNT(tinst)));
 358        sparx5_update_counter(&portstats[spx5_stats_rx_jabbers_cnt],
 359                              spx5_inst_rd(inst, DEV5G_RX_JABBERS_CNT(tinst)));
 360        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_jabbers_cnt],
 361                              spx5_inst_rd(inst,
 362                                           DEV5G_PMAC_RX_JABBERS_CNT(tinst)));
 363        sparx5_update_counter(&portstats[spx5_stats_rx_size64_cnt],
 364                              spx5_inst_rd(inst, DEV5G_RX_SIZE64_CNT(tinst)));
 365        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size64_cnt],
 366                              spx5_inst_rd(inst,
 367                                           DEV5G_PMAC_RX_SIZE64_CNT(tinst)));
 368        sparx5_update_counter(&portstats[spx5_stats_rx_size65to127_cnt],
 369                              spx5_inst_rd(inst,
 370                                           DEV5G_RX_SIZE65TO127_CNT(tinst)));
 371        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size65to127_cnt],
 372                              spx5_inst_rd(inst,
 373                                           DEV5G_PMAC_RX_SIZE65TO127_CNT(tinst)));
 374        sparx5_update_counter(&portstats[spx5_stats_rx_size128to255_cnt],
 375                              spx5_inst_rd(inst,
 376                                           DEV5G_RX_SIZE128TO255_CNT(tinst)));
 377        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size128to255_cnt],
 378                              spx5_inst_rd(inst,
 379                                           DEV5G_PMAC_RX_SIZE128TO255_CNT(tinst)));
 380        sparx5_update_counter(&portstats[spx5_stats_rx_size256to511_cnt],
 381                              spx5_inst_rd(inst,
 382                                           DEV5G_RX_SIZE256TO511_CNT(tinst)));
 383        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size256to511_cnt],
 384                              spx5_inst_rd(inst,
 385                                           DEV5G_PMAC_RX_SIZE256TO511_CNT(tinst)));
 386        sparx5_update_counter(&portstats[spx5_stats_rx_size512to1023_cnt],
 387                              spx5_inst_rd(inst,
 388                                           DEV5G_RX_SIZE512TO1023_CNT(tinst)));
 389        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size512to1023_cnt],
 390                              spx5_inst_rd(inst,
 391                                           DEV5G_PMAC_RX_SIZE512TO1023_CNT(tinst)));
 392        sparx5_update_counter(&portstats[spx5_stats_rx_size1024to1518_cnt],
 393                              spx5_inst_rd(inst,
 394                                           DEV5G_RX_SIZE1024TO1518_CNT(tinst)));
 395        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
 396                              spx5_inst_rd(inst,
 397                                           DEV5G_PMAC_RX_SIZE1024TO1518_CNT(tinst)));
 398        sparx5_update_counter(&portstats[spx5_stats_rx_size1519tomax_cnt],
 399                              spx5_inst_rd(inst,
 400                                           DEV5G_RX_SIZE1519TOMAX_CNT(tinst)));
 401        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
 402                              spx5_inst_rd(inst,
 403                                           DEV5G_PMAC_RX_SIZE1519TOMAX_CNT(tinst)));
 404        sparx5_update_counter(&portstats[spx5_stats_tx_size64_cnt],
 405                              spx5_inst_rd(inst, DEV5G_TX_SIZE64_CNT(tinst)));
 406        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size64_cnt],
 407                              spx5_inst_rd(inst,
 408                                           DEV5G_PMAC_TX_SIZE64_CNT(tinst)));
 409        sparx5_update_counter(&portstats[spx5_stats_tx_size65to127_cnt],
 410                              spx5_inst_rd(inst,
 411                                           DEV5G_TX_SIZE65TO127_CNT(tinst)));
 412        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size65to127_cnt],
 413                              spx5_inst_rd(inst,
 414                                           DEV5G_PMAC_TX_SIZE65TO127_CNT(tinst)));
 415        sparx5_update_counter(&portstats[spx5_stats_tx_size128to255_cnt],
 416                              spx5_inst_rd(inst,
 417                                           DEV5G_TX_SIZE128TO255_CNT(tinst)));
 418        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size128to255_cnt],
 419                              spx5_inst_rd(inst,
 420                                           DEV5G_PMAC_TX_SIZE128TO255_CNT(tinst)));
 421        sparx5_update_counter(&portstats[spx5_stats_tx_size256to511_cnt],
 422                              spx5_inst_rd(inst,
 423                                           DEV5G_TX_SIZE256TO511_CNT(tinst)));
 424        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size256to511_cnt],
 425                              spx5_inst_rd(inst,
 426                                           DEV5G_PMAC_TX_SIZE256TO511_CNT(tinst)));
 427        sparx5_update_counter(&portstats[spx5_stats_tx_size512to1023_cnt],
 428                              spx5_inst_rd(inst,
 429                                           DEV5G_TX_SIZE512TO1023_CNT(tinst)));
 430        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size512to1023_cnt],
 431                              spx5_inst_rd(inst,
 432                                           DEV5G_PMAC_TX_SIZE512TO1023_CNT(tinst)));
 433        sparx5_update_counter(&portstats[spx5_stats_tx_size1024to1518_cnt],
 434                              spx5_inst_rd(inst,
 435                                           DEV5G_TX_SIZE1024TO1518_CNT(tinst)));
 436        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
 437                              spx5_inst_rd(inst,
 438                                           DEV5G_PMAC_TX_SIZE1024TO1518_CNT(tinst)));
 439        sparx5_update_counter(&portstats[spx5_stats_tx_size1519tomax_cnt],
 440                              spx5_inst_rd(inst,
 441                                           DEV5G_TX_SIZE1519TOMAX_CNT(tinst)));
 442        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
 443                              spx5_inst_rd(inst,
 444                                           DEV5G_PMAC_TX_SIZE1519TOMAX_CNT(tinst)));
 445}
 446
 447static void sparx5_get_dev_misc_stats(u64 *portstats, void __iomem *inst, u32
 448                                      tinst)
 449{
 450        sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_err_cnt],
 451                              spx5_inst_rd(inst,
 452                                           DEV5G_MM_RX_ASSEMBLY_ERR_CNT(tinst)));
 453        sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_ok_cnt],
 454                              spx5_inst_rd(inst,
 455                                           DEV5G_MM_RX_ASSEMBLY_OK_CNT(tinst)));
 456        sparx5_update_counter(&portstats[spx5_stats_mm_rx_merge_frag_cnt],
 457                              spx5_inst_rd(inst,
 458                                           DEV5G_MM_RX_MERGE_FRAG_CNT(tinst)));
 459        sparx5_update_counter(&portstats[spx5_stats_mm_rx_smd_err_cnt],
 460                              spx5_inst_rd(inst,
 461                                           DEV5G_MM_RX_SMD_ERR_CNT(tinst)));
 462        sparx5_update_counter(&portstats[spx5_stats_mm_tx_pfragment_cnt],
 463                              spx5_inst_rd(inst,
 464                                           DEV5G_MM_TX_PFRAGMENT_CNT(tinst)));
 465        sparx5_update_counter(&portstats[spx5_stats_rx_bad_bytes_cnt],
 466                              spx5_inst_rd(inst,
 467                                           DEV5G_RX_BAD_BYTES_CNT(tinst)));
 468        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
 469                              spx5_inst_rd(inst,
 470                                           DEV5G_PMAC_RX_BAD_BYTES_CNT(tinst)));
 471        sparx5_update_counter(&portstats[spx5_stats_rx_in_bytes_cnt],
 472                              spx5_inst_rd(inst, DEV5G_RX_IN_BYTES_CNT(tinst)));
 473        sparx5_update_counter(&portstats[spx5_stats_rx_ipg_shrink_cnt],
 474                              spx5_inst_rd(inst,
 475                                           DEV5G_RX_IPG_SHRINK_CNT(tinst)));
 476        sparx5_update_counter(&portstats[spx5_stats_rx_tagged_frms_cnt],
 477                              spx5_inst_rd(inst,
 478                                           DEV5G_RX_TAGGED_FRMS_CNT(tinst)));
 479        sparx5_update_counter(&portstats[spx5_stats_rx_untagged_frms_cnt],
 480                              spx5_inst_rd(inst,
 481                                           DEV5G_RX_UNTAGGED_FRMS_CNT(tinst)));
 482        sparx5_update_counter(&portstats[spx5_stats_tx_out_bytes_cnt],
 483                              spx5_inst_rd(inst,
 484                                           DEV5G_TX_OUT_BYTES_CNT(tinst)));
 485        sparx5_update_counter(&portstats[spx5_stats_tx_tagged_frms_cnt],
 486                              spx5_inst_rd(inst,
 487                                           DEV5G_TX_TAGGED_FRMS_CNT(tinst)));
 488        sparx5_update_counter(&portstats[spx5_stats_tx_untagged_frms_cnt],
 489                              spx5_inst_rd(inst,
 490                                           DEV5G_TX_UNTAGGED_FRMS_CNT(tinst)));
 491        sparx5_update_counter(&portstats[spx5_stats_rx_hih_cksm_err_cnt],
 492                              spx5_inst_rd(inst,
 493                                           DEV5G_RX_HIH_CKSM_ERR_CNT(tinst)));
 494        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_hih_cksm_err_cnt],
 495                              spx5_inst_rd(inst,
 496                                           DEV5G_PMAC_RX_HIH_CKSM_ERR_CNT(tinst)));
 497        sparx5_update_counter(&portstats[spx5_stats_rx_xgmii_prot_err_cnt],
 498                              spx5_inst_rd(inst,
 499                                           DEV5G_RX_XGMII_PROT_ERR_CNT(tinst)));
 500        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_xgmii_prot_err_cnt],
 501                              spx5_inst_rd(inst,
 502                                           DEV5G_PMAC_RX_XGMII_PROT_ERR_CNT(tinst)));
 503}
 504
 505static void sparx5_get_device_stats(struct sparx5 *sparx5, int portno)
 506{
 507        u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
 508        u32 tinst = sparx5_port_dev_index(portno);
 509        u32 dev = sparx5_to_high_dev(portno);
 510        void __iomem *inst;
 511
 512        inst = spx5_inst_get(sparx5, dev, tinst);
 513        sparx5_get_dev_phy_stats(portstats, inst, tinst);
 514        sparx5_get_dev_mac_stats(portstats, inst, tinst);
 515        sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
 516        sparx5_get_dev_rmon_stats(portstats, inst, tinst);
 517        sparx5_get_dev_misc_stats(portstats, inst, tinst);
 518}
 519
 520static void sparx5_get_asm_phy_stats(u64 *portstats, void __iomem *inst, int
 521                                     portno)
 522{
 523        sparx5_update_counter(&portstats[spx5_stats_rx_symbol_err_cnt],
 524                              spx5_inst_rd(inst,
 525                                           ASM_RX_SYMBOL_ERR_CNT(portno)));
 526        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_symbol_err_cnt],
 527                              spx5_inst_rd(inst,
 528                                           ASM_PMAC_RX_SYMBOL_ERR_CNT(portno)));
 529}
 530
 531static void sparx5_get_asm_mac_stats(u64 *portstats, void __iomem *inst, int
 532                                     portno)
 533{
 534        sparx5_update_counter(&portstats[spx5_stats_tx_uc_cnt],
 535                              spx5_inst_rd(inst, ASM_TX_UC_CNT(portno)));
 536        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_uc_cnt],
 537                              spx5_inst_rd(inst, ASM_PMAC_TX_UC_CNT(portno)));
 538        sparx5_update_counter(&portstats[spx5_stats_tx_mc_cnt],
 539                              spx5_inst_rd(inst, ASM_TX_MC_CNT(portno)));
 540        sparx5_update_counter(&portstats[spx5_stats_tx_bc_cnt],
 541                              spx5_inst_rd(inst, ASM_TX_BC_CNT(portno)));
 542        sparx5_update_counter(&portstats[spx5_stats_tx_backoff1_cnt],
 543                              spx5_inst_rd(inst, ASM_TX_BACKOFF1_CNT(portno)));
 544        sparx5_update_counter(&portstats[spx5_stats_tx_multi_coll_cnt],
 545                              spx5_inst_rd(inst,
 546                                           ASM_TX_MULTI_COLL_CNT(portno)));
 547        sparx5_update_counter(&portstats[spx5_stats_rx_uc_cnt],
 548                              spx5_inst_rd(inst, ASM_RX_UC_CNT(portno)));
 549        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_uc_cnt],
 550                              spx5_inst_rd(inst, ASM_PMAC_RX_UC_CNT(portno)));
 551        sparx5_update_counter(&portstats[spx5_stats_rx_mc_cnt],
 552                              spx5_inst_rd(inst, ASM_RX_MC_CNT(portno)));
 553        sparx5_update_counter(&portstats[spx5_stats_rx_bc_cnt],
 554                              spx5_inst_rd(inst, ASM_RX_BC_CNT(portno)));
 555        sparx5_update_counter(&portstats[spx5_stats_rx_crc_err_cnt],
 556                              spx5_inst_rd(inst, ASM_RX_CRC_ERR_CNT(portno)));
 557        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_crc_err_cnt],
 558                              spx5_inst_rd(inst,
 559                                           ASM_PMAC_RX_CRC_ERR_CNT(portno)));
 560        sparx5_update_counter(&portstats[spx5_stats_rx_alignment_lost_cnt],
 561                              spx5_inst_rd(inst,
 562                                           ASM_RX_ALIGNMENT_LOST_CNT(portno)));
 563        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
 564                              spx5_inst_rd(inst,
 565                                           ASM_PMAC_RX_ALIGNMENT_LOST_CNT(portno)));
 566        sparx5_update_counter(&portstats[spx5_stats_tx_ok_bytes_cnt],
 567                              spx5_inst_rd(inst, ASM_TX_OK_BYTES_CNT(portno)));
 568        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
 569                              spx5_inst_rd(inst,
 570                                           ASM_PMAC_TX_OK_BYTES_CNT(portno)));
 571        sparx5_update_counter(&portstats[spx5_stats_tx_defer_cnt],
 572                              spx5_inst_rd(inst, ASM_TX_DEFER_CNT(portno)));
 573        sparx5_update_counter(&portstats[spx5_stats_tx_late_coll_cnt],
 574                              spx5_inst_rd(inst, ASM_TX_LATE_COLL_CNT(portno)));
 575        sparx5_update_counter(&portstats[spx5_stats_tx_xcoll_cnt],
 576                              spx5_inst_rd(inst, ASM_TX_XCOLL_CNT(portno)));
 577        sparx5_update_counter(&portstats[spx5_stats_tx_csense_cnt],
 578                              spx5_inst_rd(inst, ASM_TX_CSENSE_CNT(portno)));
 579        sparx5_update_counter(&portstats[spx5_stats_rx_ok_bytes_cnt],
 580                              spx5_inst_rd(inst, ASM_RX_OK_BYTES_CNT(portno)));
 581        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
 582                              spx5_inst_rd(inst,
 583                                           ASM_PMAC_RX_OK_BYTES_CNT(portno)));
 584        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_mc_cnt],
 585                              spx5_inst_rd(inst, ASM_PMAC_TX_MC_CNT(portno)));
 586        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_bc_cnt],
 587                              spx5_inst_rd(inst, ASM_PMAC_TX_BC_CNT(portno)));
 588        sparx5_update_counter(&portstats[spx5_stats_tx_xdefer_cnt],
 589                              spx5_inst_rd(inst, ASM_TX_XDEFER_CNT(portno)));
 590        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_mc_cnt],
 591                              spx5_inst_rd(inst, ASM_PMAC_RX_MC_CNT(portno)));
 592        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bc_cnt],
 593                              spx5_inst_rd(inst, ASM_PMAC_RX_BC_CNT(portno)));
 594        sparx5_update_counter(&portstats[spx5_stats_rx_in_range_len_err_cnt],
 595                              spx5_inst_rd(inst,
 596                                           ASM_RX_IN_RANGE_LEN_ERR_CNT(portno)));
 597        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
 598                              spx5_inst_rd(inst,
 599                                           ASM_PMAC_RX_IN_RANGE_LEN_ERR_CNT(portno)));
 600        sparx5_update_counter(&portstats[spx5_stats_rx_out_of_range_len_err_cnt],
 601                              spx5_inst_rd(inst,
 602                                           ASM_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
 603        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
 604                              spx5_inst_rd(inst,
 605                                           ASM_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
 606        sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
 607                              spx5_inst_rd(inst, ASM_RX_OVERSIZE_CNT(portno)));
 608        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
 609                              spx5_inst_rd(inst,
 610                                           ASM_PMAC_RX_OVERSIZE_CNT(portno)));
 611}
 612
 613static void sparx5_get_asm_mac_ctrl_stats(u64 *portstats, void __iomem *inst,
 614                                          int portno)
 615{
 616        sparx5_update_counter(&portstats[spx5_stats_tx_pause_cnt],
 617                              spx5_inst_rd(inst, ASM_TX_PAUSE_CNT(portno)));
 618        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_pause_cnt],
 619                              spx5_inst_rd(inst,
 620                                           ASM_PMAC_TX_PAUSE_CNT(portno)));
 621        sparx5_update_counter(&portstats[spx5_stats_rx_pause_cnt],
 622                              spx5_inst_rd(inst, ASM_RX_PAUSE_CNT(portno)));
 623        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_pause_cnt],
 624                              spx5_inst_rd(inst,
 625                                           ASM_PMAC_RX_PAUSE_CNT(portno)));
 626        sparx5_update_counter(&portstats[spx5_stats_rx_unsup_opcode_cnt],
 627                              spx5_inst_rd(inst,
 628                                           ASM_RX_UNSUP_OPCODE_CNT(portno)));
 629        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
 630                              spx5_inst_rd(inst,
 631                                           ASM_PMAC_RX_UNSUP_OPCODE_CNT(portno)));
 632}
 633
 634static void sparx5_get_asm_rmon_stats(u64 *portstats, void __iomem *inst, int
 635                                      portno)
 636{
 637        sparx5_update_counter(&portstats[spx5_stats_rx_undersize_cnt],
 638                              spx5_inst_rd(inst, ASM_RX_UNDERSIZE_CNT(portno)));
 639        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_undersize_cnt],
 640                              spx5_inst_rd(inst,
 641                                           ASM_PMAC_RX_UNDERSIZE_CNT(portno)));
 642        sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
 643                              spx5_inst_rd(inst, ASM_RX_OVERSIZE_CNT(portno)));
 644        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
 645                              spx5_inst_rd(inst,
 646                                           ASM_PMAC_RX_OVERSIZE_CNT(portno)));
 647        sparx5_update_counter(&portstats[spx5_stats_rx_fragments_cnt],
 648                              spx5_inst_rd(inst, ASM_RX_FRAGMENTS_CNT(portno)));
 649        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_fragments_cnt],
 650                              spx5_inst_rd(inst,
 651                                           ASM_PMAC_RX_FRAGMENTS_CNT(portno)));
 652        sparx5_update_counter(&portstats[spx5_stats_rx_jabbers_cnt],
 653                              spx5_inst_rd(inst, ASM_RX_JABBERS_CNT(portno)));
 654        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_jabbers_cnt],
 655                              spx5_inst_rd(inst,
 656                                           ASM_PMAC_RX_JABBERS_CNT(portno)));
 657        sparx5_update_counter(&portstats[spx5_stats_rx_size64_cnt],
 658                              spx5_inst_rd(inst, ASM_RX_SIZE64_CNT(portno)));
 659        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size64_cnt],
 660                              spx5_inst_rd(inst,
 661                                           ASM_PMAC_RX_SIZE64_CNT(portno)));
 662        sparx5_update_counter(&portstats[spx5_stats_rx_size65to127_cnt],
 663                              spx5_inst_rd(inst,
 664                                           ASM_RX_SIZE65TO127_CNT(portno)));
 665        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size65to127_cnt],
 666                              spx5_inst_rd(inst,
 667                                           ASM_PMAC_RX_SIZE65TO127_CNT(portno)));
 668        sparx5_update_counter(&portstats[spx5_stats_rx_size128to255_cnt],
 669                              spx5_inst_rd(inst,
 670                                           ASM_RX_SIZE128TO255_CNT(portno)));
 671        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size128to255_cnt],
 672                              spx5_inst_rd(inst,
 673                                           ASM_PMAC_RX_SIZE128TO255_CNT(portno)));
 674        sparx5_update_counter(&portstats[spx5_stats_rx_size256to511_cnt],
 675                              spx5_inst_rd(inst,
 676                                           ASM_RX_SIZE256TO511_CNT(portno)));
 677        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size256to511_cnt],
 678                              spx5_inst_rd(inst,
 679                                           ASM_PMAC_RX_SIZE256TO511_CNT(portno)));
 680        sparx5_update_counter(&portstats[spx5_stats_rx_size512to1023_cnt],
 681                              spx5_inst_rd(inst,
 682                                           ASM_RX_SIZE512TO1023_CNT(portno)));
 683        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size512to1023_cnt],
 684                              spx5_inst_rd(inst,
 685                                           ASM_PMAC_RX_SIZE512TO1023_CNT(portno)));
 686        sparx5_update_counter(&portstats[spx5_stats_rx_size1024to1518_cnt],
 687                              spx5_inst_rd(inst,
 688                                           ASM_RX_SIZE1024TO1518_CNT(portno)));
 689        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
 690                              spx5_inst_rd(inst,
 691                                           ASM_PMAC_RX_SIZE1024TO1518_CNT(portno)));
 692        sparx5_update_counter(&portstats[spx5_stats_rx_size1519tomax_cnt],
 693                              spx5_inst_rd(inst,
 694                                           ASM_RX_SIZE1519TOMAX_CNT(portno)));
 695        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
 696                              spx5_inst_rd(inst,
 697                                           ASM_PMAC_RX_SIZE1519TOMAX_CNT(portno)));
 698        sparx5_update_counter(&portstats[spx5_stats_tx_size64_cnt],
 699                              spx5_inst_rd(inst, ASM_TX_SIZE64_CNT(portno)));
 700        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size64_cnt],
 701                              spx5_inst_rd(inst,
 702                                           ASM_PMAC_TX_SIZE64_CNT(portno)));
 703        sparx5_update_counter(&portstats[spx5_stats_tx_size65to127_cnt],
 704                              spx5_inst_rd(inst,
 705                                           ASM_TX_SIZE65TO127_CNT(portno)));
 706        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size65to127_cnt],
 707                              spx5_inst_rd(inst,
 708                                           ASM_PMAC_TX_SIZE65TO127_CNT(portno)));
 709        sparx5_update_counter(&portstats[spx5_stats_tx_size128to255_cnt],
 710                              spx5_inst_rd(inst,
 711                                           ASM_TX_SIZE128TO255_CNT(portno)));
 712        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size128to255_cnt],
 713                              spx5_inst_rd(inst,
 714                                           ASM_PMAC_TX_SIZE128TO255_CNT(portno)));
 715        sparx5_update_counter(&portstats[spx5_stats_tx_size256to511_cnt],
 716                              spx5_inst_rd(inst,
 717                                           ASM_TX_SIZE256TO511_CNT(portno)));
 718        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size256to511_cnt],
 719                              spx5_inst_rd(inst,
 720                                           ASM_PMAC_TX_SIZE256TO511_CNT(portno)));
 721        sparx5_update_counter(&portstats[spx5_stats_tx_size512to1023_cnt],
 722                              spx5_inst_rd(inst,
 723                                           ASM_TX_SIZE512TO1023_CNT(portno)));
 724        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size512to1023_cnt],
 725                              spx5_inst_rd(inst,
 726                                           ASM_PMAC_TX_SIZE512TO1023_CNT(portno)));
 727        sparx5_update_counter(&portstats[spx5_stats_tx_size1024to1518_cnt],
 728                              spx5_inst_rd(inst,
 729                                           ASM_TX_SIZE1024TO1518_CNT(portno)));
 730        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
 731                              spx5_inst_rd(inst,
 732                                           ASM_PMAC_TX_SIZE1024TO1518_CNT(portno)));
 733        sparx5_update_counter(&portstats[spx5_stats_tx_size1519tomax_cnt],
 734                              spx5_inst_rd(inst,
 735                                           ASM_TX_SIZE1519TOMAX_CNT(portno)));
 736        sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
 737                              spx5_inst_rd(inst,
 738                                           ASM_PMAC_TX_SIZE1519TOMAX_CNT(portno)));
 739}
 740
 741static void sparx5_get_asm_misc_stats(u64 *portstats, void __iomem *inst, int
 742                                      portno)
 743{
 744        sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_err_cnt],
 745                              spx5_inst_rd(inst,
 746                                           ASM_MM_RX_ASSEMBLY_ERR_CNT(portno)));
 747        sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_ok_cnt],
 748                              spx5_inst_rd(inst,
 749                                           ASM_MM_RX_ASSEMBLY_OK_CNT(portno)));
 750        sparx5_update_counter(&portstats[spx5_stats_mm_rx_merge_frag_cnt],
 751                              spx5_inst_rd(inst,
 752                                           ASM_MM_RX_MERGE_FRAG_CNT(portno)));
 753        sparx5_update_counter(&portstats[spx5_stats_mm_rx_smd_err_cnt],
 754                              spx5_inst_rd(inst,
 755                                           ASM_MM_RX_SMD_ERR_CNT(portno)));
 756        sparx5_update_counter(&portstats[spx5_stats_mm_tx_pfragment_cnt],
 757                              spx5_inst_rd(inst,
 758                                           ASM_MM_TX_PFRAGMENT_CNT(portno)));
 759        sparx5_update_counter(&portstats[spx5_stats_rx_bad_bytes_cnt],
 760                              spx5_inst_rd(inst, ASM_RX_BAD_BYTES_CNT(portno)));
 761        sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
 762                              spx5_inst_rd(inst,
 763                                           ASM_PMAC_RX_BAD_BYTES_CNT(portno)));
 764        sparx5_update_counter(&portstats[spx5_stats_rx_in_bytes_cnt],
 765                              spx5_inst_rd(inst, ASM_RX_IN_BYTES_CNT(portno)));
 766        sparx5_update_counter(&portstats[spx5_stats_rx_ipg_shrink_cnt],
 767                              spx5_inst_rd(inst,
 768                                           ASM_RX_IPG_SHRINK_CNT(portno)));
 769        sparx5_update_counter(&portstats[spx5_stats_rx_sync_lost_err_cnt],
 770                              spx5_inst_rd(inst,
 771                                           ASM_RX_SYNC_LOST_ERR_CNT(portno)));
 772        sparx5_update_counter(&portstats[spx5_stats_rx_tagged_frms_cnt],
 773                              spx5_inst_rd(inst,
 774                                           ASM_RX_TAGGED_FRMS_CNT(portno)));
 775        sparx5_update_counter(&portstats[spx5_stats_rx_untagged_frms_cnt],
 776                              spx5_inst_rd(inst,
 777                                           ASM_RX_UNTAGGED_FRMS_CNT(portno)));
 778        sparx5_update_counter(&portstats[spx5_stats_tx_out_bytes_cnt],
 779                              spx5_inst_rd(inst, ASM_TX_OUT_BYTES_CNT(portno)));
 780        sparx5_update_counter(&portstats[spx5_stats_tx_tagged_frms_cnt],
 781                              spx5_inst_rd(inst,
 782                                           ASM_TX_TAGGED_FRMS_CNT(portno)));
 783        sparx5_update_counter(&portstats[spx5_stats_tx_untagged_frms_cnt],
 784                              spx5_inst_rd(inst,
 785                                           ASM_TX_UNTAGGED_FRMS_CNT(portno)));
 786}
 787
 788static void sparx5_get_asm_stats(struct sparx5 *sparx5, int portno)
 789{
 790        u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
 791        void __iomem *inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
 792
 793        sparx5_get_asm_phy_stats(portstats, inst, portno);
 794        sparx5_get_asm_mac_stats(portstats, inst, portno);
 795        sparx5_get_asm_mac_ctrl_stats(portstats, inst, portno);
 796        sparx5_get_asm_rmon_stats(portstats, inst, portno);
 797        sparx5_get_asm_misc_stats(portstats, inst, portno);
 798}
 799
 800static const struct ethtool_rmon_hist_range sparx5_rmon_ranges[] = {
 801        {    0,    64 },
 802        {   65,   127 },
 803        {  128,   255 },
 804        {  256,   511 },
 805        {  512,  1023 },
 806        { 1024,  1518 },
 807        { 1519, 10239 },
 808        {}
 809};
 810
 811static void sparx5_get_eth_phy_stats(struct net_device *ndev,
 812                                     struct ethtool_eth_phy_stats *phy_stats)
 813{
 814        struct sparx5_port *port = netdev_priv(ndev);
 815        struct sparx5 *sparx5 = port->sparx5;
 816        int portno = port->portno;
 817        void __iomem *inst;
 818        u64 *portstats;
 819
 820        portstats = &sparx5->stats[portno * sparx5->num_stats];
 821        if (sparx5_is_baser(port->conf.portmode)) {
 822                u32 tinst = sparx5_port_dev_index(portno);
 823                u32 dev = sparx5_to_high_dev(portno);
 824
 825                inst = spx5_inst_get(sparx5, dev, tinst);
 826                sparx5_get_dev_phy_stats(portstats, inst, tinst);
 827        } else {
 828                inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
 829                sparx5_get_asm_phy_stats(portstats, inst, portno);
 830        }
 831        phy_stats->SymbolErrorDuringCarrier =
 832                portstats[spx5_stats_rx_symbol_err_cnt] +
 833                portstats[spx5_stats_pmac_rx_symbol_err_cnt];
 834}
 835
 836static void sparx5_get_eth_mac_stats(struct net_device *ndev,
 837                                     struct ethtool_eth_mac_stats *mac_stats)
 838{
 839        struct sparx5_port *port = netdev_priv(ndev);
 840        struct sparx5 *sparx5 = port->sparx5;
 841        int portno = port->portno;
 842        void __iomem *inst;
 843        u64 *portstats;
 844
 845        portstats = &sparx5->stats[portno * sparx5->num_stats];
 846        if (sparx5_is_baser(port->conf.portmode)) {
 847                u32 tinst = sparx5_port_dev_index(portno);
 848                u32 dev = sparx5_to_high_dev(portno);
 849
 850                inst = spx5_inst_get(sparx5, dev, tinst);
 851                sparx5_get_dev_mac_stats(portstats, inst, tinst);
 852        } else {
 853                inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
 854                sparx5_get_asm_mac_stats(portstats, inst, portno);
 855        }
 856        mac_stats->FramesTransmittedOK = portstats[spx5_stats_tx_uc_cnt] +
 857                portstats[spx5_stats_pmac_tx_uc_cnt] +
 858                portstats[spx5_stats_tx_mc_cnt] +
 859                portstats[spx5_stats_tx_bc_cnt];
 860        mac_stats->SingleCollisionFrames =
 861                portstats[spx5_stats_tx_backoff1_cnt];
 862        mac_stats->MultipleCollisionFrames =
 863                portstats[spx5_stats_tx_multi_coll_cnt];
 864        mac_stats->FramesReceivedOK = portstats[spx5_stats_rx_uc_cnt] +
 865                portstats[spx5_stats_pmac_rx_uc_cnt] +
 866                portstats[spx5_stats_rx_mc_cnt] +
 867                portstats[spx5_stats_rx_bc_cnt];
 868        mac_stats->FrameCheckSequenceErrors =
 869                portstats[spx5_stats_rx_crc_err_cnt] +
 870                portstats[spx5_stats_pmac_rx_crc_err_cnt];
 871        mac_stats->AlignmentErrors = portstats[spx5_stats_rx_alignment_lost_cnt]
 872                + portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
 873        mac_stats->OctetsTransmittedOK = portstats[spx5_stats_tx_ok_bytes_cnt] +
 874                portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
 875        mac_stats->FramesWithDeferredXmissions =
 876                portstats[spx5_stats_tx_defer_cnt];
 877        mac_stats->LateCollisions =
 878                portstats[spx5_stats_tx_late_coll_cnt];
 879        mac_stats->FramesAbortedDueToXSColls =
 880                portstats[spx5_stats_tx_xcoll_cnt];
 881        mac_stats->CarrierSenseErrors = portstats[spx5_stats_tx_csense_cnt];
 882        mac_stats->OctetsReceivedOK = portstats[spx5_stats_rx_ok_bytes_cnt] +
 883                portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
 884        mac_stats->MulticastFramesXmittedOK = portstats[spx5_stats_tx_mc_cnt] +
 885                portstats[spx5_stats_pmac_tx_mc_cnt];
 886        mac_stats->BroadcastFramesXmittedOK = portstats[spx5_stats_tx_bc_cnt] +
 887                portstats[spx5_stats_pmac_tx_bc_cnt];
 888        mac_stats->FramesWithExcessiveDeferral =
 889                portstats[spx5_stats_tx_xdefer_cnt];
 890        mac_stats->MulticastFramesReceivedOK = portstats[spx5_stats_rx_mc_cnt] +
 891                portstats[spx5_stats_pmac_rx_mc_cnt];
 892        mac_stats->BroadcastFramesReceivedOK = portstats[spx5_stats_rx_bc_cnt] +
 893                portstats[spx5_stats_pmac_rx_bc_cnt];
 894        mac_stats->InRangeLengthErrors =
 895                portstats[spx5_stats_rx_in_range_len_err_cnt] +
 896                portstats[spx5_stats_pmac_rx_in_range_len_err_cnt];
 897        mac_stats->OutOfRangeLengthField =
 898                portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
 899                portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt];
 900        mac_stats->FrameTooLongErrors = portstats[spx5_stats_rx_oversize_cnt] +
 901                portstats[spx5_stats_pmac_rx_oversize_cnt];
 902}
 903
 904static void sparx5_get_eth_mac_ctrl_stats(struct net_device *ndev,
 905                                          struct ethtool_eth_ctrl_stats *mac_ctrl_stats)
 906{
 907        struct sparx5_port *port = netdev_priv(ndev);
 908        struct sparx5 *sparx5 = port->sparx5;
 909        int portno = port->portno;
 910        void __iomem *inst;
 911        u64 *portstats;
 912
 913        portstats = &sparx5->stats[portno * sparx5->num_stats];
 914        if (sparx5_is_baser(port->conf.portmode)) {
 915                u32 tinst = sparx5_port_dev_index(portno);
 916                u32 dev = sparx5_to_high_dev(portno);
 917
 918                inst = spx5_inst_get(sparx5, dev, tinst);
 919                sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
 920        } else {
 921                inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
 922                sparx5_get_asm_mac_ctrl_stats(portstats, inst, portno);
 923        }
 924        mac_ctrl_stats->MACControlFramesTransmitted =
 925                portstats[spx5_stats_tx_pause_cnt] +
 926                portstats[spx5_stats_pmac_tx_pause_cnt];
 927        mac_ctrl_stats->MACControlFramesReceived =
 928                portstats[spx5_stats_rx_pause_cnt] +
 929                portstats[spx5_stats_pmac_rx_pause_cnt];
 930        mac_ctrl_stats->UnsupportedOpcodesReceived =
 931                portstats[spx5_stats_rx_unsup_opcode_cnt] +
 932                portstats[spx5_stats_pmac_rx_unsup_opcode_cnt];
 933}
 934
 935static void sparx5_get_eth_rmon_stats(struct net_device *ndev,
 936                                      struct ethtool_rmon_stats *rmon_stats,
 937                                      const struct ethtool_rmon_hist_range **ranges)
 938{
 939        struct sparx5_port *port = netdev_priv(ndev);
 940        struct sparx5 *sparx5 = port->sparx5;
 941        int portno = port->portno;
 942        void __iomem *inst;
 943        u64 *portstats;
 944
 945        portstats = &sparx5->stats[portno * sparx5->num_stats];
 946        if (sparx5_is_baser(port->conf.portmode)) {
 947                u32 tinst = sparx5_port_dev_index(portno);
 948                u32 dev = sparx5_to_high_dev(portno);
 949
 950                inst = spx5_inst_get(sparx5, dev, tinst);
 951                sparx5_get_dev_rmon_stats(portstats, inst, tinst);
 952        } else {
 953                inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
 954                sparx5_get_asm_rmon_stats(portstats, inst, portno);
 955        }
 956        rmon_stats->undersize_pkts = portstats[spx5_stats_rx_undersize_cnt] +
 957                portstats[spx5_stats_pmac_rx_undersize_cnt];
 958        rmon_stats->oversize_pkts = portstats[spx5_stats_rx_oversize_cnt] +
 959                portstats[spx5_stats_pmac_rx_oversize_cnt];
 960        rmon_stats->fragments = portstats[spx5_stats_rx_fragments_cnt] +
 961                portstats[spx5_stats_pmac_rx_fragments_cnt];
 962        rmon_stats->jabbers = portstats[spx5_stats_rx_jabbers_cnt] +
 963                portstats[spx5_stats_pmac_rx_jabbers_cnt];
 964        rmon_stats->hist[0] = portstats[spx5_stats_rx_size64_cnt] +
 965                portstats[spx5_stats_pmac_rx_size64_cnt];
 966        rmon_stats->hist[1] = portstats[spx5_stats_rx_size65to127_cnt] +
 967                portstats[spx5_stats_pmac_rx_size65to127_cnt];
 968        rmon_stats->hist[2] = portstats[spx5_stats_rx_size128to255_cnt] +
 969                portstats[spx5_stats_pmac_rx_size128to255_cnt];
 970        rmon_stats->hist[3] = portstats[spx5_stats_rx_size256to511_cnt] +
 971                portstats[spx5_stats_pmac_rx_size256to511_cnt];
 972        rmon_stats->hist[4] = portstats[spx5_stats_rx_size512to1023_cnt] +
 973                portstats[spx5_stats_pmac_rx_size512to1023_cnt];
 974        rmon_stats->hist[5] = portstats[spx5_stats_rx_size1024to1518_cnt] +
 975                portstats[spx5_stats_pmac_rx_size1024to1518_cnt];
 976        rmon_stats->hist[6] = portstats[spx5_stats_rx_size1519tomax_cnt] +
 977                portstats[spx5_stats_pmac_rx_size1519tomax_cnt];
 978        rmon_stats->hist_tx[0] = portstats[spx5_stats_tx_size64_cnt] +
 979                portstats[spx5_stats_pmac_tx_size64_cnt];
 980        rmon_stats->hist_tx[1] = portstats[spx5_stats_tx_size65to127_cnt] +
 981                portstats[spx5_stats_pmac_tx_size65to127_cnt];
 982        rmon_stats->hist_tx[2] = portstats[spx5_stats_tx_size128to255_cnt] +
 983                portstats[spx5_stats_pmac_tx_size128to255_cnt];
 984        rmon_stats->hist_tx[3] = portstats[spx5_stats_tx_size256to511_cnt] +
 985                portstats[spx5_stats_pmac_tx_size256to511_cnt];
 986        rmon_stats->hist_tx[4] = portstats[spx5_stats_tx_size512to1023_cnt] +
 987                portstats[spx5_stats_pmac_tx_size512to1023_cnt];
 988        rmon_stats->hist_tx[5] = portstats[spx5_stats_tx_size1024to1518_cnt] +
 989                portstats[spx5_stats_pmac_tx_size1024to1518_cnt];
 990        rmon_stats->hist_tx[6] = portstats[spx5_stats_tx_size1519tomax_cnt] +
 991                portstats[spx5_stats_pmac_tx_size1519tomax_cnt];
 992        *ranges = sparx5_rmon_ranges;
 993}
 994
 995static int sparx5_get_sset_count(struct net_device *ndev, int sset)
 996{
 997        struct sparx5_port *port = netdev_priv(ndev);
 998        struct sparx5  *sparx5 = port->sparx5;
 999
1000        if (sset != ETH_SS_STATS)
1001                return -EOPNOTSUPP;
1002        return sparx5->num_ethtool_stats;
1003}
1004
1005static void sparx5_get_sset_strings(struct net_device *ndev, u32 sset, u8 *data)
1006{
1007        struct sparx5_port *port = netdev_priv(ndev);
1008        struct sparx5  *sparx5 = port->sparx5;
1009        int idx;
1010
1011        if (sset != ETH_SS_STATS)
1012                return;
1013
1014        for (idx = 0; idx < sparx5->num_ethtool_stats; idx++)
1015                strncpy(data + idx * ETH_GSTRING_LEN,
1016                        sparx5->stats_layout[idx], ETH_GSTRING_LEN);
1017}
1018
1019static void sparx5_get_sset_data(struct net_device *ndev,
1020                                 struct ethtool_stats *stats, u64 *data)
1021{
1022        struct sparx5_port *port = netdev_priv(ndev);
1023        struct sparx5 *sparx5 = port->sparx5;
1024        int portno = port->portno;
1025        void __iomem *inst;
1026        u64 *portstats;
1027        int idx;
1028
1029        portstats = &sparx5->stats[portno * sparx5->num_stats];
1030        if (sparx5_is_baser(port->conf.portmode)) {
1031                u32 tinst = sparx5_port_dev_index(portno);
1032                u32 dev = sparx5_to_high_dev(portno);
1033
1034                inst = spx5_inst_get(sparx5, dev, tinst);
1035                sparx5_get_dev_misc_stats(portstats, inst, tinst);
1036        } else {
1037                inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
1038                sparx5_get_asm_misc_stats(portstats, inst, portno);
1039        }
1040        sparx5_get_ana_ac_stats_stats(sparx5, portno);
1041        sparx5_get_queue_sys_stats(sparx5, portno);
1042        /* Copy port counters to the ethtool buffer */
1043        for (idx = spx5_stats_mm_rx_assembly_err_cnt;
1044             idx < spx5_stats_mm_rx_assembly_err_cnt +
1045             sparx5->num_ethtool_stats; idx++)
1046                *data++ = portstats[idx];
1047}
1048
1049void sparx5_get_stats64(struct net_device *ndev,
1050                        struct rtnl_link_stats64 *stats)
1051{
1052        struct sparx5_port *port = netdev_priv(ndev);
1053        struct sparx5 *sparx5 = port->sparx5;
1054        u64 *portstats;
1055        int idx;
1056
1057        if (!sparx5->stats)
1058                return; /* Not initialized yet */
1059
1060        portstats = &sparx5->stats[port->portno * sparx5->num_stats];
1061
1062        stats->rx_packets = portstats[spx5_stats_rx_uc_cnt] +
1063                portstats[spx5_stats_pmac_rx_uc_cnt] +
1064                portstats[spx5_stats_rx_mc_cnt] +
1065                portstats[spx5_stats_rx_bc_cnt];
1066        stats->tx_packets = portstats[spx5_stats_tx_uc_cnt] +
1067                portstats[spx5_stats_pmac_tx_uc_cnt] +
1068                portstats[spx5_stats_tx_mc_cnt] +
1069                portstats[spx5_stats_tx_bc_cnt];
1070        stats->rx_bytes = portstats[spx5_stats_rx_ok_bytes_cnt] +
1071                portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
1072        stats->tx_bytes = portstats[spx5_stats_tx_ok_bytes_cnt] +
1073                portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
1074        stats->rx_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1075                portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1076                portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1077                portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1078                portstats[spx5_stats_rx_oversize_cnt] +
1079                portstats[spx5_stats_pmac_rx_oversize_cnt] +
1080                portstats[spx5_stats_rx_crc_err_cnt] +
1081                portstats[spx5_stats_pmac_rx_crc_err_cnt] +
1082                portstats[spx5_stats_rx_alignment_lost_cnt] +
1083                portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1084        stats->tx_errors = portstats[spx5_stats_tx_xcoll_cnt] +
1085                portstats[spx5_stats_tx_csense_cnt] +
1086                portstats[spx5_stats_tx_late_coll_cnt];
1087        stats->multicast = portstats[spx5_stats_rx_mc_cnt] +
1088                portstats[spx5_stats_pmac_rx_mc_cnt];
1089        stats->collisions = portstats[spx5_stats_tx_late_coll_cnt] +
1090                portstats[spx5_stats_tx_xcoll_cnt] +
1091                portstats[spx5_stats_tx_backoff1_cnt];
1092        stats->rx_length_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1093                portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1094                portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1095                portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1096                portstats[spx5_stats_rx_oversize_cnt] +
1097                portstats[spx5_stats_pmac_rx_oversize_cnt];
1098        stats->rx_crc_errors = portstats[spx5_stats_rx_crc_err_cnt] +
1099                portstats[spx5_stats_pmac_rx_crc_err_cnt];
1100        stats->rx_frame_errors = portstats[spx5_stats_rx_alignment_lost_cnt] +
1101                portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1102        stats->tx_aborted_errors = portstats[spx5_stats_tx_xcoll_cnt];
1103        stats->tx_carrier_errors = portstats[spx5_stats_tx_csense_cnt];
1104        stats->tx_window_errors = portstats[spx5_stats_tx_late_coll_cnt];
1105        stats->rx_dropped = portstats[spx5_stats_ana_ac_port_stat_lsb_cnt];
1106        for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++stats)
1107                stats->rx_dropped += portstats[spx5_stats_green_p0_rx_port_drop
1108                                               + idx];
1109        stats->tx_dropped = portstats[spx5_stats_tx_local_drop];
1110}
1111
1112static void sparx5_update_port_stats(struct sparx5 *sparx5, int portno)
1113{
1114        if (sparx5_is_baser(sparx5->ports[portno]->conf.portmode))
1115                sparx5_get_device_stats(sparx5, portno);
1116        else
1117                sparx5_get_asm_stats(sparx5, portno);
1118        sparx5_get_ana_ac_stats_stats(sparx5, portno);
1119        sparx5_get_queue_sys_stats(sparx5, portno);
1120}
1121
1122static void sparx5_update_stats(struct sparx5 *sparx5)
1123{
1124        int idx;
1125
1126        for (idx = 0; idx < SPX5_PORTS; idx++)
1127                if (sparx5->ports[idx])
1128                        sparx5_update_port_stats(sparx5, idx);
1129}
1130
1131static void sparx5_check_stats_work(struct work_struct *work)
1132{
1133        struct delayed_work *dwork = to_delayed_work(work);
1134        struct sparx5 *sparx5 = container_of(dwork,
1135                                             struct sparx5,
1136                                             stats_work);
1137
1138        sparx5_update_stats(sparx5);
1139
1140        queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1141                           SPX5_STATS_CHECK_DELAY);
1142}
1143
1144static int sparx5_get_link_settings(struct net_device *ndev,
1145                                    struct ethtool_link_ksettings *cmd)
1146{
1147        struct sparx5_port *port = netdev_priv(ndev);
1148
1149        return phylink_ethtool_ksettings_get(port->phylink, cmd);
1150}
1151
1152static int sparx5_set_link_settings(struct net_device *ndev,
1153                                    const struct ethtool_link_ksettings *cmd)
1154{
1155        struct sparx5_port *port = netdev_priv(ndev);
1156
1157        return phylink_ethtool_ksettings_set(port->phylink, cmd);
1158}
1159
1160static void sparx5_config_stats(struct sparx5 *sparx5)
1161{
1162        /* Enable global events for port policer drops */
1163        spx5_rmw(ANA_AC_PORT_SGE_CFG_MASK_SET(0xf0f0),
1164                 ANA_AC_PORT_SGE_CFG_MASK,
1165                 sparx5,
1166                 ANA_AC_PORT_SGE_CFG(SPX5_PORT_POLICER_DROPS));
1167}
1168
1169static void sparx5_config_port_stats(struct sparx5 *sparx5, int portno)
1170{
1171        /* Clear Queue System counters */
1172        spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno) |
1173                XQS_STAT_CFG_STAT_CLEAR_SHOT_SET(3), sparx5,
1174                XQS_STAT_CFG);
1175
1176        /* Use counter for port policer drop count */
1177        spx5_rmw(ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE_SET(1) |
1178                 ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE_SET(0) |
1179                 ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK_SET(0xff),
1180                 ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE |
1181                 ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE |
1182                 ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK,
1183                 sparx5, ANA_AC_PORT_STAT_CFG(portno, SPX5_PORT_POLICER_DROPS));
1184}
1185
1186const struct ethtool_ops sparx5_ethtool_ops = {
1187        .get_sset_count         = sparx5_get_sset_count,
1188        .get_strings            = sparx5_get_sset_strings,
1189        .get_ethtool_stats      = sparx5_get_sset_data,
1190        .get_link_ksettings     = sparx5_get_link_settings,
1191        .set_link_ksettings     = sparx5_set_link_settings,
1192        .get_link               = ethtool_op_get_link,
1193        .get_eth_phy_stats      = sparx5_get_eth_phy_stats,
1194        .get_eth_mac_stats      = sparx5_get_eth_mac_stats,
1195        .get_eth_ctrl_stats     = sparx5_get_eth_mac_ctrl_stats,
1196        .get_rmon_stats         = sparx5_get_eth_rmon_stats,
1197};
1198
1199int sparx_stats_init(struct sparx5 *sparx5)
1200{
1201        char queue_name[32];
1202        int portno;
1203
1204        sparx5->stats_layout = sparx5_stats_layout;
1205        sparx5->num_stats = spx5_stats_count;
1206        sparx5->num_ethtool_stats = ARRAY_SIZE(sparx5_stats_layout);
1207        sparx5->stats = devm_kcalloc(sparx5->dev,
1208                                     SPX5_PORTS_ALL * sparx5->num_stats,
1209                                     sizeof(u64), GFP_KERNEL);
1210        if (!sparx5->stats)
1211                return -ENOMEM;
1212
1213        mutex_init(&sparx5->queue_stats_lock);
1214        sparx5_config_stats(sparx5);
1215        for (portno = 0; portno < SPX5_PORTS; portno++)
1216                if (sparx5->ports[portno])
1217                        sparx5_config_port_stats(sparx5, portno);
1218
1219        snprintf(queue_name, sizeof(queue_name), "%s-stats",
1220                 dev_name(sparx5->dev));
1221        sparx5->stats_queue = create_singlethread_workqueue(queue_name);
1222        INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
1223        queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1224                           SPX5_STATS_CHECK_DELAY);
1225
1226        return 0;
1227}
1228