Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /* Microchip Sparx5 Switch driver
0003  *
0004  * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
0005  */
0006 
0007 #include <linux/ethtool.h>
0008 
0009 #include "sparx5_main_regs.h"
0010 #include "sparx5_main.h"
0011 #include "sparx5_port.h"
0012 
0013 /* Index of ANA_AC port counters */
0014 #define SPX5_PORT_POLICER_DROPS 0
0015 
0016 /* Add a potentially wrapping 32 bit value to a 64 bit counter */
0017 static void sparx5_update_counter(u64 *cnt, u32 val)
0018 {
0019     if (val < (*cnt & U32_MAX))
0020         *cnt += (u64)1 << 32; /* value has wrapped */
0021     *cnt = (*cnt & ~(u64)U32_MAX) + val;
0022 }
0023 
0024 enum sparx5_stats_entry {
0025     spx5_stats_rx_symbol_err_cnt = 0,
0026     spx5_stats_pmac_rx_symbol_err_cnt = 1,
0027     spx5_stats_tx_uc_cnt = 2,
0028     spx5_stats_pmac_tx_uc_cnt = 3,
0029     spx5_stats_tx_mc_cnt = 4,
0030     spx5_stats_tx_bc_cnt = 5,
0031     spx5_stats_tx_backoff1_cnt = 6,
0032     spx5_stats_tx_multi_coll_cnt = 7,
0033     spx5_stats_rx_uc_cnt = 8,
0034     spx5_stats_pmac_rx_uc_cnt = 9,
0035     spx5_stats_rx_mc_cnt = 10,
0036     spx5_stats_rx_bc_cnt = 11,
0037     spx5_stats_rx_crc_err_cnt = 12,
0038     spx5_stats_pmac_rx_crc_err_cnt = 13,
0039     spx5_stats_rx_alignment_lost_cnt = 14,
0040     spx5_stats_pmac_rx_alignment_lost_cnt = 15,
0041     spx5_stats_tx_ok_bytes_cnt = 16,
0042     spx5_stats_pmac_tx_ok_bytes_cnt = 17,
0043     spx5_stats_tx_defer_cnt = 18,
0044     spx5_stats_tx_late_coll_cnt = 19,
0045     spx5_stats_tx_xcoll_cnt = 20,
0046     spx5_stats_tx_csense_cnt = 21,
0047     spx5_stats_rx_ok_bytes_cnt = 22,
0048     spx5_stats_pmac_rx_ok_bytes_cnt = 23,
0049     spx5_stats_pmac_tx_mc_cnt = 24,
0050     spx5_stats_pmac_tx_bc_cnt = 25,
0051     spx5_stats_tx_xdefer_cnt = 26,
0052     spx5_stats_pmac_rx_mc_cnt = 27,
0053     spx5_stats_pmac_rx_bc_cnt = 28,
0054     spx5_stats_rx_in_range_len_err_cnt = 29,
0055     spx5_stats_pmac_rx_in_range_len_err_cnt = 30,
0056     spx5_stats_rx_out_of_range_len_err_cnt = 31,
0057     spx5_stats_pmac_rx_out_of_range_len_err_cnt = 32,
0058     spx5_stats_rx_oversize_cnt = 33,
0059     spx5_stats_pmac_rx_oversize_cnt = 34,
0060     spx5_stats_tx_pause_cnt = 35,
0061     spx5_stats_pmac_tx_pause_cnt = 36,
0062     spx5_stats_rx_pause_cnt = 37,
0063     spx5_stats_pmac_rx_pause_cnt = 38,
0064     spx5_stats_rx_unsup_opcode_cnt = 39,
0065     spx5_stats_pmac_rx_unsup_opcode_cnt = 40,
0066     spx5_stats_rx_undersize_cnt = 41,
0067     spx5_stats_pmac_rx_undersize_cnt = 42,
0068     spx5_stats_rx_fragments_cnt = 43,
0069     spx5_stats_pmac_rx_fragments_cnt = 44,
0070     spx5_stats_rx_jabbers_cnt = 45,
0071     spx5_stats_pmac_rx_jabbers_cnt = 46,
0072     spx5_stats_rx_size64_cnt = 47,
0073     spx5_stats_pmac_rx_size64_cnt = 48,
0074     spx5_stats_rx_size65to127_cnt = 49,
0075     spx5_stats_pmac_rx_size65to127_cnt = 50,
0076     spx5_stats_rx_size128to255_cnt = 51,
0077     spx5_stats_pmac_rx_size128to255_cnt = 52,
0078     spx5_stats_rx_size256to511_cnt = 53,
0079     spx5_stats_pmac_rx_size256to511_cnt = 54,
0080     spx5_stats_rx_size512to1023_cnt = 55,
0081     spx5_stats_pmac_rx_size512to1023_cnt = 56,
0082     spx5_stats_rx_size1024to1518_cnt = 57,
0083     spx5_stats_pmac_rx_size1024to1518_cnt = 58,
0084     spx5_stats_rx_size1519tomax_cnt = 59,
0085     spx5_stats_pmac_rx_size1519tomax_cnt = 60,
0086     spx5_stats_tx_size64_cnt = 61,
0087     spx5_stats_pmac_tx_size64_cnt = 62,
0088     spx5_stats_tx_size65to127_cnt = 63,
0089     spx5_stats_pmac_tx_size65to127_cnt = 64,
0090     spx5_stats_tx_size128to255_cnt = 65,
0091     spx5_stats_pmac_tx_size128to255_cnt = 66,
0092     spx5_stats_tx_size256to511_cnt = 67,
0093     spx5_stats_pmac_tx_size256to511_cnt = 68,
0094     spx5_stats_tx_size512to1023_cnt = 69,
0095     spx5_stats_pmac_tx_size512to1023_cnt = 70,
0096     spx5_stats_tx_size1024to1518_cnt = 71,
0097     spx5_stats_pmac_tx_size1024to1518_cnt = 72,
0098     spx5_stats_tx_size1519tomax_cnt = 73,
0099     spx5_stats_pmac_tx_size1519tomax_cnt = 74,
0100     spx5_stats_mm_rx_assembly_err_cnt = 75,
0101     spx5_stats_mm_rx_assembly_ok_cnt = 76,
0102     spx5_stats_mm_rx_merge_frag_cnt = 77,
0103     spx5_stats_mm_rx_smd_err_cnt = 78,
0104     spx5_stats_mm_tx_pfragment_cnt = 79,
0105     spx5_stats_rx_bad_bytes_cnt = 80,
0106     spx5_stats_pmac_rx_bad_bytes_cnt = 81,
0107     spx5_stats_rx_in_bytes_cnt = 82,
0108     spx5_stats_rx_ipg_shrink_cnt = 83,
0109     spx5_stats_rx_sync_lost_err_cnt = 84,
0110     spx5_stats_rx_tagged_frms_cnt = 85,
0111     spx5_stats_rx_untagged_frms_cnt = 86,
0112     spx5_stats_tx_out_bytes_cnt = 87,
0113     spx5_stats_tx_tagged_frms_cnt = 88,
0114     spx5_stats_tx_untagged_frms_cnt = 89,
0115     spx5_stats_rx_hih_cksm_err_cnt = 90,
0116     spx5_stats_pmac_rx_hih_cksm_err_cnt = 91,
0117     spx5_stats_rx_xgmii_prot_err_cnt = 92,
0118     spx5_stats_pmac_rx_xgmii_prot_err_cnt = 93,
0119     spx5_stats_ana_ac_port_stat_lsb_cnt = 94,
0120     spx5_stats_green_p0_rx_fwd = 95,
0121     spx5_stats_green_p0_rx_port_drop = 111,
0122     spx5_stats_green_p0_tx_port = 127,
0123     spx5_stats_rx_local_drop = 143,
0124     spx5_stats_tx_local_drop = 144,
0125     spx5_stats_count = 145,
0126 };
0127 
0128 static const char *const sparx5_stats_layout[] = {
0129     "mm_rx_assembly_err_cnt",
0130     "mm_rx_assembly_ok_cnt",
0131     "mm_rx_merge_frag_cnt",
0132     "mm_rx_smd_err_cnt",
0133     "mm_tx_pfragment_cnt",
0134     "rx_bad_bytes_cnt",
0135     "pmac_rx_bad_bytes_cnt",
0136     "rx_in_bytes_cnt",
0137     "rx_ipg_shrink_cnt",
0138     "rx_sync_lost_err_cnt",
0139     "rx_tagged_frms_cnt",
0140     "rx_untagged_frms_cnt",
0141     "tx_out_bytes_cnt",
0142     "tx_tagged_frms_cnt",
0143     "tx_untagged_frms_cnt",
0144     "rx_hih_cksm_err_cnt",
0145     "pmac_rx_hih_cksm_err_cnt",
0146     "rx_xgmii_prot_err_cnt",
0147     "pmac_rx_xgmii_prot_err_cnt",
0148     "rx_port_policer_drop",
0149     "rx_fwd_green_p0",
0150     "rx_fwd_green_p1",
0151     "rx_fwd_green_p2",
0152     "rx_fwd_green_p3",
0153     "rx_fwd_green_p4",
0154     "rx_fwd_green_p5",
0155     "rx_fwd_green_p6",
0156     "rx_fwd_green_p7",
0157     "rx_fwd_yellow_p0",
0158     "rx_fwd_yellow_p1",
0159     "rx_fwd_yellow_p2",
0160     "rx_fwd_yellow_p3",
0161     "rx_fwd_yellow_p4",
0162     "rx_fwd_yellow_p5",
0163     "rx_fwd_yellow_p6",
0164     "rx_fwd_yellow_p7",
0165     "rx_port_drop_green_p0",
0166     "rx_port_drop_green_p1",
0167     "rx_port_drop_green_p2",
0168     "rx_port_drop_green_p3",
0169     "rx_port_drop_green_p4",
0170     "rx_port_drop_green_p5",
0171     "rx_port_drop_green_p6",
0172     "rx_port_drop_green_p7",
0173     "rx_port_drop_yellow_p0",
0174     "rx_port_drop_yellow_p1",
0175     "rx_port_drop_yellow_p2",
0176     "rx_port_drop_yellow_p3",
0177     "rx_port_drop_yellow_p4",
0178     "rx_port_drop_yellow_p5",
0179     "rx_port_drop_yellow_p6",
0180     "rx_port_drop_yellow_p7",
0181     "tx_port_green_p0",
0182     "tx_port_green_p1",
0183     "tx_port_green_p2",
0184     "tx_port_green_p3",
0185     "tx_port_green_p4",
0186     "tx_port_green_p5",
0187     "tx_port_green_p6",
0188     "tx_port_green_p7",
0189     "tx_port_yellow_p0",
0190     "tx_port_yellow_p1",
0191     "tx_port_yellow_p2",
0192     "tx_port_yellow_p3",
0193     "tx_port_yellow_p4",
0194     "tx_port_yellow_p5",
0195     "tx_port_yellow_p6",
0196     "tx_port_yellow_p7",
0197     "rx_local_drop",
0198     "tx_local_drop",
0199 };
0200 
0201 static void sparx5_get_queue_sys_stats(struct sparx5 *sparx5, int portno)
0202 {
0203     u64 *portstats;
0204     u64 *stats;
0205     u32 addr;
0206     int idx;
0207 
0208     portstats = &sparx5->stats[portno * sparx5->num_stats];
0209     mutex_lock(&sparx5->queue_stats_lock);
0210     spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(portno), sparx5, XQS_STAT_CFG);
0211     addr = 0;
0212     stats = &portstats[spx5_stats_green_p0_rx_fwd];
0213     for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
0214         sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
0215     addr = 16;
0216     stats = &portstats[spx5_stats_green_p0_rx_port_drop];
0217     for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
0218         sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
0219     addr = 256;
0220     stats = &portstats[spx5_stats_green_p0_tx_port];
0221     for (idx = 0; idx < 2 * SPX5_PRIOS; ++idx, ++addr, ++stats)
0222         sparx5_update_counter(stats, spx5_rd(sparx5, XQS_CNT(addr)));
0223     sparx5_update_counter(&portstats[spx5_stats_rx_local_drop],
0224                   spx5_rd(sparx5, XQS_CNT(32)));
0225     sparx5_update_counter(&portstats[spx5_stats_tx_local_drop],
0226                   spx5_rd(sparx5, XQS_CNT(272)));
0227     mutex_unlock(&sparx5->queue_stats_lock);
0228 }
0229 
0230 static void sparx5_get_ana_ac_stats_stats(struct sparx5 *sparx5, int portno)
0231 {
0232     u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
0233 
0234     sparx5_update_counter(&portstats[spx5_stats_ana_ac_port_stat_lsb_cnt],
0235                   spx5_rd(sparx5, ANA_AC_PORT_STAT_LSB_CNT(portno,
0236                                        SPX5_PORT_POLICER_DROPS)));
0237 }
0238 
0239 static void sparx5_get_dev_phy_stats(u64 *portstats, void __iomem *inst, u32
0240                      tinst)
0241 {
0242     sparx5_update_counter(&portstats[spx5_stats_rx_symbol_err_cnt],
0243                   spx5_inst_rd(inst,
0244                        DEV5G_RX_SYMBOL_ERR_CNT(tinst)));
0245     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_symbol_err_cnt],
0246                   spx5_inst_rd(inst,
0247                        DEV5G_PMAC_RX_SYMBOL_ERR_CNT(tinst)));
0248 }
0249 
0250 static void sparx5_get_dev_mac_stats(u64 *portstats, void __iomem *inst, u32
0251                      tinst)
0252 {
0253     sparx5_update_counter(&portstats[spx5_stats_tx_uc_cnt],
0254                   spx5_inst_rd(inst, DEV5G_TX_UC_CNT(tinst)));
0255     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_uc_cnt],
0256                   spx5_inst_rd(inst, DEV5G_PMAC_TX_UC_CNT(tinst)));
0257     sparx5_update_counter(&portstats[spx5_stats_tx_mc_cnt],
0258                   spx5_inst_rd(inst, DEV5G_TX_MC_CNT(tinst)));
0259     sparx5_update_counter(&portstats[spx5_stats_tx_bc_cnt],
0260                   spx5_inst_rd(inst, DEV5G_TX_BC_CNT(tinst)));
0261     sparx5_update_counter(&portstats[spx5_stats_rx_uc_cnt],
0262                   spx5_inst_rd(inst, DEV5G_RX_UC_CNT(tinst)));
0263     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_uc_cnt],
0264                   spx5_inst_rd(inst, DEV5G_PMAC_RX_UC_CNT(tinst)));
0265     sparx5_update_counter(&portstats[spx5_stats_rx_mc_cnt],
0266                   spx5_inst_rd(inst, DEV5G_RX_MC_CNT(tinst)));
0267     sparx5_update_counter(&portstats[spx5_stats_rx_bc_cnt],
0268                   spx5_inst_rd(inst, DEV5G_RX_BC_CNT(tinst)));
0269     sparx5_update_counter(&portstats[spx5_stats_rx_crc_err_cnt],
0270                   spx5_inst_rd(inst, DEV5G_RX_CRC_ERR_CNT(tinst)));
0271     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_crc_err_cnt],
0272                   spx5_inst_rd(inst,
0273                        DEV5G_PMAC_RX_CRC_ERR_CNT(tinst)));
0274     sparx5_update_counter(&portstats[spx5_stats_rx_alignment_lost_cnt],
0275                   spx5_inst_rd(inst,
0276                        DEV5G_RX_ALIGNMENT_LOST_CNT(tinst)));
0277     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
0278                   spx5_inst_rd(inst,
0279                        DEV5G_PMAC_RX_ALIGNMENT_LOST_CNT(tinst)));
0280     sparx5_update_counter(&portstats[spx5_stats_tx_ok_bytes_cnt],
0281                   spx5_inst_rd(inst, DEV5G_TX_OK_BYTES_CNT(tinst)));
0282     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
0283                   spx5_inst_rd(inst,
0284                        DEV5G_PMAC_TX_OK_BYTES_CNT(tinst)));
0285     sparx5_update_counter(&portstats[spx5_stats_rx_ok_bytes_cnt],
0286                   spx5_inst_rd(inst, DEV5G_RX_OK_BYTES_CNT(tinst)));
0287     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
0288                   spx5_inst_rd(inst,
0289                        DEV5G_PMAC_RX_OK_BYTES_CNT(tinst)));
0290     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_mc_cnt],
0291                   spx5_inst_rd(inst, DEV5G_PMAC_TX_MC_CNT(tinst)));
0292     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_bc_cnt],
0293                   spx5_inst_rd(inst, DEV5G_PMAC_TX_BC_CNT(tinst)));
0294     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_mc_cnt],
0295                   spx5_inst_rd(inst, DEV5G_PMAC_RX_MC_CNT(tinst)));
0296     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bc_cnt],
0297                   spx5_inst_rd(inst, DEV5G_PMAC_RX_BC_CNT(tinst)));
0298     sparx5_update_counter(&portstats[spx5_stats_rx_in_range_len_err_cnt],
0299                   spx5_inst_rd(inst,
0300                        DEV5G_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
0301     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
0302                   spx5_inst_rd(inst,
0303                        DEV5G_PMAC_RX_IN_RANGE_LEN_ERR_CNT(tinst)));
0304     sparx5_update_counter(&portstats[spx5_stats_rx_out_of_range_len_err_cnt],
0305                   spx5_inst_rd(inst,
0306                        DEV5G_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
0307     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
0308                   spx5_inst_rd(inst,
0309                        DEV5G_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(tinst)));
0310     sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
0311                   spx5_inst_rd(inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
0312     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
0313                   spx5_inst_rd(inst,
0314                        DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
0315 }
0316 
0317 static void sparx5_get_dev_mac_ctrl_stats(u64 *portstats, void __iomem *inst,
0318                       u32 tinst)
0319 {
0320     sparx5_update_counter(&portstats[spx5_stats_tx_pause_cnt],
0321                   spx5_inst_rd(inst, DEV5G_TX_PAUSE_CNT(tinst)));
0322     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_pause_cnt],
0323                   spx5_inst_rd(inst,
0324                        DEV5G_PMAC_TX_PAUSE_CNT(tinst)));
0325     sparx5_update_counter(&portstats[spx5_stats_rx_pause_cnt],
0326                   spx5_inst_rd(inst, DEV5G_RX_PAUSE_CNT(tinst)));
0327     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_pause_cnt],
0328                   spx5_inst_rd(inst,
0329                        DEV5G_PMAC_RX_PAUSE_CNT(tinst)));
0330     sparx5_update_counter(&portstats[spx5_stats_rx_unsup_opcode_cnt],
0331                   spx5_inst_rd(inst,
0332                        DEV5G_RX_UNSUP_OPCODE_CNT(tinst)));
0333     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
0334                   spx5_inst_rd(inst,
0335                        DEV5G_PMAC_RX_UNSUP_OPCODE_CNT(tinst)));
0336 }
0337 
0338 static void sparx5_get_dev_rmon_stats(u64 *portstats, void __iomem *inst, u32
0339                       tinst)
0340 {
0341     sparx5_update_counter(&portstats[spx5_stats_rx_undersize_cnt],
0342                   spx5_inst_rd(inst,
0343                        DEV5G_RX_UNDERSIZE_CNT(tinst)));
0344     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_undersize_cnt],
0345                   spx5_inst_rd(inst,
0346                        DEV5G_PMAC_RX_UNDERSIZE_CNT(tinst)));
0347     sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
0348                   spx5_inst_rd(inst, DEV5G_RX_OVERSIZE_CNT(tinst)));
0349     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
0350                   spx5_inst_rd(inst,
0351                        DEV5G_PMAC_RX_OVERSIZE_CNT(tinst)));
0352     sparx5_update_counter(&portstats[spx5_stats_rx_fragments_cnt],
0353                   spx5_inst_rd(inst,
0354                        DEV5G_RX_FRAGMENTS_CNT(tinst)));
0355     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_fragments_cnt],
0356                   spx5_inst_rd(inst,
0357                        DEV5G_PMAC_RX_FRAGMENTS_CNT(tinst)));
0358     sparx5_update_counter(&portstats[spx5_stats_rx_jabbers_cnt],
0359                   spx5_inst_rd(inst, DEV5G_RX_JABBERS_CNT(tinst)));
0360     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_jabbers_cnt],
0361                   spx5_inst_rd(inst,
0362                        DEV5G_PMAC_RX_JABBERS_CNT(tinst)));
0363     sparx5_update_counter(&portstats[spx5_stats_rx_size64_cnt],
0364                   spx5_inst_rd(inst, DEV5G_RX_SIZE64_CNT(tinst)));
0365     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size64_cnt],
0366                   spx5_inst_rd(inst,
0367                        DEV5G_PMAC_RX_SIZE64_CNT(tinst)));
0368     sparx5_update_counter(&portstats[spx5_stats_rx_size65to127_cnt],
0369                   spx5_inst_rd(inst,
0370                        DEV5G_RX_SIZE65TO127_CNT(tinst)));
0371     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size65to127_cnt],
0372                   spx5_inst_rd(inst,
0373                        DEV5G_PMAC_RX_SIZE65TO127_CNT(tinst)));
0374     sparx5_update_counter(&portstats[spx5_stats_rx_size128to255_cnt],
0375                   spx5_inst_rd(inst,
0376                        DEV5G_RX_SIZE128TO255_CNT(tinst)));
0377     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size128to255_cnt],
0378                   spx5_inst_rd(inst,
0379                        DEV5G_PMAC_RX_SIZE128TO255_CNT(tinst)));
0380     sparx5_update_counter(&portstats[spx5_stats_rx_size256to511_cnt],
0381                   spx5_inst_rd(inst,
0382                        DEV5G_RX_SIZE256TO511_CNT(tinst)));
0383     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size256to511_cnt],
0384                   spx5_inst_rd(inst,
0385                        DEV5G_PMAC_RX_SIZE256TO511_CNT(tinst)));
0386     sparx5_update_counter(&portstats[spx5_stats_rx_size512to1023_cnt],
0387                   spx5_inst_rd(inst,
0388                        DEV5G_RX_SIZE512TO1023_CNT(tinst)));
0389     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size512to1023_cnt],
0390                   spx5_inst_rd(inst,
0391                        DEV5G_PMAC_RX_SIZE512TO1023_CNT(tinst)));
0392     sparx5_update_counter(&portstats[spx5_stats_rx_size1024to1518_cnt],
0393                   spx5_inst_rd(inst,
0394                        DEV5G_RX_SIZE1024TO1518_CNT(tinst)));
0395     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
0396                   spx5_inst_rd(inst,
0397                        DEV5G_PMAC_RX_SIZE1024TO1518_CNT(tinst)));
0398     sparx5_update_counter(&portstats[spx5_stats_rx_size1519tomax_cnt],
0399                   spx5_inst_rd(inst,
0400                        DEV5G_RX_SIZE1519TOMAX_CNT(tinst)));
0401     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
0402                   spx5_inst_rd(inst,
0403                        DEV5G_PMAC_RX_SIZE1519TOMAX_CNT(tinst)));
0404     sparx5_update_counter(&portstats[spx5_stats_tx_size64_cnt],
0405                   spx5_inst_rd(inst, DEV5G_TX_SIZE64_CNT(tinst)));
0406     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size64_cnt],
0407                   spx5_inst_rd(inst,
0408                        DEV5G_PMAC_TX_SIZE64_CNT(tinst)));
0409     sparx5_update_counter(&portstats[spx5_stats_tx_size65to127_cnt],
0410                   spx5_inst_rd(inst,
0411                        DEV5G_TX_SIZE65TO127_CNT(tinst)));
0412     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size65to127_cnt],
0413                   spx5_inst_rd(inst,
0414                        DEV5G_PMAC_TX_SIZE65TO127_CNT(tinst)));
0415     sparx5_update_counter(&portstats[spx5_stats_tx_size128to255_cnt],
0416                   spx5_inst_rd(inst,
0417                        DEV5G_TX_SIZE128TO255_CNT(tinst)));
0418     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size128to255_cnt],
0419                   spx5_inst_rd(inst,
0420                        DEV5G_PMAC_TX_SIZE128TO255_CNT(tinst)));
0421     sparx5_update_counter(&portstats[spx5_stats_tx_size256to511_cnt],
0422                   spx5_inst_rd(inst,
0423                        DEV5G_TX_SIZE256TO511_CNT(tinst)));
0424     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size256to511_cnt],
0425                   spx5_inst_rd(inst,
0426                        DEV5G_PMAC_TX_SIZE256TO511_CNT(tinst)));
0427     sparx5_update_counter(&portstats[spx5_stats_tx_size512to1023_cnt],
0428                   spx5_inst_rd(inst,
0429                        DEV5G_TX_SIZE512TO1023_CNT(tinst)));
0430     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size512to1023_cnt],
0431                   spx5_inst_rd(inst,
0432                        DEV5G_PMAC_TX_SIZE512TO1023_CNT(tinst)));
0433     sparx5_update_counter(&portstats[spx5_stats_tx_size1024to1518_cnt],
0434                   spx5_inst_rd(inst,
0435                        DEV5G_TX_SIZE1024TO1518_CNT(tinst)));
0436     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
0437                   spx5_inst_rd(inst,
0438                        DEV5G_PMAC_TX_SIZE1024TO1518_CNT(tinst)));
0439     sparx5_update_counter(&portstats[spx5_stats_tx_size1519tomax_cnt],
0440                   spx5_inst_rd(inst,
0441                        DEV5G_TX_SIZE1519TOMAX_CNT(tinst)));
0442     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
0443                   spx5_inst_rd(inst,
0444                        DEV5G_PMAC_TX_SIZE1519TOMAX_CNT(tinst)));
0445 }
0446 
0447 static void sparx5_get_dev_misc_stats(u64 *portstats, void __iomem *inst, u32
0448                       tinst)
0449 {
0450     sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_err_cnt],
0451                   spx5_inst_rd(inst,
0452                        DEV5G_MM_RX_ASSEMBLY_ERR_CNT(tinst)));
0453     sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_ok_cnt],
0454                   spx5_inst_rd(inst,
0455                        DEV5G_MM_RX_ASSEMBLY_OK_CNT(tinst)));
0456     sparx5_update_counter(&portstats[spx5_stats_mm_rx_merge_frag_cnt],
0457                   spx5_inst_rd(inst,
0458                        DEV5G_MM_RX_MERGE_FRAG_CNT(tinst)));
0459     sparx5_update_counter(&portstats[spx5_stats_mm_rx_smd_err_cnt],
0460                   spx5_inst_rd(inst,
0461                        DEV5G_MM_RX_SMD_ERR_CNT(tinst)));
0462     sparx5_update_counter(&portstats[spx5_stats_mm_tx_pfragment_cnt],
0463                   spx5_inst_rd(inst,
0464                        DEV5G_MM_TX_PFRAGMENT_CNT(tinst)));
0465     sparx5_update_counter(&portstats[spx5_stats_rx_bad_bytes_cnt],
0466                   spx5_inst_rd(inst,
0467                        DEV5G_RX_BAD_BYTES_CNT(tinst)));
0468     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
0469                   spx5_inst_rd(inst,
0470                        DEV5G_PMAC_RX_BAD_BYTES_CNT(tinst)));
0471     sparx5_update_counter(&portstats[spx5_stats_rx_in_bytes_cnt],
0472                   spx5_inst_rd(inst, DEV5G_RX_IN_BYTES_CNT(tinst)));
0473     sparx5_update_counter(&portstats[spx5_stats_rx_ipg_shrink_cnt],
0474                   spx5_inst_rd(inst,
0475                        DEV5G_RX_IPG_SHRINK_CNT(tinst)));
0476     sparx5_update_counter(&portstats[spx5_stats_rx_tagged_frms_cnt],
0477                   spx5_inst_rd(inst,
0478                        DEV5G_RX_TAGGED_FRMS_CNT(tinst)));
0479     sparx5_update_counter(&portstats[spx5_stats_rx_untagged_frms_cnt],
0480                   spx5_inst_rd(inst,
0481                        DEV5G_RX_UNTAGGED_FRMS_CNT(tinst)));
0482     sparx5_update_counter(&portstats[spx5_stats_tx_out_bytes_cnt],
0483                   spx5_inst_rd(inst,
0484                        DEV5G_TX_OUT_BYTES_CNT(tinst)));
0485     sparx5_update_counter(&portstats[spx5_stats_tx_tagged_frms_cnt],
0486                   spx5_inst_rd(inst,
0487                        DEV5G_TX_TAGGED_FRMS_CNT(tinst)));
0488     sparx5_update_counter(&portstats[spx5_stats_tx_untagged_frms_cnt],
0489                   spx5_inst_rd(inst,
0490                        DEV5G_TX_UNTAGGED_FRMS_CNT(tinst)));
0491     sparx5_update_counter(&portstats[spx5_stats_rx_hih_cksm_err_cnt],
0492                   spx5_inst_rd(inst,
0493                        DEV5G_RX_HIH_CKSM_ERR_CNT(tinst)));
0494     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_hih_cksm_err_cnt],
0495                   spx5_inst_rd(inst,
0496                        DEV5G_PMAC_RX_HIH_CKSM_ERR_CNT(tinst)));
0497     sparx5_update_counter(&portstats[spx5_stats_rx_xgmii_prot_err_cnt],
0498                   spx5_inst_rd(inst,
0499                        DEV5G_RX_XGMII_PROT_ERR_CNT(tinst)));
0500     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_xgmii_prot_err_cnt],
0501                   spx5_inst_rd(inst,
0502                        DEV5G_PMAC_RX_XGMII_PROT_ERR_CNT(tinst)));
0503 }
0504 
0505 static void sparx5_get_device_stats(struct sparx5 *sparx5, int portno)
0506 {
0507     u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
0508     u32 tinst = sparx5_port_dev_index(portno);
0509     u32 dev = sparx5_to_high_dev(portno);
0510     void __iomem *inst;
0511 
0512     inst = spx5_inst_get(sparx5, dev, tinst);
0513     sparx5_get_dev_phy_stats(portstats, inst, tinst);
0514     sparx5_get_dev_mac_stats(portstats, inst, tinst);
0515     sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
0516     sparx5_get_dev_rmon_stats(portstats, inst, tinst);
0517     sparx5_get_dev_misc_stats(portstats, inst, tinst);
0518 }
0519 
0520 static void sparx5_get_asm_phy_stats(u64 *portstats, void __iomem *inst, int
0521                      portno)
0522 {
0523     sparx5_update_counter(&portstats[spx5_stats_rx_symbol_err_cnt],
0524                   spx5_inst_rd(inst,
0525                        ASM_RX_SYMBOL_ERR_CNT(portno)));
0526     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_symbol_err_cnt],
0527                   spx5_inst_rd(inst,
0528                        ASM_PMAC_RX_SYMBOL_ERR_CNT(portno)));
0529 }
0530 
0531 static void sparx5_get_asm_mac_stats(u64 *portstats, void __iomem *inst, int
0532                      portno)
0533 {
0534     sparx5_update_counter(&portstats[spx5_stats_tx_uc_cnt],
0535                   spx5_inst_rd(inst, ASM_TX_UC_CNT(portno)));
0536     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_uc_cnt],
0537                   spx5_inst_rd(inst, ASM_PMAC_TX_UC_CNT(portno)));
0538     sparx5_update_counter(&portstats[spx5_stats_tx_mc_cnt],
0539                   spx5_inst_rd(inst, ASM_TX_MC_CNT(portno)));
0540     sparx5_update_counter(&portstats[spx5_stats_tx_bc_cnt],
0541                   spx5_inst_rd(inst, ASM_TX_BC_CNT(portno)));
0542     sparx5_update_counter(&portstats[spx5_stats_tx_backoff1_cnt],
0543                   spx5_inst_rd(inst, ASM_TX_BACKOFF1_CNT(portno)));
0544     sparx5_update_counter(&portstats[spx5_stats_tx_multi_coll_cnt],
0545                   spx5_inst_rd(inst,
0546                        ASM_TX_MULTI_COLL_CNT(portno)));
0547     sparx5_update_counter(&portstats[spx5_stats_rx_uc_cnt],
0548                   spx5_inst_rd(inst, ASM_RX_UC_CNT(portno)));
0549     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_uc_cnt],
0550                   spx5_inst_rd(inst, ASM_PMAC_RX_UC_CNT(portno)));
0551     sparx5_update_counter(&portstats[spx5_stats_rx_mc_cnt],
0552                   spx5_inst_rd(inst, ASM_RX_MC_CNT(portno)));
0553     sparx5_update_counter(&portstats[spx5_stats_rx_bc_cnt],
0554                   spx5_inst_rd(inst, ASM_RX_BC_CNT(portno)));
0555     sparx5_update_counter(&portstats[spx5_stats_rx_crc_err_cnt],
0556                   spx5_inst_rd(inst, ASM_RX_CRC_ERR_CNT(portno)));
0557     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_crc_err_cnt],
0558                   spx5_inst_rd(inst,
0559                        ASM_PMAC_RX_CRC_ERR_CNT(portno)));
0560     sparx5_update_counter(&portstats[spx5_stats_rx_alignment_lost_cnt],
0561                   spx5_inst_rd(inst,
0562                        ASM_RX_ALIGNMENT_LOST_CNT(portno)));
0563     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_alignment_lost_cnt],
0564                   spx5_inst_rd(inst,
0565                        ASM_PMAC_RX_ALIGNMENT_LOST_CNT(portno)));
0566     sparx5_update_counter(&portstats[spx5_stats_tx_ok_bytes_cnt],
0567                   spx5_inst_rd(inst, ASM_TX_OK_BYTES_CNT(portno)));
0568     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_ok_bytes_cnt],
0569                   spx5_inst_rd(inst,
0570                        ASM_PMAC_TX_OK_BYTES_CNT(portno)));
0571     sparx5_update_counter(&portstats[spx5_stats_tx_defer_cnt],
0572                   spx5_inst_rd(inst, ASM_TX_DEFER_CNT(portno)));
0573     sparx5_update_counter(&portstats[spx5_stats_tx_late_coll_cnt],
0574                   spx5_inst_rd(inst, ASM_TX_LATE_COLL_CNT(portno)));
0575     sparx5_update_counter(&portstats[spx5_stats_tx_xcoll_cnt],
0576                   spx5_inst_rd(inst, ASM_TX_XCOLL_CNT(portno)));
0577     sparx5_update_counter(&portstats[spx5_stats_tx_csense_cnt],
0578                   spx5_inst_rd(inst, ASM_TX_CSENSE_CNT(portno)));
0579     sparx5_update_counter(&portstats[spx5_stats_rx_ok_bytes_cnt],
0580                   spx5_inst_rd(inst, ASM_RX_OK_BYTES_CNT(portno)));
0581     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_ok_bytes_cnt],
0582                   spx5_inst_rd(inst,
0583                        ASM_PMAC_RX_OK_BYTES_CNT(portno)));
0584     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_mc_cnt],
0585                   spx5_inst_rd(inst, ASM_PMAC_TX_MC_CNT(portno)));
0586     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_bc_cnt],
0587                   spx5_inst_rd(inst, ASM_PMAC_TX_BC_CNT(portno)));
0588     sparx5_update_counter(&portstats[spx5_stats_tx_xdefer_cnt],
0589                   spx5_inst_rd(inst, ASM_TX_XDEFER_CNT(portno)));
0590     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_mc_cnt],
0591                   spx5_inst_rd(inst, ASM_PMAC_RX_MC_CNT(portno)));
0592     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bc_cnt],
0593                   spx5_inst_rd(inst, ASM_PMAC_RX_BC_CNT(portno)));
0594     sparx5_update_counter(&portstats[spx5_stats_rx_in_range_len_err_cnt],
0595                   spx5_inst_rd(inst,
0596                        ASM_RX_IN_RANGE_LEN_ERR_CNT(portno)));
0597     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_in_range_len_err_cnt],
0598                   spx5_inst_rd(inst,
0599                        ASM_PMAC_RX_IN_RANGE_LEN_ERR_CNT(portno)));
0600     sparx5_update_counter(&portstats[spx5_stats_rx_out_of_range_len_err_cnt],
0601                   spx5_inst_rd(inst,
0602                        ASM_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
0603     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt],
0604                   spx5_inst_rd(inst,
0605                        ASM_PMAC_RX_OUT_OF_RANGE_LEN_ERR_CNT(portno)));
0606     sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
0607                   spx5_inst_rd(inst, ASM_RX_OVERSIZE_CNT(portno)));
0608     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
0609                   spx5_inst_rd(inst,
0610                        ASM_PMAC_RX_OVERSIZE_CNT(portno)));
0611 }
0612 
0613 static void sparx5_get_asm_mac_ctrl_stats(u64 *portstats, void __iomem *inst,
0614                       int portno)
0615 {
0616     sparx5_update_counter(&portstats[spx5_stats_tx_pause_cnt],
0617                   spx5_inst_rd(inst, ASM_TX_PAUSE_CNT(portno)));
0618     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_pause_cnt],
0619                   spx5_inst_rd(inst,
0620                        ASM_PMAC_TX_PAUSE_CNT(portno)));
0621     sparx5_update_counter(&portstats[spx5_stats_rx_pause_cnt],
0622                   spx5_inst_rd(inst, ASM_RX_PAUSE_CNT(portno)));
0623     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_pause_cnt],
0624                   spx5_inst_rd(inst,
0625                        ASM_PMAC_RX_PAUSE_CNT(portno)));
0626     sparx5_update_counter(&portstats[spx5_stats_rx_unsup_opcode_cnt],
0627                   spx5_inst_rd(inst,
0628                        ASM_RX_UNSUP_OPCODE_CNT(portno)));
0629     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_unsup_opcode_cnt],
0630                   spx5_inst_rd(inst,
0631                        ASM_PMAC_RX_UNSUP_OPCODE_CNT(portno)));
0632 }
0633 
0634 static void sparx5_get_asm_rmon_stats(u64 *portstats, void __iomem *inst, int
0635                       portno)
0636 {
0637     sparx5_update_counter(&portstats[spx5_stats_rx_undersize_cnt],
0638                   spx5_inst_rd(inst, ASM_RX_UNDERSIZE_CNT(portno)));
0639     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_undersize_cnt],
0640                   spx5_inst_rd(inst,
0641                        ASM_PMAC_RX_UNDERSIZE_CNT(portno)));
0642     sparx5_update_counter(&portstats[spx5_stats_rx_oversize_cnt],
0643                   spx5_inst_rd(inst, ASM_RX_OVERSIZE_CNT(portno)));
0644     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_oversize_cnt],
0645                   spx5_inst_rd(inst,
0646                        ASM_PMAC_RX_OVERSIZE_CNT(portno)));
0647     sparx5_update_counter(&portstats[spx5_stats_rx_fragments_cnt],
0648                   spx5_inst_rd(inst, ASM_RX_FRAGMENTS_CNT(portno)));
0649     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_fragments_cnt],
0650                   spx5_inst_rd(inst,
0651                        ASM_PMAC_RX_FRAGMENTS_CNT(portno)));
0652     sparx5_update_counter(&portstats[spx5_stats_rx_jabbers_cnt],
0653                   spx5_inst_rd(inst, ASM_RX_JABBERS_CNT(portno)));
0654     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_jabbers_cnt],
0655                   spx5_inst_rd(inst,
0656                        ASM_PMAC_RX_JABBERS_CNT(portno)));
0657     sparx5_update_counter(&portstats[spx5_stats_rx_size64_cnt],
0658                   spx5_inst_rd(inst, ASM_RX_SIZE64_CNT(portno)));
0659     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size64_cnt],
0660                   spx5_inst_rd(inst,
0661                        ASM_PMAC_RX_SIZE64_CNT(portno)));
0662     sparx5_update_counter(&portstats[spx5_stats_rx_size65to127_cnt],
0663                   spx5_inst_rd(inst,
0664                        ASM_RX_SIZE65TO127_CNT(portno)));
0665     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size65to127_cnt],
0666                   spx5_inst_rd(inst,
0667                        ASM_PMAC_RX_SIZE65TO127_CNT(portno)));
0668     sparx5_update_counter(&portstats[spx5_stats_rx_size128to255_cnt],
0669                   spx5_inst_rd(inst,
0670                        ASM_RX_SIZE128TO255_CNT(portno)));
0671     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size128to255_cnt],
0672                   spx5_inst_rd(inst,
0673                        ASM_PMAC_RX_SIZE128TO255_CNT(portno)));
0674     sparx5_update_counter(&portstats[spx5_stats_rx_size256to511_cnt],
0675                   spx5_inst_rd(inst,
0676                        ASM_RX_SIZE256TO511_CNT(portno)));
0677     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size256to511_cnt],
0678                   spx5_inst_rd(inst,
0679                        ASM_PMAC_RX_SIZE256TO511_CNT(portno)));
0680     sparx5_update_counter(&portstats[spx5_stats_rx_size512to1023_cnt],
0681                   spx5_inst_rd(inst,
0682                        ASM_RX_SIZE512TO1023_CNT(portno)));
0683     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size512to1023_cnt],
0684                   spx5_inst_rd(inst,
0685                        ASM_PMAC_RX_SIZE512TO1023_CNT(portno)));
0686     sparx5_update_counter(&portstats[spx5_stats_rx_size1024to1518_cnt],
0687                   spx5_inst_rd(inst,
0688                        ASM_RX_SIZE1024TO1518_CNT(portno)));
0689     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1024to1518_cnt],
0690                   spx5_inst_rd(inst,
0691                        ASM_PMAC_RX_SIZE1024TO1518_CNT(portno)));
0692     sparx5_update_counter(&portstats[spx5_stats_rx_size1519tomax_cnt],
0693                   spx5_inst_rd(inst,
0694                        ASM_RX_SIZE1519TOMAX_CNT(portno)));
0695     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_size1519tomax_cnt],
0696                   spx5_inst_rd(inst,
0697                        ASM_PMAC_RX_SIZE1519TOMAX_CNT(portno)));
0698     sparx5_update_counter(&portstats[spx5_stats_tx_size64_cnt],
0699                   spx5_inst_rd(inst, ASM_TX_SIZE64_CNT(portno)));
0700     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size64_cnt],
0701                   spx5_inst_rd(inst,
0702                        ASM_PMAC_TX_SIZE64_CNT(portno)));
0703     sparx5_update_counter(&portstats[spx5_stats_tx_size65to127_cnt],
0704                   spx5_inst_rd(inst,
0705                        ASM_TX_SIZE65TO127_CNT(portno)));
0706     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size65to127_cnt],
0707                   spx5_inst_rd(inst,
0708                        ASM_PMAC_TX_SIZE65TO127_CNT(portno)));
0709     sparx5_update_counter(&portstats[spx5_stats_tx_size128to255_cnt],
0710                   spx5_inst_rd(inst,
0711                        ASM_TX_SIZE128TO255_CNT(portno)));
0712     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size128to255_cnt],
0713                   spx5_inst_rd(inst,
0714                        ASM_PMAC_TX_SIZE128TO255_CNT(portno)));
0715     sparx5_update_counter(&portstats[spx5_stats_tx_size256to511_cnt],
0716                   spx5_inst_rd(inst,
0717                        ASM_TX_SIZE256TO511_CNT(portno)));
0718     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size256to511_cnt],
0719                   spx5_inst_rd(inst,
0720                        ASM_PMAC_TX_SIZE256TO511_CNT(portno)));
0721     sparx5_update_counter(&portstats[spx5_stats_tx_size512to1023_cnt],
0722                   spx5_inst_rd(inst,
0723                        ASM_TX_SIZE512TO1023_CNT(portno)));
0724     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size512to1023_cnt],
0725                   spx5_inst_rd(inst,
0726                        ASM_PMAC_TX_SIZE512TO1023_CNT(portno)));
0727     sparx5_update_counter(&portstats[spx5_stats_tx_size1024to1518_cnt],
0728                   spx5_inst_rd(inst,
0729                        ASM_TX_SIZE1024TO1518_CNT(portno)));
0730     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1024to1518_cnt],
0731                   spx5_inst_rd(inst,
0732                        ASM_PMAC_TX_SIZE1024TO1518_CNT(portno)));
0733     sparx5_update_counter(&portstats[spx5_stats_tx_size1519tomax_cnt],
0734                   spx5_inst_rd(inst,
0735                        ASM_TX_SIZE1519TOMAX_CNT(portno)));
0736     sparx5_update_counter(&portstats[spx5_stats_pmac_tx_size1519tomax_cnt],
0737                   spx5_inst_rd(inst,
0738                        ASM_PMAC_TX_SIZE1519TOMAX_CNT(portno)));
0739 }
0740 
0741 static void sparx5_get_asm_misc_stats(u64 *portstats, void __iomem *inst, int
0742                       portno)
0743 {
0744     sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_err_cnt],
0745                   spx5_inst_rd(inst,
0746                        ASM_MM_RX_ASSEMBLY_ERR_CNT(portno)));
0747     sparx5_update_counter(&portstats[spx5_stats_mm_rx_assembly_ok_cnt],
0748                   spx5_inst_rd(inst,
0749                        ASM_MM_RX_ASSEMBLY_OK_CNT(portno)));
0750     sparx5_update_counter(&portstats[spx5_stats_mm_rx_merge_frag_cnt],
0751                   spx5_inst_rd(inst,
0752                        ASM_MM_RX_MERGE_FRAG_CNT(portno)));
0753     sparx5_update_counter(&portstats[spx5_stats_mm_rx_smd_err_cnt],
0754                   spx5_inst_rd(inst,
0755                        ASM_MM_RX_SMD_ERR_CNT(portno)));
0756     sparx5_update_counter(&portstats[spx5_stats_mm_tx_pfragment_cnt],
0757                   spx5_inst_rd(inst,
0758                        ASM_MM_TX_PFRAGMENT_CNT(portno)));
0759     sparx5_update_counter(&portstats[spx5_stats_rx_bad_bytes_cnt],
0760                   spx5_inst_rd(inst, ASM_RX_BAD_BYTES_CNT(portno)));
0761     sparx5_update_counter(&portstats[spx5_stats_pmac_rx_bad_bytes_cnt],
0762                   spx5_inst_rd(inst,
0763                        ASM_PMAC_RX_BAD_BYTES_CNT(portno)));
0764     sparx5_update_counter(&portstats[spx5_stats_rx_in_bytes_cnt],
0765                   spx5_inst_rd(inst, ASM_RX_IN_BYTES_CNT(portno)));
0766     sparx5_update_counter(&portstats[spx5_stats_rx_ipg_shrink_cnt],
0767                   spx5_inst_rd(inst,
0768                        ASM_RX_IPG_SHRINK_CNT(portno)));
0769     sparx5_update_counter(&portstats[spx5_stats_rx_sync_lost_err_cnt],
0770                   spx5_inst_rd(inst,
0771                        ASM_RX_SYNC_LOST_ERR_CNT(portno)));
0772     sparx5_update_counter(&portstats[spx5_stats_rx_tagged_frms_cnt],
0773                   spx5_inst_rd(inst,
0774                        ASM_RX_TAGGED_FRMS_CNT(portno)));
0775     sparx5_update_counter(&portstats[spx5_stats_rx_untagged_frms_cnt],
0776                   spx5_inst_rd(inst,
0777                        ASM_RX_UNTAGGED_FRMS_CNT(portno)));
0778     sparx5_update_counter(&portstats[spx5_stats_tx_out_bytes_cnt],
0779                   spx5_inst_rd(inst, ASM_TX_OUT_BYTES_CNT(portno)));
0780     sparx5_update_counter(&portstats[spx5_stats_tx_tagged_frms_cnt],
0781                   spx5_inst_rd(inst,
0782                        ASM_TX_TAGGED_FRMS_CNT(portno)));
0783     sparx5_update_counter(&portstats[spx5_stats_tx_untagged_frms_cnt],
0784                   spx5_inst_rd(inst,
0785                        ASM_TX_UNTAGGED_FRMS_CNT(portno)));
0786 }
0787 
0788 static void sparx5_get_asm_stats(struct sparx5 *sparx5, int portno)
0789 {
0790     u64 *portstats = &sparx5->stats[portno * sparx5->num_stats];
0791     void __iomem *inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
0792 
0793     sparx5_get_asm_phy_stats(portstats, inst, portno);
0794     sparx5_get_asm_mac_stats(portstats, inst, portno);
0795     sparx5_get_asm_mac_ctrl_stats(portstats, inst, portno);
0796     sparx5_get_asm_rmon_stats(portstats, inst, portno);
0797     sparx5_get_asm_misc_stats(portstats, inst, portno);
0798 }
0799 
0800 static const struct ethtool_rmon_hist_range sparx5_rmon_ranges[] = {
0801     {    0,    64 },
0802     {   65,   127 },
0803     {  128,   255 },
0804     {  256,   511 },
0805     {  512,  1023 },
0806     { 1024,  1518 },
0807     { 1519, 10239 },
0808     {}
0809 };
0810 
0811 static void sparx5_get_eth_phy_stats(struct net_device *ndev,
0812                      struct ethtool_eth_phy_stats *phy_stats)
0813 {
0814     struct sparx5_port *port = netdev_priv(ndev);
0815     struct sparx5 *sparx5 = port->sparx5;
0816     int portno = port->portno;
0817     void __iomem *inst;
0818     u64 *portstats;
0819 
0820     portstats = &sparx5->stats[portno * sparx5->num_stats];
0821     if (sparx5_is_baser(port->conf.portmode)) {
0822         u32 tinst = sparx5_port_dev_index(portno);
0823         u32 dev = sparx5_to_high_dev(portno);
0824 
0825         inst = spx5_inst_get(sparx5, dev, tinst);
0826         sparx5_get_dev_phy_stats(portstats, inst, tinst);
0827     } else {
0828         inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
0829         sparx5_get_asm_phy_stats(portstats, inst, portno);
0830     }
0831     phy_stats->SymbolErrorDuringCarrier =
0832         portstats[spx5_stats_rx_symbol_err_cnt] +
0833         portstats[spx5_stats_pmac_rx_symbol_err_cnt];
0834 }
0835 
0836 static void sparx5_get_eth_mac_stats(struct net_device *ndev,
0837                      struct ethtool_eth_mac_stats *mac_stats)
0838 {
0839     struct sparx5_port *port = netdev_priv(ndev);
0840     struct sparx5 *sparx5 = port->sparx5;
0841     int portno = port->portno;
0842     void __iomem *inst;
0843     u64 *portstats;
0844 
0845     portstats = &sparx5->stats[portno * sparx5->num_stats];
0846     if (sparx5_is_baser(port->conf.portmode)) {
0847         u32 tinst = sparx5_port_dev_index(portno);
0848         u32 dev = sparx5_to_high_dev(portno);
0849 
0850         inst = spx5_inst_get(sparx5, dev, tinst);
0851         sparx5_get_dev_mac_stats(portstats, inst, tinst);
0852     } else {
0853         inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
0854         sparx5_get_asm_mac_stats(portstats, inst, portno);
0855     }
0856     mac_stats->FramesTransmittedOK = portstats[spx5_stats_tx_uc_cnt] +
0857         portstats[spx5_stats_pmac_tx_uc_cnt] +
0858         portstats[spx5_stats_tx_mc_cnt] +
0859         portstats[spx5_stats_tx_bc_cnt];
0860     mac_stats->SingleCollisionFrames =
0861         portstats[spx5_stats_tx_backoff1_cnt];
0862     mac_stats->MultipleCollisionFrames =
0863         portstats[spx5_stats_tx_multi_coll_cnt];
0864     mac_stats->FramesReceivedOK = portstats[spx5_stats_rx_uc_cnt] +
0865         portstats[spx5_stats_pmac_rx_uc_cnt] +
0866         portstats[spx5_stats_rx_mc_cnt] +
0867         portstats[spx5_stats_rx_bc_cnt];
0868     mac_stats->FrameCheckSequenceErrors =
0869         portstats[spx5_stats_rx_crc_err_cnt] +
0870         portstats[spx5_stats_pmac_rx_crc_err_cnt];
0871     mac_stats->AlignmentErrors = portstats[spx5_stats_rx_alignment_lost_cnt]
0872         + portstats[spx5_stats_pmac_rx_alignment_lost_cnt];
0873     mac_stats->OctetsTransmittedOK = portstats[spx5_stats_tx_ok_bytes_cnt] +
0874         portstats[spx5_stats_pmac_tx_ok_bytes_cnt];
0875     mac_stats->FramesWithDeferredXmissions =
0876         portstats[spx5_stats_tx_defer_cnt];
0877     mac_stats->LateCollisions =
0878         portstats[spx5_stats_tx_late_coll_cnt];
0879     mac_stats->FramesAbortedDueToXSColls =
0880         portstats[spx5_stats_tx_xcoll_cnt];
0881     mac_stats->CarrierSenseErrors = portstats[spx5_stats_tx_csense_cnt];
0882     mac_stats->OctetsReceivedOK = portstats[spx5_stats_rx_ok_bytes_cnt] +
0883         portstats[spx5_stats_pmac_rx_ok_bytes_cnt];
0884     mac_stats->MulticastFramesXmittedOK = portstats[spx5_stats_tx_mc_cnt] +
0885         portstats[spx5_stats_pmac_tx_mc_cnt];
0886     mac_stats->BroadcastFramesXmittedOK = portstats[spx5_stats_tx_bc_cnt] +
0887         portstats[spx5_stats_pmac_tx_bc_cnt];
0888     mac_stats->FramesWithExcessiveDeferral =
0889         portstats[spx5_stats_tx_xdefer_cnt];
0890     mac_stats->MulticastFramesReceivedOK = portstats[spx5_stats_rx_mc_cnt] +
0891         portstats[spx5_stats_pmac_rx_mc_cnt];
0892     mac_stats->BroadcastFramesReceivedOK = portstats[spx5_stats_rx_bc_cnt] +
0893         portstats[spx5_stats_pmac_rx_bc_cnt];
0894     mac_stats->InRangeLengthErrors =
0895         portstats[spx5_stats_rx_in_range_len_err_cnt] +
0896         portstats[spx5_stats_pmac_rx_in_range_len_err_cnt];
0897     mac_stats->OutOfRangeLengthField =
0898         portstats[spx5_stats_rx_out_of_range_len_err_cnt] +
0899         portstats[spx5_stats_pmac_rx_out_of_range_len_err_cnt];
0900     mac_stats->FrameTooLongErrors = portstats[spx5_stats_rx_oversize_cnt] +
0901         portstats[spx5_stats_pmac_rx_oversize_cnt];
0902 }
0903 
0904 static void sparx5_get_eth_mac_ctrl_stats(struct net_device *ndev,
0905                       struct ethtool_eth_ctrl_stats *mac_ctrl_stats)
0906 {
0907     struct sparx5_port *port = netdev_priv(ndev);
0908     struct sparx5 *sparx5 = port->sparx5;
0909     int portno = port->portno;
0910     void __iomem *inst;
0911     u64 *portstats;
0912 
0913     portstats = &sparx5->stats[portno * sparx5->num_stats];
0914     if (sparx5_is_baser(port->conf.portmode)) {
0915         u32 tinst = sparx5_port_dev_index(portno);
0916         u32 dev = sparx5_to_high_dev(portno);
0917 
0918         inst = spx5_inst_get(sparx5, dev, tinst);
0919         sparx5_get_dev_mac_ctrl_stats(portstats, inst, tinst);
0920     } else {
0921         inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
0922         sparx5_get_asm_mac_ctrl_stats(portstats, inst, portno);
0923     }
0924     mac_ctrl_stats->MACControlFramesTransmitted =
0925         portstats[spx5_stats_tx_pause_cnt] +
0926         portstats[spx5_stats_pmac_tx_pause_cnt];
0927     mac_ctrl_stats->MACControlFramesReceived =
0928         portstats[spx5_stats_rx_pause_cnt] +
0929         portstats[spx5_stats_pmac_rx_pause_cnt];
0930     mac_ctrl_stats->UnsupportedOpcodesReceived =
0931         portstats[spx5_stats_rx_unsup_opcode_cnt] +
0932         portstats[spx5_stats_pmac_rx_unsup_opcode_cnt];
0933 }
0934 
0935 static void sparx5_get_eth_rmon_stats(struct net_device *ndev,
0936                       struct ethtool_rmon_stats *rmon_stats,
0937                       const struct ethtool_rmon_hist_range **ranges)
0938 {
0939     struct sparx5_port *port = netdev_priv(ndev);
0940     struct sparx5 *sparx5 = port->sparx5;
0941     int portno = port->portno;
0942     void __iomem *inst;
0943     u64 *portstats;
0944 
0945     portstats = &sparx5->stats[portno * sparx5->num_stats];
0946     if (sparx5_is_baser(port->conf.portmode)) {
0947         u32 tinst = sparx5_port_dev_index(portno);
0948         u32 dev = sparx5_to_high_dev(portno);
0949 
0950         inst = spx5_inst_get(sparx5, dev, tinst);
0951         sparx5_get_dev_rmon_stats(portstats, inst, tinst);
0952     } else {
0953         inst = spx5_inst_get(sparx5, TARGET_ASM, 0);
0954         sparx5_get_asm_rmon_stats(portstats, inst, portno);
0955     }
0956     rmon_stats->undersize_pkts = portstats[spx5_stats_rx_undersize_cnt] +
0957         portstats[spx5_stats_pmac_rx_undersize_cnt];
0958     rmon_stats->oversize_pkts = portstats[spx5_stats_rx_oversize_cnt] +
0959         portstats[spx5_stats_pmac_rx_oversize_cnt];
0960     rmon_stats->fragments = portstats[spx5_stats_rx_fragments_cnt] +
0961         portstats[spx5_stats_pmac_rx_fragments_cnt];
0962     rmon_stats->jabbers = portstats[spx5_stats_rx_jabbers_cnt] +
0963         portstats[spx5_stats_pmac_rx_jabbers_cnt];
0964     rmon_stats->hist[0] = portstats[spx5_stats_rx_size64_cnt] +
0965         portstats[spx5_stats_pmac_rx_size64_cnt];
0966     rmon_stats->hist[1] = portstats[spx5_stats_rx_size65to127_cnt] +
0967         portstats[spx5_stats_pmac_rx_size65to127_cnt];
0968     rmon_stats->hist[2] = portstats[spx5_stats_rx_size128to255_cnt] +
0969         portstats[spx5_stats_pmac_rx_size128to255_cnt];
0970     rmon_stats->hist[3] = portstats[spx5_stats_rx_size256to511_cnt] +
0971         portstats[spx5_stats_pmac_rx_size256to511_cnt];
0972     rmon_stats->hist[4] = portstats[spx5_stats_rx_size512to1023_cnt] +
0973         portstats[spx5_stats_pmac_rx_size512to1023_cnt];
0974     rmon_stats->hist[5] = portstats[spx5_stats_rx_size1024to1518_cnt] +
0975         portstats[spx5_stats_pmac_rx_size1024to1518_cnt];
0976     rmon_stats->hist[6] = portstats[spx5_stats_rx_size1519tomax_cnt] +
0977         portstats[spx5_stats_pmac_rx_size1519tomax_cnt];
0978     rmon_stats->hist_tx[0] = portstats[spx5_stats_tx_size64_cnt] +
0979         portstats[spx5_stats_pmac_tx_size64_cnt];
0980     rmon_stats->hist_tx[1] = portstats[spx5_stats_tx_size65to127_cnt] +
0981         portstats[spx5_stats_pmac_tx_size65to127_cnt];
0982     rmon_stats->hist_tx[2] = portstats[spx5_stats_tx_size128to255_cnt] +
0983         portstats[spx5_stats_pmac_tx_size128to255_cnt];
0984     rmon_stats->hist_tx[3] = portstats[spx5_stats_tx_size256to511_cnt] +
0985         portstats[spx5_stats_pmac_tx_size256to511_cnt];
0986     rmon_stats->hist_tx[4] = portstats[spx5_stats_tx_size512to1023_cnt] +
0987         portstats[spx5_stats_pmac_tx_size512to1023_cnt];
0988     rmon_stats->hist_tx[5] = portstats[spx5_stats_tx_size1024to1518_cnt] +
0989         portstats[spx5_stats_pmac_tx_size1024to1518_cnt];
0990     rmon_stats->hist_tx[6] = portstats[spx5_stats_tx_size1519tomax_cnt] +
0991         portstats[spx5_stats_pmac_tx_size1519tomax_cnt];
0992     *ranges = sparx5_rmon_ranges;
0993 }
0994 
0995 static int sparx5_get_sset_count(struct net_device *ndev, int sset)
0996 {
0997     struct sparx5_port *port = netdev_priv(ndev);
0998     struct sparx5  *sparx5 = port->sparx5;
0999 
1000     if (sset != ETH_SS_STATS)
1001         return -EOPNOTSUPP;
1002     return sparx5->num_ethtool_stats;
1003 }
1004 
1005 static 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 
1019 static 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 
1049 void 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 
1112 static 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 
1122 static 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 
1131 static 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 
1144 static 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 
1152 static 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 
1160 static 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 
1169 static 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 
1186 static 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 
1219 const 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 
1233 int 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 }