0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/ethtool.h>
0020 #include <linux/kernel.h>
0021 #include <linux/netdevice.h>
0022 #include <linux/phy.h>
0023
0024 #include "altera_tse.h"
0025
0026 #define TSE_STATS_LEN 31
0027 #define TSE_NUM_REGS 128
0028
0029 static char const stat_gstrings[][ETH_GSTRING_LEN] = {
0030 "tx_packets",
0031 "rx_packets",
0032 "rx_crc_errors",
0033 "rx_align_errors",
0034 "tx_bytes",
0035 "rx_bytes",
0036 "tx_pause",
0037 "rx_pause",
0038 "rx_errors",
0039 "tx_errors",
0040 "rx_unicast",
0041 "rx_multicast",
0042 "rx_broadcast",
0043 "tx_discards",
0044 "tx_unicast",
0045 "tx_multicast",
0046 "tx_broadcast",
0047 "ether_drops",
0048 "rx_total_bytes",
0049 "rx_total_packets",
0050 "rx_undersize",
0051 "rx_oversize",
0052 "rx_64_bytes",
0053 "rx_65_127_bytes",
0054 "rx_128_255_bytes",
0055 "rx_256_511_bytes",
0056 "rx_512_1023_bytes",
0057 "rx_1024_1518_bytes",
0058 "rx_gte_1519_bytes",
0059 "rx_jabbers",
0060 "rx_runts",
0061 };
0062
0063 static void tse_get_drvinfo(struct net_device *dev,
0064 struct ethtool_drvinfo *info)
0065 {
0066 struct altera_tse_private *priv = netdev_priv(dev);
0067 u32 rev = ioread32(&priv->mac_dev->megacore_revision);
0068
0069 strcpy(info->driver, "altera_tse");
0070 snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d",
0071 rev & 0xFFFF, (rev & 0xFFFF0000) >> 16);
0072 sprintf(info->bus_info, "platform");
0073 }
0074
0075
0076
0077
0078 static void tse_gstrings(struct net_device *dev, u32 stringset, u8 *buf)
0079 {
0080 memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN);
0081 }
0082
0083 static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
0084 u64 *buf)
0085 {
0086 struct altera_tse_private *priv = netdev_priv(dev);
0087 u64 ext;
0088
0089 buf[0] = csrrd32(priv->mac_dev,
0090 tse_csroffs(frames_transmitted_ok));
0091 buf[1] = csrrd32(priv->mac_dev,
0092 tse_csroffs(frames_received_ok));
0093 buf[2] = csrrd32(priv->mac_dev,
0094 tse_csroffs(frames_check_sequence_errors));
0095 buf[3] = csrrd32(priv->mac_dev,
0096 tse_csroffs(alignment_errors));
0097
0098
0099 ext = (u64) csrrd32(priv->mac_dev,
0100 tse_csroffs(msb_octets_transmitted_ok)) << 32;
0101
0102 ext |= csrrd32(priv->mac_dev,
0103 tse_csroffs(octets_transmitted_ok));
0104 buf[4] = ext;
0105
0106
0107 ext = (u64) csrrd32(priv->mac_dev,
0108 tse_csroffs(msb_octets_received_ok)) << 32;
0109
0110 ext |= csrrd32(priv->mac_dev,
0111 tse_csroffs(octets_received_ok));
0112 buf[5] = ext;
0113
0114 buf[6] = csrrd32(priv->mac_dev,
0115 tse_csroffs(tx_pause_mac_ctrl_frames));
0116 buf[7] = csrrd32(priv->mac_dev,
0117 tse_csroffs(rx_pause_mac_ctrl_frames));
0118 buf[8] = csrrd32(priv->mac_dev,
0119 tse_csroffs(if_in_errors));
0120 buf[9] = csrrd32(priv->mac_dev,
0121 tse_csroffs(if_out_errors));
0122 buf[10] = csrrd32(priv->mac_dev,
0123 tse_csroffs(if_in_ucast_pkts));
0124 buf[11] = csrrd32(priv->mac_dev,
0125 tse_csroffs(if_in_multicast_pkts));
0126 buf[12] = csrrd32(priv->mac_dev,
0127 tse_csroffs(if_in_broadcast_pkts));
0128 buf[13] = csrrd32(priv->mac_dev,
0129 tse_csroffs(if_out_discards));
0130 buf[14] = csrrd32(priv->mac_dev,
0131 tse_csroffs(if_out_ucast_pkts));
0132 buf[15] = csrrd32(priv->mac_dev,
0133 tse_csroffs(if_out_multicast_pkts));
0134 buf[16] = csrrd32(priv->mac_dev,
0135 tse_csroffs(if_out_broadcast_pkts));
0136 buf[17] = csrrd32(priv->mac_dev,
0137 tse_csroffs(ether_stats_drop_events));
0138
0139
0140 ext = (u64) csrrd32(priv->mac_dev,
0141 tse_csroffs(msb_ether_stats_octets)) << 32;
0142 ext |= csrrd32(priv->mac_dev,
0143 tse_csroffs(ether_stats_octets));
0144 buf[18] = ext;
0145
0146 buf[19] = csrrd32(priv->mac_dev,
0147 tse_csroffs(ether_stats_pkts));
0148 buf[20] = csrrd32(priv->mac_dev,
0149 tse_csroffs(ether_stats_undersize_pkts));
0150 buf[21] = csrrd32(priv->mac_dev,
0151 tse_csroffs(ether_stats_oversize_pkts));
0152 buf[22] = csrrd32(priv->mac_dev,
0153 tse_csroffs(ether_stats_pkts_64_octets));
0154 buf[23] = csrrd32(priv->mac_dev,
0155 tse_csroffs(ether_stats_pkts_65to127_octets));
0156 buf[24] = csrrd32(priv->mac_dev,
0157 tse_csroffs(ether_stats_pkts_128to255_octets));
0158 buf[25] = csrrd32(priv->mac_dev,
0159 tse_csroffs(ether_stats_pkts_256to511_octets));
0160 buf[26] = csrrd32(priv->mac_dev,
0161 tse_csroffs(ether_stats_pkts_512to1023_octets));
0162 buf[27] = csrrd32(priv->mac_dev,
0163 tse_csroffs(ether_stats_pkts_1024to1518_octets));
0164 buf[28] = csrrd32(priv->mac_dev,
0165 tse_csroffs(ether_stats_pkts_1519tox_octets));
0166 buf[29] = csrrd32(priv->mac_dev,
0167 tse_csroffs(ether_stats_jabbers));
0168 buf[30] = csrrd32(priv->mac_dev,
0169 tse_csroffs(ether_stats_fragments));
0170 }
0171
0172 static int tse_sset_count(struct net_device *dev, int sset)
0173 {
0174 switch (sset) {
0175 case ETH_SS_STATS:
0176 return TSE_STATS_LEN;
0177 default:
0178 return -EOPNOTSUPP;
0179 }
0180 }
0181
0182 static u32 tse_get_msglevel(struct net_device *dev)
0183 {
0184 struct altera_tse_private *priv = netdev_priv(dev);
0185 return priv->msg_enable;
0186 }
0187
0188 static void tse_set_msglevel(struct net_device *dev, uint32_t data)
0189 {
0190 struct altera_tse_private *priv = netdev_priv(dev);
0191 priv->msg_enable = data;
0192 }
0193
0194 static int tse_reglen(struct net_device *dev)
0195 {
0196 return TSE_NUM_REGS * sizeof(u32);
0197 }
0198
0199 static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs,
0200 void *regbuf)
0201 {
0202 int i;
0203 struct altera_tse_private *priv = netdev_priv(dev);
0204 u32 *buf = regbuf;
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 regs->version = 1;
0219
0220 for (i = 0; i < TSE_NUM_REGS; i++)
0221 buf[i] = csrrd32(priv->mac_dev, i * 4);
0222 }
0223
0224 static const struct ethtool_ops tse_ethtool_ops = {
0225 .get_drvinfo = tse_get_drvinfo,
0226 .get_regs_len = tse_reglen,
0227 .get_regs = tse_get_regs,
0228 .get_link = ethtool_op_get_link,
0229 .get_strings = tse_gstrings,
0230 .get_sset_count = tse_sset_count,
0231 .get_ethtool_stats = tse_fill_stats,
0232 .get_msglevel = tse_get_msglevel,
0233 .set_msglevel = tse_set_msglevel,
0234 .get_link_ksettings = phy_ethtool_get_link_ksettings,
0235 .set_link_ksettings = phy_ethtool_set_link_ksettings,
0236 };
0237
0238 void altera_tse_set_ethtool_ops(struct net_device *netdev)
0239 {
0240 netdev->ethtool_ops = &tse_ethtool_ops;
0241 }