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