cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sparx5_ethtool.c (50622B)


      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	INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
   1257	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
   1258			   SPX5_STATS_CHECK_DELAY);
   1259
   1260	return 0;
   1261}