1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Ethtool support for Altera Triple-Speed Ethernet MAC driver 3 * Copyright (C) 2008-2014 Altera Corporation. All rights reserved 4 * 5 * Contributors: 6 * Dalon Westergreen 7 * Thomas Chou 8 * Ian Abbott 9 * Yuriy Kozlov 10 * Tobias Klauser 11 * Andriy Smolskyy 12 * Roman Bulgakov 13 * Dmytro Mytarchuk 14 * 15 * Original driver contributed by SLS. 16 * Major updates contributed by GlobalLogic 17 */ 18 19 #include <linux/ethtool.h> 20 #include <linux/kernel.h> 21 #include <linux/netdevice.h> 22 #include <linux/phy.h> 23 24 #include "altera_tse.h" 25 26 #define TSE_STATS_LEN 31 27 #define TSE_NUM_REGS 128 28 29 static char const stat_gstrings[][ETH_GSTRING_LEN] = { 30 "tx_packets", 31 "rx_packets", 32 "rx_crc_errors", 33 "rx_align_errors", 34 "tx_bytes", 35 "rx_bytes", 36 "tx_pause", 37 "rx_pause", 38 "rx_errors", 39 "tx_errors", 40 "rx_unicast", 41 "rx_multicast", 42 "rx_broadcast", 43 "tx_discards", 44 "tx_unicast", 45 "tx_multicast", 46 "tx_broadcast", 47 "ether_drops", 48 "rx_total_bytes", 49 "rx_total_packets", 50 "rx_undersize", 51 "rx_oversize", 52 "rx_64_bytes", 53 "rx_65_127_bytes", 54 "rx_128_255_bytes", 55 "rx_256_511_bytes", 56 "rx_512_1023_bytes", 57 "rx_1024_1518_bytes", 58 "rx_gte_1519_bytes", 59 "rx_jabbers", 60 "rx_runts", 61 }; 62 63 static void tse_get_drvinfo(struct net_device *dev, 64 struct ethtool_drvinfo *info) 65 { 66 struct altera_tse_private *priv = netdev_priv(dev); 67 u32 rev = ioread32(&priv->mac_dev->megacore_revision); 68 69 strcpy(info->driver, "altera_tse"); 70 snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d", 71 rev & 0xFFFF, (rev & 0xFFFF0000) >> 16); 72 sprintf(info->bus_info, "platform"); 73 } 74 75 /* Fill in a buffer with the strings which correspond to the 76 * stats 77 */ 78 static void tse_gstrings(struct net_device *dev, u32 stringset, u8 *buf) 79 { 80 memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN); 81 } 82 83 static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, 84 u64 *buf) 85 { 86 struct altera_tse_private *priv = netdev_priv(dev); 87 u64 ext; 88 89 buf[0] = csrrd32(priv->mac_dev, 90 tse_csroffs(frames_transmitted_ok)); 91 buf[1] = csrrd32(priv->mac_dev, 92 tse_csroffs(frames_received_ok)); 93 buf[2] = csrrd32(priv->mac_dev, 94 tse_csroffs(frames_check_sequence_errors)); 95 buf[3] = csrrd32(priv->mac_dev, 96 tse_csroffs(alignment_errors)); 97 98 /* Extended aOctetsTransmittedOK counter */ 99 ext = (u64) csrrd32(priv->mac_dev, 100 tse_csroffs(msb_octets_transmitted_ok)) << 32; 101 102 ext |= csrrd32(priv->mac_dev, 103 tse_csroffs(octets_transmitted_ok)); 104 buf[4] = ext; 105 106 /* Extended aOctetsReceivedOK counter */ 107 ext = (u64) csrrd32(priv->mac_dev, 108 tse_csroffs(msb_octets_received_ok)) << 32; 109 110 ext |= csrrd32(priv->mac_dev, 111 tse_csroffs(octets_received_ok)); 112 buf[5] = ext; 113 114 buf[6] = csrrd32(priv->mac_dev, 115 tse_csroffs(tx_pause_mac_ctrl_frames)); 116 buf[7] = csrrd32(priv->mac_dev, 117 tse_csroffs(rx_pause_mac_ctrl_frames)); 118 buf[8] = csrrd32(priv->mac_dev, 119 tse_csroffs(if_in_errors)); 120 buf[9] = csrrd32(priv->mac_dev, 121 tse_csroffs(if_out_errors)); 122 buf[10] = csrrd32(priv->mac_dev, 123 tse_csroffs(if_in_ucast_pkts)); 124 buf[11] = csrrd32(priv->mac_dev, 125 tse_csroffs(if_in_multicast_pkts)); 126 buf[12] = csrrd32(priv->mac_dev, 127 tse_csroffs(if_in_broadcast_pkts)); 128 buf[13] = csrrd32(priv->mac_dev, 129 tse_csroffs(if_out_discards)); 130 buf[14] = csrrd32(priv->mac_dev, 131 tse_csroffs(if_out_ucast_pkts)); 132 buf[15] = csrrd32(priv->mac_dev, 133 tse_csroffs(if_out_multicast_pkts)); 134 buf[16] = csrrd32(priv->mac_dev, 135 tse_csroffs(if_out_broadcast_pkts)); 136 buf[17] = csrrd32(priv->mac_dev, 137 tse_csroffs(ether_stats_drop_events)); 138 139 /* Extended etherStatsOctets counter */ 140 ext = (u64) csrrd32(priv->mac_dev, 141 tse_csroffs(msb_ether_stats_octets)) << 32; 142 ext |= csrrd32(priv->mac_dev, 143 tse_csroffs(ether_stats_octets)); 144 buf[18] = ext; 145 146 buf[19] = csrrd32(priv->mac_dev, 147 tse_csroffs(ether_stats_pkts)); 148 buf[20] = csrrd32(priv->mac_dev, 149 tse_csroffs(ether_stats_undersize_pkts)); 150 buf[21] = csrrd32(priv->mac_dev, 151 tse_csroffs(ether_stats_oversize_pkts)); 152 buf[22] = csrrd32(priv->mac_dev, 153 tse_csroffs(ether_stats_pkts_64_octets)); 154 buf[23] = csrrd32(priv->mac_dev, 155 tse_csroffs(ether_stats_pkts_65to127_octets)); 156 buf[24] = csrrd32(priv->mac_dev, 157 tse_csroffs(ether_stats_pkts_128to255_octets)); 158 buf[25] = csrrd32(priv->mac_dev, 159 tse_csroffs(ether_stats_pkts_256to511_octets)); 160 buf[26] = csrrd32(priv->mac_dev, 161 tse_csroffs(ether_stats_pkts_512to1023_octets)); 162 buf[27] = csrrd32(priv->mac_dev, 163 tse_csroffs(ether_stats_pkts_1024to1518_octets)); 164 buf[28] = csrrd32(priv->mac_dev, 165 tse_csroffs(ether_stats_pkts_1519tox_octets)); 166 buf[29] = csrrd32(priv->mac_dev, 167 tse_csroffs(ether_stats_jabbers)); 168 buf[30] = csrrd32(priv->mac_dev, 169 tse_csroffs(ether_stats_fragments)); 170 } 171 172 static int tse_sset_count(struct net_device *dev, int sset) 173 { 174 switch (sset) { 175 case ETH_SS_STATS: 176 return TSE_STATS_LEN; 177 default: 178 return -EOPNOTSUPP; 179 } 180 } 181 182 static u32 tse_get_msglevel(struct net_device *dev) 183 { 184 struct altera_tse_private *priv = netdev_priv(dev); 185 return priv->msg_enable; 186 } 187 188 static void tse_set_msglevel(struct net_device *dev, uint32_t data) 189 { 190 struct altera_tse_private *priv = netdev_priv(dev); 191 priv->msg_enable = data; 192 } 193 194 static int tse_reglen(struct net_device *dev) 195 { 196 return TSE_NUM_REGS * sizeof(u32); 197 } 198 199 static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs, 200 void *regbuf) 201 { 202 struct altera_tse_private *priv = netdev_priv(dev); 203 u32 *buf = regbuf; 204 int i; 205 206 /* Set version to a known value, so ethtool knows 207 * how to do any special formatting of this data. 208 * This version number will need to change if and 209 * when this register table is changed. 210 * 211 * version[31:0] = 1: Dump the first 128 TSE Registers 212 * Upper bits are all 0 by default 213 * 214 * Upper 16-bits will indicate feature presence for 215 * Ethtool register decoding in future version. 216 */ 217 218 regs->version = 1; 219 220 for (i = 0; i < TSE_NUM_REGS; i++) 221 buf[i] = csrrd32(priv->mac_dev, i * 4); 222 } 223 224 static int tse_ethtool_set_link_ksettings(struct net_device *dev, 225 const struct ethtool_link_ksettings *cmd) 226 { 227 struct altera_tse_private *priv = netdev_priv(dev); 228 229 return phylink_ethtool_ksettings_set(priv->phylink, cmd); 230 } 231 232 static int tse_ethtool_get_link_ksettings(struct net_device *dev, 233 struct ethtool_link_ksettings *cmd) 234 { 235 struct altera_tse_private *priv = netdev_priv(dev); 236 237 return phylink_ethtool_ksettings_get(priv->phylink, cmd); 238 } 239 240 static const struct ethtool_ops tse_ethtool_ops = { 241 .get_drvinfo = tse_get_drvinfo, 242 .get_regs_len = tse_reglen, 243 .get_regs = tse_get_regs, 244 .get_link = ethtool_op_get_link, 245 .get_strings = tse_gstrings, 246 .get_sset_count = tse_sset_count, 247 .get_ethtool_stats = tse_fill_stats, 248 .get_msglevel = tse_get_msglevel, 249 .set_msglevel = tse_set_msglevel, 250 .get_link_ksettings = tse_ethtool_get_link_ksettings, 251 .set_link_ksettings = tse_ethtool_set_link_ksettings, 252 .get_ts_info = ethtool_op_get_ts_info, 253 }; 254 255 void altera_tse_set_ethtool_ops(struct net_device *netdev) 256 { 257 netdev->ethtool_ops = &tse_ethtool_ops; 258 } 259