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