1 // SPDX-License-Identifier: GPL-2.0+ 2 // Copyright (c) 2024 Hisilicon Limited. 3 4 #include <linux/ethtool.h> 5 #include <linux/phy.h> 6 #include <linux/rtnetlink.h> 7 #include "hbg_common.h" 8 #include "hbg_err.h" 9 #include "hbg_ethtool.h" 10 #include "hbg_hw.h" 11 12 struct hbg_ethtool_stats { 13 char name[ETH_GSTRING_LEN]; 14 unsigned long offset; 15 u32 reg; /* set to 0 if stats is not updated via dump reg */ 16 }; 17 18 #define HBG_STATS_I(stats) { #stats, HBG_STATS_FIELD_OFF(stats), 0} 19 #define HBG_STATS_REG_I(stats, reg) { #stats, HBG_STATS_FIELD_OFF(stats), reg} 20 21 static const struct hbg_ethtool_stats hbg_ethtool_stats_info[] = { 22 HBG_STATS_I(rx_desc_l2_err_cnt), 23 HBG_STATS_I(rx_desc_pkt_len_err_cnt), 24 HBG_STATS_I(rx_desc_l3_wrong_head_cnt), 25 HBG_STATS_I(rx_desc_l3_csum_err_cnt), 26 HBG_STATS_I(rx_desc_l3_len_err_cnt), 27 HBG_STATS_I(rx_desc_l3_zero_ttl_cnt), 28 HBG_STATS_I(rx_desc_l3_other_cnt), 29 HBG_STATS_I(rx_desc_l4_wrong_head_cnt), 30 HBG_STATS_I(rx_desc_l4_len_err_cnt), 31 HBG_STATS_I(rx_desc_l4_csum_err_cnt), 32 HBG_STATS_I(rx_desc_l4_zero_port_num_cnt), 33 HBG_STATS_I(rx_desc_l4_other_cnt), 34 HBG_STATS_I(rx_desc_ip_ver_err_cnt), 35 HBG_STATS_I(rx_desc_ipv4_pkt_cnt), 36 HBG_STATS_I(rx_desc_ipv6_pkt_cnt), 37 HBG_STATS_I(rx_desc_no_ip_pkt_cnt), 38 HBG_STATS_I(rx_desc_ip_pkt_cnt), 39 HBG_STATS_I(rx_desc_tcp_pkt_cnt), 40 HBG_STATS_I(rx_desc_udp_pkt_cnt), 41 HBG_STATS_I(rx_desc_vlan_pkt_cnt), 42 HBG_STATS_I(rx_desc_icmp_pkt_cnt), 43 HBG_STATS_I(rx_desc_arp_pkt_cnt), 44 HBG_STATS_I(rx_desc_rarp_pkt_cnt), 45 HBG_STATS_I(rx_desc_multicast_pkt_cnt), 46 HBG_STATS_I(rx_desc_broadcast_pkt_cnt), 47 HBG_STATS_I(rx_desc_ipsec_pkt_cnt), 48 HBG_STATS_I(rx_desc_ip_opt_pkt_cnt), 49 HBG_STATS_I(rx_desc_key_not_match_cnt), 50 51 HBG_STATS_REG_I(rx_octets_bad_cnt, HBG_REG_RX_OCTETS_BAD_ADDR), 52 HBG_STATS_REG_I(rx_octets_total_filt_cnt, 53 HBG_REG_RX_OCTETS_TOTAL_FILT_ADDR), 54 HBG_STATS_REG_I(rx_uc_pkt_cnt, HBG_REG_RX_UC_PKTS_ADDR), 55 HBG_STATS_REG_I(rx_vlan_pkt_cnt, HBG_REG_RX_TAGGED_ADDR), 56 HBG_STATS_REG_I(rx_filt_pkt_cnt, HBG_REG_RX_FILT_PKT_CNT_ADDR), 57 HBG_STATS_REG_I(rx_data_error_cnt, HBG_REG_RX_DATA_ERR_ADDR), 58 HBG_STATS_REG_I(rx_frame_long_err_cnt, HBG_REG_RX_LONG_ERRORS_ADDR), 59 HBG_STATS_REG_I(rx_jabber_err_cnt, HBG_REG_RX_JABBER_ERRORS_ADDR), 60 HBG_STATS_REG_I(rx_frame_very_long_err_cnt, 61 HBG_REG_RX_VERY_LONG_ERR_CNT_ADDR), 62 HBG_STATS_REG_I(rx_frame_runt_err_cnt, HBG_REG_RX_RUNT_ERR_CNT_ADDR), 63 HBG_STATS_REG_I(rx_frame_short_err_cnt, HBG_REG_RX_SHORT_ERR_CNT_ADDR), 64 HBG_STATS_REG_I(rx_overflow_cnt, HBG_REG_RX_OVER_FLOW_CNT_ADDR), 65 HBG_STATS_REG_I(rx_bufrq_err_cnt, HBG_REG_RX_BUFRQ_ERR_CNT_ADDR), 66 HBG_STATS_REG_I(rx_we_err_cnt, HBG_REG_RX_WE_ERR_CNT_ADDR), 67 HBG_STATS_REG_I(rx_overrun_cnt, HBG_REG_RX_OVERRUN_CNT_ADDR), 68 HBG_STATS_REG_I(rx_lengthfield_err_cnt, 69 HBG_REG_RX_LENGTHFIELD_ERR_CNT_ADDR), 70 HBG_STATS_REG_I(rx_fail_comma_cnt, HBG_REG_RX_FAIL_COMMA_CNT_ADDR), 71 HBG_STATS_I(rx_dma_err_cnt), 72 HBG_STATS_I(rx_fifo_less_empty_thrsld_cnt), 73 74 HBG_STATS_REG_I(tx_uc_pkt_cnt, HBG_REG_TX_UC_PKTS_ADDR), 75 HBG_STATS_REG_I(tx_vlan_pkt_cnt, HBG_REG_TX_TAGGED_ADDR), 76 HBG_STATS_REG_I(tx_octets_bad_cnt, HBG_REG_OCTETS_TRANSMITTED_BAD_ADDR), 77 78 HBG_STATS_REG_I(tx_underrun_err_cnt, HBG_REG_TX_UNDERRUN_ADDR), 79 HBG_STATS_REG_I(tx_add_cs_fail_cnt, HBG_REG_TX_CS_FAIL_CNT_ADDR), 80 HBG_STATS_REG_I(tx_bufrl_err_cnt, HBG_REG_TX_BUFRL_ERR_CNT_ADDR), 81 HBG_STATS_REG_I(tx_crc_err_cnt, HBG_REG_TX_CRC_ERROR_ADDR), 82 HBG_STATS_REG_I(tx_drop_cnt, HBG_REG_TX_DROP_CNT_ADDR), 83 HBG_STATS_REG_I(tx_excessive_length_drop_cnt, 84 HBG_REG_TX_EXCESSIVE_LENGTH_DROP_ADDR), 85 HBG_STATS_I(tx_dma_err_cnt), 86 HBG_STATS_I(tx_timeout_cnt), 87 }; 88 89 static const struct hbg_ethtool_stats hbg_ethtool_rmon_stats_info[] = { 90 HBG_STATS_I(rx_desc_frag_cnt), 91 HBG_STATS_REG_I(rx_framesize_64, HBG_REG_RX_PKTS_64OCTETS_ADDR), 92 HBG_STATS_REG_I(rx_framesize_65_127, 93 HBG_REG_RX_PKTS_65TO127OCTETS_ADDR), 94 HBG_STATS_REG_I(rx_framesize_128_255, 95 HBG_REG_RX_PKTS_128TO255OCTETS_ADDR), 96 HBG_STATS_REG_I(rx_framesize_256_511, 97 HBG_REG_RX_PKTS_256TO511OCTETS_ADDR), 98 HBG_STATS_REG_I(rx_framesize_512_1023, 99 HBG_REG_RX_PKTS_512TO1023OCTETS_ADDR), 100 HBG_STATS_REG_I(rx_framesize_1024_1518, 101 HBG_REG_RX_PKTS_1024TO1518OCTETS_ADDR), 102 HBG_STATS_REG_I(rx_framesize_bt_1518, 103 HBG_REG_RX_PKTS_1519TOMAXOCTETS_ADDR), 104 HBG_STATS_REG_I(tx_framesize_64, HBG_REG_TX_PKTS_64OCTETS_ADDR), 105 HBG_STATS_REG_I(tx_framesize_65_127, 106 HBG_REG_TX_PKTS_65TO127OCTETS_ADDR), 107 HBG_STATS_REG_I(tx_framesize_128_255, 108 HBG_REG_TX_PKTS_128TO255OCTETS_ADDR), 109 HBG_STATS_REG_I(tx_framesize_256_511, 110 HBG_REG_TX_PKTS_256TO511OCTETS_ADDR), 111 HBG_STATS_REG_I(tx_framesize_512_1023, 112 HBG_REG_TX_PKTS_512TO1023OCTETS_ADDR), 113 HBG_STATS_REG_I(tx_framesize_1024_1518, 114 HBG_REG_TX_PKTS_1024TO1518OCTETS_ADDR), 115 HBG_STATS_REG_I(tx_framesize_bt_1518, 116 HBG_REG_TX_PKTS_1519TOMAXOCTETS_ADDR), 117 }; 118 119 static const struct hbg_ethtool_stats hbg_ethtool_mac_stats_info[] = { 120 HBG_STATS_REG_I(rx_mc_pkt_cnt, HBG_REG_RX_MC_PKTS_ADDR), 121 HBG_STATS_REG_I(rx_bc_pkt_cnt, HBG_REG_RX_BC_PKTS_ADDR), 122 HBG_STATS_REG_I(rx_align_error_cnt, HBG_REG_RX_ALIGN_ERRORS_ADDR), 123 HBG_STATS_REG_I(rx_octets_total_ok_cnt, 124 HBG_REG_RX_OCTETS_TOTAL_OK_ADDR), 125 HBG_STATS_REG_I(rx_trans_pkt_cnt, HBG_REG_RX_TRANS_PKG_CNT_ADDR), 126 HBG_STATS_REG_I(rx_fcs_error_cnt, HBG_REG_RX_FCS_ERRORS_ADDR), 127 HBG_STATS_REG_I(tx_mc_pkt_cnt, HBG_REG_TX_MC_PKTS_ADDR), 128 HBG_STATS_REG_I(tx_bc_pkt_cnt, HBG_REG_TX_BC_PKTS_ADDR), 129 HBG_STATS_REG_I(tx_octets_total_ok_cnt, 130 HBG_REG_OCTETS_TRANSMITTED_OK_ADDR), 131 HBG_STATS_REG_I(tx_trans_pkt_cnt, HBG_REG_TX_TRANS_PKG_CNT_ADDR), 132 }; 133 134 static const struct hbg_ethtool_stats hbg_ethtool_ctrl_stats_info[] = { 135 HBG_STATS_REG_I(rx_pause_macctl_frame_cnt, 136 HBG_REG_RX_PAUSE_MACCTL_FRAMCOUNTER_ADDR), 137 HBG_STATS_REG_I(tx_pause_frame_cnt, HBG_REG_TX_PAUSE_FRAMES_ADDR), 138 HBG_STATS_REG_I(rx_unknown_macctl_frame_cnt, 139 HBG_REG_RX_UNKNOWN_MACCTL_FRAMCOUNTER_ADDR), 140 }; 141 142 enum hbg_reg_dump_type { 143 HBG_DUMP_REG_TYPE_SPEC = 0, 144 HBG_DUMP_REG_TYPE_MDIO, 145 HBG_DUMP_REG_TYPE_GMAC, 146 HBG_DUMP_REG_TYPE_PCU, 147 }; 148 149 struct hbg_reg_info { 150 u32 type; 151 u32 offset; 152 u32 val; 153 }; 154 155 #define HBG_DUMP_SPEC_I(offset) {HBG_DUMP_REG_TYPE_SPEC, offset, 0} 156 #define HBG_DUMP_MDIO_I(offset) {HBG_DUMP_REG_TYPE_MDIO, offset, 0} 157 #define HBG_DUMP_GMAC_I(offset) {HBG_DUMP_REG_TYPE_GMAC, offset, 0} 158 #define HBG_DUMP_PCU_I(offset) {HBG_DUMP_REG_TYPE_PCU, offset, 0} 159 160 static const struct hbg_reg_info hbg_dump_reg_infos[] = { 161 /* dev specs */ 162 HBG_DUMP_SPEC_I(HBG_REG_SPEC_VALID_ADDR), 163 HBG_DUMP_SPEC_I(HBG_REG_EVENT_REQ_ADDR), 164 HBG_DUMP_SPEC_I(HBG_REG_MAC_ID_ADDR), 165 HBG_DUMP_SPEC_I(HBG_REG_PHY_ID_ADDR), 166 HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_ADDR), 167 HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_HIGH_ADDR), 168 HBG_DUMP_SPEC_I(HBG_REG_UC_MAC_NUM_ADDR), 169 HBG_DUMP_SPEC_I(HBG_REG_MDIO_FREQ_ADDR), 170 HBG_DUMP_SPEC_I(HBG_REG_MAX_MTU_ADDR), 171 HBG_DUMP_SPEC_I(HBG_REG_MIN_MTU_ADDR), 172 HBG_DUMP_SPEC_I(HBG_REG_TX_FIFO_NUM_ADDR), 173 HBG_DUMP_SPEC_I(HBG_REG_RX_FIFO_NUM_ADDR), 174 HBG_DUMP_SPEC_I(HBG_REG_VLAN_LAYERS_ADDR), 175 176 /* mdio */ 177 HBG_DUMP_MDIO_I(HBG_REG_MDIO_COMMAND_ADDR), 178 HBG_DUMP_MDIO_I(HBG_REG_MDIO_ADDR_ADDR), 179 HBG_DUMP_MDIO_I(HBG_REG_MDIO_WDATA_ADDR), 180 HBG_DUMP_MDIO_I(HBG_REG_MDIO_RDATA_ADDR), 181 HBG_DUMP_MDIO_I(HBG_REG_MDIO_STA_ADDR), 182 183 /* gmac */ 184 HBG_DUMP_GMAC_I(HBG_REG_DUPLEX_TYPE_ADDR), 185 HBG_DUMP_GMAC_I(HBG_REG_FD_FC_TYPE_ADDR), 186 HBG_DUMP_GMAC_I(HBG_REG_FC_TX_TIMER_ADDR), 187 HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_LOW_ADDR), 188 HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_HIGH_ADDR), 189 HBG_DUMP_GMAC_I(HBG_REG_MAX_FRAME_SIZE_ADDR), 190 HBG_DUMP_GMAC_I(HBG_REG_PORT_MODE_ADDR), 191 HBG_DUMP_GMAC_I(HBG_REG_PORT_ENABLE_ADDR), 192 HBG_DUMP_GMAC_I(HBG_REG_PAUSE_ENABLE_ADDR), 193 HBG_DUMP_GMAC_I(HBG_REG_AN_NEG_STATE_ADDR), 194 HBG_DUMP_GMAC_I(HBG_REG_TRANSMIT_CTRL_ADDR), 195 HBG_DUMP_GMAC_I(HBG_REG_REC_FILT_CTRL_ADDR), 196 HBG_DUMP_GMAC_I(HBG_REG_LINE_LOOP_BACK_ADDR), 197 HBG_DUMP_GMAC_I(HBG_REG_CF_CRC_STRIP_ADDR), 198 HBG_DUMP_GMAC_I(HBG_REG_MODE_CHANGE_EN_ADDR), 199 HBG_DUMP_GMAC_I(HBG_REG_LOOP_REG_ADDR), 200 HBG_DUMP_GMAC_I(HBG_REG_RECV_CTRL_ADDR), 201 HBG_DUMP_GMAC_I(HBG_REG_VLAN_CODE_ADDR), 202 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_0_ADDR), 203 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_0_ADDR), 204 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_1_ADDR), 205 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_1_ADDR), 206 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_2_ADDR), 207 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_2_ADDR), 208 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_3_ADDR), 209 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_3_ADDR), 210 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_4_ADDR), 211 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_4_ADDR), 212 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_5_ADDR), 213 HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_5_ADDR), 214 215 /* pcu */ 216 HBG_DUMP_PCU_I(HBG_REG_TX_FIFO_THRSLD_ADDR), 217 HBG_DUMP_PCU_I(HBG_REG_RX_FIFO_THRSLD_ADDR), 218 HBG_DUMP_PCU_I(HBG_REG_CFG_FIFO_THRSLD_ADDR), 219 HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_MSK_ADDR), 220 HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_STAT_ADDR), 221 HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_CLR_ADDR), 222 HBG_DUMP_PCU_I(HBG_REG_TX_BUS_ERR_ADDR_ADDR), 223 HBG_DUMP_PCU_I(HBG_REG_RX_BUS_ERR_ADDR_ADDR), 224 HBG_DUMP_PCU_I(HBG_REG_MAX_FRAME_LEN_ADDR), 225 HBG_DUMP_PCU_I(HBG_REG_DEBUG_ST_MCH_ADDR), 226 HBG_DUMP_PCU_I(HBG_REG_FIFO_CURR_STATUS_ADDR), 227 HBG_DUMP_PCU_I(HBG_REG_FIFO_HIST_STATUS_ADDR), 228 HBG_DUMP_PCU_I(HBG_REG_CF_CFF_DATA_NUM_ADDR), 229 HBG_DUMP_PCU_I(HBG_REG_CF_TX_PAUSE_ADDR), 230 HBG_DUMP_PCU_I(HBG_REG_RX_CFF_ADDR_ADDR), 231 HBG_DUMP_PCU_I(HBG_REG_RX_BUF_SIZE_ADDR), 232 HBG_DUMP_PCU_I(HBG_REG_BUS_CTRL_ADDR), 233 HBG_DUMP_PCU_I(HBG_REG_RX_CTRL_ADDR), 234 HBG_DUMP_PCU_I(HBG_REG_RX_PKT_MODE_ADDR), 235 HBG_DUMP_PCU_I(HBG_REG_DBG_ST0_ADDR), 236 HBG_DUMP_PCU_I(HBG_REG_DBG_ST1_ADDR), 237 HBG_DUMP_PCU_I(HBG_REG_DBG_ST2_ADDR), 238 HBG_DUMP_PCU_I(HBG_REG_BUS_RST_EN_ADDR), 239 HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_MSK_ADDR), 240 HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_STAT_ADDR), 241 HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_CLR_ADDR), 242 HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_MSK_ADDR), 243 HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_STAT_ADDR), 244 HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_CLR_ADDR), 245 }; 246 247 static const u32 hbg_dump_type_base_array[] = { 248 [HBG_DUMP_REG_TYPE_SPEC] = 0, 249 [HBG_DUMP_REG_TYPE_MDIO] = HBG_REG_MDIO_BASE, 250 [HBG_DUMP_REG_TYPE_GMAC] = HBG_REG_SGMII_BASE, 251 [HBG_DUMP_REG_TYPE_PCU] = HBG_REG_SGMII_BASE, 252 }; 253 254 static int hbg_ethtool_get_regs_len(struct net_device *netdev) 255 { 256 return ARRAY_SIZE(hbg_dump_reg_infos) * sizeof(struct hbg_reg_info); 257 } 258 259 static void hbg_ethtool_get_regs(struct net_device *netdev, 260 struct ethtool_regs *regs, void *data) 261 { 262 struct hbg_priv *priv = netdev_priv(netdev); 263 struct hbg_reg_info *info; 264 u32 i, offset = 0; 265 266 regs->version = 0; 267 for (i = 0; i < ARRAY_SIZE(hbg_dump_reg_infos); i++) { 268 info = data + offset; 269 270 *info = hbg_dump_reg_infos[i]; 271 info->val = hbg_reg_read(priv, info->offset); 272 info->offset -= hbg_dump_type_base_array[info->type]; 273 274 offset += sizeof(*info); 275 } 276 } 277 278 static void hbg_ethtool_get_pauseparam(struct net_device *net_dev, 279 struct ethtool_pauseparam *param) 280 { 281 struct hbg_priv *priv = netdev_priv(net_dev); 282 283 param->autoneg = priv->mac.pause_autoneg; 284 hbg_hw_get_pause_enable(priv, ¶m->tx_pause, ¶m->rx_pause); 285 } 286 287 static int hbg_ethtool_set_pauseparam(struct net_device *net_dev, 288 struct ethtool_pauseparam *param) 289 { 290 struct hbg_priv *priv = netdev_priv(net_dev); 291 292 priv->mac.pause_autoneg = param->autoneg; 293 phy_set_asym_pause(priv->mac.phydev, param->rx_pause, param->tx_pause); 294 295 if (!param->autoneg) 296 hbg_hw_set_pause_enable(priv, param->tx_pause, param->rx_pause); 297 298 priv->user_def.pause_param = *param; 299 return 0; 300 } 301 302 static int hbg_ethtool_reset(struct net_device *netdev, u32 *flags) 303 { 304 struct hbg_priv *priv = netdev_priv(netdev); 305 306 if (*flags != ETH_RESET_DEDICATED) 307 return -EOPNOTSUPP; 308 309 *flags = 0; 310 return hbg_reset(priv); 311 } 312 313 static void hbg_update_stats_by_info(struct hbg_priv *priv, 314 const struct hbg_ethtool_stats *info, 315 u32 info_len) 316 { 317 const struct hbg_ethtool_stats *stats; 318 u32 i; 319 320 if (test_bit(HBG_NIC_STATE_RESETTING, &priv->state)) 321 return; 322 323 for (i = 0; i < info_len; i++) { 324 stats = &info[i]; 325 if (!stats->reg) 326 continue; 327 328 HBG_STATS_U(&priv->stats, stats->offset, 329 hbg_reg_read(priv, stats->reg)); 330 } 331 } 332 333 void hbg_update_stats(struct hbg_priv *priv) 334 { 335 hbg_update_stats_by_info(priv, hbg_ethtool_stats_info, 336 ARRAY_SIZE(hbg_ethtool_stats_info)); 337 hbg_update_stats_by_info(priv, hbg_ethtool_rmon_stats_info, 338 ARRAY_SIZE(hbg_ethtool_rmon_stats_info)); 339 hbg_update_stats_by_info(priv, hbg_ethtool_mac_stats_info, 340 ARRAY_SIZE(hbg_ethtool_mac_stats_info)); 341 hbg_update_stats_by_info(priv, hbg_ethtool_ctrl_stats_info, 342 ARRAY_SIZE(hbg_ethtool_ctrl_stats_info)); 343 } 344 345 static int hbg_ethtool_get_sset_count(struct net_device *netdev, int stringset) 346 { 347 if (stringset != ETH_SS_STATS) 348 return -EOPNOTSUPP; 349 350 return ARRAY_SIZE(hbg_ethtool_stats_info); 351 } 352 353 static void hbg_ethtool_get_strings(struct net_device *netdev, 354 u32 stringset, u8 *data) 355 { 356 u32 i; 357 358 if (stringset != ETH_SS_STATS) 359 return; 360 361 for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++) 362 ethtool_puts(&data, hbg_ethtool_stats_info[i].name); 363 } 364 365 static void hbg_ethtool_get_stats(struct net_device *netdev, 366 struct ethtool_stats *stats, u64 *data) 367 { 368 struct hbg_priv *priv = netdev_priv(netdev); 369 u32 i; 370 371 hbg_update_stats(priv); 372 for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++) 373 *data++ = HBG_STATS_R(&priv->stats, 374 hbg_ethtool_stats_info[i].offset); 375 } 376 377 static void hbg_ethtool_get_pause_stats(struct net_device *netdev, 378 struct ethtool_pause_stats *epstats) 379 { 380 struct hbg_priv *priv = netdev_priv(netdev); 381 struct hbg_stats *stats = &priv->stats; 382 383 hbg_update_stats(priv); 384 epstats->rx_pause_frames = stats->rx_pause_macctl_frame_cnt; 385 epstats->tx_pause_frames = stats->tx_pause_frame_cnt; 386 } 387 388 static void hbg_ethtool_get_eth_mac_stats(struct net_device *netdev, 389 struct ethtool_eth_mac_stats *emstats) 390 { 391 struct hbg_priv *priv = netdev_priv(netdev); 392 struct hbg_stats *stats = &priv->stats; 393 394 hbg_update_stats(priv); 395 emstats->FramesTransmittedOK = stats->tx_trans_pkt_cnt; 396 emstats->FramesReceivedOK = stats->rx_trans_pkt_cnt; 397 emstats->FrameCheckSequenceErrors = stats->rx_fcs_error_cnt; 398 emstats->AlignmentErrors = stats->rx_align_error_cnt; 399 emstats->OctetsTransmittedOK = stats->tx_octets_total_ok_cnt; 400 emstats->OctetsReceivedOK = stats->rx_octets_total_ok_cnt; 401 402 emstats->MulticastFramesXmittedOK = stats->tx_mc_pkt_cnt; 403 emstats->BroadcastFramesXmittedOK = stats->tx_bc_pkt_cnt; 404 emstats->MulticastFramesReceivedOK = stats->rx_mc_pkt_cnt; 405 emstats->BroadcastFramesReceivedOK = stats->rx_bc_pkt_cnt; 406 emstats->InRangeLengthErrors = stats->rx_fcs_error_cnt + 407 stats->rx_jabber_err_cnt + 408 stats->rx_unknown_macctl_frame_cnt + 409 stats->rx_bufrq_err_cnt + 410 stats->rx_we_err_cnt; 411 emstats->OutOfRangeLengthField = stats->rx_frame_short_err_cnt + 412 stats->rx_frame_runt_err_cnt + 413 stats->rx_lengthfield_err_cnt + 414 stats->rx_frame_long_err_cnt + 415 stats->rx_frame_very_long_err_cnt; 416 emstats->FrameTooLongErrors = stats->rx_frame_long_err_cnt + 417 stats->rx_frame_very_long_err_cnt; 418 } 419 420 static void 421 hbg_ethtool_get_eth_ctrl_stats(struct net_device *netdev, 422 struct ethtool_eth_ctrl_stats *ecstats) 423 { 424 struct hbg_priv *priv = netdev_priv(netdev); 425 struct hbg_stats *s = &priv->stats; 426 427 hbg_update_stats(priv); 428 ecstats->MACControlFramesTransmitted = s->tx_pause_frame_cnt; 429 ecstats->MACControlFramesReceived = s->rx_pause_macctl_frame_cnt; 430 ecstats->UnsupportedOpcodesReceived = s->rx_unknown_macctl_frame_cnt; 431 } 432 433 static const struct ethtool_rmon_hist_range hbg_rmon_ranges[] = { 434 { 0, 64 }, 435 { 65, 127 }, 436 { 128, 255 }, 437 { 256, 511 }, 438 { 512, 1023 }, 439 { 1024, 1518 }, 440 { 1519, 4095 }, 441 }; 442 443 static void 444 hbg_ethtool_get_rmon_stats(struct net_device *netdev, 445 struct ethtool_rmon_stats *rmon_stats, 446 const struct ethtool_rmon_hist_range **ranges) 447 { 448 struct hbg_priv *priv = netdev_priv(netdev); 449 struct hbg_stats *stats = &priv->stats; 450 451 hbg_update_stats(priv); 452 rmon_stats->undersize_pkts = stats->rx_frame_short_err_cnt + 453 stats->rx_frame_runt_err_cnt + 454 stats->rx_lengthfield_err_cnt; 455 rmon_stats->oversize_pkts = stats->rx_frame_long_err_cnt + 456 stats->rx_frame_very_long_err_cnt; 457 rmon_stats->fragments = stats->rx_desc_frag_cnt; 458 rmon_stats->hist[0] = stats->rx_framesize_64; 459 rmon_stats->hist[1] = stats->rx_framesize_65_127; 460 rmon_stats->hist[2] = stats->rx_framesize_128_255; 461 rmon_stats->hist[3] = stats->rx_framesize_256_511; 462 rmon_stats->hist[4] = stats->rx_framesize_512_1023; 463 rmon_stats->hist[5] = stats->rx_framesize_1024_1518; 464 rmon_stats->hist[6] = stats->rx_framesize_bt_1518; 465 466 rmon_stats->hist_tx[0] = stats->tx_framesize_64; 467 rmon_stats->hist_tx[1] = stats->tx_framesize_65_127; 468 rmon_stats->hist_tx[2] = stats->tx_framesize_128_255; 469 rmon_stats->hist_tx[3] = stats->tx_framesize_256_511; 470 rmon_stats->hist_tx[4] = stats->tx_framesize_512_1023; 471 rmon_stats->hist_tx[5] = stats->tx_framesize_1024_1518; 472 rmon_stats->hist_tx[6] = stats->tx_framesize_bt_1518; 473 474 *ranges = hbg_rmon_ranges; 475 } 476 477 static const struct ethtool_ops hbg_ethtool_ops = { 478 .get_link = ethtool_op_get_link, 479 .get_link_ksettings = phy_ethtool_get_link_ksettings, 480 .set_link_ksettings = phy_ethtool_set_link_ksettings, 481 .get_regs_len = hbg_ethtool_get_regs_len, 482 .get_regs = hbg_ethtool_get_regs, 483 .get_pauseparam = hbg_ethtool_get_pauseparam, 484 .set_pauseparam = hbg_ethtool_set_pauseparam, 485 .reset = hbg_ethtool_reset, 486 .nway_reset = phy_ethtool_nway_reset, 487 .get_sset_count = hbg_ethtool_get_sset_count, 488 .get_strings = hbg_ethtool_get_strings, 489 .get_ethtool_stats = hbg_ethtool_get_stats, 490 .get_pause_stats = hbg_ethtool_get_pause_stats, 491 .get_eth_mac_stats = hbg_ethtool_get_eth_mac_stats, 492 .get_eth_ctrl_stats = hbg_ethtool_get_eth_ctrl_stats, 493 .get_rmon_stats = hbg_ethtool_get_rmon_stats, 494 }; 495 496 void hbg_ethtool_set_ops(struct net_device *netdev) 497 { 498 netdev->ethtool_ops = &hbg_ethtool_ops; 499 } 500