brintos

brintos / linux-shallow public Read only

0
0
Text · 6.9 KiB · 81313c8 Raw
259 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Ethtool support for Altera Triple-Speed Ethernet MAC driver3 * Copyright (C) 2008-2014 Altera Corporation. All rights reserved4 *5 * Contributors:6 *   Dalon Westergreen7 *   Thomas Chou8 *   Ian Abbott9 *   Yuriy Kozlov10 *   Tobias Klauser11 *   Andriy Smolskyy12 *   Roman Bulgakov13 *   Dmytro Mytarchuk14 *15 * Original driver contributed by SLS.16 * Major updates contributed by GlobalLogic17 */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	3127#define TSE_NUM_REGS	12828 29static 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 63static 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 the76 * stats77 */78static 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 83static 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 172static 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 182static 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 188static 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 194static int tse_reglen(struct net_device *dev)195{196	return TSE_NUM_REGS * sizeof(u32);197}198 199static 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 knows207	 * how to do any special formatting of this data.208	 * This version number will need to change if and209	 * when this register table is changed.210	 *211	 * version[31:0] = 1: Dump the first 128 TSE Registers212	 *      Upper bits are all 0 by default213	 *214	 * Upper 16-bits will indicate feature presence for215	 * 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 224static 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 232static 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 240static 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 255void altera_tse_set_ethtool_ops(struct net_device *netdev)256{257	netdev->ethtool_ops = &tse_ethtool_ops;258}259