Linux Audio

Check our new training course

Loading...
v6.8
   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		ethtool_puts(&data, sparx5->stats_layout[idx]);
 
1016}
1017
1018static void sparx5_get_sset_data(struct net_device *ndev,
1019				 struct ethtool_stats *stats, u64 *data)
1020{
1021	struct sparx5_port *port = netdev_priv(ndev);
1022	struct sparx5 *sparx5 = port->sparx5;
1023	int portno = port->portno;
1024	void __iomem *inst;
1025	u64 *portstats;
1026	int idx;
1027
1028	portstats = &sparx5->stats[portno * sparx5->num_stats];
1029	if (sparx5_is_baser(port->conf.portmode)) {
1030		u32 tinst = sparx5_port_dev_index(portno);
1031		u32 dev = sparx5_to_high_dev(portno);
1032
1033		inst = spx5_inst_get(sparx5, dev, tinst);
1034		sparx5_get_dev_misc_stats(portstats, inst, tinst);
1035	} else {
1036		inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
1037		sparx5_get_asm_misc_stats(portstats, inst, portno);
1038	}
1039	sparx5_get_ana_ac_stats_stats(sparx5, portno);
1040	sparx5_get_queue_sys_stats(sparx5, portno);
1041	/* Copy port counters to the ethtool buffer */
1042	for (idx = spx5_stats_mm_rx_assembly_err_cnt;
1043	     idx < spx5_stats_mm_rx_assembly_err_cnt +
1044	     sparx5->num_ethtool_stats; idx++)
1045		*data++ = portstats[idx];
1046}
1047
1048void sparx5_get_stats64(struct net_device *ndev,
1049			struct rtnl_link_stats64 *stats)
1050{
1051	struct sparx5_port *port = netdev_priv(ndev);
1052	struct sparx5 *sparx5 = port->sparx5;
1053	u64 *portstats;
1054	int idx;
1055
1056	if (!sparx5->stats)
1057		return; /* Not initialized yet */
1058
1059	portstats = &sparx5->stats[port->portno * sparx5->num_stats];
1060
1061	stats->rx_packets = portstats[spx5_stats_rx_uc_cnt] +
1062		portstats[spx5_stats_pmac_rx_uc_cnt] +
1063		portstats[spx5_stats_rx_mc_cnt] +
1064		portstats[spx5_stats_rx_bc_cnt];
1065	stats->tx_packets = portstats[spx5_stats_tx_uc_cnt] +
1066		portstats[spx5_stats_pmac_tx_uc_cnt] +
1067		portstats[spx5_stats_tx_mc_cnt] +
1068		portstats[spx5_stats_tx_bc_cnt];
1069	stats->rx_bytes = portstats[spx5_stats_rx_ok_bytes_cnt] +
1070		portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
1071	stats->tx_bytes = portstats[spx5_stats_tx_ok_bytes_cnt] +
1072		portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
1073	stats->rx_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1074		portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1075		portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1076		portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1077		portstats[spx5_stats_rx_oversize_cnt] +
1078		portstats[spx5_stats_pmac_rx_oversize_cnt] +
1079		portstats[spx5_stats_rx_crc_err_cnt] +
1080		portstats[spx5_stats_pmac_rx_crc_err_cnt] +
1081		portstats[spx5_stats_rx_alignment_lost_cnt] +
1082		portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1083	stats->tx_errors = portstats[spx5_stats_tx_xcoll_cnt] +
1084		portstats[spx5_stats_tx_csense_cnt] +
1085		portstats[spx5_stats_tx_late_coll_cnt];
1086	stats->multicast = portstats[spx5_stats_rx_mc_cnt] +
1087		portstats[spx5_stats_pmac_rx_mc_cnt];
1088	stats->collisions = portstats[spx5_stats_tx_late_coll_cnt] +
1089		portstats[spx5_stats_tx_xcoll_cnt] +
1090		portstats[spx5_stats_tx_backoff1_cnt];
1091	stats->rx_length_errors = portstats[spx5_stats_rx_in_range_len_err_cnt] +
1092		portstats[spx5_stats_pmac_rx_in_range_len_err_cnt] +
1093		portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
1094		portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt] +
1095		portstats[spx5_stats_rx_oversize_cnt] +
1096		portstats[spx5_stats_pmac_rx_oversize_cnt];
1097	stats->rx_crc_errors = portstats[spx5_stats_rx_crc_err_cnt] +
1098		portstats[spx5_stats_pmac_rx_crc_err_cnt];
1099	stats->rx_frame_errors = portstats[spx5_stats_rx_alignment_lost_cnt] +
1100		portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
1101	stats->tx_aborted_errors = portstats[spx5_stats_tx_xcoll_cnt];
1102	stats->tx_carrier_errors = portstats[spx5_stats_tx_csense_cnt];
1103	stats->tx_window_errors = portstats[spx5_stats_tx_late_coll_cnt];
1104	stats->rx_dropped = portstats[spx5_stats_ana_ac_port_stat_lsb_cnt];
1105	for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx)
1106		stats->rx_dropped += portstats[spx5_stats_green_p0_rx_port_drop
1107					       + idx];
1108	stats->tx_dropped = portstats[spx5_stats_tx_local_drop];
1109}
1110
1111static void sparx5_update_port_stats(struct sparx5 *sparx5, int portno)
1112{
1113	if (sparx5_is_baser(sparx5->ports[portno]->conf.portmode))
1114		sparx5_get_device_stats(sparx5, portno);
1115	else
1116		sparx5_get_asm_stats(sparx5, portno);
1117	sparx5_get_ana_ac_stats_stats(sparx5, portno);
1118	sparx5_get_queue_sys_stats(sparx5, portno);
1119}
1120
1121static void sparx5_update_stats(struct sparx5 *sparx5)
1122{
1123	int idx;
1124
1125	for (idx = 0; idx < SPX5_PORTS; idx++)
1126		if (sparx5->ports[idx])
1127			sparx5_update_port_stats(sparx5, idx);
1128}
1129
1130static void sparx5_check_stats_work(struct work_struct *work)
1131{
1132	struct delayed_work *dwork = to_delayed_work(work);
1133	struct sparx5 *sparx5 = container_of(dwork,
1134					     struct sparx5,
1135					     stats_work);
1136
1137	sparx5_update_stats(sparx5);
1138
1139	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1140			   SPX5_STATS_CHECK_DELAY);
1141}
1142
1143static int sparx5_get_link_settings(struct net_device *ndev,
1144				    struct ethtool_link_ksettings *cmd)
1145{
1146	struct sparx5_port *port = netdev_priv(ndev);
1147
1148	return phylink_ethtool_ksettings_get(port->phylink, cmd);
1149}
1150
1151static int sparx5_set_link_settings(struct net_device *ndev,
1152				    const struct ethtool_link_ksettings *cmd)
1153{
1154	struct sparx5_port *port = netdev_priv(ndev);
1155
1156	return phylink_ethtool_ksettings_set(port->phylink, cmd);
1157}
1158
1159static void sparx5_config_stats(struct sparx5 *sparx5)
1160{
1161	/* Enable global events for port policer drops */
1162	spx5_rmw(ANA_AC_PORT_SGE_CFG_MASK_SET(0xf0f0),
1163		 ANA_AC_PORT_SGE_CFG_MASK,
1164		 sparx5,
1165		 ANA_AC_PORT_SGE_CFG(SPX5_PORT_POLICER_DROPS));
1166}
1167
1168static void sparx5_config_port_stats(struct sparx5 *sparx5, int portno)
1169{
1170	/* Clear Queue System counters */
1171	spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno) |
1172		XQS_STAT_CFG_STAT_CLEAR_SHOT_SET(3), sparx5,
1173		XQS_STAT_CFG);
1174
1175	/* Use counter for port policer drop count */
1176	spx5_rmw(ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE_SET(1) |
1177		 ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE_SET(0) |
1178		 ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK_SET(0xff),
1179		 ANA_AC_PORT_STAT_CFG_CFG_CNT_FRM_TYPE |
1180		 ANA_AC_PORT_STAT_CFG_CFG_CNT_BYTE |
1181		 ANA_AC_PORT_STAT_CFG_CFG_PRIO_MASK,
1182		 sparx5, ANA_AC_PORT_STAT_CFG(portno, SPX5_PORT_POLICER_DROPS));
1183}
1184
1185static int sparx5_get_ts_info(struct net_device *dev,
1186			      struct ethtool_ts_info *info)
1187{
1188	struct sparx5_port *port = netdev_priv(dev);
1189	struct sparx5 *sparx5 = port->sparx5;
1190	struct sparx5_phc *phc;
1191
1192	if (!sparx5->ptp)
1193		return ethtool_op_get_ts_info(dev, info);
1194
1195	phc = &sparx5->phc[SPARX5_PHC_PORT];
1196
1197	info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
1198	if (info->phc_index == -1) {
1199		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1200					 SOF_TIMESTAMPING_RX_SOFTWARE |
1201					 SOF_TIMESTAMPING_SOFTWARE;
1202		return 0;
1203	}
1204	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1205				 SOF_TIMESTAMPING_RX_SOFTWARE |
1206				 SOF_TIMESTAMPING_SOFTWARE |
1207				 SOF_TIMESTAMPING_TX_HARDWARE |
1208				 SOF_TIMESTAMPING_RX_HARDWARE |
1209				 SOF_TIMESTAMPING_RAW_HARDWARE;
1210	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
1211			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
1212	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1213			   BIT(HWTSTAMP_FILTER_ALL);
1214
1215	return 0;
1216}
1217
1218const struct ethtool_ops sparx5_ethtool_ops = {
1219	.get_sset_count         = sparx5_get_sset_count,
1220	.get_strings            = sparx5_get_sset_strings,
1221	.get_ethtool_stats      = sparx5_get_sset_data,
1222	.get_link_ksettings	= sparx5_get_link_settings,
1223	.set_link_ksettings	= sparx5_set_link_settings,
1224	.get_link               = ethtool_op_get_link,
1225	.get_eth_phy_stats      = sparx5_get_eth_phy_stats,
1226	.get_eth_mac_stats      = sparx5_get_eth_mac_stats,
1227	.get_eth_ctrl_stats     = sparx5_get_eth_mac_ctrl_stats,
1228	.get_rmon_stats         = sparx5_get_eth_rmon_stats,
1229	.get_ts_info            = sparx5_get_ts_info,
1230};
1231
1232int sparx_stats_init(struct sparx5 *sparx5)
1233{
1234	char queue_name[32];
1235	int portno;
1236
1237	sparx5->stats_layout = sparx5_stats_layout;
1238	sparx5->num_stats = spx5_stats_count;
1239	sparx5->num_ethtool_stats = ARRAY_SIZE(sparx5_stats_layout);
1240	sparx5->stats = devm_kcalloc(sparx5->dev,
1241				     SPX5_PORTS_ALL * sparx5->num_stats,
1242				     sizeof(u64), GFP_KERNEL);
1243	if (!sparx5->stats)
1244		return -ENOMEM;
1245
1246	mutex_init(&sparx5->queue_stats_lock);
1247	sparx5_config_stats(sparx5);
1248	for (portno = 0; portno < SPX5_PORTS; portno++)
1249		if (sparx5->ports[portno])
1250			sparx5_config_port_stats(sparx5, portno);
1251
1252	snprintf(queue_name, sizeof(queue_name), "%s-stats",
1253		 dev_name(sparx5->dev));
1254	sparx5->stats_queue = create_singlethread_workqueue(queue_name);
1255	if (!sparx5->stats_queue)
1256		return -ENOMEM;
1257
1258	INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
1259	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1260			   SPX5_STATS_CHECK_DELAY);
1261
1262	return 0;
1263}
v6.2
   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)
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
1186static int sparx5_get_ts_info(struct net_device *dev,
1187			      struct ethtool_ts_info *info)
1188{
1189	struct sparx5_port *port = netdev_priv(dev);
1190	struct sparx5 *sparx5 = port->sparx5;
1191	struct sparx5_phc *phc;
1192
1193	if (!sparx5->ptp)
1194		return ethtool_op_get_ts_info(dev, info);
1195
1196	phc = &sparx5->phc[SPARX5_PHC_PORT];
1197
1198	info->phc_index = phc->clock ? ptp_clock_index(phc->clock) : -1;
1199	if (info->phc_index == -1) {
1200		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1201					 SOF_TIMESTAMPING_RX_SOFTWARE |
1202					 SOF_TIMESTAMPING_SOFTWARE;
1203		return 0;
1204	}
1205	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1206				 SOF_TIMESTAMPING_RX_SOFTWARE |
1207				 SOF_TIMESTAMPING_SOFTWARE |
1208				 SOF_TIMESTAMPING_TX_HARDWARE |
1209				 SOF_TIMESTAMPING_RX_HARDWARE |
1210				 SOF_TIMESTAMPING_RAW_HARDWARE;
1211	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
1212			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
1213	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1214			   BIT(HWTSTAMP_FILTER_ALL);
1215
1216	return 0;
1217}
1218
1219const struct ethtool_ops sparx5_ethtool_ops = {
1220	.get_sset_count         = sparx5_get_sset_count,
1221	.get_strings            = sparx5_get_sset_strings,
1222	.get_ethtool_stats      = sparx5_get_sset_data,
1223	.get_link_ksettings	= sparx5_get_link_settings,
1224	.set_link_ksettings	= sparx5_set_link_settings,
1225	.get_link               = ethtool_op_get_link,
1226	.get_eth_phy_stats      = sparx5_get_eth_phy_stats,
1227	.get_eth_mac_stats      = sparx5_get_eth_mac_stats,
1228	.get_eth_ctrl_stats     = sparx5_get_eth_mac_ctrl_stats,
1229	.get_rmon_stats         = sparx5_get_eth_rmon_stats,
1230	.get_ts_info            = sparx5_get_ts_info,
1231};
1232
1233int sparx_stats_init(struct sparx5 *sparx5)
1234{
1235	char queue_name[32];
1236	int portno;
1237
1238	sparx5->stats_layout = sparx5_stats_layout;
1239	sparx5->num_stats = spx5_stats_count;
1240	sparx5->num_ethtool_stats = ARRAY_SIZE(sparx5_stats_layout);
1241	sparx5->stats = devm_kcalloc(sparx5->dev,
1242				     SPX5_PORTS_ALL * sparx5->num_stats,
1243				     sizeof(u64), GFP_KERNEL);
1244	if (!sparx5->stats)
1245		return -ENOMEM;
1246
1247	mutex_init(&sparx5->queue_stats_lock);
1248	sparx5_config_stats(sparx5);
1249	for (portno = 0; portno < SPX5_PORTS; portno++)
1250		if (sparx5->ports[portno])
1251			sparx5_config_port_stats(sparx5, portno);
1252
1253	snprintf(queue_name, sizeof(queue_name), "%s-stats",
1254		 dev_name(sparx5->dev));
1255	sparx5->stats_queue = create_singlethread_workqueue(queue_name);
1256	if (!sparx5->stats_queue)
1257		return -ENOMEM;
1258
1259	INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
1260	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
1261			   SPX5_STATS_CHECK_DELAY);
1262
1263	return 0;
1264}