0001
0002
0003
0004
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
0014 #define SPX5_PORT_POLICER_DROPS 0
0015
0016
0017 static void sparx5_update_counter(u64 *cnt, u32 val)
0018 {
0019 if (val < (*cnt & U32_MAX))
0020 *cnt += (u64)1 << 32;
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
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;
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
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
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
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 }