brintos

brintos / linux-shallow public Read only

0
0
Text · 39.0 KiB · 2a37592 Raw
1406 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*******************************************************************************3  STMMAC Ethtool support4 5  Copyright (C) 2007-2009  STMicroelectronics Ltd6 7 8  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>9*******************************************************************************/10 11#include <linux/etherdevice.h>12#include <linux/ethtool.h>13#include <linux/interrupt.h>14#include <linux/io.h>15#include <linux/mii.h>16#include <linux/phylink.h>17#include <linux/net_tstamp.h>18 19#include "stmmac.h"20#include "dwmac_dma.h"21#include "dwxgmac2.h"22#include "dwmac5.h"23 24#define REG_SPACE_SIZE	0x106025#define GMAC4_REG_SPACE_SIZE	0x116C26#define MAC100_ETHTOOL_NAME	"st_mac100"27#define GMAC_ETHTOOL_NAME	"st_gmac"28#define XGMAC_ETHTOOL_NAME	"st_xgmac"29 30/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h31 *32 * It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the33 * same time due to the conflicting macro names.34 */35#define GMAC4_DMA_CHAN_BASE_ADDR  0x0000110036 37#define ETHTOOL_DMA_OFFSET	5538 39struct stmmac_stats {40	char stat_string[ETH_GSTRING_LEN];41	int sizeof_stat;42	int stat_offset;43};44 45#define STMMAC_STAT(m)	\46	{ #m, sizeof_field(struct stmmac_extra_stats, m),	\47	offsetof(struct stmmac_priv, xstats.m)}48 49static const struct stmmac_stats stmmac_gstrings_stats[] = {50	/* Transmit errors */51	STMMAC_STAT(tx_underflow),52	STMMAC_STAT(tx_carrier),53	STMMAC_STAT(tx_losscarrier),54	STMMAC_STAT(vlan_tag),55	STMMAC_STAT(tx_deferred),56	STMMAC_STAT(tx_vlan),57	STMMAC_STAT(tx_jabber),58	STMMAC_STAT(tx_frame_flushed),59	STMMAC_STAT(tx_payload_error),60	STMMAC_STAT(tx_ip_header_error),61	/* Receive errors */62	STMMAC_STAT(rx_desc),63	STMMAC_STAT(sa_filter_fail),64	STMMAC_STAT(overflow_error),65	STMMAC_STAT(ipc_csum_error),66	STMMAC_STAT(rx_collision),67	STMMAC_STAT(rx_crc_errors),68	STMMAC_STAT(dribbling_bit),69	STMMAC_STAT(rx_length),70	STMMAC_STAT(rx_mii),71	STMMAC_STAT(rx_multicast),72	STMMAC_STAT(rx_gmac_overflow),73	STMMAC_STAT(rx_watchdog),74	STMMAC_STAT(da_rx_filter_fail),75	STMMAC_STAT(sa_rx_filter_fail),76	STMMAC_STAT(rx_missed_cntr),77	STMMAC_STAT(rx_overflow_cntr),78	STMMAC_STAT(rx_vlan),79	STMMAC_STAT(rx_split_hdr_pkt_n),80	/* Tx/Rx IRQ error info */81	STMMAC_STAT(tx_undeflow_irq),82	STMMAC_STAT(tx_process_stopped_irq),83	STMMAC_STAT(tx_jabber_irq),84	STMMAC_STAT(rx_overflow_irq),85	STMMAC_STAT(rx_buf_unav_irq),86	STMMAC_STAT(rx_process_stopped_irq),87	STMMAC_STAT(rx_watchdog_irq),88	STMMAC_STAT(tx_early_irq),89	STMMAC_STAT(fatal_bus_error_irq),90	/* Tx/Rx IRQ Events */91	STMMAC_STAT(rx_early_irq),92	STMMAC_STAT(threshold),93	STMMAC_STAT(irq_receive_pmt_irq_n),94	/* MMC info */95	STMMAC_STAT(mmc_tx_irq_n),96	STMMAC_STAT(mmc_rx_irq_n),97	STMMAC_STAT(mmc_rx_csum_offload_irq_n),98	/* EEE */99	STMMAC_STAT(irq_tx_path_in_lpi_mode_n),100	STMMAC_STAT(irq_tx_path_exit_lpi_mode_n),101	STMMAC_STAT(irq_rx_path_in_lpi_mode_n),102	STMMAC_STAT(irq_rx_path_exit_lpi_mode_n),103	STMMAC_STAT(phy_eee_wakeup_error_n),104	/* Extended RDES status */105	STMMAC_STAT(ip_hdr_err),106	STMMAC_STAT(ip_payload_err),107	STMMAC_STAT(ip_csum_bypassed),108	STMMAC_STAT(ipv4_pkt_rcvd),109	STMMAC_STAT(ipv6_pkt_rcvd),110	STMMAC_STAT(no_ptp_rx_msg_type_ext),111	STMMAC_STAT(ptp_rx_msg_type_sync),112	STMMAC_STAT(ptp_rx_msg_type_follow_up),113	STMMAC_STAT(ptp_rx_msg_type_delay_req),114	STMMAC_STAT(ptp_rx_msg_type_delay_resp),115	STMMAC_STAT(ptp_rx_msg_type_pdelay_req),116	STMMAC_STAT(ptp_rx_msg_type_pdelay_resp),117	STMMAC_STAT(ptp_rx_msg_type_pdelay_follow_up),118	STMMAC_STAT(ptp_rx_msg_type_announce),119	STMMAC_STAT(ptp_rx_msg_type_management),120	STMMAC_STAT(ptp_rx_msg_pkt_reserved_type),121	STMMAC_STAT(ptp_frame_type),122	STMMAC_STAT(ptp_ver),123	STMMAC_STAT(timestamp_dropped),124	STMMAC_STAT(av_pkt_rcvd),125	STMMAC_STAT(av_tagged_pkt_rcvd),126	STMMAC_STAT(vlan_tag_priority_val),127	STMMAC_STAT(l3_filter_match),128	STMMAC_STAT(l4_filter_match),129	STMMAC_STAT(l3_l4_filter_no_match),130	/* PCS */131	STMMAC_STAT(irq_pcs_ane_n),132	STMMAC_STAT(irq_pcs_link_n),133	STMMAC_STAT(irq_rgmii_n),134	/* DEBUG */135	STMMAC_STAT(mtl_tx_status_fifo_full),136	STMMAC_STAT(mtl_tx_fifo_not_empty),137	STMMAC_STAT(mmtl_fifo_ctrl),138	STMMAC_STAT(mtl_tx_fifo_read_ctrl_write),139	STMMAC_STAT(mtl_tx_fifo_read_ctrl_wait),140	STMMAC_STAT(mtl_tx_fifo_read_ctrl_read),141	STMMAC_STAT(mtl_tx_fifo_read_ctrl_idle),142	STMMAC_STAT(mac_tx_in_pause),143	STMMAC_STAT(mac_tx_frame_ctrl_xfer),144	STMMAC_STAT(mac_tx_frame_ctrl_idle),145	STMMAC_STAT(mac_tx_frame_ctrl_wait),146	STMMAC_STAT(mac_tx_frame_ctrl_pause),147	STMMAC_STAT(mac_gmii_tx_proto_engine),148	STMMAC_STAT(mtl_rx_fifo_fill_level_full),149	STMMAC_STAT(mtl_rx_fifo_fill_above_thresh),150	STMMAC_STAT(mtl_rx_fifo_fill_below_thresh),151	STMMAC_STAT(mtl_rx_fifo_fill_level_empty),152	STMMAC_STAT(mtl_rx_fifo_read_ctrl_flush),153	STMMAC_STAT(mtl_rx_fifo_read_ctrl_read_data),154	STMMAC_STAT(mtl_rx_fifo_read_ctrl_status),155	STMMAC_STAT(mtl_rx_fifo_read_ctrl_idle),156	STMMAC_STAT(mtl_rx_fifo_ctrl_active),157	STMMAC_STAT(mac_rx_frame_ctrl_fifo),158	STMMAC_STAT(mac_gmii_rx_proto_engine),159	/* EST */160	STMMAC_STAT(mtl_est_cgce),161	STMMAC_STAT(mtl_est_hlbs),162	STMMAC_STAT(mtl_est_hlbf),163	STMMAC_STAT(mtl_est_btre),164	STMMAC_STAT(mtl_est_btrlm),165};166#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)167 168/* statistics collected in queue which will be summed up for all TX or RX169 * queues, or summed up for both TX and RX queues(napi_poll, normal_irq_n).170 */171static const char stmmac_qstats_string[][ETH_GSTRING_LEN] = {172	"rx_pkt_n",173	"rx_normal_irq_n",174	"tx_pkt_n",175	"tx_normal_irq_n",176	"tx_clean",177	"tx_set_ic_bit",178	"tx_tso_frames",179	"tx_tso_nfrags",180	"normal_irq_n",181	"napi_poll",182};183#define STMMAC_QSTATS ARRAY_SIZE(stmmac_qstats_string)184 185/* HW MAC Management counters (if supported) */186#define STMMAC_MMC_STAT(m)	\187	{ #m, sizeof_field(struct stmmac_counters, m),	\188	offsetof(struct stmmac_priv, mmc.m)}189 190static const struct stmmac_stats stmmac_mmc[] = {191	STMMAC_MMC_STAT(mmc_tx_octetcount_gb),192	STMMAC_MMC_STAT(mmc_tx_framecount_gb),193	STMMAC_MMC_STAT(mmc_tx_broadcastframe_g),194	STMMAC_MMC_STAT(mmc_tx_multicastframe_g),195	STMMAC_MMC_STAT(mmc_tx_64_octets_gb),196	STMMAC_MMC_STAT(mmc_tx_65_to_127_octets_gb),197	STMMAC_MMC_STAT(mmc_tx_128_to_255_octets_gb),198	STMMAC_MMC_STAT(mmc_tx_256_to_511_octets_gb),199	STMMAC_MMC_STAT(mmc_tx_512_to_1023_octets_gb),200	STMMAC_MMC_STAT(mmc_tx_1024_to_max_octets_gb),201	STMMAC_MMC_STAT(mmc_tx_unicast_gb),202	STMMAC_MMC_STAT(mmc_tx_multicast_gb),203	STMMAC_MMC_STAT(mmc_tx_broadcast_gb),204	STMMAC_MMC_STAT(mmc_tx_underflow_error),205	STMMAC_MMC_STAT(mmc_tx_singlecol_g),206	STMMAC_MMC_STAT(mmc_tx_multicol_g),207	STMMAC_MMC_STAT(mmc_tx_deferred),208	STMMAC_MMC_STAT(mmc_tx_latecol),209	STMMAC_MMC_STAT(mmc_tx_exesscol),210	STMMAC_MMC_STAT(mmc_tx_carrier_error),211	STMMAC_MMC_STAT(mmc_tx_octetcount_g),212	STMMAC_MMC_STAT(mmc_tx_framecount_g),213	STMMAC_MMC_STAT(mmc_tx_excessdef),214	STMMAC_MMC_STAT(mmc_tx_pause_frame),215	STMMAC_MMC_STAT(mmc_tx_vlan_frame_g),216	STMMAC_MMC_STAT(mmc_tx_oversize_g),217	STMMAC_MMC_STAT(mmc_tx_lpi_usec),218	STMMAC_MMC_STAT(mmc_tx_lpi_tran),219	STMMAC_MMC_STAT(mmc_rx_framecount_gb),220	STMMAC_MMC_STAT(mmc_rx_octetcount_gb),221	STMMAC_MMC_STAT(mmc_rx_octetcount_g),222	STMMAC_MMC_STAT(mmc_rx_broadcastframe_g),223	STMMAC_MMC_STAT(mmc_rx_multicastframe_g),224	STMMAC_MMC_STAT(mmc_rx_crc_error),225	STMMAC_MMC_STAT(mmc_rx_align_error),226	STMMAC_MMC_STAT(mmc_rx_run_error),227	STMMAC_MMC_STAT(mmc_rx_jabber_error),228	STMMAC_MMC_STAT(mmc_rx_undersize_g),229	STMMAC_MMC_STAT(mmc_rx_oversize_g),230	STMMAC_MMC_STAT(mmc_rx_64_octets_gb),231	STMMAC_MMC_STAT(mmc_rx_65_to_127_octets_gb),232	STMMAC_MMC_STAT(mmc_rx_128_to_255_octets_gb),233	STMMAC_MMC_STAT(mmc_rx_256_to_511_octets_gb),234	STMMAC_MMC_STAT(mmc_rx_512_to_1023_octets_gb),235	STMMAC_MMC_STAT(mmc_rx_1024_to_max_octets_gb),236	STMMAC_MMC_STAT(mmc_rx_unicast_g),237	STMMAC_MMC_STAT(mmc_rx_length_error),238	STMMAC_MMC_STAT(mmc_rx_autofrangetype),239	STMMAC_MMC_STAT(mmc_rx_pause_frames),240	STMMAC_MMC_STAT(mmc_rx_fifo_overflow),241	STMMAC_MMC_STAT(mmc_rx_vlan_frames_gb),242	STMMAC_MMC_STAT(mmc_rx_watchdog_error),243	STMMAC_MMC_STAT(mmc_rx_error),244	STMMAC_MMC_STAT(mmc_rx_lpi_usec),245	STMMAC_MMC_STAT(mmc_rx_lpi_tran),246	STMMAC_MMC_STAT(mmc_rx_discard_frames_gb),247	STMMAC_MMC_STAT(mmc_rx_discard_octets_gb),248	STMMAC_MMC_STAT(mmc_rx_align_err_frames),249	STMMAC_MMC_STAT(mmc_rx_ipv4_gd),250	STMMAC_MMC_STAT(mmc_rx_ipv4_hderr),251	STMMAC_MMC_STAT(mmc_rx_ipv4_nopay),252	STMMAC_MMC_STAT(mmc_rx_ipv4_frag),253	STMMAC_MMC_STAT(mmc_rx_ipv4_udsbl),254	STMMAC_MMC_STAT(mmc_rx_ipv4_gd_octets),255	STMMAC_MMC_STAT(mmc_rx_ipv4_hderr_octets),256	STMMAC_MMC_STAT(mmc_rx_ipv4_nopay_octets),257	STMMAC_MMC_STAT(mmc_rx_ipv4_frag_octets),258	STMMAC_MMC_STAT(mmc_rx_ipv4_udsbl_octets),259	STMMAC_MMC_STAT(mmc_rx_ipv6_gd_octets),260	STMMAC_MMC_STAT(mmc_rx_ipv6_hderr_octets),261	STMMAC_MMC_STAT(mmc_rx_ipv6_nopay_octets),262	STMMAC_MMC_STAT(mmc_rx_ipv6_gd),263	STMMAC_MMC_STAT(mmc_rx_ipv6_hderr),264	STMMAC_MMC_STAT(mmc_rx_ipv6_nopay),265	STMMAC_MMC_STAT(mmc_rx_udp_gd),266	STMMAC_MMC_STAT(mmc_rx_udp_err),267	STMMAC_MMC_STAT(mmc_rx_tcp_gd),268	STMMAC_MMC_STAT(mmc_rx_tcp_err),269	STMMAC_MMC_STAT(mmc_rx_icmp_gd),270	STMMAC_MMC_STAT(mmc_rx_icmp_err),271	STMMAC_MMC_STAT(mmc_rx_udp_gd_octets),272	STMMAC_MMC_STAT(mmc_rx_udp_err_octets),273	STMMAC_MMC_STAT(mmc_rx_tcp_gd_octets),274	STMMAC_MMC_STAT(mmc_rx_tcp_err_octets),275	STMMAC_MMC_STAT(mmc_rx_icmp_gd_octets),276	STMMAC_MMC_STAT(mmc_rx_icmp_err_octets),277	STMMAC_MMC_STAT(mmc_sgf_pass_fragment_cntr),278	STMMAC_MMC_STAT(mmc_sgf_fail_fragment_cntr),279	STMMAC_MMC_STAT(mmc_tx_fpe_fragment_cntr),280	STMMAC_MMC_STAT(mmc_tx_hold_req_cntr),281	STMMAC_MMC_STAT(mmc_tx_gate_overrun_cntr),282	STMMAC_MMC_STAT(mmc_rx_packet_assembly_err_cntr),283	STMMAC_MMC_STAT(mmc_rx_packet_smd_err_cntr),284	STMMAC_MMC_STAT(mmc_rx_packet_assembly_ok_cntr),285	STMMAC_MMC_STAT(mmc_rx_fpe_fragment_cntr),286};287#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc)288 289static const char stmmac_qstats_tx_string[][ETH_GSTRING_LEN] = {290	"tx_pkt_n",291	"tx_irq_n",292#define STMMAC_TXQ_STATS ARRAY_SIZE(stmmac_qstats_tx_string)293};294 295static const char stmmac_qstats_rx_string[][ETH_GSTRING_LEN] = {296	"rx_pkt_n",297	"rx_irq_n",298#define STMMAC_RXQ_STATS ARRAY_SIZE(stmmac_qstats_rx_string)299};300 301static void stmmac_ethtool_getdrvinfo(struct net_device *dev,302				      struct ethtool_drvinfo *info)303{304	struct stmmac_priv *priv = netdev_priv(dev);305 306	if (priv->plat->has_gmac || priv->plat->has_gmac4)307		strscpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver));308	else if (priv->plat->has_xgmac)309		strscpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver));310	else311		strscpy(info->driver, MAC100_ETHTOOL_NAME,312			sizeof(info->driver));313 314	if (priv->plat->pdev) {315		strscpy(info->bus_info, pci_name(priv->plat->pdev),316			sizeof(info->bus_info));317	}318}319 320static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,321					     struct ethtool_link_ksettings *cmd)322{323	struct stmmac_priv *priv = netdev_priv(dev);324 325	if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&326	    (priv->hw->pcs & STMMAC_PCS_RGMII ||327	     priv->hw->pcs & STMMAC_PCS_SGMII)) {328		struct rgmii_adv adv;329		u32 supported, advertising, lp_advertising;330 331		if (!priv->xstats.pcs_link) {332			cmd->base.speed = SPEED_UNKNOWN;333			cmd->base.duplex = DUPLEX_UNKNOWN;334			return 0;335		}336		cmd->base.duplex = priv->xstats.pcs_duplex;337 338		cmd->base.speed = priv->xstats.pcs_speed;339 340		/* Get and convert ADV/LP_ADV from the HW AN registers */341		if (stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv))342			return -EOPNOTSUPP;	/* should never happen indeed */343 344		/* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */345 346		ethtool_convert_link_mode_to_legacy_u32(347			&supported, cmd->link_modes.supported);348		ethtool_convert_link_mode_to_legacy_u32(349			&advertising, cmd->link_modes.advertising);350		ethtool_convert_link_mode_to_legacy_u32(351			&lp_advertising, cmd->link_modes.lp_advertising);352 353		if (adv.pause & STMMAC_PCS_PAUSE)354			advertising |= ADVERTISED_Pause;355		if (adv.pause & STMMAC_PCS_ASYM_PAUSE)356			advertising |= ADVERTISED_Asym_Pause;357		if (adv.lp_pause & STMMAC_PCS_PAUSE)358			lp_advertising |= ADVERTISED_Pause;359		if (adv.lp_pause & STMMAC_PCS_ASYM_PAUSE)360			lp_advertising |= ADVERTISED_Asym_Pause;361 362		/* Reg49[3] always set because ANE is always supported */363		cmd->base.autoneg = ADVERTISED_Autoneg;364		supported |= SUPPORTED_Autoneg;365		advertising |= ADVERTISED_Autoneg;366		lp_advertising |= ADVERTISED_Autoneg;367 368		if (adv.duplex) {369			supported |= (SUPPORTED_1000baseT_Full |370				      SUPPORTED_100baseT_Full |371				      SUPPORTED_10baseT_Full);372			advertising |= (ADVERTISED_1000baseT_Full |373					ADVERTISED_100baseT_Full |374					ADVERTISED_10baseT_Full);375		} else {376			supported |= (SUPPORTED_1000baseT_Half |377				      SUPPORTED_100baseT_Half |378				      SUPPORTED_10baseT_Half);379			advertising |= (ADVERTISED_1000baseT_Half |380					ADVERTISED_100baseT_Half |381					ADVERTISED_10baseT_Half);382		}383		if (adv.lp_duplex)384			lp_advertising |= (ADVERTISED_1000baseT_Full |385					   ADVERTISED_100baseT_Full |386					   ADVERTISED_10baseT_Full);387		else388			lp_advertising |= (ADVERTISED_1000baseT_Half |389					   ADVERTISED_100baseT_Half |390					   ADVERTISED_10baseT_Half);391		cmd->base.port = PORT_OTHER;392 393		ethtool_convert_legacy_u32_to_link_mode(394			cmd->link_modes.supported, supported);395		ethtool_convert_legacy_u32_to_link_mode(396			cmd->link_modes.advertising, advertising);397		ethtool_convert_legacy_u32_to_link_mode(398			cmd->link_modes.lp_advertising, lp_advertising);399 400		return 0;401	}402 403	return phylink_ethtool_ksettings_get(priv->phylink, cmd);404}405 406static int407stmmac_ethtool_set_link_ksettings(struct net_device *dev,408				  const struct ethtool_link_ksettings *cmd)409{410	struct stmmac_priv *priv = netdev_priv(dev);411 412	if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&413	    (priv->hw->pcs & STMMAC_PCS_RGMII ||414	     priv->hw->pcs & STMMAC_PCS_SGMII)) {415		/* Only support ANE */416		if (cmd->base.autoneg != AUTONEG_ENABLE)417			return -EINVAL;418 419		mutex_lock(&priv->lock);420		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0);421		mutex_unlock(&priv->lock);422 423		return 0;424	}425 426	return phylink_ethtool_ksettings_set(priv->phylink, cmd);427}428 429static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)430{431	struct stmmac_priv *priv = netdev_priv(dev);432	return priv->msg_enable;433}434 435static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)436{437	struct stmmac_priv *priv = netdev_priv(dev);438	priv->msg_enable = level;439 440}441 442static int stmmac_ethtool_get_regs_len(struct net_device *dev)443{444	struct stmmac_priv *priv = netdev_priv(dev);445 446	if (priv->plat->has_xgmac)447		return XGMAC_REGSIZE * 4;448	else if (priv->plat->has_gmac4)449		return GMAC4_REG_SPACE_SIZE;450	return REG_SPACE_SIZE;451}452 453static void stmmac_ethtool_gregs(struct net_device *dev,454			  struct ethtool_regs *regs, void *space)455{456	struct stmmac_priv *priv = netdev_priv(dev);457	u32 *reg_space = (u32 *) space;458 459	stmmac_dump_mac_regs(priv, priv->hw, reg_space);460	stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);461 462	/* Copy DMA registers to where ethtool expects them */463	if (priv->plat->has_gmac4) {464		/* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */465		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],466		       &reg_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],467		       NUM_DWMAC4_DMA_REGS * 4);468	} else if (!priv->plat->has_xgmac) {469		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],470		       &reg_space[DMA_BUS_MODE / 4],471		       NUM_DWMAC1000_DMA_REGS * 4);472	}473}474 475static int stmmac_nway_reset(struct net_device *dev)476{477	struct stmmac_priv *priv = netdev_priv(dev);478 479	return phylink_ethtool_nway_reset(priv->phylink);480}481 482static void stmmac_get_ringparam(struct net_device *netdev,483				 struct ethtool_ringparam *ring,484				 struct kernel_ethtool_ringparam *kernel_ring,485				 struct netlink_ext_ack *extack)486{487	struct stmmac_priv *priv = netdev_priv(netdev);488 489	ring->rx_max_pending = DMA_MAX_RX_SIZE;490	ring->tx_max_pending = DMA_MAX_TX_SIZE;491	ring->rx_pending = priv->dma_conf.dma_rx_size;492	ring->tx_pending = priv->dma_conf.dma_tx_size;493}494 495static int stmmac_set_ringparam(struct net_device *netdev,496				struct ethtool_ringparam *ring,497				struct kernel_ethtool_ringparam *kernel_ring,498				struct netlink_ext_ack *extack)499{500	if (ring->rx_mini_pending || ring->rx_jumbo_pending ||501	    ring->rx_pending < DMA_MIN_RX_SIZE ||502	    ring->rx_pending > DMA_MAX_RX_SIZE ||503	    !is_power_of_2(ring->rx_pending) ||504	    ring->tx_pending < DMA_MIN_TX_SIZE ||505	    ring->tx_pending > DMA_MAX_TX_SIZE ||506	    !is_power_of_2(ring->tx_pending))507		return -EINVAL;508 509	return stmmac_reinit_ringparam(netdev, ring->rx_pending,510				       ring->tx_pending);511}512 513static void514stmmac_get_pauseparam(struct net_device *netdev,515		      struct ethtool_pauseparam *pause)516{517	struct stmmac_priv *priv = netdev_priv(netdev);518	struct rgmii_adv adv_lp;519 520	if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {521		pause->autoneg = 1;522		if (!adv_lp.pause)523			return;524	} else {525		phylink_ethtool_get_pauseparam(priv->phylink, pause);526	}527}528 529static int530stmmac_set_pauseparam(struct net_device *netdev,531		      struct ethtool_pauseparam *pause)532{533	struct stmmac_priv *priv = netdev_priv(netdev);534	struct rgmii_adv adv_lp;535 536	if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {537		pause->autoneg = 1;538		if (!adv_lp.pause)539			return -EOPNOTSUPP;540		return 0;541	} else {542		return phylink_ethtool_set_pauseparam(priv->phylink, pause);543	}544}545 546static u64 stmmac_get_rx_normal_irq_n(struct stmmac_priv *priv, int q)547{548	u64 total;549	int cpu;550 551	total = 0;552	for_each_possible_cpu(cpu) {553		struct stmmac_pcpu_stats *pcpu;554		unsigned int start;555		u64 irq_n;556 557		pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);558		do {559			start = u64_stats_fetch_begin(&pcpu->syncp);560			irq_n = u64_stats_read(&pcpu->rx_normal_irq_n[q]);561		} while (u64_stats_fetch_retry(&pcpu->syncp, start));562		total += irq_n;563	}564	return total;565}566 567static u64 stmmac_get_tx_normal_irq_n(struct stmmac_priv *priv, int q)568{569	u64 total;570	int cpu;571 572	total = 0;573	for_each_possible_cpu(cpu) {574		struct stmmac_pcpu_stats *pcpu;575		unsigned int start;576		u64 irq_n;577 578		pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);579		do {580			start = u64_stats_fetch_begin(&pcpu->syncp);581			irq_n = u64_stats_read(&pcpu->tx_normal_irq_n[q]);582		} while (u64_stats_fetch_retry(&pcpu->syncp, start));583		total += irq_n;584	}585	return total;586}587 588static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)589{590	u32 tx_cnt = priv->plat->tx_queues_to_use;591	u32 rx_cnt = priv->plat->rx_queues_to_use;592	unsigned int start;593	int q;594 595	for (q = 0; q < tx_cnt; q++) {596		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];597		u64 pkt_n;598 599		do {600			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);601			pkt_n = u64_stats_read(&txq_stats->napi.tx_pkt_n);602		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));603 604		*data++ = pkt_n;605		*data++ = stmmac_get_tx_normal_irq_n(priv, q);606	}607 608	for (q = 0; q < rx_cnt; q++) {609		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];610		u64 pkt_n;611 612		do {613			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);614			pkt_n = u64_stats_read(&rxq_stats->napi.rx_pkt_n);615		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));616 617		*data++ = pkt_n;618		*data++ = stmmac_get_rx_normal_irq_n(priv, q);619	}620}621 622static void stmmac_get_ethtool_stats(struct net_device *dev,623				 struct ethtool_stats *dummy, u64 *data)624{625	struct stmmac_priv *priv = netdev_priv(dev);626	u32 rx_queues_count = priv->plat->rx_queues_to_use;627	u32 tx_queues_count = priv->plat->tx_queues_to_use;628	u64 napi_poll = 0, normal_irq_n = 0;629	int i, j = 0, pos, ret;630	unsigned long count;631	unsigned int start;632 633	if (priv->dma_cap.asp) {634		for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {635			if (!stmmac_safety_feat_dump(priv, &priv->sstats, i,636						&count, NULL))637				data[j++] = count;638		}639	}640 641	/* Update the DMA HW counters for dwmac10/100 */642	ret = stmmac_dma_diagnostic_fr(priv, &priv->xstats, priv->ioaddr);643	if (ret) {644		/* If supported, for new GMAC chips expose the MMC counters */645		if (priv->dma_cap.rmon) {646			stmmac_mmc_read(priv, priv->mmcaddr, &priv->mmc);647 648			for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {649				char *p;650				p = (char *)priv + stmmac_mmc[i].stat_offset;651 652				data[j++] = (stmmac_mmc[i].sizeof_stat ==653					     sizeof(u64)) ? (*(u64 *)p) :654					     (*(u32 *)p);655			}656		}657		if (priv->eee_enabled) {658			int val = phylink_get_eee_err(priv->phylink);659			if (val)660				priv->xstats.phy_eee_wakeup_error_n = val;661		}662 663		if (priv->synopsys_id >= DWMAC_CORE_3_50)664			stmmac_mac_debug(priv, priv->ioaddr,665					(void *)&priv->xstats,666					rx_queues_count, tx_queues_count);667	}668	for (i = 0; i < STMMAC_STATS_LEN; i++) {669		char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;670		data[j++] = (stmmac_gstrings_stats[i].sizeof_stat ==671			     sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);672	}673 674	pos = j;675	for (i = 0; i < rx_queues_count; i++) {676		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i];677		struct stmmac_napi_rx_stats snapshot;678		u64 n_irq;679 680		j = pos;681		do {682			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);683			snapshot = rxq_stats->napi;684		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));685 686		data[j++] += u64_stats_read(&snapshot.rx_pkt_n);687		n_irq = stmmac_get_rx_normal_irq_n(priv, i);688		data[j++] += n_irq;689		normal_irq_n += n_irq;690		napi_poll += u64_stats_read(&snapshot.poll);691	}692 693	pos = j;694	for (i = 0; i < tx_queues_count; i++) {695		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i];696		struct stmmac_napi_tx_stats napi_snapshot;697		struct stmmac_q_tx_stats q_snapshot;698		u64 n_irq;699 700		j = pos;701		do {702			start = u64_stats_fetch_begin(&txq_stats->q_syncp);703			q_snapshot = txq_stats->q;704		} while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));705		do {706			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);707			napi_snapshot = txq_stats->napi;708		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));709 710		data[j++] += u64_stats_read(&napi_snapshot.tx_pkt_n);711		n_irq = stmmac_get_tx_normal_irq_n(priv, i);712		data[j++] += n_irq;713		normal_irq_n += n_irq;714		data[j++] += u64_stats_read(&napi_snapshot.tx_clean);715		data[j++] += u64_stats_read(&q_snapshot.tx_set_ic_bit) +716			u64_stats_read(&napi_snapshot.tx_set_ic_bit);717		data[j++] += u64_stats_read(&q_snapshot.tx_tso_frames);718		data[j++] += u64_stats_read(&q_snapshot.tx_tso_nfrags);719		napi_poll += u64_stats_read(&napi_snapshot.poll);720	}721	normal_irq_n += priv->xstats.rx_early_irq;722	data[j++] = normal_irq_n;723	data[j++] = napi_poll;724 725	stmmac_get_per_qstats(priv, &data[j]);726}727 728static int stmmac_get_sset_count(struct net_device *netdev, int sset)729{730	struct stmmac_priv *priv = netdev_priv(netdev);731	u32 tx_cnt = priv->plat->tx_queues_to_use;732	u32 rx_cnt = priv->plat->rx_queues_to_use;733	int i, len, safety_len = 0;734 735	switch (sset) {736	case ETH_SS_STATS:737		len = STMMAC_STATS_LEN + STMMAC_QSTATS +738		      STMMAC_TXQ_STATS * tx_cnt +739		      STMMAC_RXQ_STATS * rx_cnt;740 741		if (priv->dma_cap.rmon)742			len += STMMAC_MMC_STATS_LEN;743		if (priv->dma_cap.asp) {744			for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {745				if (!stmmac_safety_feat_dump(priv,746							&priv->sstats, i,747							NULL, NULL))748					safety_len++;749			}750 751			len += safety_len;752		}753 754		return len;755	case ETH_SS_TEST:756		return stmmac_selftest_get_count(priv);757	default:758		return -EOPNOTSUPP;759	}760}761 762static void stmmac_get_qstats_string(struct stmmac_priv *priv, u8 *data)763{764	u32 tx_cnt = priv->plat->tx_queues_to_use;765	u32 rx_cnt = priv->plat->rx_queues_to_use;766	int q, stat;767 768	for (q = 0; q < tx_cnt; q++) {769		for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {770			snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q,771				 stmmac_qstats_tx_string[stat]);772			data += ETH_GSTRING_LEN;773		}774	}775	for (q = 0; q < rx_cnt; q++) {776		for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {777			snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q,778				 stmmac_qstats_rx_string[stat]);779			data += ETH_GSTRING_LEN;780		}781	}782}783 784static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)785{786	int i;787	u8 *p = data;788	struct stmmac_priv *priv = netdev_priv(dev);789 790	switch (stringset) {791	case ETH_SS_STATS:792		if (priv->dma_cap.asp) {793			for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {794				const char *desc;795				if (!stmmac_safety_feat_dump(priv,796							&priv->sstats, i,797							NULL, &desc)) {798					memcpy(p, desc, ETH_GSTRING_LEN);799					p += ETH_GSTRING_LEN;800				}801			}802		}803		if (priv->dma_cap.rmon)804			for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {805				memcpy(p, stmmac_mmc[i].stat_string,806				       ETH_GSTRING_LEN);807				p += ETH_GSTRING_LEN;808			}809		for (i = 0; i < STMMAC_STATS_LEN; i++) {810			memcpy(p, stmmac_gstrings_stats[i].stat_string, ETH_GSTRING_LEN);811			p += ETH_GSTRING_LEN;812		}813		for (i = 0; i < STMMAC_QSTATS; i++) {814			memcpy(p, stmmac_qstats_string[i], ETH_GSTRING_LEN);815			p += ETH_GSTRING_LEN;816		}817		stmmac_get_qstats_string(priv, p);818		break;819	case ETH_SS_TEST:820		stmmac_selftest_get_strings(priv, p);821		break;822	default:823		WARN_ON(1);824		break;825	}826}827 828/* Currently only support WOL through Magic packet. */829static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)830{831	struct stmmac_priv *priv = netdev_priv(dev);832 833	if (!priv->plat->pmt)834		return phylink_ethtool_get_wol(priv->phylink, wol);835 836	mutex_lock(&priv->lock);837	if (device_can_wakeup(priv->device)) {838		wol->supported = WAKE_MAGIC | WAKE_UCAST;839		if (priv->hw_cap_support && !priv->dma_cap.pmt_magic_frame)840			wol->supported &= ~WAKE_MAGIC;841		wol->wolopts = priv->wolopts;842	}843	mutex_unlock(&priv->lock);844}845 846static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)847{848	struct stmmac_priv *priv = netdev_priv(dev);849	u32 support = WAKE_MAGIC | WAKE_UCAST;850 851	if (!device_can_wakeup(priv->device))852		return -EOPNOTSUPP;853 854	if (!priv->plat->pmt) {855		int ret = phylink_ethtool_set_wol(priv->phylink, wol);856 857		if (!ret)858			device_set_wakeup_enable(priv->device, !!wol->wolopts);859		return ret;860	}861 862	/* By default almost all GMAC devices support the WoL via863	 * magic frame but we can disable it if the HW capability864	 * register shows no support for pmt_magic_frame. */865	if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))866		wol->wolopts &= ~WAKE_MAGIC;867 868	if (wol->wolopts & ~support)869		return -EINVAL;870 871	if (wol->wolopts) {872		pr_info("stmmac: wakeup enable\n");873		device_set_wakeup_enable(priv->device, 1);874		/* Avoid unbalanced enable_irq_wake calls */875		if (priv->wol_irq_disabled)876			enable_irq_wake(priv->wol_irq);877		priv->wol_irq_disabled = false;878	} else {879		device_set_wakeup_enable(priv->device, 0);880		/* Avoid unbalanced disable_irq_wake calls */881		if (!priv->wol_irq_disabled)882			disable_irq_wake(priv->wol_irq);883		priv->wol_irq_disabled = true;884	}885 886	mutex_lock(&priv->lock);887	priv->wolopts = wol->wolopts;888	mutex_unlock(&priv->lock);889 890	return 0;891}892 893static int stmmac_ethtool_op_get_eee(struct net_device *dev,894				     struct ethtool_keee *edata)895{896	struct stmmac_priv *priv = netdev_priv(dev);897 898	if (!priv->dma_cap.eee)899		return -EOPNOTSUPP;900 901	edata->tx_lpi_timer = priv->tx_lpi_timer;902	edata->tx_lpi_enabled = priv->tx_lpi_enabled;903 904	return phylink_ethtool_get_eee(priv->phylink, edata);905}906 907static int stmmac_ethtool_op_set_eee(struct net_device *dev,908				     struct ethtool_keee *edata)909{910	struct stmmac_priv *priv = netdev_priv(dev);911	int ret;912 913	if (!priv->dma_cap.eee)914		return -EOPNOTSUPP;915 916	if (priv->tx_lpi_enabled != edata->tx_lpi_enabled)917		netdev_warn(priv->dev,918			    "Setting EEE tx-lpi is not supported\n");919 920	if (!edata->eee_enabled)921		stmmac_disable_eee_mode(priv);922 923	ret = phylink_ethtool_set_eee(priv->phylink, edata);924	if (ret)925		return ret;926 927	if (edata->eee_enabled &&928	    priv->tx_lpi_timer != edata->tx_lpi_timer) {929		priv->tx_lpi_timer = edata->tx_lpi_timer;930		stmmac_eee_init(priv);931	}932 933	return 0;934}935 936static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv)937{938	unsigned long clk = clk_get_rate(priv->plat->stmmac_clk);939 940	if (!clk) {941		clk = priv->plat->clk_ref_rate;942		if (!clk)943			return 0;944	}945 946	return (usec * (clk / 1000000)) / 256;947}948 949static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv)950{951	unsigned long clk = clk_get_rate(priv->plat->stmmac_clk);952 953	if (!clk) {954		clk = priv->plat->clk_ref_rate;955		if (!clk)956			return 0;957	}958 959	return (riwt * 256) / (clk / 1000000);960}961 962static int __stmmac_get_coalesce(struct net_device *dev,963				 struct ethtool_coalesce *ec,964				 int queue)965{966	struct stmmac_priv *priv = netdev_priv(dev);967	u32 max_cnt;968	u32 rx_cnt;969	u32 tx_cnt;970 971	rx_cnt = priv->plat->rx_queues_to_use;972	tx_cnt = priv->plat->tx_queues_to_use;973	max_cnt = max(rx_cnt, tx_cnt);974 975	if (queue < 0)976		queue = 0;977	else if (queue >= max_cnt)978		return -EINVAL;979 980	if (queue < tx_cnt) {981		ec->tx_coalesce_usecs = priv->tx_coal_timer[queue];982		ec->tx_max_coalesced_frames = priv->tx_coal_frames[queue];983	} else {984		ec->tx_coalesce_usecs = 0;985		ec->tx_max_coalesced_frames = 0;986	}987 988	if (priv->use_riwt && queue < rx_cnt) {989		ec->rx_max_coalesced_frames = priv->rx_coal_frames[queue];990		ec->rx_coalesce_usecs = stmmac_riwt2usec(priv->rx_riwt[queue],991							 priv);992	} else {993		ec->rx_max_coalesced_frames = 0;994		ec->rx_coalesce_usecs = 0;995	}996 997	return 0;998}999 1000static int stmmac_get_coalesce(struct net_device *dev,1001			       struct ethtool_coalesce *ec,1002			       struct kernel_ethtool_coalesce *kernel_coal,1003			       struct netlink_ext_ack *extack)1004{1005	return __stmmac_get_coalesce(dev, ec, -1);1006}1007 1008static int stmmac_get_per_queue_coalesce(struct net_device *dev, u32 queue,1009					 struct ethtool_coalesce *ec)1010{1011	return __stmmac_get_coalesce(dev, ec, queue);1012}1013 1014static int __stmmac_set_coalesce(struct net_device *dev,1015				 struct ethtool_coalesce *ec,1016				 int queue)1017{1018	struct stmmac_priv *priv = netdev_priv(dev);1019	bool all_queues = false;1020	unsigned int rx_riwt;1021	u32 max_cnt;1022	u32 rx_cnt;1023	u32 tx_cnt;1024 1025	rx_cnt = priv->plat->rx_queues_to_use;1026	tx_cnt = priv->plat->tx_queues_to_use;1027	max_cnt = max(rx_cnt, tx_cnt);1028 1029	if (queue < 0)1030		all_queues = true;1031	else if (queue >= max_cnt)1032		return -EINVAL;1033 1034	if (priv->use_riwt) {1035		rx_riwt = stmmac_usec2riwt(ec->rx_coalesce_usecs, priv);1036 1037		if ((rx_riwt > MAX_DMA_RIWT) || (rx_riwt < MIN_DMA_RIWT))1038			return -EINVAL;1039 1040		if (all_queues) {1041			int i;1042 1043			for (i = 0; i < rx_cnt; i++) {1044				priv->rx_riwt[i] = rx_riwt;1045				stmmac_rx_watchdog(priv, priv->ioaddr,1046						   rx_riwt, i);1047				priv->rx_coal_frames[i] =1048					ec->rx_max_coalesced_frames;1049			}1050		} else if (queue < rx_cnt) {1051			priv->rx_riwt[queue] = rx_riwt;1052			stmmac_rx_watchdog(priv, priv->ioaddr,1053					   rx_riwt, queue);1054			priv->rx_coal_frames[queue] =1055				ec->rx_max_coalesced_frames;1056		}1057	}1058 1059	if ((ec->tx_coalesce_usecs == 0) &&1060	    (ec->tx_max_coalesced_frames == 0))1061		return -EINVAL;1062 1063	if ((ec->tx_coalesce_usecs > STMMAC_MAX_COAL_TX_TICK) ||1064	    (ec->tx_max_coalesced_frames > STMMAC_TX_MAX_FRAMES))1065		return -EINVAL;1066 1067	if (all_queues) {1068		int i;1069 1070		for (i = 0; i < tx_cnt; i++) {1071			priv->tx_coal_frames[i] =1072				ec->tx_max_coalesced_frames;1073			priv->tx_coal_timer[i] =1074				ec->tx_coalesce_usecs;1075		}1076	} else if (queue < tx_cnt) {1077		priv->tx_coal_frames[queue] =1078			ec->tx_max_coalesced_frames;1079		priv->tx_coal_timer[queue] =1080			ec->tx_coalesce_usecs;1081	}1082 1083	return 0;1084}1085 1086static int stmmac_set_coalesce(struct net_device *dev,1087			       struct ethtool_coalesce *ec,1088			       struct kernel_ethtool_coalesce *kernel_coal,1089			       struct netlink_ext_ack *extack)1090{1091	return __stmmac_set_coalesce(dev, ec, -1);1092}1093 1094static int stmmac_set_per_queue_coalesce(struct net_device *dev, u32 queue,1095					 struct ethtool_coalesce *ec)1096{1097	return __stmmac_set_coalesce(dev, ec, queue);1098}1099 1100static int stmmac_get_rxnfc(struct net_device *dev,1101			    struct ethtool_rxnfc *rxnfc, u32 *rule_locs)1102{1103	struct stmmac_priv *priv = netdev_priv(dev);1104 1105	switch (rxnfc->cmd) {1106	case ETHTOOL_GRXRINGS:1107		rxnfc->data = priv->plat->rx_queues_to_use;1108		break;1109	default:1110		return -EOPNOTSUPP;1111	}1112 1113	return 0;1114}1115 1116static u32 stmmac_get_rxfh_key_size(struct net_device *dev)1117{1118	struct stmmac_priv *priv = netdev_priv(dev);1119 1120	return sizeof(priv->rss.key);1121}1122 1123static u32 stmmac_get_rxfh_indir_size(struct net_device *dev)1124{1125	struct stmmac_priv *priv = netdev_priv(dev);1126 1127	return ARRAY_SIZE(priv->rss.table);1128}1129 1130static int stmmac_get_rxfh(struct net_device *dev,1131			   struct ethtool_rxfh_param *rxfh)1132{1133	struct stmmac_priv *priv = netdev_priv(dev);1134	int i;1135 1136	if (rxfh->indir) {1137		for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)1138			rxfh->indir[i] = priv->rss.table[i];1139	}1140 1141	if (rxfh->key)1142		memcpy(rxfh->key, priv->rss.key, sizeof(priv->rss.key));1143	rxfh->hfunc = ETH_RSS_HASH_TOP;1144 1145	return 0;1146}1147 1148static int stmmac_set_rxfh(struct net_device *dev,1149			   struct ethtool_rxfh_param *rxfh,1150			   struct netlink_ext_ack *extack)1151{1152	struct stmmac_priv *priv = netdev_priv(dev);1153	int i;1154 1155	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&1156	    rxfh->hfunc != ETH_RSS_HASH_TOP)1157		return -EOPNOTSUPP;1158 1159	if (rxfh->indir) {1160		for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)1161			priv->rss.table[i] = rxfh->indir[i];1162	}1163 1164	if (rxfh->key)1165		memcpy(priv->rss.key, rxfh->key, sizeof(priv->rss.key));1166 1167	return stmmac_rss_configure(priv, priv->hw, &priv->rss,1168				    priv->plat->rx_queues_to_use);1169}1170 1171static void stmmac_get_channels(struct net_device *dev,1172				struct ethtool_channels *chan)1173{1174	struct stmmac_priv *priv = netdev_priv(dev);1175 1176	chan->rx_count = priv->plat->rx_queues_to_use;1177	chan->tx_count = priv->plat->tx_queues_to_use;1178	chan->max_rx = priv->dma_cap.number_rx_queues;1179	chan->max_tx = priv->dma_cap.number_tx_queues;1180}1181 1182static int stmmac_set_channels(struct net_device *dev,1183			       struct ethtool_channels *chan)1184{1185	struct stmmac_priv *priv = netdev_priv(dev);1186 1187	if (chan->rx_count > priv->dma_cap.number_rx_queues ||1188	    chan->tx_count > priv->dma_cap.number_tx_queues ||1189	    !chan->rx_count || !chan->tx_count)1190		return -EINVAL;1191 1192	return stmmac_reinit_queues(dev, chan->rx_count, chan->tx_count);1193}1194 1195static int stmmac_get_ts_info(struct net_device *dev,1196			      struct kernel_ethtool_ts_info *info)1197{1198	struct stmmac_priv *priv = netdev_priv(dev);1199 1200	if ((priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) {1201 1202		info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |1203					SOF_TIMESTAMPING_TX_HARDWARE |1204					SOF_TIMESTAMPING_RX_HARDWARE |1205					SOF_TIMESTAMPING_RAW_HARDWARE;1206 1207		if (priv->ptp_clock)1208			info->phc_index = ptp_clock_index(priv->ptp_clock);1209		else1210			info->phc_index = 0;1211 1212		info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);1213 1214		info->rx_filters = ((1 << HWTSTAMP_FILTER_NONE) |1215				    (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |1216				    (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |1217				    (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |1218				    (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |1219				    (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |1220				    (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |1221				    (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |1222				    (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |1223				    (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |1224				    (1 << HWTSTAMP_FILTER_ALL));1225		return 0;1226	} else1227		return ethtool_op_get_ts_info(dev, info);1228}1229 1230static int stmmac_get_tunable(struct net_device *dev,1231			      const struct ethtool_tunable *tuna, void *data)1232{1233	struct stmmac_priv *priv = netdev_priv(dev);1234	int ret = 0;1235 1236	switch (tuna->id) {1237	case ETHTOOL_RX_COPYBREAK:1238		*(u32 *)data = priv->rx_copybreak;1239		break;1240	default:1241		ret = -EINVAL;1242		break;1243	}1244 1245	return ret;1246}1247 1248static int stmmac_set_tunable(struct net_device *dev,1249			      const struct ethtool_tunable *tuna,1250			      const void *data)1251{1252	struct stmmac_priv *priv = netdev_priv(dev);1253	int ret = 0;1254 1255	switch (tuna->id) {1256	case ETHTOOL_RX_COPYBREAK:1257		priv->rx_copybreak = *(u32 *)data;1258		break;1259	default:1260		ret = -EINVAL;1261		break;1262	}1263 1264	return ret;1265}1266 1267static int stmmac_get_mm(struct net_device *ndev,1268			 struct ethtool_mm_state *state)1269{1270	struct stmmac_priv *priv = netdev_priv(ndev);1271	unsigned long flags;1272	u32 frag_size;1273 1274	if (!priv->dma_cap.fpesel)1275		return -EOPNOTSUPP;1276 1277	spin_lock_irqsave(&priv->fpe_cfg.lock, flags);1278 1279	state->max_verify_time = STMMAC_FPE_MM_MAX_VERIFY_TIME_MS;1280	state->verify_enabled = priv->fpe_cfg.verify_enabled;1281	state->pmac_enabled = priv->fpe_cfg.pmac_enabled;1282	state->verify_time = priv->fpe_cfg.verify_time;1283	state->tx_enabled = priv->fpe_cfg.tx_enabled;1284	state->verify_status = priv->fpe_cfg.status;1285	state->rx_min_frag_size = ETH_ZLEN;1286 1287	/* FPE active if common tx_enabled and1288	 * (verification success or disabled(forced))1289	 */1290	if (state->tx_enabled &&1291	    (state->verify_status == ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ||1292	     state->verify_status == ETHTOOL_MM_VERIFY_STATUS_DISABLED))1293		state->tx_active = true;1294	else1295		state->tx_active = false;1296 1297	frag_size = stmmac_fpe_get_add_frag_size(priv, priv->ioaddr);1298	state->tx_min_frag_size = ethtool_mm_frag_size_add_to_min(frag_size);1299 1300	spin_unlock_irqrestore(&priv->fpe_cfg.lock, flags);1301 1302	return 0;1303}1304 1305static int stmmac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,1306			 struct netlink_ext_ack *extack)1307{1308	struct stmmac_priv *priv = netdev_priv(ndev);1309	struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg;1310	unsigned long flags;1311	u32 frag_size;1312	int err;1313 1314	err = ethtool_mm_frag_size_min_to_add(cfg->tx_min_frag_size,1315					      &frag_size, extack);1316	if (err)1317		return err;1318 1319	/* Wait for the verification that's currently in progress to finish */1320	timer_shutdown_sync(&fpe_cfg->verify_timer);1321 1322	spin_lock_irqsave(&fpe_cfg->lock, flags);1323 1324	fpe_cfg->verify_enabled = cfg->verify_enabled;1325	fpe_cfg->pmac_enabled = cfg->pmac_enabled;1326	fpe_cfg->verify_time = cfg->verify_time;1327	fpe_cfg->tx_enabled = cfg->tx_enabled;1328 1329	if (!cfg->verify_enabled)1330		fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_DISABLED;1331 1332	stmmac_fpe_set_add_frag_size(priv, priv->ioaddr, frag_size);1333	stmmac_fpe_apply(priv);1334 1335	spin_unlock_irqrestore(&fpe_cfg->lock, flags);1336 1337	return 0;1338}1339 1340static void stmmac_get_mm_stats(struct net_device *ndev,1341				struct ethtool_mm_stats *s)1342{1343	struct stmmac_priv *priv = netdev_priv(ndev);1344	struct stmmac_counters *mmc = &priv->mmc;1345 1346	if (!priv->dma_cap.rmon)1347		return;1348 1349	stmmac_mmc_read(priv, priv->mmcaddr, mmc);1350 1351	s->MACMergeFrameAssErrorCount = mmc->mmc_rx_packet_assembly_err_cntr;1352	s->MACMergeFrameAssOkCount = mmc->mmc_rx_packet_assembly_ok_cntr;1353	s->MACMergeFrameSmdErrorCount = mmc->mmc_rx_packet_smd_err_cntr;1354	s->MACMergeFragCountRx = mmc->mmc_rx_fpe_fragment_cntr;1355	s->MACMergeFragCountTx = mmc->mmc_tx_fpe_fragment_cntr;1356	s->MACMergeHoldCount = mmc->mmc_tx_hold_req_cntr;1357}1358 1359static const struct ethtool_ops stmmac_ethtool_ops = {1360	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |1361				     ETHTOOL_COALESCE_MAX_FRAMES,1362	.get_drvinfo = stmmac_ethtool_getdrvinfo,1363	.get_msglevel = stmmac_ethtool_getmsglevel,1364	.set_msglevel = stmmac_ethtool_setmsglevel,1365	.get_regs = stmmac_ethtool_gregs,1366	.get_regs_len = stmmac_ethtool_get_regs_len,1367	.get_link = ethtool_op_get_link,1368	.nway_reset = stmmac_nway_reset,1369	.get_ringparam = stmmac_get_ringparam,1370	.set_ringparam = stmmac_set_ringparam,1371	.get_pauseparam = stmmac_get_pauseparam,1372	.set_pauseparam = stmmac_set_pauseparam,1373	.self_test = stmmac_selftest_run,1374	.get_ethtool_stats = stmmac_get_ethtool_stats,1375	.get_strings = stmmac_get_strings,1376	.get_wol = stmmac_get_wol,1377	.set_wol = stmmac_set_wol,1378	.get_eee = stmmac_ethtool_op_get_eee,1379	.set_eee = stmmac_ethtool_op_set_eee,1380	.get_sset_count	= stmmac_get_sset_count,1381	.get_rxnfc = stmmac_get_rxnfc,1382	.get_rxfh_key_size = stmmac_get_rxfh_key_size,1383	.get_rxfh_indir_size = stmmac_get_rxfh_indir_size,1384	.get_rxfh = stmmac_get_rxfh,1385	.set_rxfh = stmmac_set_rxfh,1386	.get_ts_info = stmmac_get_ts_info,1387	.get_coalesce = stmmac_get_coalesce,1388	.set_coalesce = stmmac_set_coalesce,1389	.get_per_queue_coalesce = stmmac_get_per_queue_coalesce,1390	.set_per_queue_coalesce = stmmac_set_per_queue_coalesce,1391	.get_channels = stmmac_get_channels,1392	.set_channels = stmmac_set_channels,1393	.get_tunable = stmmac_get_tunable,1394	.set_tunable = stmmac_set_tunable,1395	.get_link_ksettings = stmmac_ethtool_get_link_ksettings,1396	.set_link_ksettings = stmmac_ethtool_set_link_ksettings,1397	.get_mm = stmmac_get_mm,1398	.set_mm = stmmac_set_mm,1399	.get_mm_stats = stmmac_get_mm_stats,1400};1401 1402void stmmac_set_ethtool_ops(struct net_device *netdev)1403{1404	netdev->ethtool_ops = &stmmac_ethtool_ops;1405}1406