17268f33eSAlexander Lobakin // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2133fac0eSSudarsana Kalluru /* QLogic qede NIC Driver
3e8f1cb50SMintz, Yuval  * Copyright (c) 2015-2017  QLogic Corporation
4c4fad2a5SAlexander Lobakin  * Copyright (c) 2019-2020 Marvell International Ltd.
5133fac0eSSudarsana Kalluru  */
67268f33eSAlexander Lobakin 
7133fac0eSSudarsana Kalluru #include <linux/version.h>
8133fac0eSSudarsana Kalluru #include <linux/types.h>
9133fac0eSSudarsana Kalluru #include <linux/netdevice.h>
1016f46bf0SSudarsana Reddy Kalluru #include <linux/etherdevice.h>
11133fac0eSSudarsana Kalluru #include <linux/ethtool.h>
12133fac0eSSudarsana Kalluru #include <linux/string.h>
13133fac0eSSudarsana Kalluru #include <linux/pci.h>
14133fac0eSSudarsana Kalluru #include <linux/capability.h>
15f29ffdb6SMintz, Yuval #include <linux/vmalloc.h>
16bdb5d8ecSAlexander Lobakin #include <linux/phylink.h>
17bdb5d8ecSAlexander Lobakin 
18133fac0eSSudarsana Kalluru #include "qede.h"
194c55215cSSudarsana Reddy Kalluru #include "qede_ptp.h"
20133fac0eSSudarsana Kalluru 
21133fac0eSSudarsana Kalluru #define QEDE_RQSTAT_OFFSET(stat_name) \
22133fac0eSSudarsana Kalluru 	 (offsetof(struct qede_rx_queue, stat_name))
23133fac0eSSudarsana Kalluru #define QEDE_RQSTAT_STRING(stat_name) (#stat_name)
24133fac0eSSudarsana Kalluru #define QEDE_RQSTAT(stat_name) \
25133fac0eSSudarsana Kalluru 	 {QEDE_RQSTAT_OFFSET(stat_name), QEDE_RQSTAT_STRING(stat_name)}
2616f46bf0SSudarsana Reddy Kalluru 
2716f46bf0SSudarsana Reddy Kalluru #define QEDE_SELFTEST_POLL_COUNT 100
28d44a3cedSSudarsana Reddy Kalluru #define QEDE_DUMP_VERSION	0x1
29d44a3cedSSudarsana Reddy Kalluru #define QEDE_DUMP_NVM_ARG_COUNT	2
3016f46bf0SSudarsana Reddy Kalluru 
31133fac0eSSudarsana Kalluru static const struct {
32133fac0eSSudarsana Kalluru 	u64 offset;
33133fac0eSSudarsana Kalluru 	char string[ETH_GSTRING_LEN];
34133fac0eSSudarsana Kalluru } qede_rqstats_arr[] = {
3568db9ec2SSudarsana Reddy Kalluru 	QEDE_RQSTAT(rcv_pkts),
36133fac0eSSudarsana Kalluru 	QEDE_RQSTAT(rx_hw_errors),
37133fac0eSSudarsana Kalluru 	QEDE_RQSTAT(rx_alloc_errors),
38c72a6125SManish Chopra 	QEDE_RQSTAT(rx_ip_frags),
39496e0517SMintz, Yuval 	QEDE_RQSTAT(xdp_no_pass),
40133fac0eSSudarsana Kalluru };
41133fac0eSSudarsana Kalluru 
42133fac0eSSudarsana Kalluru #define QEDE_NUM_RQSTATS ARRAY_SIZE(qede_rqstats_arr)
4368db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT_OFFSET(stat_name) \
4468db9ec2SSudarsana Reddy Kalluru 	(offsetof(struct qede_tx_queue, stat_name))
4568db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT_STRING(stat_name) (#stat_name)
4668db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT(stat_name) \
4768db9ec2SSudarsana Reddy Kalluru 	{QEDE_TQSTAT_OFFSET(stat_name), QEDE_TQSTAT_STRING(stat_name)}
4868db9ec2SSudarsana Reddy Kalluru #define QEDE_NUM_TQSTATS ARRAY_SIZE(qede_tqstats_arr)
4968db9ec2SSudarsana Reddy Kalluru static const struct {
5068db9ec2SSudarsana Reddy Kalluru 	u64 offset;
5168db9ec2SSudarsana Reddy Kalluru 	char string[ETH_GSTRING_LEN];
5268db9ec2SSudarsana Reddy Kalluru } qede_tqstats_arr[] = {
5368db9ec2SSudarsana Reddy Kalluru 	QEDE_TQSTAT(xmit_pkts),
5468db9ec2SSudarsana Reddy Kalluru 	QEDE_TQSTAT(stopped_cnt),
55dcc6abaeSMichael Shteinbok 	QEDE_TQSTAT(tx_mem_alloc_err),
5668db9ec2SSudarsana Reddy Kalluru };
5768db9ec2SSudarsana Reddy Kalluru 
589c79ddaaSMintz, Yuval #define QEDE_STAT_OFFSET(stat_name, type, base) \
599c79ddaaSMintz, Yuval 	(offsetof(type, stat_name) + (base))
604dbcd640SMintz, Yuval #define QEDE_STAT_STRING(stat_name)	(#stat_name)
619c79ddaaSMintz, Yuval #define _QEDE_STAT(stat_name, type, base, attr) \
629c79ddaaSMintz, Yuval 	{QEDE_STAT_OFFSET(stat_name, type, base), \
639c79ddaaSMintz, Yuval 	 QEDE_STAT_STRING(stat_name), \
649c79ddaaSMintz, Yuval 	 attr}
659c79ddaaSMintz, Yuval #define QEDE_STAT(stat_name) \
669c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_common, 0, 0x0)
679c79ddaaSMintz, Yuval #define QEDE_PF_STAT(stat_name) \
689c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_common, 0, \
699c79ddaaSMintz, Yuval 		   BIT(QEDE_STAT_PF_ONLY))
709c79ddaaSMintz, Yuval #define QEDE_PF_BB_STAT(stat_name) \
719c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_bb, \
729c79ddaaSMintz, Yuval 		   offsetof(struct qede_stats, bb), \
739c79ddaaSMintz, Yuval 		   BIT(QEDE_STAT_PF_ONLY) | BIT(QEDE_STAT_BB_ONLY))
749c79ddaaSMintz, Yuval #define QEDE_PF_AH_STAT(stat_name) \
759c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_ah, \
769c79ddaaSMintz, Yuval 		   offsetof(struct qede_stats, ah), \
779c79ddaaSMintz, Yuval 		   BIT(QEDE_STAT_PF_ONLY) | BIT(QEDE_STAT_AH_ONLY))
78133fac0eSSudarsana Kalluru static const struct {
79133fac0eSSudarsana Kalluru 	u64 offset;
80133fac0eSSudarsana Kalluru 	char string[ETH_GSTRING_LEN];
819c79ddaaSMintz, Yuval 	unsigned long attr;
829c79ddaaSMintz, Yuval #define QEDE_STAT_PF_ONLY	0
839c79ddaaSMintz, Yuval #define QEDE_STAT_BB_ONLY	1
849c79ddaaSMintz, Yuval #define QEDE_STAT_AH_ONLY	2
85133fac0eSSudarsana Kalluru } qede_stats_arr[] = {
86133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_ucast_bytes),
87133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_mcast_bytes),
88133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_bcast_bytes),
89133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_ucast_pkts),
90133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_mcast_pkts),
91133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_bcast_pkts),
92133fac0eSSudarsana Kalluru 
93133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_ucast_bytes),
94133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_mcast_bytes),
95133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_bcast_bytes),
96133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_ucast_pkts),
97133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_mcast_pkts),
98133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_bcast_pkts),
99133fac0eSSudarsana Kalluru 
100133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_64_byte_packets),
101d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_65_to_127_byte_packets),
102d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_128_to_255_byte_packets),
103d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_256_to_511_byte_packets),
104d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_512_to_1023_byte_packets),
105d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_1024_to_1518_byte_packets),
1069c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_1519_to_1522_byte_packets),
1079c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_1519_to_2047_byte_packets),
1089c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_2048_to_4095_byte_packets),
1099c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_4096_to_9216_byte_packets),
1109c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_9217_to_16383_byte_packets),
1119c79ddaaSMintz, Yuval 	QEDE_PF_AH_STAT(rx_1519_to_max_byte_packets),
112133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_64_byte_packets),
113133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_65_to_127_byte_packets),
114133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_128_to_255_byte_packets),
115133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_256_to_511_byte_packets),
116133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_512_to_1023_byte_packets),
117133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_1024_to_1518_byte_packets),
1189c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_1519_to_2047_byte_packets),
1199c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_2048_to_4095_byte_packets),
1209c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_4096_to_9216_byte_packets),
1219c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_9217_to_16383_byte_packets),
1229c79ddaaSMintz, Yuval 	QEDE_PF_AH_STAT(tx_1519_to_max_byte_packets),
123133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_mac_crtl_frames),
124133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_mac_ctrl_frames),
125133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_pause_frames),
126133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_pause_frames),
127133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_pfc_frames),
128133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_pfc_frames),
129133fac0eSSudarsana Kalluru 
130133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_crc_errors),
131133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_align_errors),
132133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_carrier_errors),
133133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_oversize_packets),
134133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_jabbers),
135133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_undersize_packets),
136133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_fragments),
1379c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_lpi_entry_count),
1389c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_total_collisions),
139133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(brb_truncates),
140133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(brb_discards),
141133fac0eSSudarsana Kalluru 	QEDE_STAT(no_buff_discards),
142133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(mftag_filter_discards),
143133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(mac_filter_discards),
144608e00d0SManish Chopra 	QEDE_PF_STAT(gft_filter_drop),
145133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_err_drop_pkts),
1461a5a366fSSudarsana Reddy Kalluru 	QEDE_STAT(ttl0_discard),
1471a5a366fSSudarsana Reddy Kalluru 	QEDE_STAT(packet_too_big_discard),
148133fac0eSSudarsana Kalluru 
149133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_pkts),
150133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_events),
151133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_aborts_num),
152133fac0eSSudarsana Kalluru 	QEDE_STAT(non_coalesced_pkts),
153133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_bytes),
15432d26a68SSudarsana Reddy Kalluru 
15532d26a68SSudarsana Reddy Kalluru 	QEDE_STAT(link_change_count),
1569adebac3SSudarsana Reddy Kalluru 	QEDE_STAT(ptp_skip_txts),
157133fac0eSSudarsana Kalluru };
158133fac0eSSudarsana Kalluru 
159133fac0eSSudarsana Kalluru #define QEDE_NUM_STATS	ARRAY_SIZE(qede_stats_arr)
1609c79ddaaSMintz, Yuval #define QEDE_STAT_IS_PF_ONLY(i) \
1619c79ddaaSMintz, Yuval 	test_bit(QEDE_STAT_PF_ONLY, &qede_stats_arr[i].attr)
1629c79ddaaSMintz, Yuval #define QEDE_STAT_IS_BB_ONLY(i) \
1639c79ddaaSMintz, Yuval 	test_bit(QEDE_STAT_BB_ONLY, &qede_stats_arr[i].attr)
1649c79ddaaSMintz, Yuval #define QEDE_STAT_IS_AH_ONLY(i) \
1659c79ddaaSMintz, Yuval 	test_bit(QEDE_STAT_AH_ONLY, &qede_stats_arr[i].attr)
166133fac0eSSudarsana Kalluru 
167f3e72109SYuval Mintz enum {
168f3e72109SYuval Mintz 	QEDE_PRI_FLAG_CMT,
169f15cff04SSudarsana Reddy Kalluru 	QEDE_PRI_FLAG_SMART_AN_SUPPORT, /* MFW supports SmartAN */
1707d9acd87SIgor Russkikh 	QEDE_PRI_FLAG_RECOVER_ON_ERROR,
171f3e72109SYuval Mintz 	QEDE_PRI_FLAG_LEN,
172f3e72109SYuval Mintz };
173f3e72109SYuval Mintz 
174f3e72109SYuval Mintz static const char qede_private_arr[QEDE_PRI_FLAG_LEN][ETH_GSTRING_LEN] = {
175f3e72109SYuval Mintz 	"Coupled-Function",
176f15cff04SSudarsana Reddy Kalluru 	"SmartAN capable",
1777d9acd87SIgor Russkikh 	"Recover on error",
178f3e72109SYuval Mintz };
179f3e72109SYuval Mintz 
1803044a02eSSudarsana Reddy Kalluru enum qede_ethtool_tests {
18116f46bf0SSudarsana Reddy Kalluru 	QEDE_ETHTOOL_INT_LOOPBACK,
1823044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_INTERRUPT_TEST,
1833044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_MEMORY_TEST,
1843044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_REGISTER_TEST,
1853044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_CLOCK_TEST,
1867a4b21b7SMintz, Yuval 	QEDE_ETHTOOL_NVRAM_TEST,
1873044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_TEST_MAX
1883044a02eSSudarsana Reddy Kalluru };
1893044a02eSSudarsana Reddy Kalluru 
1903044a02eSSudarsana Reddy Kalluru static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = {
19116f46bf0SSudarsana Reddy Kalluru 	"Internal loopback (offline)",
1923044a02eSSudarsana Reddy Kalluru 	"Interrupt (online)\t",
1933044a02eSSudarsana Reddy Kalluru 	"Memory (online)\t\t",
1943044a02eSSudarsana Reddy Kalluru 	"Register (online)\t",
1953044a02eSSudarsana Reddy Kalluru 	"Clock (online)\t\t",
1967a4b21b7SMintz, Yuval 	"Nvram (online)\t\t",
1973044a02eSSudarsana Reddy Kalluru };
1983044a02eSSudarsana Reddy Kalluru 
1991d4e4eccSAlexander Lobakin /* Forced speed capabilities maps */
2001d4e4eccSAlexander Lobakin 
2011d4e4eccSAlexander Lobakin struct qede_forced_speed_map {
2021d4e4eccSAlexander Lobakin 	u32		speed;
2031d4e4eccSAlexander Lobakin 	__ETHTOOL_DECLARE_LINK_MODE_MASK(caps);
2041d4e4eccSAlexander Lobakin 
2051d4e4eccSAlexander Lobakin 	const u32	*cap_arr;
2061d4e4eccSAlexander Lobakin 	u32		arr_size;
2071d4e4eccSAlexander Lobakin };
2081d4e4eccSAlexander Lobakin 
2091d4e4eccSAlexander Lobakin #define QEDE_FORCED_SPEED_MAP(value)					\
2101d4e4eccSAlexander Lobakin {									\
2111d4e4eccSAlexander Lobakin 	.speed		= SPEED_##value,				\
2121d4e4eccSAlexander Lobakin 	.cap_arr	= qede_forced_speed_##value,			\
2131d4e4eccSAlexander Lobakin 	.arr_size	= ARRAY_SIZE(qede_forced_speed_##value),	\
2141d4e4eccSAlexander Lobakin }
2151d4e4eccSAlexander Lobakin 
2161d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_1000[] __initconst = {
2171d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
2181d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2191d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
2201d4e4eccSAlexander Lobakin };
2211d4e4eccSAlexander Lobakin 
2221d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_10000[] __initconst = {
2231d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
2241d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
2251d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
2261d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
2271d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
2281d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
2291d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
2301d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
2311d4e4eccSAlexander Lobakin };
2321d4e4eccSAlexander Lobakin 
2331d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_20000[] __initconst = {
2341d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
2351d4e4eccSAlexander Lobakin };
2361d4e4eccSAlexander Lobakin 
2371d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_25000[] __initconst = {
2381d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
2391d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
2401d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
2411d4e4eccSAlexander Lobakin };
2421d4e4eccSAlexander Lobakin 
2431d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_40000[] __initconst = {
2441d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
2451d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
2461d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
2471d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
2481d4e4eccSAlexander Lobakin };
2491d4e4eccSAlexander Lobakin 
2501d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_50000[] __initconst = {
2511d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
2521d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
2531d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
2541d4e4eccSAlexander Lobakin };
2551d4e4eccSAlexander Lobakin 
2561d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_100000[] __initconst = {
2571d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
2581d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
2591d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
2601d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
2611d4e4eccSAlexander Lobakin };
2621d4e4eccSAlexander Lobakin 
2631d4e4eccSAlexander Lobakin static struct qede_forced_speed_map qede_forced_speed_maps[] __ro_after_init = {
2641d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(1000),
2651d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(10000),
2661d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(20000),
2671d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(25000),
2681d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(40000),
2691d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(50000),
2701d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(100000),
2711d4e4eccSAlexander Lobakin };
2721d4e4eccSAlexander Lobakin 
2731d4e4eccSAlexander Lobakin void __init qede_forced_speed_maps_init(void)
2741d4e4eccSAlexander Lobakin {
2751d4e4eccSAlexander Lobakin 	struct qede_forced_speed_map *map;
2761d4e4eccSAlexander Lobakin 	u32 i;
2771d4e4eccSAlexander Lobakin 
2781d4e4eccSAlexander Lobakin 	for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
2791d4e4eccSAlexander Lobakin 		map = qede_forced_speed_maps + i;
2801d4e4eccSAlexander Lobakin 
2811d4e4eccSAlexander Lobakin 		linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps);
2821d4e4eccSAlexander Lobakin 		map->cap_arr = NULL;
2831d4e4eccSAlexander Lobakin 		map->arr_size = 0;
2841d4e4eccSAlexander Lobakin 	}
2851d4e4eccSAlexander Lobakin }
2861d4e4eccSAlexander Lobakin 
2871d4e4eccSAlexander Lobakin /* Ethtool callbacks */
2881d4e4eccSAlexander Lobakin 
2894dbcd640SMintz, Yuval static void qede_get_strings_stats_txq(struct qede_dev *edev,
2904dbcd640SMintz, Yuval 				       struct qede_tx_queue *txq, u8 **buf)
2914dbcd640SMintz, Yuval {
2924dbcd640SMintz, Yuval 	int i;
2934dbcd640SMintz, Yuval 
2944dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_TQSTATS; i++) {
295cb6aeb07SMintz, Yuval 		if (txq->is_xdp)
296cb6aeb07SMintz, Yuval 			sprintf(*buf, "%d [XDP]: %s",
297cb6aeb07SMintz, Yuval 				QEDE_TXQ_XDP_TO_IDX(edev, txq),
298cb6aeb07SMintz, Yuval 				qede_tqstats_arr[i].string);
299cb6aeb07SMintz, Yuval 		else
3005e7baf0fSManish Chopra 			sprintf(*buf, "%d_%d: %s", txq->index, txq->cos,
3014dbcd640SMintz, Yuval 				qede_tqstats_arr[i].string);
3024dbcd640SMintz, Yuval 		*buf += ETH_GSTRING_LEN;
3034dbcd640SMintz, Yuval 	}
3044dbcd640SMintz, Yuval }
3054dbcd640SMintz, Yuval 
3064dbcd640SMintz, Yuval static void qede_get_strings_stats_rxq(struct qede_dev *edev,
3074dbcd640SMintz, Yuval 				       struct qede_rx_queue *rxq, u8 **buf)
3084dbcd640SMintz, Yuval {
3094dbcd640SMintz, Yuval 	int i;
3104dbcd640SMintz, Yuval 
3114dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_RQSTATS; i++) {
3124dbcd640SMintz, Yuval 		sprintf(*buf, "%d: %s", rxq->rxq_id,
3134dbcd640SMintz, Yuval 			qede_rqstats_arr[i].string);
3144dbcd640SMintz, Yuval 		*buf += ETH_GSTRING_LEN;
3154dbcd640SMintz, Yuval 	}
3164dbcd640SMintz, Yuval }
3174dbcd640SMintz, Yuval 
3189c79ddaaSMintz, Yuval static bool qede_is_irrelevant_stat(struct qede_dev *edev, int stat_index)
3199c79ddaaSMintz, Yuval {
3209c79ddaaSMintz, Yuval 	return (IS_VF(edev) && QEDE_STAT_IS_PF_ONLY(stat_index)) ||
3219c79ddaaSMintz, Yuval 	       (QEDE_IS_BB(edev) && QEDE_STAT_IS_AH_ONLY(stat_index)) ||
3229c79ddaaSMintz, Yuval 	       (QEDE_IS_AH(edev) && QEDE_STAT_IS_BB_ONLY(stat_index));
3239c79ddaaSMintz, Yuval }
3249c79ddaaSMintz, Yuval 
325133fac0eSSudarsana Kalluru static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf)
326133fac0eSSudarsana Kalluru {
3274dbcd640SMintz, Yuval 	struct qede_fastpath *fp;
3284dbcd640SMintz, Yuval 	int i;
329133fac0eSSudarsana Kalluru 
3304dbcd640SMintz, Yuval 	/* Account for queue statistics */
3314dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_QUEUE_CNT(edev); i++) {
3324dbcd640SMintz, Yuval 		fp = &edev->fp_array[i];
33368db9ec2SSudarsana Reddy Kalluru 
3344dbcd640SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_RX)
3354dbcd640SMintz, Yuval 			qede_get_strings_stats_rxq(edev, fp->rxq, &buf);
3364dbcd640SMintz, Yuval 
337cb6aeb07SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_XDP)
338cb6aeb07SMintz, Yuval 			qede_get_strings_stats_txq(edev, fp->xdp_tx, &buf);
339cb6aeb07SMintz, Yuval 
3405e7baf0fSManish Chopra 		if (fp->type & QEDE_FASTPATH_TX) {
3415e7baf0fSManish Chopra 			int cos;
3425e7baf0fSManish Chopra 
3435e7baf0fSManish Chopra 			for_each_cos_in_txq(edev, cos)
3445e7baf0fSManish Chopra 				qede_get_strings_stats_txq(edev,
3455e7baf0fSManish Chopra 							   &fp->txq[cos], &buf);
3465e7baf0fSManish Chopra 		}
347cbbf049aSMintz, Yuval 	}
348cbbf049aSMintz, Yuval 
3494dbcd640SMintz, Yuval 	/* Account for non-queue statistics */
3504dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_STATS; i++) {
3519c79ddaaSMintz, Yuval 		if (qede_is_irrelevant_stat(edev, i))
352fefb0202SYuval Mintz 			continue;
3534dbcd640SMintz, Yuval 		strcpy(buf, qede_stats_arr[i].string);
3544dbcd640SMintz, Yuval 		buf += ETH_GSTRING_LEN;
355133fac0eSSudarsana Kalluru 	}
356133fac0eSSudarsana Kalluru }
357133fac0eSSudarsana Kalluru 
358133fac0eSSudarsana Kalluru static void qede_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
359133fac0eSSudarsana Kalluru {
360133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
361133fac0eSSudarsana Kalluru 
362133fac0eSSudarsana Kalluru 	switch (stringset) {
363133fac0eSSudarsana Kalluru 	case ETH_SS_STATS:
364133fac0eSSudarsana Kalluru 		qede_get_strings_stats(edev, buf);
365133fac0eSSudarsana Kalluru 		break;
366f3e72109SYuval Mintz 	case ETH_SS_PRIV_FLAGS:
367f3e72109SYuval Mintz 		memcpy(buf, qede_private_arr,
368f3e72109SYuval Mintz 		       ETH_GSTRING_LEN * QEDE_PRI_FLAG_LEN);
369f3e72109SYuval Mintz 		break;
3703044a02eSSudarsana Reddy Kalluru 	case ETH_SS_TEST:
3713044a02eSSudarsana Reddy Kalluru 		memcpy(buf, qede_tests_str_arr,
3723044a02eSSudarsana Reddy Kalluru 		       ETH_GSTRING_LEN * QEDE_ETHTOOL_TEST_MAX);
3733044a02eSSudarsana Reddy Kalluru 		break;
374133fac0eSSudarsana Kalluru 	default:
375133fac0eSSudarsana Kalluru 		DP_VERBOSE(edev, QED_MSG_DEBUG,
376133fac0eSSudarsana Kalluru 			   "Unsupported stringset 0x%08x\n", stringset);
377133fac0eSSudarsana Kalluru 	}
378133fac0eSSudarsana Kalluru }
379133fac0eSSudarsana Kalluru 
3804dbcd640SMintz, Yuval static void qede_get_ethtool_stats_txq(struct qede_tx_queue *txq, u64 **buf)
3814dbcd640SMintz, Yuval {
3824dbcd640SMintz, Yuval 	int i;
3834dbcd640SMintz, Yuval 
3844dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_TQSTATS; i++) {
3854dbcd640SMintz, Yuval 		**buf = *((u64 *)(((void *)txq) + qede_tqstats_arr[i].offset));
3864dbcd640SMintz, Yuval 		(*buf)++;
3874dbcd640SMintz, Yuval 	}
3884dbcd640SMintz, Yuval }
3894dbcd640SMintz, Yuval 
3904dbcd640SMintz, Yuval static void qede_get_ethtool_stats_rxq(struct qede_rx_queue *rxq, u64 **buf)
3914dbcd640SMintz, Yuval {
3924dbcd640SMintz, Yuval 	int i;
3934dbcd640SMintz, Yuval 
3944dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_RQSTATS; i++) {
3954dbcd640SMintz, Yuval 		**buf = *((u64 *)(((void *)rxq) + qede_rqstats_arr[i].offset));
3964dbcd640SMintz, Yuval 		(*buf)++;
3974dbcd640SMintz, Yuval 	}
3984dbcd640SMintz, Yuval }
3994dbcd640SMintz, Yuval 
400133fac0eSSudarsana Kalluru static void qede_get_ethtool_stats(struct net_device *dev,
401133fac0eSSudarsana Kalluru 				   struct ethtool_stats *stats, u64 *buf)
402133fac0eSSudarsana Kalluru {
403133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
4044dbcd640SMintz, Yuval 	struct qede_fastpath *fp;
4054dbcd640SMintz, Yuval 	int i;
406133fac0eSSudarsana Kalluru 
407133fac0eSSudarsana Kalluru 	qede_fill_by_demand_stats(edev);
408133fac0eSSudarsana Kalluru 
409567b3c12SMintz, Yuval 	/* Need to protect the access to the fastpath array */
410567b3c12SMintz, Yuval 	__qede_lock(edev);
411567b3c12SMintz, Yuval 
4124dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_QUEUE_CNT(edev); i++) {
4134dbcd640SMintz, Yuval 		fp = &edev->fp_array[i];
414133fac0eSSudarsana Kalluru 
4154dbcd640SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_RX)
4164dbcd640SMintz, Yuval 			qede_get_ethtool_stats_rxq(fp->rxq, &buf);
41768db9ec2SSudarsana Reddy Kalluru 
418cb6aeb07SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_XDP)
419cb6aeb07SMintz, Yuval 			qede_get_ethtool_stats_txq(fp->xdp_tx, &buf);
420cb6aeb07SMintz, Yuval 
4215e7baf0fSManish Chopra 		if (fp->type & QEDE_FASTPATH_TX) {
4225e7baf0fSManish Chopra 			int cos;
4235e7baf0fSManish Chopra 
4245e7baf0fSManish Chopra 			for_each_cos_in_txq(edev, cos)
4255e7baf0fSManish Chopra 				qede_get_ethtool_stats_txq(&fp->txq[cos], &buf);
4265e7baf0fSManish Chopra 		}
42768db9ec2SSudarsana Reddy Kalluru 	}
42868db9ec2SSudarsana Reddy Kalluru 
4294dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_STATS; i++) {
4309c79ddaaSMintz, Yuval 		if (qede_is_irrelevant_stat(edev, i))
431fefb0202SYuval Mintz 			continue;
4324dbcd640SMintz, Yuval 		*buf = *((u64 *)(((void *)&edev->stats) +
4334dbcd640SMintz, Yuval 				 qede_stats_arr[i].offset));
4344dbcd640SMintz, Yuval 
4354dbcd640SMintz, Yuval 		buf++;
436fefb0202SYuval Mintz 	}
437133fac0eSSudarsana Kalluru 
438567b3c12SMintz, Yuval 	__qede_unlock(edev);
439133fac0eSSudarsana Kalluru }
440133fac0eSSudarsana Kalluru 
441133fac0eSSudarsana Kalluru static int qede_get_sset_count(struct net_device *dev, int stringset)
442133fac0eSSudarsana Kalluru {
443133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
4449c79ddaaSMintz, Yuval 	int num_stats = QEDE_NUM_STATS, i;
445133fac0eSSudarsana Kalluru 
446133fac0eSSudarsana Kalluru 	switch (stringset) {
447133fac0eSSudarsana Kalluru 	case ETH_SS_STATS:
448fefb0202SYuval Mintz 		for (i = 0; i < QEDE_NUM_STATS; i++)
4499c79ddaaSMintz, Yuval 			if (qede_is_irrelevant_stat(edev, i))
450fefb0202SYuval Mintz 				num_stats--;
4514dbcd640SMintz, Yuval 
4524dbcd640SMintz, Yuval 		/* Account for the Regular Tx statistics */
4535e7baf0fSManish Chopra 		num_stats += QEDE_TSS_COUNT(edev) * QEDE_NUM_TQSTATS *
4545e7baf0fSManish Chopra 				edev->dev_info.num_tc;
4554dbcd640SMintz, Yuval 
4564dbcd640SMintz, Yuval 		/* Account for the Regular Rx statistics */
4574dbcd640SMintz, Yuval 		num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_RQSTATS;
4584dbcd640SMintz, Yuval 
459cb6aeb07SMintz, Yuval 		/* Account for XDP statistics [if needed] */
460cb6aeb07SMintz, Yuval 		if (edev->xdp_prog)
461cb6aeb07SMintz, Yuval 			num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_TQSTATS;
4624dbcd640SMintz, Yuval 		return num_stats;
4634dbcd640SMintz, Yuval 
464f3e72109SYuval Mintz 	case ETH_SS_PRIV_FLAGS:
465f3e72109SYuval Mintz 		return QEDE_PRI_FLAG_LEN;
4663044a02eSSudarsana Reddy Kalluru 	case ETH_SS_TEST:
4676ecb0a0cSYuval Mintz 		if (!IS_VF(edev))
4683044a02eSSudarsana Reddy Kalluru 			return QEDE_ETHTOOL_TEST_MAX;
4696ecb0a0cSYuval Mintz 		else
4706ecb0a0cSYuval Mintz 			return 0;
471133fac0eSSudarsana Kalluru 	default:
472133fac0eSSudarsana Kalluru 		DP_VERBOSE(edev, QED_MSG_DEBUG,
473133fac0eSSudarsana Kalluru 			   "Unsupported stringset 0x%08x\n", stringset);
474133fac0eSSudarsana Kalluru 		return -EINVAL;
475133fac0eSSudarsana Kalluru 	}
476133fac0eSSudarsana Kalluru }
477133fac0eSSudarsana Kalluru 
478f3e72109SYuval Mintz static u32 qede_get_priv_flags(struct net_device *dev)
479f3e72109SYuval Mintz {
480f3e72109SYuval Mintz 	struct qede_dev *edev = netdev_priv(dev);
481f15cff04SSudarsana Reddy Kalluru 	u32 flags = 0;
482f3e72109SYuval Mintz 
483f15cff04SSudarsana Reddy Kalluru 	if (edev->dev_info.common.num_hwfns > 1)
484f15cff04SSudarsana Reddy Kalluru 		flags |= BIT(QEDE_PRI_FLAG_CMT);
485f15cff04SSudarsana Reddy Kalluru 
486f15cff04SSudarsana Reddy Kalluru 	if (edev->dev_info.common.smart_an)
487f15cff04SSudarsana Reddy Kalluru 		flags |= BIT(QEDE_PRI_FLAG_SMART_AN_SUPPORT);
488f15cff04SSudarsana Reddy Kalluru 
4897d9acd87SIgor Russkikh 	if (edev->err_flags & BIT(QEDE_ERR_IS_RECOVERABLE))
4907d9acd87SIgor Russkikh 		flags |= BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR);
4917d9acd87SIgor Russkikh 
492f15cff04SSudarsana Reddy Kalluru 	return flags;
493f3e72109SYuval Mintz }
494f3e72109SYuval Mintz 
4957d9acd87SIgor Russkikh static int qede_set_priv_flags(struct net_device *dev, u32 flags)
4967d9acd87SIgor Russkikh {
4977d9acd87SIgor Russkikh 	struct qede_dev *edev = netdev_priv(dev);
4987d9acd87SIgor Russkikh 	u32 cflags = qede_get_priv_flags(dev);
4997d9acd87SIgor Russkikh 	u32 dflags = flags ^ cflags;
5007d9acd87SIgor Russkikh 
5017d9acd87SIgor Russkikh 	/* can only change RECOVER_ON_ERROR flag */
5027d9acd87SIgor Russkikh 	if (dflags & ~BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR))
5037d9acd87SIgor Russkikh 		return -EINVAL;
5047d9acd87SIgor Russkikh 
5057d9acd87SIgor Russkikh 	if (flags & BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR))
5067d9acd87SIgor Russkikh 		set_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags);
5077d9acd87SIgor Russkikh 	else
5087d9acd87SIgor Russkikh 		clear_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags);
5097d9acd87SIgor Russkikh 
5107d9acd87SIgor Russkikh 	return 0;
5117d9acd87SIgor Russkikh }
5127d9acd87SIgor Russkikh 
513054c67d1SSudarsana Reddy Kalluru static int qede_get_link_ksettings(struct net_device *dev,
514054c67d1SSudarsana Reddy Kalluru 				   struct ethtool_link_ksettings *cmd)
515133fac0eSSudarsana Kalluru {
516bdb5d8ecSAlexander Lobakin 	typeof(cmd->link_modes) *link_modes = &cmd->link_modes;
517054c67d1SSudarsana Reddy Kalluru 	struct ethtool_link_settings *base = &cmd->base;
518133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
519133fac0eSSudarsana Kalluru 	struct qed_link_output current_link;
520133fac0eSSudarsana Kalluru 
521567b3c12SMintz, Yuval 	__qede_lock(edev);
522567b3c12SMintz, Yuval 
523133fac0eSSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
524133fac0eSSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
525133fac0eSSudarsana Kalluru 
526bdb5d8ecSAlexander Lobakin 	linkmode_copy(link_modes->supported, current_link.supported_caps);
527bdb5d8ecSAlexander Lobakin 	linkmode_copy(link_modes->advertising, current_link.advertised_caps);
528bdb5d8ecSAlexander Lobakin 	linkmode_copy(link_modes->lp_advertising, current_link.lp_caps);
529054c67d1SSudarsana Reddy Kalluru 
530133fac0eSSudarsana Kalluru 	if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) {
531054c67d1SSudarsana Reddy Kalluru 		base->speed = current_link.speed;
532054c67d1SSudarsana Reddy Kalluru 		base->duplex = current_link.duplex;
533133fac0eSSudarsana Kalluru 	} else {
534054c67d1SSudarsana Reddy Kalluru 		base->speed = SPEED_UNKNOWN;
535054c67d1SSudarsana Reddy Kalluru 		base->duplex = DUPLEX_UNKNOWN;
536133fac0eSSudarsana Kalluru 	}
537567b3c12SMintz, Yuval 
538567b3c12SMintz, Yuval 	__qede_unlock(edev);
539567b3c12SMintz, Yuval 
540054c67d1SSudarsana Reddy Kalluru 	base->port = current_link.port;
541054c67d1SSudarsana Reddy Kalluru 	base->autoneg = (current_link.autoneg) ? AUTONEG_ENABLE :
542133fac0eSSudarsana Kalluru 			AUTONEG_DISABLE;
543133fac0eSSudarsana Kalluru 
544133fac0eSSudarsana Kalluru 	return 0;
545133fac0eSSudarsana Kalluru }
546133fac0eSSudarsana Kalluru 
547054c67d1SSudarsana Reddy Kalluru static int qede_set_link_ksettings(struct net_device *dev,
548054c67d1SSudarsana Reddy Kalluru 				   const struct ethtool_link_ksettings *cmd)
549133fac0eSSudarsana Kalluru {
550054c67d1SSudarsana Reddy Kalluru 	const struct ethtool_link_settings *base = &cmd->base;
551133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
5521d4e4eccSAlexander Lobakin 	const struct qede_forced_speed_map *map;
553133fac0eSSudarsana Kalluru 	struct qed_link_output current_link;
554133fac0eSSudarsana Kalluru 	struct qed_link_params params;
5551d4e4eccSAlexander Lobakin 	u32 i;
556133fac0eSSudarsana Kalluru 
557fe7cd2bfSYuval Mintz 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
558054c67d1SSudarsana Reddy Kalluru 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
559133fac0eSSudarsana Kalluru 		return -EOPNOTSUPP;
560133fac0eSSudarsana Kalluru 	}
561133fac0eSSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
562133fac0eSSudarsana Kalluru 	memset(&params, 0, sizeof(params));
563133fac0eSSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
564133fac0eSSudarsana Kalluru 
565133fac0eSSudarsana Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS;
566133fac0eSSudarsana Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG;
567bdb5d8ecSAlexander Lobakin 
568054c67d1SSudarsana Reddy Kalluru 	if (base->autoneg == AUTONEG_ENABLE) {
569bdb5d8ecSAlexander Lobakin 		if (!phylink_test(current_link.supported_caps, Autoneg)) {
570161adb04Ssudarsana.kalluru@cavium.com 			DP_INFO(edev, "Auto negotiation is not supported\n");
571161adb04Ssudarsana.kalluru@cavium.com 			return -EOPNOTSUPP;
572161adb04Ssudarsana.kalluru@cavium.com 		}
573161adb04Ssudarsana.kalluru@cavium.com 
574133fac0eSSudarsana Kalluru 		params.autoneg = true;
575133fac0eSSudarsana Kalluru 		params.forced_speed = 0;
576bdb5d8ecSAlexander Lobakin 
577bdb5d8ecSAlexander Lobakin 		linkmode_copy(params.adv_speeds, cmd->link_modes.advertising);
578133fac0eSSudarsana Kalluru 	} else {		/* forced speed */
579133fac0eSSudarsana Kalluru 		params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED;
580133fac0eSSudarsana Kalluru 		params.autoneg = false;
581054c67d1SSudarsana Reddy Kalluru 		params.forced_speed = base->speed;
582bdb5d8ecSAlexander Lobakin 
5831d4e4eccSAlexander Lobakin 		for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
5841d4e4eccSAlexander Lobakin 			map = qede_forced_speed_maps + i;
585bdb5d8ecSAlexander Lobakin 
5861d4e4eccSAlexander Lobakin 			if (base->speed != map->speed ||
5871d4e4eccSAlexander Lobakin 			    !linkmode_intersects(current_link.supported_caps,
5881d4e4eccSAlexander Lobakin 						 map->caps))
5891d4e4eccSAlexander Lobakin 				continue;
5901d4e4eccSAlexander Lobakin 
5911d4e4eccSAlexander Lobakin 			linkmode_and(params.adv_speeds,
5921d4e4eccSAlexander Lobakin 				     current_link.supported_caps, map->caps);
5931d4e4eccSAlexander Lobakin 			goto set_link;
5941d4e4eccSAlexander Lobakin 		}
5951d4e4eccSAlexander Lobakin 
596054c67d1SSudarsana Reddy Kalluru 		DP_INFO(edev, "Unsupported speed %u\n", base->speed);
597133fac0eSSudarsana Kalluru 		return -EINVAL;
598133fac0eSSudarsana Kalluru 	}
599bdb5d8ecSAlexander Lobakin 
6001d4e4eccSAlexander Lobakin set_link:
601133fac0eSSudarsana Kalluru 	params.link_up = true;
602133fac0eSSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &params);
603133fac0eSSudarsana Kalluru 
604133fac0eSSudarsana Kalluru 	return 0;
605133fac0eSSudarsana Kalluru }
606133fac0eSSudarsana Kalluru 
607133fac0eSSudarsana Kalluru static void qede_get_drvinfo(struct net_device *ndev,
608133fac0eSSudarsana Kalluru 			     struct ethtool_drvinfo *info)
609133fac0eSSudarsana Kalluru {
610133fac0eSSudarsana Kalluru 	char mfw[ETHTOOL_FWVERS_LEN], storm[ETHTOOL_FWVERS_LEN];
611133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
612a88381deSSudarsana Reddy Kalluru 	char mbi[ETHTOOL_FWVERS_LEN];
613133fac0eSSudarsana Kalluru 
614133fac0eSSudarsana Kalluru 	strlcpy(info->driver, "qede", sizeof(info->driver));
615133fac0eSSudarsana Kalluru 
616133fac0eSSudarsana Kalluru 	snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",
617133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_major,
618133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_minor,
619133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_rev,
620133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_eng);
621133fac0eSSudarsana Kalluru 
622133fac0eSSudarsana Kalluru 	snprintf(mfw, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",
623133fac0eSSudarsana Kalluru 		 (edev->dev_info.common.mfw_rev >> 24) & 0xFF,
624133fac0eSSudarsana Kalluru 		 (edev->dev_info.common.mfw_rev >> 16) & 0xFF,
625133fac0eSSudarsana Kalluru 		 (edev->dev_info.common.mfw_rev >> 8) & 0xFF,
626133fac0eSSudarsana Kalluru 		 edev->dev_info.common.mfw_rev & 0xFF);
627133fac0eSSudarsana Kalluru 
62888ea96f8SShai Malin 	if ((strlen(storm) + strlen("[storm]")) <
629a88381deSSudarsana Reddy Kalluru 	    sizeof(info->version))
630a88381deSSudarsana Reddy Kalluru 		snprintf(info->version, sizeof(info->version),
63188ea96f8SShai Malin 			 "[storm %s]", storm);
632a88381deSSudarsana Reddy Kalluru 	else
633a88381deSSudarsana Reddy Kalluru 		snprintf(info->version, sizeof(info->version),
63488ea96f8SShai Malin 			 "%s", storm);
635a88381deSSudarsana Reddy Kalluru 
636a88381deSSudarsana Reddy Kalluru 	if (edev->dev_info.common.mbi_version) {
637a88381deSSudarsana Reddy Kalluru 		snprintf(mbi, ETHTOOL_FWVERS_LEN, "%d.%d.%d",
638a88381deSSudarsana Reddy Kalluru 			 (edev->dev_info.common.mbi_version &
639a88381deSSudarsana Reddy Kalluru 			  QED_MBI_VERSION_2_MASK) >> QED_MBI_VERSION_2_OFFSET,
640a88381deSSudarsana Reddy Kalluru 			 (edev->dev_info.common.mbi_version &
641a88381deSSudarsana Reddy Kalluru 			  QED_MBI_VERSION_1_MASK) >> QED_MBI_VERSION_1_OFFSET,
642a88381deSSudarsana Reddy Kalluru 			 (edev->dev_info.common.mbi_version &
643a88381deSSudarsana Reddy Kalluru 			  QED_MBI_VERSION_0_MASK) >> QED_MBI_VERSION_0_OFFSET);
644133fac0eSSudarsana Kalluru 		snprintf(info->fw_version, sizeof(info->fw_version),
645a88381deSSudarsana Reddy Kalluru 			 "mbi %s [mfw %s]", mbi, mfw);
646133fac0eSSudarsana Kalluru 	} else {
647133fac0eSSudarsana Kalluru 		snprintf(info->fw_version, sizeof(info->fw_version),
648a88381deSSudarsana Reddy Kalluru 			 "mfw %s", mfw);
649133fac0eSSudarsana Kalluru 	}
650133fac0eSSudarsana Kalluru 
651133fac0eSSudarsana Kalluru 	strlcpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info));
652133fac0eSSudarsana Kalluru }
653133fac0eSSudarsana Kalluru 
65414d39648SMintz, Yuval static void qede_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
65514d39648SMintz, Yuval {
65614d39648SMintz, Yuval 	struct qede_dev *edev = netdev_priv(ndev);
65714d39648SMintz, Yuval 
65814d39648SMintz, Yuval 	if (edev->dev_info.common.wol_support) {
65914d39648SMintz, Yuval 		wol->supported = WAKE_MAGIC;
66014d39648SMintz, Yuval 		wol->wolopts = edev->wol_enabled ? WAKE_MAGIC : 0;
66114d39648SMintz, Yuval 	}
66214d39648SMintz, Yuval }
66314d39648SMintz, Yuval 
66414d39648SMintz, Yuval static int qede_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
66514d39648SMintz, Yuval {
66614d39648SMintz, Yuval 	struct qede_dev *edev = netdev_priv(ndev);
66714d39648SMintz, Yuval 	bool wol_requested;
66814d39648SMintz, Yuval 	int rc;
66914d39648SMintz, Yuval 
67014d39648SMintz, Yuval 	if (wol->wolopts & ~WAKE_MAGIC) {
67114d39648SMintz, Yuval 		DP_INFO(edev,
67214d39648SMintz, Yuval 			"Can't support WoL options other than magic-packet\n");
67314d39648SMintz, Yuval 		return -EINVAL;
67414d39648SMintz, Yuval 	}
67514d39648SMintz, Yuval 
67614d39648SMintz, Yuval 	wol_requested = !!(wol->wolopts & WAKE_MAGIC);
67714d39648SMintz, Yuval 	if (wol_requested == edev->wol_enabled)
67814d39648SMintz, Yuval 		return 0;
67914d39648SMintz, Yuval 
68014d39648SMintz, Yuval 	/* Need to actually change configuration */
68114d39648SMintz, Yuval 	if (!edev->dev_info.common.wol_support) {
68214d39648SMintz, Yuval 		DP_INFO(edev, "Device doesn't support WoL\n");
68314d39648SMintz, Yuval 		return -EINVAL;
68414d39648SMintz, Yuval 	}
68514d39648SMintz, Yuval 
68614d39648SMintz, Yuval 	rc = edev->ops->common->update_wol(edev->cdev, wol_requested);
68714d39648SMintz, Yuval 	if (!rc)
68814d39648SMintz, Yuval 		edev->wol_enabled = wol_requested;
68914d39648SMintz, Yuval 
69014d39648SMintz, Yuval 	return rc;
69114d39648SMintz, Yuval }
69214d39648SMintz, Yuval 
693133fac0eSSudarsana Kalluru static u32 qede_get_msglevel(struct net_device *ndev)
694133fac0eSSudarsana Kalluru {
695133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
696133fac0eSSudarsana Kalluru 
6971a635e48SYuval Mintz 	return ((u32)edev->dp_level << QED_LOG_LEVEL_SHIFT) | edev->dp_module;
698133fac0eSSudarsana Kalluru }
699133fac0eSSudarsana Kalluru 
700133fac0eSSudarsana Kalluru static void qede_set_msglevel(struct net_device *ndev, u32 level)
701133fac0eSSudarsana Kalluru {
702133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
703133fac0eSSudarsana Kalluru 	u32 dp_module = 0;
704133fac0eSSudarsana Kalluru 	u8 dp_level = 0;
705133fac0eSSudarsana Kalluru 
706133fac0eSSudarsana Kalluru 	qede_config_debug(level, &dp_module, &dp_level);
707133fac0eSSudarsana Kalluru 
708133fac0eSSudarsana Kalluru 	edev->dp_level = dp_level;
709133fac0eSSudarsana Kalluru 	edev->dp_module = dp_module;
710133fac0eSSudarsana Kalluru 	edev->ops->common->update_msglvl(edev->cdev,
711133fac0eSSudarsana Kalluru 					 dp_module, dp_level);
712133fac0eSSudarsana Kalluru }
713133fac0eSSudarsana Kalluru 
71432a7a570SSudarsana Kalluru static int qede_nway_reset(struct net_device *dev)
71532a7a570SSudarsana Kalluru {
71632a7a570SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
71732a7a570SSudarsana Kalluru 	struct qed_link_output current_link;
71832a7a570SSudarsana Kalluru 	struct qed_link_params link_params;
71932a7a570SSudarsana Kalluru 
720fe7cd2bfSYuval Mintz 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
7211a635e48SYuval Mintz 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
722fe7cd2bfSYuval Mintz 		return -EOPNOTSUPP;
723fe7cd2bfSYuval Mintz 	}
724fe7cd2bfSYuval Mintz 
72532a7a570SSudarsana Kalluru 	if (!netif_running(dev))
72632a7a570SSudarsana Kalluru 		return 0;
72732a7a570SSudarsana Kalluru 
72832a7a570SSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
72932a7a570SSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
73032a7a570SSudarsana Kalluru 	if (!current_link.link_up)
73132a7a570SSudarsana Kalluru 		return 0;
73232a7a570SSudarsana Kalluru 
73332a7a570SSudarsana Kalluru 	/* Toggle the link */
73432a7a570SSudarsana Kalluru 	memset(&link_params, 0, sizeof(link_params));
73532a7a570SSudarsana Kalluru 	link_params.link_up = false;
73632a7a570SSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
73732a7a570SSudarsana Kalluru 	link_params.link_up = true;
73832a7a570SSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
73932a7a570SSudarsana Kalluru 
74032a7a570SSudarsana Kalluru 	return 0;
74132a7a570SSudarsana Kalluru }
74232a7a570SSudarsana Kalluru 
743133fac0eSSudarsana Kalluru static u32 qede_get_link(struct net_device *dev)
744133fac0eSSudarsana Kalluru {
745133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
746133fac0eSSudarsana Kalluru 	struct qed_link_output current_link;
747133fac0eSSudarsana Kalluru 
748133fac0eSSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
749133fac0eSSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
750133fac0eSSudarsana Kalluru 
751133fac0eSSudarsana Kalluru 	return current_link.link_up;
752133fac0eSSudarsana Kalluru }
753133fac0eSSudarsana Kalluru 
754ccfa110cSSudarsana Reddy Kalluru static int qede_flash_device(struct net_device *dev,
755ccfa110cSSudarsana Reddy Kalluru 			     struct ethtool_flash *flash)
756ccfa110cSSudarsana Reddy Kalluru {
757ccfa110cSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
758ccfa110cSSudarsana Reddy Kalluru 
759ccfa110cSSudarsana Reddy Kalluru 	return edev->ops->common->nvm_flash(edev->cdev, flash->data);
760ccfa110cSSudarsana Reddy Kalluru }
761ccfa110cSSudarsana Reddy Kalluru 
762d552fa84SSudarsana Reddy Kalluru static int qede_get_coalesce(struct net_device *dev,
763f3ccfda1SYufeng Mo 			     struct ethtool_coalesce *coal,
764f3ccfda1SYufeng Mo 			     struct kernel_ethtool_coalesce *kernel_coal,
765f3ccfda1SYufeng Mo 			     struct netlink_ext_ack *extack)
766d552fa84SSudarsana Reddy Kalluru {
767bf5a94bfSRahul Verma 	void *rx_handle = NULL, *tx_handle = NULL;
768d552fa84SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
769bf5a94bfSRahul Verma 	u16 rx_coal, tx_coal, i, rc = 0;
770bf5a94bfSRahul Verma 	struct qede_fastpath *fp;
771bf5a94bfSRahul Verma 
772bf5a94bfSRahul Verma 	rx_coal = QED_DEFAULT_RX_USECS;
773bf5a94bfSRahul Verma 	tx_coal = QED_DEFAULT_TX_USECS;
774d552fa84SSudarsana Reddy Kalluru 
775d552fa84SSudarsana Reddy Kalluru 	memset(coal, 0, sizeof(struct ethtool_coalesce));
776d2890deaSSudarsana Reddy Kalluru 
777bf5a94bfSRahul Verma 	__qede_lock(edev);
778bf5a94bfSRahul Verma 	if (edev->state == QEDE_STATE_OPEN) {
779bf5a94bfSRahul Verma 		for_each_queue(i) {
780bf5a94bfSRahul Verma 			fp = &edev->fp_array[i];
781d552fa84SSudarsana Reddy Kalluru 
782bf5a94bfSRahul Verma 			if (fp->type & QEDE_FASTPATH_RX) {
783bf5a94bfSRahul Verma 				rx_handle = fp->rxq->handle;
784bf5a94bfSRahul Verma 				break;
785bf5a94bfSRahul Verma 			}
786bf5a94bfSRahul Verma 		}
787bf5a94bfSRahul Verma 
788bf5a94bfSRahul Verma 		rc = edev->ops->get_coalesce(edev->cdev, &rx_coal, rx_handle);
789bf5a94bfSRahul Verma 		if (rc) {
790bf5a94bfSRahul Verma 			DP_INFO(edev, "Read Rx coalesce error\n");
791bf5a94bfSRahul Verma 			goto out;
792bf5a94bfSRahul Verma 		}
793bf5a94bfSRahul Verma 
794bf5a94bfSRahul Verma 		for_each_queue(i) {
7955e7baf0fSManish Chopra 			struct qede_tx_queue *txq;
7965e7baf0fSManish Chopra 
797bf5a94bfSRahul Verma 			fp = &edev->fp_array[i];
7985e7baf0fSManish Chopra 
7995e7baf0fSManish Chopra 			/* All TX queues of given fastpath uses same
8005e7baf0fSManish Chopra 			 * coalescing value, so no need to iterate over
8015e7baf0fSManish Chopra 			 * all TCs, TC0 txq should suffice.
8025e7baf0fSManish Chopra 			 */
803bf5a94bfSRahul Verma 			if (fp->type & QEDE_FASTPATH_TX) {
8045e7baf0fSManish Chopra 				txq = QEDE_FP_TC0_TXQ(fp);
8055e7baf0fSManish Chopra 				tx_handle = txq->handle;
806bf5a94bfSRahul Verma 				break;
807bf5a94bfSRahul Verma 			}
808bf5a94bfSRahul Verma 		}
809bf5a94bfSRahul Verma 
810bf5a94bfSRahul Verma 		rc = edev->ops->get_coalesce(edev->cdev, &tx_coal, tx_handle);
811bf5a94bfSRahul Verma 		if (rc)
812bf5a94bfSRahul Verma 			DP_INFO(edev, "Read Tx coalesce error\n");
813bf5a94bfSRahul Verma 	}
814bf5a94bfSRahul Verma 
815bf5a94bfSRahul Verma out:
816bf5a94bfSRahul Verma 	__qede_unlock(edev);
817bf5a94bfSRahul Verma 
818bf5a94bfSRahul Verma 	coal->rx_coalesce_usecs = rx_coal;
819bf5a94bfSRahul Verma 	coal->tx_coalesce_usecs = tx_coal;
820bf5a94bfSRahul Verma 
821bf5a94bfSRahul Verma 	return rc;
822d552fa84SSudarsana Reddy Kalluru }
823d552fa84SSudarsana Reddy Kalluru 
824f3ccfda1SYufeng Mo int qede_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal,
825f3ccfda1SYufeng Mo 		      struct kernel_ethtool_coalesce *kernel_coal,
826f3ccfda1SYufeng Mo 		      struct netlink_ext_ack *extack)
827d552fa84SSudarsana Reddy Kalluru {
828d552fa84SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
829477f2d14SRahul Verma 	struct qede_fastpath *fp;
830d552fa84SSudarsana Reddy Kalluru 	int i, rc = 0;
831477f2d14SRahul Verma 	u16 rxc, txc;
832d552fa84SSudarsana Reddy Kalluru 
833d552fa84SSudarsana Reddy Kalluru 	if (!netif_running(dev)) {
834d552fa84SSudarsana Reddy Kalluru 		DP_INFO(edev, "Interface is down\n");
835d552fa84SSudarsana Reddy Kalluru 		return -EINVAL;
836d552fa84SSudarsana Reddy Kalluru 	}
837d552fa84SSudarsana Reddy Kalluru 
838d552fa84SSudarsana Reddy Kalluru 	if (coal->rx_coalesce_usecs > QED_COALESCE_MAX ||
839d552fa84SSudarsana Reddy Kalluru 	    coal->tx_coalesce_usecs > QED_COALESCE_MAX) {
840d552fa84SSudarsana Reddy Kalluru 		DP_INFO(edev,
841d552fa84SSudarsana Reddy Kalluru 			"Can't support requested %s coalesce value [max supported value %d]\n",
842477f2d14SRahul Verma 			coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx" :
843477f2d14SRahul Verma 			"tx", QED_COALESCE_MAX);
844d552fa84SSudarsana Reddy Kalluru 		return -EINVAL;
845d552fa84SSudarsana Reddy Kalluru 	}
846d552fa84SSudarsana Reddy Kalluru 
847d552fa84SSudarsana Reddy Kalluru 	rxc = (u16)coal->rx_coalesce_usecs;
848d552fa84SSudarsana Reddy Kalluru 	txc = (u16)coal->tx_coalesce_usecs;
8499a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
850477f2d14SRahul Verma 		fp = &edev->fp_array[i];
851477f2d14SRahul Verma 
852477f2d14SRahul Verma 		if (edev->fp_array[i].type & QEDE_FASTPATH_RX) {
853477f2d14SRahul Verma 			rc = edev->ops->common->set_coalesce(edev->cdev,
854477f2d14SRahul Verma 							     rxc, 0,
855477f2d14SRahul Verma 							     fp->rxq->handle);
856d552fa84SSudarsana Reddy Kalluru 			if (rc) {
857477f2d14SRahul Verma 				DP_INFO(edev,
858477f2d14SRahul Verma 					"Set RX coalesce error, rc = %d\n", rc);
859d552fa84SSudarsana Reddy Kalluru 				return rc;
860d552fa84SSudarsana Reddy Kalluru 			}
861b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].rxc = rxc;
862b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].isvalid = true;
863d552fa84SSudarsana Reddy Kalluru 		}
864d552fa84SSudarsana Reddy Kalluru 
865477f2d14SRahul Verma 		if (edev->fp_array[i].type & QEDE_FASTPATH_TX) {
8665e7baf0fSManish Chopra 			struct qede_tx_queue *txq;
8675e7baf0fSManish Chopra 
8685e7baf0fSManish Chopra 			/* All TX queues of given fastpath uses same
8695e7baf0fSManish Chopra 			 * coalescing value, so no need to iterate over
8705e7baf0fSManish Chopra 			 * all TCs, TC0 txq should suffice.
8715e7baf0fSManish Chopra 			 */
8725e7baf0fSManish Chopra 			txq = QEDE_FP_TC0_TXQ(fp);
8735e7baf0fSManish Chopra 
874477f2d14SRahul Verma 			rc = edev->ops->common->set_coalesce(edev->cdev,
875477f2d14SRahul Verma 							     0, txc,
8765e7baf0fSManish Chopra 							     txq->handle);
877477f2d14SRahul Verma 			if (rc) {
878477f2d14SRahul Verma 				DP_INFO(edev,
879477f2d14SRahul Verma 					"Set TX coalesce error, rc = %d\n", rc);
880477f2d14SRahul Verma 				return rc;
881477f2d14SRahul Verma 			}
882b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].txc = txc;
883b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].isvalid = true;
884477f2d14SRahul Verma 		}
885477f2d14SRahul Verma 	}
886477f2d14SRahul Verma 
887d552fa84SSudarsana Reddy Kalluru 	return rc;
888d552fa84SSudarsana Reddy Kalluru }
889d552fa84SSudarsana Reddy Kalluru 
89001ef7e05SSudarsana Kalluru static void qede_get_ringparam(struct net_device *dev,
891*74624944SHao Chen 			       struct ethtool_ringparam *ering,
892*74624944SHao Chen 			       struct kernel_ethtool_ringparam *kernel_ering,
893*74624944SHao Chen 			       struct netlink_ext_ack *extack)
89401ef7e05SSudarsana Kalluru {
89501ef7e05SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
89601ef7e05SSudarsana Kalluru 
89701ef7e05SSudarsana Kalluru 	ering->rx_max_pending = NUM_RX_BDS_MAX;
89801ef7e05SSudarsana Kalluru 	ering->rx_pending = edev->q_num_rx_buffers;
89901ef7e05SSudarsana Kalluru 	ering->tx_max_pending = NUM_TX_BDS_MAX;
90001ef7e05SSudarsana Kalluru 	ering->tx_pending = edev->q_num_tx_buffers;
90101ef7e05SSudarsana Kalluru }
90201ef7e05SSudarsana Kalluru 
90301ef7e05SSudarsana Kalluru static int qede_set_ringparam(struct net_device *dev,
904*74624944SHao Chen 			      struct ethtool_ringparam *ering,
905*74624944SHao Chen 			      struct kernel_ethtool_ringparam *kernel_ering,
906*74624944SHao Chen 			      struct netlink_ext_ack *extack)
90701ef7e05SSudarsana Kalluru {
90801ef7e05SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
90901ef7e05SSudarsana Kalluru 
91001ef7e05SSudarsana Kalluru 	DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
91101ef7e05SSudarsana Kalluru 		   "Set ring params command parameters: rx_pending = %d, tx_pending = %d\n",
91201ef7e05SSudarsana Kalluru 		   ering->rx_pending, ering->tx_pending);
91301ef7e05SSudarsana Kalluru 
91401ef7e05SSudarsana Kalluru 	/* Validate legality of configuration */
91501ef7e05SSudarsana Kalluru 	if (ering->rx_pending > NUM_RX_BDS_MAX ||
91601ef7e05SSudarsana Kalluru 	    ering->rx_pending < NUM_RX_BDS_MIN ||
91701ef7e05SSudarsana Kalluru 	    ering->tx_pending > NUM_TX_BDS_MAX ||
91801ef7e05SSudarsana Kalluru 	    ering->tx_pending < NUM_TX_BDS_MIN) {
91901ef7e05SSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
92001ef7e05SSudarsana Kalluru 			   "Can only support Rx Buffer size [0%08x,...,0x%08x] and Tx Buffer size [0x%08x,...,0x%08x]\n",
92101ef7e05SSudarsana Kalluru 			   NUM_RX_BDS_MIN, NUM_RX_BDS_MAX,
92201ef7e05SSudarsana Kalluru 			   NUM_TX_BDS_MIN, NUM_TX_BDS_MAX);
92301ef7e05SSudarsana Kalluru 		return -EINVAL;
92401ef7e05SSudarsana Kalluru 	}
92501ef7e05SSudarsana Kalluru 
92601ef7e05SSudarsana Kalluru 	/* Change ring size and re-load */
92701ef7e05SSudarsana Kalluru 	edev->q_num_rx_buffers = ering->rx_pending;
92801ef7e05SSudarsana Kalluru 	edev->q_num_tx_buffers = ering->tx_pending;
92901ef7e05SSudarsana Kalluru 
930567b3c12SMintz, Yuval 	qede_reload(edev, NULL, false);
93101ef7e05SSudarsana Kalluru 
93201ef7e05SSudarsana Kalluru 	return 0;
93301ef7e05SSudarsana Kalluru }
93401ef7e05SSudarsana Kalluru 
9350f7db144SSudarsana Kalluru static void qede_get_pauseparam(struct net_device *dev,
9360f7db144SSudarsana Kalluru 				struct ethtool_pauseparam *epause)
9370f7db144SSudarsana Kalluru {
9380f7db144SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
9390f7db144SSudarsana Kalluru 	struct qed_link_output current_link;
9400f7db144SSudarsana Kalluru 
9410f7db144SSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
9420f7db144SSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
9430f7db144SSudarsana Kalluru 
9440f7db144SSudarsana Kalluru 	if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
9450f7db144SSudarsana Kalluru 		epause->autoneg = true;
9460f7db144SSudarsana Kalluru 	if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE)
9470f7db144SSudarsana Kalluru 		epause->rx_pause = true;
9480f7db144SSudarsana Kalluru 	if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE)
9490f7db144SSudarsana Kalluru 		epause->tx_pause = true;
9500f7db144SSudarsana Kalluru 
9510f7db144SSudarsana Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
9520f7db144SSudarsana Kalluru 		   "ethtool_pauseparam: cmd %d  autoneg %d  rx_pause %d  tx_pause %d\n",
9530f7db144SSudarsana Kalluru 		   epause->cmd, epause->autoneg, epause->rx_pause,
9540f7db144SSudarsana Kalluru 		   epause->tx_pause);
9550f7db144SSudarsana Kalluru }
9560f7db144SSudarsana Kalluru 
9570f7db144SSudarsana Kalluru static int qede_set_pauseparam(struct net_device *dev,
9580f7db144SSudarsana Kalluru 			       struct ethtool_pauseparam *epause)
9590f7db144SSudarsana Kalluru {
9600f7db144SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
9610f7db144SSudarsana Kalluru 	struct qed_link_params params;
9620f7db144SSudarsana Kalluru 	struct qed_link_output current_link;
9630f7db144SSudarsana Kalluru 
964fe7cd2bfSYuval Mintz 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
9650f7db144SSudarsana Kalluru 		DP_INFO(edev,
966fe7cd2bfSYuval Mintz 			"Pause settings are not allowed to be changed\n");
9670f7db144SSudarsana Kalluru 		return -EOPNOTSUPP;
9680f7db144SSudarsana Kalluru 	}
9690f7db144SSudarsana Kalluru 
9700f7db144SSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
9710f7db144SSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
9720f7db144SSudarsana Kalluru 
9730f7db144SSudarsana Kalluru 	memset(&params, 0, sizeof(params));
9740f7db144SSudarsana Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG;
975bdb5d8ecSAlexander Lobakin 
9760f7db144SSudarsana Kalluru 	if (epause->autoneg) {
977bdb5d8ecSAlexander Lobakin 		if (!phylink_test(current_link.supported_caps, Autoneg)) {
9780f7db144SSudarsana Kalluru 			DP_INFO(edev, "autoneg not supported\n");
9790f7db144SSudarsana Kalluru 			return -EINVAL;
9800f7db144SSudarsana Kalluru 		}
981bdb5d8ecSAlexander Lobakin 
9820f7db144SSudarsana Kalluru 		params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
9830f7db144SSudarsana Kalluru 	}
984bdb5d8ecSAlexander Lobakin 
9850f7db144SSudarsana Kalluru 	if (epause->rx_pause)
9860f7db144SSudarsana Kalluru 		params.pause_config |= QED_LINK_PAUSE_RX_ENABLE;
9870f7db144SSudarsana Kalluru 	if (epause->tx_pause)
9880f7db144SSudarsana Kalluru 		params.pause_config |= QED_LINK_PAUSE_TX_ENABLE;
9890f7db144SSudarsana Kalluru 
9900f7db144SSudarsana Kalluru 	params.link_up = true;
9910f7db144SSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &params);
9920f7db144SSudarsana Kalluru 
9930f7db144SSudarsana Kalluru 	return 0;
9940f7db144SSudarsana Kalluru }
9950f7db144SSudarsana Kalluru 
996e0971c83STomer Tayar static void qede_get_regs(struct net_device *ndev,
997e0971c83STomer Tayar 			  struct ethtool_regs *regs, void *buffer)
998e0971c83STomer Tayar {
999e0971c83STomer Tayar 	struct qede_dev *edev = netdev_priv(ndev);
1000e0971c83STomer Tayar 
1001e0971c83STomer Tayar 	regs->version = 0;
1002e0971c83STomer Tayar 	memset(buffer, 0, regs->len);
1003e0971c83STomer Tayar 
1004e0971c83STomer Tayar 	if (edev->ops && edev->ops->common)
1005e0971c83STomer Tayar 		edev->ops->common->dbg_all_data(edev->cdev, buffer);
1006e0971c83STomer Tayar }
1007e0971c83STomer Tayar 
1008e0971c83STomer Tayar static int qede_get_regs_len(struct net_device *ndev)
1009e0971c83STomer Tayar {
1010e0971c83STomer Tayar 	struct qede_dev *edev = netdev_priv(ndev);
1011e0971c83STomer Tayar 
1012e0971c83STomer Tayar 	if (edev->ops && edev->ops->common)
1013e0971c83STomer Tayar 		return edev->ops->common->dbg_all_data_size(edev->cdev);
1014e0971c83STomer Tayar 	else
1015e0971c83STomer Tayar 		return -EINVAL;
1016e0971c83STomer Tayar }
1017e0971c83STomer Tayar 
1018567b3c12SMintz, Yuval static void qede_update_mtu(struct qede_dev *edev,
1019567b3c12SMintz, Yuval 			    struct qede_reload_args *args)
1020133fac0eSSudarsana Kalluru {
1021567b3c12SMintz, Yuval 	edev->ndev->mtu = args->u.mtu;
1022133fac0eSSudarsana Kalluru }
1023133fac0eSSudarsana Kalluru 
1024133fac0eSSudarsana Kalluru /* Netdevice NDOs */
1025133fac0eSSudarsana Kalluru int qede_change_mtu(struct net_device *ndev, int new_mtu)
1026133fac0eSSudarsana Kalluru {
1027133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
1028567b3c12SMintz, Yuval 	struct qede_reload_args args;
1029133fac0eSSudarsana Kalluru 
1030133fac0eSSudarsana Kalluru 	DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
1031133fac0eSSudarsana Kalluru 		   "Configuring MTU size of %d\n", new_mtu);
1032133fac0eSSudarsana Kalluru 
103318c602deSMichael Chan 	if (new_mtu > PAGE_SIZE)
103418c602deSMichael Chan 		ndev->features &= ~NETIF_F_GRO_HW;
103518c602deSMichael Chan 
1036133fac0eSSudarsana Kalluru 	/* Set the mtu field and re-start the interface if needed */
1037567b3c12SMintz, Yuval 	args.u.mtu = new_mtu;
1038567b3c12SMintz, Yuval 	args.func = &qede_update_mtu;
1039567b3c12SMintz, Yuval 	qede_reload(edev, &args, false);
104097fb3e33SMichal Kalderon #if IS_ENABLED(CONFIG_QED_RDMA)
104197fb3e33SMichal Kalderon 	qede_rdma_event_change_mtu(edev);
104297fb3e33SMichal Kalderon #endif
1043567b3c12SMintz, Yuval 	edev->ops->common->update_mtu(edev->cdev, new_mtu);
10440fefbfbaSSudarsana Kalluru 
1045133fac0eSSudarsana Kalluru 	return 0;
1046133fac0eSSudarsana Kalluru }
1047133fac0eSSudarsana Kalluru 
10488edf049dSSudarsana Kalluru static void qede_get_channels(struct net_device *dev,
10498edf049dSSudarsana Kalluru 			      struct ethtool_channels *channels)
10508edf049dSSudarsana Kalluru {
10518edf049dSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
10528edf049dSSudarsana Kalluru 
10538edf049dSSudarsana Kalluru 	channels->max_combined = QEDE_MAX_RSS_CNT(edev);
1054bdc8cbd3SSudarsana Reddy Kalluru 	channels->max_rx = QEDE_MAX_RSS_CNT(edev);
1055bdc8cbd3SSudarsana Reddy Kalluru 	channels->max_tx = QEDE_MAX_RSS_CNT(edev);
10569a4d7e86SSudarsana Reddy Kalluru 	channels->combined_count = QEDE_QUEUE_CNT(edev) - edev->fp_num_tx -
10579a4d7e86SSudarsana Reddy Kalluru 					edev->fp_num_rx;
10589a4d7e86SSudarsana Reddy Kalluru 	channels->tx_count = edev->fp_num_tx;
10599a4d7e86SSudarsana Reddy Kalluru 	channels->rx_count = edev->fp_num_rx;
10608edf049dSSudarsana Kalluru }
10618edf049dSSudarsana Kalluru 
10628edf049dSSudarsana Kalluru static int qede_set_channels(struct net_device *dev,
10638edf049dSSudarsana Kalluru 			     struct ethtool_channels *channels)
10648edf049dSSudarsana Kalluru {
10658edf049dSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
10669a4d7e86SSudarsana Reddy Kalluru 	u32 count;
10678edf049dSSudarsana Kalluru 
10688edf049dSSudarsana Kalluru 	DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
10698edf049dSSudarsana Kalluru 		   "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n",
10708edf049dSSudarsana Kalluru 		   channels->rx_count, channels->tx_count,
10718edf049dSSudarsana Kalluru 		   channels->other_count, channels->combined_count);
10728edf049dSSudarsana Kalluru 
10739a4d7e86SSudarsana Reddy Kalluru 	count = channels->rx_count + channels->tx_count +
10749a4d7e86SSudarsana Reddy Kalluru 			channels->combined_count;
10759a4d7e86SSudarsana Reddy Kalluru 
10769a4d7e86SSudarsana Reddy Kalluru 	/* We don't support `other' channels */
10779a4d7e86SSudarsana Reddy Kalluru 	if (channels->other_count) {
10788edf049dSSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
10798edf049dSSudarsana Kalluru 			   "command parameters not supported\n");
10808edf049dSSudarsana Kalluru 		return -EINVAL;
10818edf049dSSudarsana Kalluru 	}
10828edf049dSSudarsana Kalluru 
10839a4d7e86SSudarsana Reddy Kalluru 	if (!(channels->combined_count || (channels->rx_count &&
10849a4d7e86SSudarsana Reddy Kalluru 					   channels->tx_count))) {
10859a4d7e86SSudarsana Reddy Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
10869a4d7e86SSudarsana Reddy Kalluru 			   "need to request at least one transmit and one receive channel\n");
10879a4d7e86SSudarsana Reddy Kalluru 		return -EINVAL;
10889a4d7e86SSudarsana Reddy Kalluru 	}
10899a4d7e86SSudarsana Reddy Kalluru 
10909a4d7e86SSudarsana Reddy Kalluru 	if (count > QEDE_MAX_RSS_CNT(edev)) {
10919a4d7e86SSudarsana Reddy Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
10929a4d7e86SSudarsana Reddy Kalluru 			   "requested channels = %d max supported channels = %d\n",
10939a4d7e86SSudarsana Reddy Kalluru 			   count, QEDE_MAX_RSS_CNT(edev));
10949a4d7e86SSudarsana Reddy Kalluru 		return -EINVAL;
10959a4d7e86SSudarsana Reddy Kalluru 	}
10969a4d7e86SSudarsana Reddy Kalluru 
10978edf049dSSudarsana Kalluru 	/* Check if there was a change in the active parameters */
10989a4d7e86SSudarsana Reddy Kalluru 	if ((count == QEDE_QUEUE_CNT(edev)) &&
10999a4d7e86SSudarsana Reddy Kalluru 	    (channels->tx_count == edev->fp_num_tx) &&
11009a4d7e86SSudarsana Reddy Kalluru 	    (channels->rx_count == edev->fp_num_rx)) {
11018edf049dSSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11028edf049dSSudarsana Kalluru 			   "No change in active parameters\n");
11038edf049dSSudarsana Kalluru 		return 0;
11048edf049dSSudarsana Kalluru 	}
11058edf049dSSudarsana Kalluru 
11068edf049dSSudarsana Kalluru 	/* We need the number of queues to be divisible between the hwfns */
11079a4d7e86SSudarsana Reddy Kalluru 	if ((count % edev->dev_info.common.num_hwfns) ||
11089a4d7e86SSudarsana Reddy Kalluru 	    (channels->tx_count % edev->dev_info.common.num_hwfns) ||
11099a4d7e86SSudarsana Reddy Kalluru 	    (channels->rx_count % edev->dev_info.common.num_hwfns)) {
11108edf049dSSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11119a4d7e86SSudarsana Reddy Kalluru 			   "Number of channels must be divisible by %04x\n",
11128edf049dSSudarsana Kalluru 			   edev->dev_info.common.num_hwfns);
11138edf049dSSudarsana Kalluru 		return -EINVAL;
11148edf049dSSudarsana Kalluru 	}
11158edf049dSSudarsana Kalluru 
11168edf049dSSudarsana Kalluru 	/* Set number of queues and reload if necessary */
11179a4d7e86SSudarsana Reddy Kalluru 	edev->req_queues = count;
11189a4d7e86SSudarsana Reddy Kalluru 	edev->req_num_tx = channels->tx_count;
11199a4d7e86SSudarsana Reddy Kalluru 	edev->req_num_rx = channels->rx_count;
1120ed0dd915SSudarsana Reddy Kalluru 	/* Reset the indirection table if rx queue count is updated */
1121ed0dd915SSudarsana Reddy Kalluru 	if ((edev->req_queues - edev->req_num_tx) != QEDE_RSS_COUNT(edev)) {
1122ed0dd915SSudarsana Reddy Kalluru 		edev->rss_params_inited &= ~QEDE_RSS_INDIR_INITED;
1123f29ffdb6SMintz, Yuval 		memset(edev->rss_ind_table, 0, sizeof(edev->rss_ind_table));
1124ed0dd915SSudarsana Reddy Kalluru 	}
1125ed0dd915SSudarsana Reddy Kalluru 
1126567b3c12SMintz, Yuval 	qede_reload(edev, NULL, false);
11278edf049dSSudarsana Kalluru 
11288edf049dSSudarsana Kalluru 	return 0;
11298edf049dSSudarsana Kalluru }
11308edf049dSSudarsana Kalluru 
11314c55215cSSudarsana Reddy Kalluru static int qede_get_ts_info(struct net_device *dev,
11324c55215cSSudarsana Reddy Kalluru 			    struct ethtool_ts_info *info)
11334c55215cSSudarsana Reddy Kalluru {
11344c55215cSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
11354c55215cSSudarsana Reddy Kalluru 
11364c55215cSSudarsana Reddy Kalluru 	return qede_ptp_get_ts_info(edev, info);
11374c55215cSSudarsana Reddy Kalluru }
11384c55215cSSudarsana Reddy Kalluru 
11393d971cbdSSudarsana Kalluru static int qede_set_phys_id(struct net_device *dev,
11403d971cbdSSudarsana Kalluru 			    enum ethtool_phys_id_state state)
11413d971cbdSSudarsana Kalluru {
11423d971cbdSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
11433d971cbdSSudarsana Kalluru 	u8 led_state = 0;
11443d971cbdSSudarsana Kalluru 
11453d971cbdSSudarsana Kalluru 	switch (state) {
11463d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_ACTIVE:
11473d971cbdSSudarsana Kalluru 		return 1;	/* cycle on/off once per second */
11483d971cbdSSudarsana Kalluru 
11493d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_ON:
11503d971cbdSSudarsana Kalluru 		led_state = QED_LED_MODE_ON;
11513d971cbdSSudarsana Kalluru 		break;
11523d971cbdSSudarsana Kalluru 
11533d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_OFF:
11543d971cbdSSudarsana Kalluru 		led_state = QED_LED_MODE_OFF;
11553d971cbdSSudarsana Kalluru 		break;
11563d971cbdSSudarsana Kalluru 
11573d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_INACTIVE:
11583d971cbdSSudarsana Kalluru 		led_state = QED_LED_MODE_RESTORE;
11593d971cbdSSudarsana Kalluru 		break;
11603d971cbdSSudarsana Kalluru 	}
11613d971cbdSSudarsana Kalluru 
11623d971cbdSSudarsana Kalluru 	edev->ops->common->set_led(edev->cdev, led_state);
11633d971cbdSSudarsana Kalluru 
11643d971cbdSSudarsana Kalluru 	return 0;
11653d971cbdSSudarsana Kalluru }
11663d971cbdSSudarsana Kalluru 
1167961acdeaSSudarsana Reddy Kalluru static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
1168961acdeaSSudarsana Reddy Kalluru {
1169961acdeaSSudarsana Reddy Kalluru 	info->data = RXH_IP_SRC | RXH_IP_DST;
1170961acdeaSSudarsana Reddy Kalluru 
1171961acdeaSSudarsana Reddy Kalluru 	switch (info->flow_type) {
1172961acdeaSSudarsana Reddy Kalluru 	case TCP_V4_FLOW:
1173961acdeaSSudarsana Reddy Kalluru 	case TCP_V6_FLOW:
1174961acdeaSSudarsana Reddy Kalluru 		info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1175961acdeaSSudarsana Reddy Kalluru 		break;
1176961acdeaSSudarsana Reddy Kalluru 	case UDP_V4_FLOW:
1177f29ffdb6SMintz, Yuval 		if (edev->rss_caps & QED_RSS_IPV4_UDP)
1178961acdeaSSudarsana Reddy Kalluru 			info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1179961acdeaSSudarsana Reddy Kalluru 		break;
1180961acdeaSSudarsana Reddy Kalluru 	case UDP_V6_FLOW:
1181f29ffdb6SMintz, Yuval 		if (edev->rss_caps & QED_RSS_IPV6_UDP)
1182961acdeaSSudarsana Reddy Kalluru 			info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1183961acdeaSSudarsana Reddy Kalluru 		break;
1184961acdeaSSudarsana Reddy Kalluru 	case IPV4_FLOW:
1185961acdeaSSudarsana Reddy Kalluru 	case IPV6_FLOW:
1186961acdeaSSudarsana Reddy Kalluru 		break;
1187961acdeaSSudarsana Reddy Kalluru 	default:
1188961acdeaSSudarsana Reddy Kalluru 		info->data = 0;
1189961acdeaSSudarsana Reddy Kalluru 		break;
1190961acdeaSSudarsana Reddy Kalluru 	}
1191961acdeaSSudarsana Reddy Kalluru 
1192961acdeaSSudarsana Reddy Kalluru 	return 0;
1193961acdeaSSudarsana Reddy Kalluru }
1194961acdeaSSudarsana Reddy Kalluru 
1195961acdeaSSudarsana Reddy Kalluru static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
1196ec9b8dbdSChopra, Manish 			  u32 *rule_locs)
1197961acdeaSSudarsana Reddy Kalluru {
1198961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1199ec9b8dbdSChopra, Manish 	int rc = 0;
1200961acdeaSSudarsana Reddy Kalluru 
1201961acdeaSSudarsana Reddy Kalluru 	switch (info->cmd) {
1202961acdeaSSudarsana Reddy Kalluru 	case ETHTOOL_GRXRINGS:
12039a4d7e86SSudarsana Reddy Kalluru 		info->data = QEDE_RSS_COUNT(edev);
1204ec9b8dbdSChopra, Manish 		break;
1205961acdeaSSudarsana Reddy Kalluru 	case ETHTOOL_GRXFH:
1206ec9b8dbdSChopra, Manish 		rc = qede_get_rss_flags(edev, info);
1207ec9b8dbdSChopra, Manish 		break;
1208ec9b8dbdSChopra, Manish 	case ETHTOOL_GRXCLSRLCNT:
1209ec9b8dbdSChopra, Manish 		info->rule_cnt = qede_get_arfs_filter_count(edev);
1210ec9b8dbdSChopra, Manish 		info->data = QEDE_RFS_MAX_FLTR;
1211ec9b8dbdSChopra, Manish 		break;
1212ec9b8dbdSChopra, Manish 	case ETHTOOL_GRXCLSRULE:
1213ec9b8dbdSChopra, Manish 		rc = qede_get_cls_rule_entry(edev, info);
1214ec9b8dbdSChopra, Manish 		break;
1215ec9b8dbdSChopra, Manish 	case ETHTOOL_GRXCLSRLALL:
1216ec9b8dbdSChopra, Manish 		rc = qede_get_cls_rule_all(edev, info, rule_locs);
1217ec9b8dbdSChopra, Manish 		break;
1218961acdeaSSudarsana Reddy Kalluru 	default:
1219961acdeaSSudarsana Reddy Kalluru 		DP_ERR(edev, "Command parameters not supported\n");
1220ec9b8dbdSChopra, Manish 		rc = -EOPNOTSUPP;
1221961acdeaSSudarsana Reddy Kalluru 	}
1222ec9b8dbdSChopra, Manish 
1223ec9b8dbdSChopra, Manish 	return rc;
1224961acdeaSSudarsana Reddy Kalluru }
1225961acdeaSSudarsana Reddy Kalluru 
1226961acdeaSSudarsana Reddy Kalluru static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
1227961acdeaSSudarsana Reddy Kalluru {
1228f29ffdb6SMintz, Yuval 	struct qed_update_vport_params *vport_update_params;
1229961acdeaSSudarsana Reddy Kalluru 	u8 set_caps = 0, clr_caps = 0;
1230f29ffdb6SMintz, Yuval 	int rc = 0;
1231961acdeaSSudarsana Reddy Kalluru 
1232961acdeaSSudarsana Reddy Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
1233961acdeaSSudarsana Reddy Kalluru 		   "Set rss flags command parameters: flow type = %d, data = %llu\n",
1234961acdeaSSudarsana Reddy Kalluru 		   info->flow_type, info->data);
1235961acdeaSSudarsana Reddy Kalluru 
1236961acdeaSSudarsana Reddy Kalluru 	switch (info->flow_type) {
1237961acdeaSSudarsana Reddy Kalluru 	case TCP_V4_FLOW:
1238961acdeaSSudarsana Reddy Kalluru 	case TCP_V6_FLOW:
1239961acdeaSSudarsana Reddy Kalluru 		/* For TCP only 4-tuple hash is supported */
1240961acdeaSSudarsana Reddy Kalluru 		if (info->data ^ (RXH_IP_SRC | RXH_IP_DST |
1241961acdeaSSudarsana Reddy Kalluru 				  RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1242961acdeaSSudarsana Reddy Kalluru 			DP_INFO(edev, "Command parameters not supported\n");
1243961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1244961acdeaSSudarsana Reddy Kalluru 		}
1245961acdeaSSudarsana Reddy Kalluru 		return 0;
1246961acdeaSSudarsana Reddy Kalluru 	case UDP_V4_FLOW:
1247961acdeaSSudarsana Reddy Kalluru 		/* For UDP either 2-tuple hash or 4-tuple hash is supported */
1248961acdeaSSudarsana Reddy Kalluru 		if (info->data == (RXH_IP_SRC | RXH_IP_DST |
1249961acdeaSSudarsana Reddy Kalluru 				   RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1250961acdeaSSudarsana Reddy Kalluru 			set_caps = QED_RSS_IPV4_UDP;
1251961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1252961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple enabled\n");
1253961acdeaSSudarsana Reddy Kalluru 		} else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
1254961acdeaSSudarsana Reddy Kalluru 			clr_caps = QED_RSS_IPV4_UDP;
1255961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1256961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple disabled\n");
1257961acdeaSSudarsana Reddy Kalluru 		} else {
1258961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1259961acdeaSSudarsana Reddy Kalluru 		}
1260961acdeaSSudarsana Reddy Kalluru 		break;
1261961acdeaSSudarsana Reddy Kalluru 	case UDP_V6_FLOW:
1262961acdeaSSudarsana Reddy Kalluru 		/* For UDP either 2-tuple hash or 4-tuple hash is supported */
1263961acdeaSSudarsana Reddy Kalluru 		if (info->data == (RXH_IP_SRC | RXH_IP_DST |
1264961acdeaSSudarsana Reddy Kalluru 				   RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1265961acdeaSSudarsana Reddy Kalluru 			set_caps = QED_RSS_IPV6_UDP;
1266961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1267961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple enabled\n");
1268961acdeaSSudarsana Reddy Kalluru 		} else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
1269961acdeaSSudarsana Reddy Kalluru 			clr_caps = QED_RSS_IPV6_UDP;
1270961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1271961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple disabled\n");
1272961acdeaSSudarsana Reddy Kalluru 		} else {
1273961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1274961acdeaSSudarsana Reddy Kalluru 		}
1275961acdeaSSudarsana Reddy Kalluru 		break;
1276961acdeaSSudarsana Reddy Kalluru 	case IPV4_FLOW:
1277961acdeaSSudarsana Reddy Kalluru 	case IPV6_FLOW:
1278961acdeaSSudarsana Reddy Kalluru 		/* For IP only 2-tuple hash is supported */
1279961acdeaSSudarsana Reddy Kalluru 		if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) {
1280961acdeaSSudarsana Reddy Kalluru 			DP_INFO(edev, "Command parameters not supported\n");
1281961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1282961acdeaSSudarsana Reddy Kalluru 		}
1283961acdeaSSudarsana Reddy Kalluru 		return 0;
1284961acdeaSSudarsana Reddy Kalluru 	case SCTP_V4_FLOW:
1285961acdeaSSudarsana Reddy Kalluru 	case AH_ESP_V4_FLOW:
1286961acdeaSSudarsana Reddy Kalluru 	case AH_V4_FLOW:
1287961acdeaSSudarsana Reddy Kalluru 	case ESP_V4_FLOW:
1288961acdeaSSudarsana Reddy Kalluru 	case SCTP_V6_FLOW:
1289961acdeaSSudarsana Reddy Kalluru 	case AH_ESP_V6_FLOW:
1290961acdeaSSudarsana Reddy Kalluru 	case AH_V6_FLOW:
1291961acdeaSSudarsana Reddy Kalluru 	case ESP_V6_FLOW:
1292961acdeaSSudarsana Reddy Kalluru 	case IP_USER_FLOW:
1293961acdeaSSudarsana Reddy Kalluru 	case ETHER_FLOW:
1294961acdeaSSudarsana Reddy Kalluru 		/* RSS is not supported for these protocols */
1295961acdeaSSudarsana Reddy Kalluru 		if (info->data) {
1296961acdeaSSudarsana Reddy Kalluru 			DP_INFO(edev, "Command parameters not supported\n");
1297961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1298961acdeaSSudarsana Reddy Kalluru 		}
1299961acdeaSSudarsana Reddy Kalluru 		return 0;
1300961acdeaSSudarsana Reddy Kalluru 	default:
1301961acdeaSSudarsana Reddy Kalluru 		return -EINVAL;
1302961acdeaSSudarsana Reddy Kalluru 	}
1303961acdeaSSudarsana Reddy Kalluru 
1304961acdeaSSudarsana Reddy Kalluru 	/* No action is needed if there is no change in the rss capability */
1305f29ffdb6SMintz, Yuval 	if (edev->rss_caps == ((edev->rss_caps & ~clr_caps) | set_caps))
1306961acdeaSSudarsana Reddy Kalluru 		return 0;
1307961acdeaSSudarsana Reddy Kalluru 
1308961acdeaSSudarsana Reddy Kalluru 	/* Update internal configuration */
1309f29ffdb6SMintz, Yuval 	edev->rss_caps = ((edev->rss_caps & ~clr_caps) | set_caps);
1310961acdeaSSudarsana Reddy Kalluru 	edev->rss_params_inited |= QEDE_RSS_CAPS_INITED;
1311961acdeaSSudarsana Reddy Kalluru 
1312961acdeaSSudarsana Reddy Kalluru 	/* Re-configure if possible */
1313f29ffdb6SMintz, Yuval 	__qede_lock(edev);
1314f29ffdb6SMintz, Yuval 	if (edev->state == QEDE_STATE_OPEN) {
1315f29ffdb6SMintz, Yuval 		vport_update_params = vzalloc(sizeof(*vport_update_params));
1316f29ffdb6SMintz, Yuval 		if (!vport_update_params) {
1317f29ffdb6SMintz, Yuval 			__qede_unlock(edev);
1318f29ffdb6SMintz, Yuval 			return -ENOMEM;
1319961acdeaSSudarsana Reddy Kalluru 		}
1320f29ffdb6SMintz, Yuval 		qede_fill_rss_params(edev, &vport_update_params->rss_params,
1321f29ffdb6SMintz, Yuval 				     &vport_update_params->update_rss_flg);
1322f29ffdb6SMintz, Yuval 		rc = edev->ops->vport_update(edev->cdev, vport_update_params);
1323f29ffdb6SMintz, Yuval 		vfree(vport_update_params);
1324f29ffdb6SMintz, Yuval 	}
1325f29ffdb6SMintz, Yuval 	__qede_unlock(edev);
1326961acdeaSSudarsana Reddy Kalluru 
1327f29ffdb6SMintz, Yuval 	return rc;
1328961acdeaSSudarsana Reddy Kalluru }
1329961acdeaSSudarsana Reddy Kalluru 
1330961acdeaSSudarsana Reddy Kalluru static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
1331961acdeaSSudarsana Reddy Kalluru {
1332961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
13333f2a2b8bSChopra, Manish 	int rc;
1334961acdeaSSudarsana Reddy Kalluru 
1335961acdeaSSudarsana Reddy Kalluru 	switch (info->cmd) {
1336961acdeaSSudarsana Reddy Kalluru 	case ETHTOOL_SRXFH:
13373f2a2b8bSChopra, Manish 		rc = qede_set_rss_flags(edev, info);
13383f2a2b8bSChopra, Manish 		break;
13393f2a2b8bSChopra, Manish 	case ETHTOOL_SRXCLSRLINS:
13403f2a2b8bSChopra, Manish 		rc = qede_add_cls_rule(edev, info);
13413f2a2b8bSChopra, Manish 		break;
13423f2a2b8bSChopra, Manish 	case ETHTOOL_SRXCLSRLDEL:
13432ce9c93eSManish Chopra 		rc = qede_delete_flow_filter(edev, info->fs.location);
13443f2a2b8bSChopra, Manish 		break;
1345961acdeaSSudarsana Reddy Kalluru 	default:
1346961acdeaSSudarsana Reddy Kalluru 		DP_INFO(edev, "Command parameters not supported\n");
13473f2a2b8bSChopra, Manish 		rc = -EOPNOTSUPP;
1348961acdeaSSudarsana Reddy Kalluru 	}
13493f2a2b8bSChopra, Manish 
13503f2a2b8bSChopra, Manish 	return rc;
1351961acdeaSSudarsana Reddy Kalluru }
1352961acdeaSSudarsana Reddy Kalluru 
1353961acdeaSSudarsana Reddy Kalluru static u32 qede_get_rxfh_indir_size(struct net_device *dev)
1354961acdeaSSudarsana Reddy Kalluru {
1355961acdeaSSudarsana Reddy Kalluru 	return QED_RSS_IND_TABLE_SIZE;
1356961acdeaSSudarsana Reddy Kalluru }
1357961acdeaSSudarsana Reddy Kalluru 
1358961acdeaSSudarsana Reddy Kalluru static u32 qede_get_rxfh_key_size(struct net_device *dev)
1359961acdeaSSudarsana Reddy Kalluru {
1360961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1361961acdeaSSudarsana Reddy Kalluru 
1362f29ffdb6SMintz, Yuval 	return sizeof(edev->rss_key);
1363961acdeaSSudarsana Reddy Kalluru }
1364961acdeaSSudarsana Reddy Kalluru 
1365961acdeaSSudarsana Reddy Kalluru static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
1366961acdeaSSudarsana Reddy Kalluru {
1367961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1368961acdeaSSudarsana Reddy Kalluru 	int i;
1369961acdeaSSudarsana Reddy Kalluru 
1370961acdeaSSudarsana Reddy Kalluru 	if (hfunc)
1371961acdeaSSudarsana Reddy Kalluru 		*hfunc = ETH_RSS_HASH_TOP;
1372961acdeaSSudarsana Reddy Kalluru 
1373961acdeaSSudarsana Reddy Kalluru 	if (!indir)
1374961acdeaSSudarsana Reddy Kalluru 		return 0;
1375961acdeaSSudarsana Reddy Kalluru 
1376961acdeaSSudarsana Reddy Kalluru 	for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
1377f29ffdb6SMintz, Yuval 		indir[i] = edev->rss_ind_table[i];
1378961acdeaSSudarsana Reddy Kalluru 
1379961acdeaSSudarsana Reddy Kalluru 	if (key)
1380f29ffdb6SMintz, Yuval 		memcpy(key, edev->rss_key, qede_get_rxfh_key_size(dev));
1381961acdeaSSudarsana Reddy Kalluru 
1382961acdeaSSudarsana Reddy Kalluru 	return 0;
1383961acdeaSSudarsana Reddy Kalluru }
1384961acdeaSSudarsana Reddy Kalluru 
1385961acdeaSSudarsana Reddy Kalluru static int qede_set_rxfh(struct net_device *dev, const u32 *indir,
1386961acdeaSSudarsana Reddy Kalluru 			 const u8 *key, const u8 hfunc)
1387961acdeaSSudarsana Reddy Kalluru {
1388f29ffdb6SMintz, Yuval 	struct qed_update_vport_params *vport_update_params;
1389961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1390f29ffdb6SMintz, Yuval 	int i, rc = 0;
1391961acdeaSSudarsana Reddy Kalluru 
1392ba300ce3SSudarsana Reddy Kalluru 	if (edev->dev_info.common.num_hwfns > 1) {
1393ba300ce3SSudarsana Reddy Kalluru 		DP_INFO(edev,
1394ba300ce3SSudarsana Reddy Kalluru 			"RSS configuration is not supported for 100G devices\n");
1395ba300ce3SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1396ba300ce3SSudarsana Reddy Kalluru 	}
1397ba300ce3SSudarsana Reddy Kalluru 
1398961acdeaSSudarsana Reddy Kalluru 	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1399961acdeaSSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1400961acdeaSSudarsana Reddy Kalluru 
1401961acdeaSSudarsana Reddy Kalluru 	if (!indir && !key)
1402961acdeaSSudarsana Reddy Kalluru 		return 0;
1403961acdeaSSudarsana Reddy Kalluru 
1404961acdeaSSudarsana Reddy Kalluru 	if (indir) {
1405961acdeaSSudarsana Reddy Kalluru 		for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
1406f29ffdb6SMintz, Yuval 			edev->rss_ind_table[i] = indir[i];
1407961acdeaSSudarsana Reddy Kalluru 		edev->rss_params_inited |= QEDE_RSS_INDIR_INITED;
1408961acdeaSSudarsana Reddy Kalluru 	}
1409961acdeaSSudarsana Reddy Kalluru 
1410961acdeaSSudarsana Reddy Kalluru 	if (key) {
1411f29ffdb6SMintz, Yuval 		memcpy(&edev->rss_key, key, qede_get_rxfh_key_size(dev));
1412961acdeaSSudarsana Reddy Kalluru 		edev->rss_params_inited |= QEDE_RSS_KEY_INITED;
1413961acdeaSSudarsana Reddy Kalluru 	}
1414961acdeaSSudarsana Reddy Kalluru 
1415f29ffdb6SMintz, Yuval 	__qede_lock(edev);
1416f29ffdb6SMintz, Yuval 	if (edev->state == QEDE_STATE_OPEN) {
1417f29ffdb6SMintz, Yuval 		vport_update_params = vzalloc(sizeof(*vport_update_params));
1418f29ffdb6SMintz, Yuval 		if (!vport_update_params) {
1419f29ffdb6SMintz, Yuval 			__qede_unlock(edev);
1420f29ffdb6SMintz, Yuval 			return -ENOMEM;
1421961acdeaSSudarsana Reddy Kalluru 		}
1422f29ffdb6SMintz, Yuval 		qede_fill_rss_params(edev, &vport_update_params->rss_params,
1423f29ffdb6SMintz, Yuval 				     &vport_update_params->update_rss_flg);
1424f29ffdb6SMintz, Yuval 		rc = edev->ops->vport_update(edev->cdev, vport_update_params);
1425f29ffdb6SMintz, Yuval 		vfree(vport_update_params);
1426f29ffdb6SMintz, Yuval 	}
1427f29ffdb6SMintz, Yuval 	__qede_unlock(edev);
1428961acdeaSSudarsana Reddy Kalluru 
1429f29ffdb6SMintz, Yuval 	return rc;
1430961acdeaSSudarsana Reddy Kalluru }
1431961acdeaSSudarsana Reddy Kalluru 
143216f46bf0SSudarsana Reddy Kalluru /* This function enables the interrupt generation and the NAPI on the device */
143316f46bf0SSudarsana Reddy Kalluru static void qede_netif_start(struct qede_dev *edev)
143416f46bf0SSudarsana Reddy Kalluru {
143516f46bf0SSudarsana Reddy Kalluru 	int i;
143616f46bf0SSudarsana Reddy Kalluru 
143716f46bf0SSudarsana Reddy Kalluru 	if (!netif_running(edev->ndev))
143816f46bf0SSudarsana Reddy Kalluru 		return;
143916f46bf0SSudarsana Reddy Kalluru 
14409a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
144116f46bf0SSudarsana Reddy Kalluru 		/* Update and reenable interrupts */
144216f46bf0SSudarsana Reddy Kalluru 		qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_ENABLE, 1);
144316f46bf0SSudarsana Reddy Kalluru 		napi_enable(&edev->fp_array[i].napi);
144416f46bf0SSudarsana Reddy Kalluru 	}
144516f46bf0SSudarsana Reddy Kalluru }
144616f46bf0SSudarsana Reddy Kalluru 
144716f46bf0SSudarsana Reddy Kalluru /* This function disables the NAPI and the interrupt generation on the device */
144816f46bf0SSudarsana Reddy Kalluru static void qede_netif_stop(struct qede_dev *edev)
144916f46bf0SSudarsana Reddy Kalluru {
145016f46bf0SSudarsana Reddy Kalluru 	int i;
145116f46bf0SSudarsana Reddy Kalluru 
14529a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
145316f46bf0SSudarsana Reddy Kalluru 		napi_disable(&edev->fp_array[i].napi);
145416f46bf0SSudarsana Reddy Kalluru 		/* Disable interrupts */
145516f46bf0SSudarsana Reddy Kalluru 		qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_DISABLE, 0);
145616f46bf0SSudarsana Reddy Kalluru 	}
145716f46bf0SSudarsana Reddy Kalluru }
145816f46bf0SSudarsana Reddy Kalluru 
145916f46bf0SSudarsana Reddy Kalluru static int qede_selftest_transmit_traffic(struct qede_dev *edev,
146016f46bf0SSudarsana Reddy Kalluru 					  struct sk_buff *skb)
146116f46bf0SSudarsana Reddy Kalluru {
14629a4d7e86SSudarsana Reddy Kalluru 	struct qede_tx_queue *txq = NULL;
146316f46bf0SSudarsana Reddy Kalluru 	struct eth_tx_1st_bd *first_bd;
146416f46bf0SSudarsana Reddy Kalluru 	dma_addr_t mapping;
146548848a06SManish Chopra 	int i, idx;
146648848a06SManish Chopra 	u16 val;
146716f46bf0SSudarsana Reddy Kalluru 
14689a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
14695e7baf0fSManish Chopra 		struct qede_fastpath *fp = &edev->fp_array[i];
14705e7baf0fSManish Chopra 
14715e7baf0fSManish Chopra 		if (fp->type & QEDE_FASTPATH_TX) {
14725e7baf0fSManish Chopra 			txq = QEDE_FP_TC0_TXQ(fp);
14739a4d7e86SSudarsana Reddy Kalluru 			break;
14749a4d7e86SSudarsana Reddy Kalluru 		}
14759a4d7e86SSudarsana Reddy Kalluru 	}
14769a4d7e86SSudarsana Reddy Kalluru 
14779a4d7e86SSudarsana Reddy Kalluru 	if (!txq) {
14789a4d7e86SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Tx path is not available\n");
14799a4d7e86SSudarsana Reddy Kalluru 		return -1;
14809a4d7e86SSudarsana Reddy Kalluru 	}
14819a4d7e86SSudarsana Reddy Kalluru 
148216f46bf0SSudarsana Reddy Kalluru 	/* Fill the entry in the SW ring and the BDs in the FW ring */
14835a052d62SSudarsana Reddy Kalluru 	idx = txq->sw_tx_prod;
1484cb6aeb07SMintz, Yuval 	txq->sw_tx_ring.skbs[idx].skb = skb;
148516f46bf0SSudarsana Reddy Kalluru 	first_bd = qed_chain_produce(&txq->tx_pbl);
148616f46bf0SSudarsana Reddy Kalluru 	memset(first_bd, 0, sizeof(*first_bd));
148716f46bf0SSudarsana Reddy Kalluru 	val = 1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT;
148816f46bf0SSudarsana Reddy Kalluru 	first_bd->data.bd_flags.bitfields = val;
1489351a4dedSYuval Mintz 	val = skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK;
149048848a06SManish Chopra 	val = val << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT;
149148848a06SManish Chopra 	first_bd->data.bitfields |= cpu_to_le16(val);
149216f46bf0SSudarsana Reddy Kalluru 
149316f46bf0SSudarsana Reddy Kalluru 	/* Map skb linear data for DMA and set in the first BD */
149416f46bf0SSudarsana Reddy Kalluru 	mapping = dma_map_single(&edev->pdev->dev, skb->data,
149516f46bf0SSudarsana Reddy Kalluru 				 skb_headlen(skb), DMA_TO_DEVICE);
149616f46bf0SSudarsana Reddy Kalluru 	if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) {
149716f46bf0SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "SKB mapping failed\n");
149816f46bf0SSudarsana Reddy Kalluru 		return -ENOMEM;
149916f46bf0SSudarsana Reddy Kalluru 	}
150016f46bf0SSudarsana Reddy Kalluru 	BD_SET_UNMAP_ADDR_LEN(first_bd, mapping, skb_headlen(skb));
150116f46bf0SSudarsana Reddy Kalluru 
150216f46bf0SSudarsana Reddy Kalluru 	/* update the first BD with the actual num BDs */
150316f46bf0SSudarsana Reddy Kalluru 	first_bd->data.nbds = 1;
15045a052d62SSudarsana Reddy Kalluru 	txq->sw_tx_prod = (txq->sw_tx_prod + 1) % txq->num_tx_buffers;
150516f46bf0SSudarsana Reddy Kalluru 	/* 'next page' entries are counted in the producer value */
150648848a06SManish Chopra 	val = qed_chain_get_prod_idx(&txq->tx_pbl);
150748848a06SManish Chopra 	txq->tx_db.data.bd_prod = cpu_to_le16(val);
150816f46bf0SSudarsana Reddy Kalluru 
150916f46bf0SSudarsana Reddy Kalluru 	/* wmb makes sure that the BDs data is updated before updating the
151016f46bf0SSudarsana Reddy Kalluru 	 * producer, otherwise FW may read old data from the BDs.
151116f46bf0SSudarsana Reddy Kalluru 	 */
151216f46bf0SSudarsana Reddy Kalluru 	wmb();
151316f46bf0SSudarsana Reddy Kalluru 	barrier();
151416f46bf0SSudarsana Reddy Kalluru 	writel(txq->tx_db.raw, txq->doorbell_addr);
151516f46bf0SSudarsana Reddy Kalluru 
151616f46bf0SSudarsana Reddy Kalluru 	for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) {
151716f46bf0SSudarsana Reddy Kalluru 		if (qede_txq_has_work(txq))
151816f46bf0SSudarsana Reddy Kalluru 			break;
151916f46bf0SSudarsana Reddy Kalluru 		usleep_range(100, 200);
152016f46bf0SSudarsana Reddy Kalluru 	}
152116f46bf0SSudarsana Reddy Kalluru 
152216f46bf0SSudarsana Reddy Kalluru 	if (!qede_txq_has_work(txq)) {
152316f46bf0SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Tx completion didn't happen\n");
152416f46bf0SSudarsana Reddy Kalluru 		return -1;
152516f46bf0SSudarsana Reddy Kalluru 	}
152616f46bf0SSudarsana Reddy Kalluru 
152716f46bf0SSudarsana Reddy Kalluru 	first_bd = (struct eth_tx_1st_bd *)qed_chain_consume(&txq->tx_pbl);
1528fabd545cSManish Chopra 	dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
152916f46bf0SSudarsana Reddy Kalluru 			 BD_UNMAP_LEN(first_bd), DMA_TO_DEVICE);
15305a052d62SSudarsana Reddy Kalluru 	txq->sw_tx_cons = (txq->sw_tx_cons + 1) % txq->num_tx_buffers;
1531cb6aeb07SMintz, Yuval 	txq->sw_tx_ring.skbs[idx].skb = NULL;
153216f46bf0SSudarsana Reddy Kalluru 
153316f46bf0SSudarsana Reddy Kalluru 	return 0;
153416f46bf0SSudarsana Reddy Kalluru }
153516f46bf0SSudarsana Reddy Kalluru 
153616f46bf0SSudarsana Reddy Kalluru static int qede_selftest_receive_traffic(struct qede_dev *edev)
153716f46bf0SSudarsana Reddy Kalluru {
153810ee4b87SZheng Zengkai 	u16 sw_rx_index, len;
153916f46bf0SSudarsana Reddy Kalluru 	struct eth_fast_path_rx_reg_cqe *fp_cqe;
15409a4d7e86SSudarsana Reddy Kalluru 	struct qede_rx_queue *rxq = NULL;
154116f46bf0SSudarsana Reddy Kalluru 	struct sw_rx_data *sw_rx_data;
154216f46bf0SSudarsana Reddy Kalluru 	union eth_rx_cqe *cqe;
1543afe981d6SSudarsana Reddy Kalluru 	int i, iter, rc = 0;
154416f46bf0SSudarsana Reddy Kalluru 	u8 *data_ptr;
154516f46bf0SSudarsana Reddy Kalluru 
15469a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
15479a4d7e86SSudarsana Reddy Kalluru 		if (edev->fp_array[i].type & QEDE_FASTPATH_RX) {
15489a4d7e86SSudarsana Reddy Kalluru 			rxq = edev->fp_array[i].rxq;
15499a4d7e86SSudarsana Reddy Kalluru 			break;
15509a4d7e86SSudarsana Reddy Kalluru 		}
15519a4d7e86SSudarsana Reddy Kalluru 	}
15529a4d7e86SSudarsana Reddy Kalluru 
15539a4d7e86SSudarsana Reddy Kalluru 	if (!rxq) {
15549a4d7e86SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Rx path is not available\n");
15559a4d7e86SSudarsana Reddy Kalluru 		return -1;
15569a4d7e86SSudarsana Reddy Kalluru 	}
15579a4d7e86SSudarsana Reddy Kalluru 
155816f46bf0SSudarsana Reddy Kalluru 	/* The packet is expected to receive on rx-queue 0 even though RSS is
155916f46bf0SSudarsana Reddy Kalluru 	 * enabled. This is because the queue 0 is configured as the default
156016f46bf0SSudarsana Reddy Kalluru 	 * queue and that the loopback traffic is not IP.
156116f46bf0SSudarsana Reddy Kalluru 	 */
1562afe981d6SSudarsana Reddy Kalluru 	for (iter = 0; iter < QEDE_SELFTEST_POLL_COUNT; iter++) {
156316f46bf0SSudarsana Reddy Kalluru 		if (!qede_has_rx_work(rxq)) {
1564837d4eb6SSudarsana Reddy Kalluru 			usleep_range(100, 200);
1565837d4eb6SSudarsana Reddy Kalluru 			continue;
156616f46bf0SSudarsana Reddy Kalluru 		}
156716f46bf0SSudarsana Reddy Kalluru 
156816f46bf0SSudarsana Reddy Kalluru 		/* Get the CQE from the completion ring */
156916f46bf0SSudarsana Reddy Kalluru 		cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring);
157016f46bf0SSudarsana Reddy Kalluru 
157116f46bf0SSudarsana Reddy Kalluru 		/* Get the data from the SW ring */
157216f46bf0SSudarsana Reddy Kalluru 		sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
157316f46bf0SSudarsana Reddy Kalluru 		sw_rx_data = &rxq->sw_rx_ring[sw_rx_index];
157416f46bf0SSudarsana Reddy Kalluru 		fp_cqe = &cqe->fast_path_regular;
157516f46bf0SSudarsana Reddy Kalluru 		len =  le16_to_cpu(fp_cqe->len_on_first_bd);
157616f46bf0SSudarsana Reddy Kalluru 		data_ptr = (u8 *)(page_address(sw_rx_data->data) +
1577837d4eb6SSudarsana Reddy Kalluru 				  fp_cqe->placement_offset +
15788a863397SManish Chopra 				  sw_rx_data->page_offset +
15798a863397SManish Chopra 				  rxq->rx_headroom);
1580837d4eb6SSudarsana Reddy Kalluru 		if (ether_addr_equal(data_ptr,  edev->ndev->dev_addr) &&
1581837d4eb6SSudarsana Reddy Kalluru 		    ether_addr_equal(data_ptr + ETH_ALEN,
1582837d4eb6SSudarsana Reddy Kalluru 				     edev->ndev->dev_addr)) {
158316f46bf0SSudarsana Reddy Kalluru 			for (i = ETH_HLEN; i < len; i++)
158416f46bf0SSudarsana Reddy Kalluru 				if (data_ptr[i] != (unsigned char)(i & 0xff)) {
1585837d4eb6SSudarsana Reddy Kalluru 					rc = -1;
1586837d4eb6SSudarsana Reddy Kalluru 					break;
158716f46bf0SSudarsana Reddy Kalluru 				}
158816f46bf0SSudarsana Reddy Kalluru 
15899eb22357SMintz, Yuval 			qede_recycle_rx_bd_ring(rxq, 1);
1590837d4eb6SSudarsana Reddy Kalluru 			qed_chain_recycle_consumed(&rxq->rx_comp_ring);
1591837d4eb6SSudarsana Reddy Kalluru 			break;
1592837d4eb6SSudarsana Reddy Kalluru 		}
159316f46bf0SSudarsana Reddy Kalluru 
1594837d4eb6SSudarsana Reddy Kalluru 		DP_INFO(edev, "Not the transmitted packet\n");
15959eb22357SMintz, Yuval 		qede_recycle_rx_bd_ring(rxq, 1);
1596837d4eb6SSudarsana Reddy Kalluru 		qed_chain_recycle_consumed(&rxq->rx_comp_ring);
1597837d4eb6SSudarsana Reddy Kalluru 	}
1598837d4eb6SSudarsana Reddy Kalluru 
1599afe981d6SSudarsana Reddy Kalluru 	if (iter == QEDE_SELFTEST_POLL_COUNT) {
1600837d4eb6SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Failed to receive the traffic\n");
1601837d4eb6SSudarsana Reddy Kalluru 		return -1;
1602837d4eb6SSudarsana Reddy Kalluru 	}
1603837d4eb6SSudarsana Reddy Kalluru 
1604837d4eb6SSudarsana Reddy Kalluru 	qede_update_rx_prod(edev, rxq);
1605837d4eb6SSudarsana Reddy Kalluru 
1606837d4eb6SSudarsana Reddy Kalluru 	return rc;
160716f46bf0SSudarsana Reddy Kalluru }
160816f46bf0SSudarsana Reddy Kalluru 
160916f46bf0SSudarsana Reddy Kalluru static int qede_selftest_run_loopback(struct qede_dev *edev, u32 loopback_mode)
161016f46bf0SSudarsana Reddy Kalluru {
161116f46bf0SSudarsana Reddy Kalluru 	struct qed_link_params link_params;
161216f46bf0SSudarsana Reddy Kalluru 	struct sk_buff *skb = NULL;
161316f46bf0SSudarsana Reddy Kalluru 	int rc = 0, i;
161416f46bf0SSudarsana Reddy Kalluru 	u32 pkt_size;
161516f46bf0SSudarsana Reddy Kalluru 	u8 *packet;
161616f46bf0SSudarsana Reddy Kalluru 
161716f46bf0SSudarsana Reddy Kalluru 	if (!netif_running(edev->ndev)) {
161816f46bf0SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Interface is down\n");
161916f46bf0SSudarsana Reddy Kalluru 		return -EINVAL;
162016f46bf0SSudarsana Reddy Kalluru 	}
162116f46bf0SSudarsana Reddy Kalluru 
162216f46bf0SSudarsana Reddy Kalluru 	qede_netif_stop(edev);
162316f46bf0SSudarsana Reddy Kalluru 
162416f46bf0SSudarsana Reddy Kalluru 	/* Bring up the link in Loopback mode */
162516f46bf0SSudarsana Reddy Kalluru 	memset(&link_params, 0, sizeof(link_params));
162616f46bf0SSudarsana Reddy Kalluru 	link_params.link_up = true;
162716f46bf0SSudarsana Reddy Kalluru 	link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE;
162816f46bf0SSudarsana Reddy Kalluru 	link_params.loopback_mode = loopback_mode;
162916f46bf0SSudarsana Reddy Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
163016f46bf0SSudarsana Reddy Kalluru 
163116f46bf0SSudarsana Reddy Kalluru 	/* Wait for loopback configuration to apply */
163216f46bf0SSudarsana Reddy Kalluru 	msleep_interruptible(500);
163316f46bf0SSudarsana Reddy Kalluru 
1634b89869daSSudarsana Reddy Kalluru 	/* Setting max packet size to 1.5K to avoid data being split over
1635b89869daSSudarsana Reddy Kalluru 	 * multiple BDs in cases where MTU > PAGE_SIZE.
1636b89869daSSudarsana Reddy Kalluru 	 */
1637b89869daSSudarsana Reddy Kalluru 	pkt_size = (((edev->ndev->mtu < ETH_DATA_LEN) ?
1638b89869daSSudarsana Reddy Kalluru 		     edev->ndev->mtu : ETH_DATA_LEN) + ETH_HLEN);
163916f46bf0SSudarsana Reddy Kalluru 
164016f46bf0SSudarsana Reddy Kalluru 	skb = netdev_alloc_skb(edev->ndev, pkt_size);
164116f46bf0SSudarsana Reddy Kalluru 	if (!skb) {
164216f46bf0SSudarsana Reddy Kalluru 		DP_INFO(edev, "Can't allocate skb\n");
164316f46bf0SSudarsana Reddy Kalluru 		rc = -ENOMEM;
164416f46bf0SSudarsana Reddy Kalluru 		goto test_loopback_exit;
164516f46bf0SSudarsana Reddy Kalluru 	}
164616f46bf0SSudarsana Reddy Kalluru 	packet = skb_put(skb, pkt_size);
164716f46bf0SSudarsana Reddy Kalluru 	ether_addr_copy(packet, edev->ndev->dev_addr);
164816f46bf0SSudarsana Reddy Kalluru 	ether_addr_copy(packet + ETH_ALEN, edev->ndev->dev_addr);
164916f46bf0SSudarsana Reddy Kalluru 	memset(packet + (2 * ETH_ALEN), 0x77, (ETH_HLEN - (2 * ETH_ALEN)));
165016f46bf0SSudarsana Reddy Kalluru 	for (i = ETH_HLEN; i < pkt_size; i++)
165116f46bf0SSudarsana Reddy Kalluru 		packet[i] = (unsigned char)(i & 0xff);
165216f46bf0SSudarsana Reddy Kalluru 
165316f46bf0SSudarsana Reddy Kalluru 	rc = qede_selftest_transmit_traffic(edev, skb);
165416f46bf0SSudarsana Reddy Kalluru 	if (rc)
165516f46bf0SSudarsana Reddy Kalluru 		goto test_loopback_exit;
165616f46bf0SSudarsana Reddy Kalluru 
165716f46bf0SSudarsana Reddy Kalluru 	rc = qede_selftest_receive_traffic(edev);
165816f46bf0SSudarsana Reddy Kalluru 	if (rc)
165916f46bf0SSudarsana Reddy Kalluru 		goto test_loopback_exit;
166016f46bf0SSudarsana Reddy Kalluru 
166116f46bf0SSudarsana Reddy Kalluru 	DP_VERBOSE(edev, NETIF_MSG_RX_STATUS, "Loopback test successful\n");
166216f46bf0SSudarsana Reddy Kalluru 
166316f46bf0SSudarsana Reddy Kalluru test_loopback_exit:
166416f46bf0SSudarsana Reddy Kalluru 	dev_kfree_skb(skb);
166516f46bf0SSudarsana Reddy Kalluru 
166616f46bf0SSudarsana Reddy Kalluru 	/* Bring up the link in Normal mode */
166716f46bf0SSudarsana Reddy Kalluru 	memset(&link_params, 0, sizeof(link_params));
166816f46bf0SSudarsana Reddy Kalluru 	link_params.link_up = true;
166916f46bf0SSudarsana Reddy Kalluru 	link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE;
167016f46bf0SSudarsana Reddy Kalluru 	link_params.loopback_mode = QED_LINK_LOOPBACK_NONE;
167116f46bf0SSudarsana Reddy Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
167216f46bf0SSudarsana Reddy Kalluru 
167316f46bf0SSudarsana Reddy Kalluru 	/* Wait for loopback configuration to apply */
167416f46bf0SSudarsana Reddy Kalluru 	msleep_interruptible(500);
167516f46bf0SSudarsana Reddy Kalluru 
167616f46bf0SSudarsana Reddy Kalluru 	qede_netif_start(edev);
167716f46bf0SSudarsana Reddy Kalluru 
167816f46bf0SSudarsana Reddy Kalluru 	return rc;
167916f46bf0SSudarsana Reddy Kalluru }
168016f46bf0SSudarsana Reddy Kalluru 
16813044a02eSSudarsana Reddy Kalluru static void qede_self_test(struct net_device *dev,
16823044a02eSSudarsana Reddy Kalluru 			   struct ethtool_test *etest, u64 *buf)
16833044a02eSSudarsana Reddy Kalluru {
16843044a02eSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
16853044a02eSSudarsana Reddy Kalluru 
16863044a02eSSudarsana Reddy Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
16873044a02eSSudarsana Reddy Kalluru 		   "Self-test command parameters: offline = %d, external_lb = %d\n",
16883044a02eSSudarsana Reddy Kalluru 		   (etest->flags & ETH_TEST_FL_OFFLINE),
16893044a02eSSudarsana Reddy Kalluru 		   (etest->flags & ETH_TEST_FL_EXTERNAL_LB) >> 2);
16903044a02eSSudarsana Reddy Kalluru 
16913044a02eSSudarsana Reddy Kalluru 	memset(buf, 0, sizeof(u64) * QEDE_ETHTOOL_TEST_MAX);
16923044a02eSSudarsana Reddy Kalluru 
169316f46bf0SSudarsana Reddy Kalluru 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
169416f46bf0SSudarsana Reddy Kalluru 		if (qede_selftest_run_loopback(edev,
169516f46bf0SSudarsana Reddy Kalluru 					       QED_LINK_LOOPBACK_INT_PHY)) {
169616f46bf0SSudarsana Reddy Kalluru 			buf[QEDE_ETHTOOL_INT_LOOPBACK] = 1;
169716f46bf0SSudarsana Reddy Kalluru 			etest->flags |= ETH_TEST_FL_FAILED;
169816f46bf0SSudarsana Reddy Kalluru 		}
169916f46bf0SSudarsana Reddy Kalluru 	}
170016f46bf0SSudarsana Reddy Kalluru 
17013044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_interrupt(edev->cdev)) {
17023044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_INTERRUPT_TEST] = 1;
17033044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17043044a02eSSudarsana Reddy Kalluru 	}
17053044a02eSSudarsana Reddy Kalluru 
17063044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_memory(edev->cdev)) {
17073044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_MEMORY_TEST] = 1;
17083044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17093044a02eSSudarsana Reddy Kalluru 	}
17103044a02eSSudarsana Reddy Kalluru 
17113044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_register(edev->cdev)) {
17123044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_REGISTER_TEST] = 1;
17133044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17143044a02eSSudarsana Reddy Kalluru 	}
17153044a02eSSudarsana Reddy Kalluru 
17163044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_clock(edev->cdev)) {
17173044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_CLOCK_TEST] = 1;
17183044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17193044a02eSSudarsana Reddy Kalluru 	}
17207a4b21b7SMintz, Yuval 
17217a4b21b7SMintz, Yuval 	if (edev->ops->common->selftest->selftest_nvram(edev->cdev)) {
17227a4b21b7SMintz, Yuval 		buf[QEDE_ETHTOOL_NVRAM_TEST] = 1;
17237a4b21b7SMintz, Yuval 		etest->flags |= ETH_TEST_FL_FAILED;
17247a4b21b7SMintz, Yuval 	}
17253044a02eSSudarsana Reddy Kalluru }
17263044a02eSSudarsana Reddy Kalluru 
17273d789994SManish Chopra static int qede_set_tunable(struct net_device *dev,
17283d789994SManish Chopra 			    const struct ethtool_tunable *tuna,
17293d789994SManish Chopra 			    const void *data)
17303d789994SManish Chopra {
17313d789994SManish Chopra 	struct qede_dev *edev = netdev_priv(dev);
17323d789994SManish Chopra 	u32 val;
17333d789994SManish Chopra 
17343d789994SManish Chopra 	switch (tuna->id) {
17353d789994SManish Chopra 	case ETHTOOL_RX_COPYBREAK:
17363d789994SManish Chopra 		val = *(u32 *)data;
17373d789994SManish Chopra 		if (val < QEDE_MIN_PKT_LEN || val > QEDE_RX_HDR_SIZE) {
17383d789994SManish Chopra 			DP_VERBOSE(edev, QED_MSG_DEBUG,
17393d789994SManish Chopra 				   "Invalid rx copy break value, range is [%u, %u]",
17403d789994SManish Chopra 				   QEDE_MIN_PKT_LEN, QEDE_RX_HDR_SIZE);
17413d789994SManish Chopra 			return -EINVAL;
17423d789994SManish Chopra 		}
17433d789994SManish Chopra 
17443d789994SManish Chopra 		edev->rx_copybreak = *(u32 *)data;
17453d789994SManish Chopra 		break;
17463d789994SManish Chopra 	default:
17473d789994SManish Chopra 		return -EOPNOTSUPP;
17483d789994SManish Chopra 	}
17493d789994SManish Chopra 
17503d789994SManish Chopra 	return 0;
17513d789994SManish Chopra }
17523d789994SManish Chopra 
17533d789994SManish Chopra static int qede_get_tunable(struct net_device *dev,
17543d789994SManish Chopra 			    const struct ethtool_tunable *tuna, void *data)
17553d789994SManish Chopra {
17563d789994SManish Chopra 	struct qede_dev *edev = netdev_priv(dev);
17573d789994SManish Chopra 
17583d789994SManish Chopra 	switch (tuna->id) {
17593d789994SManish Chopra 	case ETHTOOL_RX_COPYBREAK:
17603d789994SManish Chopra 		*(u32 *)data = edev->rx_copybreak;
17613d789994SManish Chopra 		break;
17623d789994SManish Chopra 	default:
17633d789994SManish Chopra 		return -EOPNOTSUPP;
17643d789994SManish Chopra 	}
17653d789994SManish Chopra 
17663d789994SManish Chopra 	return 0;
17673d789994SManish Chopra }
17683d789994SManish Chopra 
1769c3dc48f7SSudarsana Reddy Kalluru static int qede_get_eee(struct net_device *dev, struct ethtool_eee *edata)
1770c3dc48f7SSudarsana Reddy Kalluru {
1771c3dc48f7SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1772c3dc48f7SSudarsana Reddy Kalluru 	struct qed_link_output current_link;
1773c3dc48f7SSudarsana Reddy Kalluru 
1774c3dc48f7SSudarsana Reddy Kalluru 	memset(&current_link, 0, sizeof(current_link));
1775c3dc48f7SSudarsana Reddy Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
1776c3dc48f7SSudarsana Reddy Kalluru 
1777c3dc48f7SSudarsana Reddy Kalluru 	if (!current_link.eee_supported) {
1778c3dc48f7SSudarsana Reddy Kalluru 		DP_INFO(edev, "EEE is not supported\n");
1779c3dc48f7SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1780c3dc48f7SSudarsana Reddy Kalluru 	}
1781c3dc48f7SSudarsana Reddy Kalluru 
1782c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.adv_caps & QED_EEE_1G_ADV)
1783c3dc48f7SSudarsana Reddy Kalluru 		edata->advertised = ADVERTISED_1000baseT_Full;
1784c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.adv_caps & QED_EEE_10G_ADV)
1785c3dc48f7SSudarsana Reddy Kalluru 		edata->advertised |= ADVERTISED_10000baseT_Full;
1786c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.sup_caps & QED_EEE_1G_ADV)
1787c3dc48f7SSudarsana Reddy Kalluru 		edata->supported = ADVERTISED_1000baseT_Full;
1788c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.sup_caps & QED_EEE_10G_ADV)
1789c3dc48f7SSudarsana Reddy Kalluru 		edata->supported |= ADVERTISED_10000baseT_Full;
1790c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.lp_adv_caps & QED_EEE_1G_ADV)
1791c3dc48f7SSudarsana Reddy Kalluru 		edata->lp_advertised = ADVERTISED_1000baseT_Full;
1792c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.lp_adv_caps & QED_EEE_10G_ADV)
1793c3dc48f7SSudarsana Reddy Kalluru 		edata->lp_advertised |= ADVERTISED_10000baseT_Full;
1794c3dc48f7SSudarsana Reddy Kalluru 
1795c3dc48f7SSudarsana Reddy Kalluru 	edata->tx_lpi_timer = current_link.eee.tx_lpi_timer;
1796c3dc48f7SSudarsana Reddy Kalluru 	edata->eee_enabled = current_link.eee.enable;
1797c3dc48f7SSudarsana Reddy Kalluru 	edata->tx_lpi_enabled = current_link.eee.tx_lpi_enable;
1798c3dc48f7SSudarsana Reddy Kalluru 	edata->eee_active = current_link.eee_active;
1799c3dc48f7SSudarsana Reddy Kalluru 
1800c3dc48f7SSudarsana Reddy Kalluru 	return 0;
1801c3dc48f7SSudarsana Reddy Kalluru }
1802c3dc48f7SSudarsana Reddy Kalluru 
1803c3dc48f7SSudarsana Reddy Kalluru static int qede_set_eee(struct net_device *dev, struct ethtool_eee *edata)
1804c3dc48f7SSudarsana Reddy Kalluru {
1805c3dc48f7SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1806c3dc48f7SSudarsana Reddy Kalluru 	struct qed_link_output current_link;
1807c3dc48f7SSudarsana Reddy Kalluru 	struct qed_link_params params;
1808c3dc48f7SSudarsana Reddy Kalluru 
1809c3dc48f7SSudarsana Reddy Kalluru 	if (!edev->ops->common->can_link_change(edev->cdev)) {
1810c3dc48f7SSudarsana Reddy Kalluru 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
1811c3dc48f7SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1812c3dc48f7SSudarsana Reddy Kalluru 	}
1813c3dc48f7SSudarsana Reddy Kalluru 
1814c3dc48f7SSudarsana Reddy Kalluru 	memset(&current_link, 0, sizeof(current_link));
1815c3dc48f7SSudarsana Reddy Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
1816c3dc48f7SSudarsana Reddy Kalluru 
1817c3dc48f7SSudarsana Reddy Kalluru 	if (!current_link.eee_supported) {
1818c3dc48f7SSudarsana Reddy Kalluru 		DP_INFO(edev, "EEE is not supported\n");
1819c3dc48f7SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1820c3dc48f7SSudarsana Reddy Kalluru 	}
1821c3dc48f7SSudarsana Reddy Kalluru 
1822c3dc48f7SSudarsana Reddy Kalluru 	memset(&params, 0, sizeof(params));
1823c3dc48f7SSudarsana Reddy Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_EEE_CONFIG;
1824c3dc48f7SSudarsana Reddy Kalluru 
1825c3dc48f7SSudarsana Reddy Kalluru 	if (!(edata->advertised & (ADVERTISED_1000baseT_Full |
1826c3dc48f7SSudarsana Reddy Kalluru 				   ADVERTISED_10000baseT_Full)) ||
1827c3dc48f7SSudarsana Reddy Kalluru 	    ((edata->advertised & (ADVERTISED_1000baseT_Full |
1828c3dc48f7SSudarsana Reddy Kalluru 				   ADVERTISED_10000baseT_Full)) !=
1829c3dc48f7SSudarsana Reddy Kalluru 	     edata->advertised)) {
1830c3dc48f7SSudarsana Reddy Kalluru 		DP_VERBOSE(edev, QED_MSG_DEBUG,
1831c3dc48f7SSudarsana Reddy Kalluru 			   "Invalid advertised capabilities %d\n",
1832c3dc48f7SSudarsana Reddy Kalluru 			   edata->advertised);
1833c3dc48f7SSudarsana Reddy Kalluru 		return -EINVAL;
1834c3dc48f7SSudarsana Reddy Kalluru 	}
1835c3dc48f7SSudarsana Reddy Kalluru 
1836c3dc48f7SSudarsana Reddy Kalluru 	if (edata->advertised & ADVERTISED_1000baseT_Full)
1837c3dc48f7SSudarsana Reddy Kalluru 		params.eee.adv_caps = QED_EEE_1G_ADV;
1838c3dc48f7SSudarsana Reddy Kalluru 	if (edata->advertised & ADVERTISED_10000baseT_Full)
1839c3dc48f7SSudarsana Reddy Kalluru 		params.eee.adv_caps |= QED_EEE_10G_ADV;
1840c3dc48f7SSudarsana Reddy Kalluru 	params.eee.enable = edata->eee_enabled;
1841c3dc48f7SSudarsana Reddy Kalluru 	params.eee.tx_lpi_enable = edata->tx_lpi_enabled;
1842c3dc48f7SSudarsana Reddy Kalluru 	params.eee.tx_lpi_timer = edata->tx_lpi_timer;
1843c3dc48f7SSudarsana Reddy Kalluru 
1844c3dc48f7SSudarsana Reddy Kalluru 	params.link_up = true;
1845c3dc48f7SSudarsana Reddy Kalluru 	edev->ops->common->set_link(edev->cdev, &params);
1846c3dc48f7SSudarsana Reddy Kalluru 
1847c3dc48f7SSudarsana Reddy Kalluru 	return 0;
1848c3dc48f7SSudarsana Reddy Kalluru }
1849c3dc48f7SSudarsana Reddy Kalluru 
18509bdca14aSAlexander Lobakin static u32 qede_link_to_ethtool_fec(u32 link_fec)
18519bdca14aSAlexander Lobakin {
18529bdca14aSAlexander Lobakin 	u32 eth_fec = 0;
18539bdca14aSAlexander Lobakin 
18549bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_NONE)
18559bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_OFF;
18569bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_FIRECODE)
18579bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_BASER;
18589bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_RS)
18599bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_RS;
18609bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_AUTO)
18619bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_AUTO;
18629bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_UNSUPPORTED)
18639bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_NONE;
18649bdca14aSAlexander Lobakin 
18659bdca14aSAlexander Lobakin 	return eth_fec;
18669bdca14aSAlexander Lobakin }
18679bdca14aSAlexander Lobakin 
18689bdca14aSAlexander Lobakin static u32 qede_ethtool_to_link_fec(u32 eth_fec)
18699bdca14aSAlexander Lobakin {
18709bdca14aSAlexander Lobakin 	u32 link_fec = 0;
18719bdca14aSAlexander Lobakin 
18729bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_OFF)
18739bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_NONE;
18749bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_BASER)
18759bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_FIRECODE;
18769bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_RS)
18779bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_RS;
18789bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_AUTO)
18799bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_AUTO;
18809bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_NONE)
18819bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_UNSUPPORTED;
18829bdca14aSAlexander Lobakin 
18839bdca14aSAlexander Lobakin 	return link_fec;
18849bdca14aSAlexander Lobakin }
18859bdca14aSAlexander Lobakin 
18869bdca14aSAlexander Lobakin static int qede_get_fecparam(struct net_device *dev,
18879bdca14aSAlexander Lobakin 			     struct ethtool_fecparam *fecparam)
18889bdca14aSAlexander Lobakin {
18899bdca14aSAlexander Lobakin 	struct qede_dev *edev = netdev_priv(dev);
18909bdca14aSAlexander Lobakin 	struct qed_link_output curr_link;
18919bdca14aSAlexander Lobakin 
18929bdca14aSAlexander Lobakin 	memset(&curr_link, 0, sizeof(curr_link));
18939bdca14aSAlexander Lobakin 	edev->ops->common->get_link(edev->cdev, &curr_link);
18949bdca14aSAlexander Lobakin 
18959bdca14aSAlexander Lobakin 	fecparam->active_fec = qede_link_to_ethtool_fec(curr_link.active_fec);
18969bdca14aSAlexander Lobakin 	fecparam->fec = qede_link_to_ethtool_fec(curr_link.sup_fec);
18979bdca14aSAlexander Lobakin 
18989bdca14aSAlexander Lobakin 	return 0;
18999bdca14aSAlexander Lobakin }
19009bdca14aSAlexander Lobakin 
19019bdca14aSAlexander Lobakin static int qede_set_fecparam(struct net_device *dev,
19029bdca14aSAlexander Lobakin 			     struct ethtool_fecparam *fecparam)
19039bdca14aSAlexander Lobakin {
19049bdca14aSAlexander Lobakin 	struct qede_dev *edev = netdev_priv(dev);
19059bdca14aSAlexander Lobakin 	struct qed_link_params params;
19069bdca14aSAlexander Lobakin 
19079bdca14aSAlexander Lobakin 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
19089bdca14aSAlexander Lobakin 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
19099bdca14aSAlexander Lobakin 		return -EOPNOTSUPP;
19109bdca14aSAlexander Lobakin 	}
19119bdca14aSAlexander Lobakin 
19129bdca14aSAlexander Lobakin 	memset(&params, 0, sizeof(params));
19139bdca14aSAlexander Lobakin 	params.override_flags |= QED_LINK_OVERRIDE_FEC_CONFIG;
19149bdca14aSAlexander Lobakin 	params.fec = qede_ethtool_to_link_fec(fecparam->fec);
19159bdca14aSAlexander Lobakin 	params.link_up = true;
19169bdca14aSAlexander Lobakin 
19179bdca14aSAlexander Lobakin 	edev->ops->common->set_link(edev->cdev, &params);
19189bdca14aSAlexander Lobakin 
19199bdca14aSAlexander Lobakin 	return 0;
19209bdca14aSAlexander Lobakin }
19219bdca14aSAlexander Lobakin 
192297df0d65SSudarsana Reddy Kalluru static int qede_get_module_info(struct net_device *dev,
192397df0d65SSudarsana Reddy Kalluru 				struct ethtool_modinfo *modinfo)
192497df0d65SSudarsana Reddy Kalluru {
192597df0d65SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
192697df0d65SSudarsana Reddy Kalluru 	u8 buf[4];
192797df0d65SSudarsana Reddy Kalluru 	int rc;
192897df0d65SSudarsana Reddy Kalluru 
192997df0d65SSudarsana Reddy Kalluru 	/* Read first 4 bytes to find the sfp type */
193097df0d65SSudarsana Reddy Kalluru 	rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
193197df0d65SSudarsana Reddy Kalluru 						   QED_I2C_DEV_ADDR_A0, 0, 4);
193297df0d65SSudarsana Reddy Kalluru 	if (rc) {
193397df0d65SSudarsana Reddy Kalluru 		DP_ERR(edev, "Failed reading EEPROM data %d\n", rc);
193497df0d65SSudarsana Reddy Kalluru 		return rc;
193597df0d65SSudarsana Reddy Kalluru 	}
193697df0d65SSudarsana Reddy Kalluru 
193797df0d65SSudarsana Reddy Kalluru 	switch (buf[0]) {
193897df0d65SSudarsana Reddy Kalluru 	case 0x3: /* SFP, SFP+, SFP-28 */
193997df0d65SSudarsana Reddy Kalluru 		modinfo->type = ETH_MODULE_SFF_8472;
194097df0d65SSudarsana Reddy Kalluru 		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
194197df0d65SSudarsana Reddy Kalluru 		break;
194297df0d65SSudarsana Reddy Kalluru 	case 0xc: /* QSFP */
194397df0d65SSudarsana Reddy Kalluru 	case 0xd: /* QSFP+ */
194497df0d65SSudarsana Reddy Kalluru 		modinfo->type = ETH_MODULE_SFF_8436;
194597df0d65SSudarsana Reddy Kalluru 		modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
194697df0d65SSudarsana Reddy Kalluru 		break;
194797df0d65SSudarsana Reddy Kalluru 	case 0x11: /* QSFP-28 */
194897df0d65SSudarsana Reddy Kalluru 		modinfo->type = ETH_MODULE_SFF_8636;
194997df0d65SSudarsana Reddy Kalluru 		modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
195097df0d65SSudarsana Reddy Kalluru 		break;
195197df0d65SSudarsana Reddy Kalluru 	default:
195297df0d65SSudarsana Reddy Kalluru 		DP_ERR(edev, "Unknown transceiver type 0x%x\n", buf[0]);
195397df0d65SSudarsana Reddy Kalluru 		return -EINVAL;
195497df0d65SSudarsana Reddy Kalluru 	}
195597df0d65SSudarsana Reddy Kalluru 
195697df0d65SSudarsana Reddy Kalluru 	return 0;
195797df0d65SSudarsana Reddy Kalluru }
195897df0d65SSudarsana Reddy Kalluru 
195997df0d65SSudarsana Reddy Kalluru static int qede_get_module_eeprom(struct net_device *dev,
196097df0d65SSudarsana Reddy Kalluru 				  struct ethtool_eeprom *ee, u8 *data)
196197df0d65SSudarsana Reddy Kalluru {
196297df0d65SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
196397df0d65SSudarsana Reddy Kalluru 	u32 start_addr = ee->offset, size = 0;
196497df0d65SSudarsana Reddy Kalluru 	u8 *buf = data;
196597df0d65SSudarsana Reddy Kalluru 	int rc = 0;
196697df0d65SSudarsana Reddy Kalluru 
196797df0d65SSudarsana Reddy Kalluru 	/* Read A0 section */
196897df0d65SSudarsana Reddy Kalluru 	if (ee->offset < ETH_MODULE_SFF_8079_LEN) {
196997df0d65SSudarsana Reddy Kalluru 		/* Limit transfer size to the A0 section boundary */
197097df0d65SSudarsana Reddy Kalluru 		if (ee->offset + ee->len > ETH_MODULE_SFF_8079_LEN)
197197df0d65SSudarsana Reddy Kalluru 			size = ETH_MODULE_SFF_8079_LEN - ee->offset;
197297df0d65SSudarsana Reddy Kalluru 		else
197397df0d65SSudarsana Reddy Kalluru 			size = ee->len;
197497df0d65SSudarsana Reddy Kalluru 
197597df0d65SSudarsana Reddy Kalluru 		rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
197697df0d65SSudarsana Reddy Kalluru 							   QED_I2C_DEV_ADDR_A0,
197797df0d65SSudarsana Reddy Kalluru 							   start_addr, size);
197897df0d65SSudarsana Reddy Kalluru 		if (rc) {
197997df0d65SSudarsana Reddy Kalluru 			DP_ERR(edev, "Failed reading A0 section  %d\n", rc);
198097df0d65SSudarsana Reddy Kalluru 			return rc;
198197df0d65SSudarsana Reddy Kalluru 		}
198297df0d65SSudarsana Reddy Kalluru 
198397df0d65SSudarsana Reddy Kalluru 		buf += size;
198497df0d65SSudarsana Reddy Kalluru 		start_addr += size;
198597df0d65SSudarsana Reddy Kalluru 	}
198697df0d65SSudarsana Reddy Kalluru 
198797df0d65SSudarsana Reddy Kalluru 	/* Read A2 section */
198897df0d65SSudarsana Reddy Kalluru 	if (start_addr >= ETH_MODULE_SFF_8079_LEN &&
198997df0d65SSudarsana Reddy Kalluru 	    start_addr < ETH_MODULE_SFF_8472_LEN) {
199097df0d65SSudarsana Reddy Kalluru 		size = ee->len - size;
199197df0d65SSudarsana Reddy Kalluru 		/* Limit transfer size to the A2 section boundary */
199297df0d65SSudarsana Reddy Kalluru 		if (start_addr + size > ETH_MODULE_SFF_8472_LEN)
199397df0d65SSudarsana Reddy Kalluru 			size = ETH_MODULE_SFF_8472_LEN - start_addr;
199497df0d65SSudarsana Reddy Kalluru 		start_addr -= ETH_MODULE_SFF_8079_LEN;
199597df0d65SSudarsana Reddy Kalluru 		rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
199697df0d65SSudarsana Reddy Kalluru 							   QED_I2C_DEV_ADDR_A2,
199797df0d65SSudarsana Reddy Kalluru 							   start_addr, size);
199897df0d65SSudarsana Reddy Kalluru 		if (rc) {
199997df0d65SSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
200097df0d65SSudarsana Reddy Kalluru 				   "Failed reading A2 section %d\n", rc);
200197df0d65SSudarsana Reddy Kalluru 			return 0;
200297df0d65SSudarsana Reddy Kalluru 		}
200397df0d65SSudarsana Reddy Kalluru 	}
200497df0d65SSudarsana Reddy Kalluru 
200597df0d65SSudarsana Reddy Kalluru 	return rc;
200697df0d65SSudarsana Reddy Kalluru }
200797df0d65SSudarsana Reddy Kalluru 
2008d44a3cedSSudarsana Reddy Kalluru static int qede_set_dump(struct net_device *dev, struct ethtool_dump *val)
2009d44a3cedSSudarsana Reddy Kalluru {
2010d44a3cedSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
2011d44a3cedSSudarsana Reddy Kalluru 	int rc = 0;
2012d44a3cedSSudarsana Reddy Kalluru 
2013d44a3cedSSudarsana Reddy Kalluru 	if (edev->dump_info.cmd == QEDE_DUMP_CMD_NONE) {
2014d44a3cedSSudarsana Reddy Kalluru 		if (val->flag > QEDE_DUMP_CMD_MAX) {
2015d44a3cedSSudarsana Reddy Kalluru 			DP_ERR(edev, "Invalid command %d\n", val->flag);
2016d44a3cedSSudarsana Reddy Kalluru 			return -EINVAL;
2017d44a3cedSSudarsana Reddy Kalluru 		}
2018d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.cmd = val->flag;
2019d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.num_args = 0;
2020d44a3cedSSudarsana Reddy Kalluru 		return 0;
2021d44a3cedSSudarsana Reddy Kalluru 	}
2022d44a3cedSSudarsana Reddy Kalluru 
2023d44a3cedSSudarsana Reddy Kalluru 	if (edev->dump_info.num_args == QEDE_DUMP_MAX_ARGS) {
2024d44a3cedSSudarsana Reddy Kalluru 		DP_ERR(edev, "Arg count = %d\n", edev->dump_info.num_args);
2025d44a3cedSSudarsana Reddy Kalluru 		return -EINVAL;
2026d44a3cedSSudarsana Reddy Kalluru 	}
2027d44a3cedSSudarsana Reddy Kalluru 
2028d44a3cedSSudarsana Reddy Kalluru 	switch (edev->dump_info.cmd) {
2029d44a3cedSSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_NVM_CFG:
2030d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.args[edev->dump_info.num_args] = val->flag;
2031d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.num_args++;
2032d44a3cedSSudarsana Reddy Kalluru 		break;
2033849dbf09SSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_GRCDUMP:
2034849dbf09SSudarsana Reddy Kalluru 		rc = edev->ops->common->set_grc_config(edev->cdev,
2035849dbf09SSudarsana Reddy Kalluru 						       val->flag, 1);
2036849dbf09SSudarsana Reddy Kalluru 		break;
2037d44a3cedSSudarsana Reddy Kalluru 	default:
2038d44a3cedSSudarsana Reddy Kalluru 		break;
2039d44a3cedSSudarsana Reddy Kalluru 	}
2040d44a3cedSSudarsana Reddy Kalluru 
2041d44a3cedSSudarsana Reddy Kalluru 	return rc;
2042d44a3cedSSudarsana Reddy Kalluru }
2043d44a3cedSSudarsana Reddy Kalluru 
2044d44a3cedSSudarsana Reddy Kalluru static int qede_get_dump_flag(struct net_device *dev,
2045d44a3cedSSudarsana Reddy Kalluru 			      struct ethtool_dump *dump)
2046d44a3cedSSudarsana Reddy Kalluru {
2047d44a3cedSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
2048d44a3cedSSudarsana Reddy Kalluru 
2049849dbf09SSudarsana Reddy Kalluru 	if (!edev->ops || !edev->ops->common) {
2050849dbf09SSudarsana Reddy Kalluru 		DP_ERR(edev, "Edev ops not populated\n");
2051849dbf09SSudarsana Reddy Kalluru 		return -EINVAL;
2052849dbf09SSudarsana Reddy Kalluru 	}
2053849dbf09SSudarsana Reddy Kalluru 
2054d44a3cedSSudarsana Reddy Kalluru 	dump->version = QEDE_DUMP_VERSION;
2055d44a3cedSSudarsana Reddy Kalluru 	switch (edev->dump_info.cmd) {
2056d44a3cedSSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_NVM_CFG:
2057d44a3cedSSudarsana Reddy Kalluru 		dump->flag = QEDE_DUMP_CMD_NVM_CFG;
20589e54ba7cSSudarsana Reddy Kalluru 		dump->len = edev->ops->common->read_nvm_cfg_len(edev->cdev,
20599e54ba7cSSudarsana Reddy Kalluru 						edev->dump_info.args[0]);
2060d44a3cedSSudarsana Reddy Kalluru 		break;
2061849dbf09SSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_GRCDUMP:
2062849dbf09SSudarsana Reddy Kalluru 		dump->flag = QEDE_DUMP_CMD_GRCDUMP;
2063849dbf09SSudarsana Reddy Kalluru 		dump->len = edev->ops->common->dbg_all_data_size(edev->cdev);
2064d44a3cedSSudarsana Reddy Kalluru 		break;
2065849dbf09SSudarsana Reddy Kalluru 	default:
2066849dbf09SSudarsana Reddy Kalluru 		DP_ERR(edev, "Invalid cmd = %d\n", edev->dump_info.cmd);
2067849dbf09SSudarsana Reddy Kalluru 		return -EINVAL;
2068d44a3cedSSudarsana Reddy Kalluru 	}
2069d44a3cedSSudarsana Reddy Kalluru 
2070d44a3cedSSudarsana Reddy Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
2071d44a3cedSSudarsana Reddy Kalluru 		   "dump->version = 0x%x dump->flag = %d dump->len = %d\n",
2072d44a3cedSSudarsana Reddy Kalluru 		   dump->version, dump->flag, dump->len);
2073d44a3cedSSudarsana Reddy Kalluru 	return 0;
2074d44a3cedSSudarsana Reddy Kalluru }
2075d44a3cedSSudarsana Reddy Kalluru 
2076d44a3cedSSudarsana Reddy Kalluru static int qede_get_dump_data(struct net_device *dev,
2077d44a3cedSSudarsana Reddy Kalluru 			      struct ethtool_dump *dump, void *buf)
2078d44a3cedSSudarsana Reddy Kalluru {
2079d44a3cedSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
2080849dbf09SSudarsana Reddy Kalluru 	int rc = 0;
2081849dbf09SSudarsana Reddy Kalluru 
2082849dbf09SSudarsana Reddy Kalluru 	if (!edev->ops || !edev->ops->common) {
2083849dbf09SSudarsana Reddy Kalluru 		DP_ERR(edev, "Edev ops not populated\n");
20849e54ba7cSSudarsana Reddy Kalluru 		rc = -EINVAL;
20859e54ba7cSSudarsana Reddy Kalluru 		goto err;
2086849dbf09SSudarsana Reddy Kalluru 	}
2087d44a3cedSSudarsana Reddy Kalluru 
2088d44a3cedSSudarsana Reddy Kalluru 	switch (edev->dump_info.cmd) {
2089d44a3cedSSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_NVM_CFG:
2090d44a3cedSSudarsana Reddy Kalluru 		if (edev->dump_info.num_args != QEDE_DUMP_NVM_ARG_COUNT) {
2091d44a3cedSSudarsana Reddy Kalluru 			DP_ERR(edev, "Arg count = %d required = %d\n",
2092d44a3cedSSudarsana Reddy Kalluru 			       edev->dump_info.num_args,
2093d44a3cedSSudarsana Reddy Kalluru 			       QEDE_DUMP_NVM_ARG_COUNT);
20949e54ba7cSSudarsana Reddy Kalluru 			rc = -EINVAL;
20959e54ba7cSSudarsana Reddy Kalluru 			goto err;
2096d44a3cedSSudarsana Reddy Kalluru 		}
2097d44a3cedSSudarsana Reddy Kalluru 		rc =  edev->ops->common->read_nvm_cfg(edev->cdev, (u8 **)&buf,
2098d44a3cedSSudarsana Reddy Kalluru 						      edev->dump_info.args[0],
2099d44a3cedSSudarsana Reddy Kalluru 						      edev->dump_info.args[1]);
2100d44a3cedSSudarsana Reddy Kalluru 		break;
2101849dbf09SSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_GRCDUMP:
2102849dbf09SSudarsana Reddy Kalluru 		memset(buf, 0, dump->len);
2103849dbf09SSudarsana Reddy Kalluru 		rc = edev->ops->common->dbg_all_data(edev->cdev, buf);
2104849dbf09SSudarsana Reddy Kalluru 		break;
2105d44a3cedSSudarsana Reddy Kalluru 	default:
2106d44a3cedSSudarsana Reddy Kalluru 		DP_ERR(edev, "Invalid cmd = %d\n", edev->dump_info.cmd);
2107d44a3cedSSudarsana Reddy Kalluru 		rc = -EINVAL;
2108d44a3cedSSudarsana Reddy Kalluru 		break;
2109d44a3cedSSudarsana Reddy Kalluru 	}
2110d44a3cedSSudarsana Reddy Kalluru 
21119e54ba7cSSudarsana Reddy Kalluru err:
2112d44a3cedSSudarsana Reddy Kalluru 	edev->dump_info.cmd = QEDE_DUMP_CMD_NONE;
2113d44a3cedSSudarsana Reddy Kalluru 	edev->dump_info.num_args = 0;
21149e54ba7cSSudarsana Reddy Kalluru 	memset(edev->dump_info.args, 0, sizeof(edev->dump_info.args));
2115d44a3cedSSudarsana Reddy Kalluru 
2116d44a3cedSSudarsana Reddy Kalluru 	return rc;
2117d44a3cedSSudarsana Reddy Kalluru }
2118d44a3cedSSudarsana Reddy Kalluru 
2119b0ec5489SBhaskar Upadhaya int qede_set_per_coalesce(struct net_device *dev, u32 queue,
2120a0d2d97dSBhaskar Upadhaya 			  struct ethtool_coalesce *coal)
2121a0d2d97dSBhaskar Upadhaya {
2122a0d2d97dSBhaskar Upadhaya 	struct qede_dev *edev = netdev_priv(dev);
2123a0d2d97dSBhaskar Upadhaya 	struct qede_fastpath *fp;
2124a0d2d97dSBhaskar Upadhaya 	u16 rxc, txc;
2125a0d2d97dSBhaskar Upadhaya 	int rc = 0;
2126a0d2d97dSBhaskar Upadhaya 
2127a0d2d97dSBhaskar Upadhaya 	if (coal->rx_coalesce_usecs > QED_COALESCE_MAX ||
2128a0d2d97dSBhaskar Upadhaya 	    coal->tx_coalesce_usecs > QED_COALESCE_MAX) {
2129a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev,
2130a0d2d97dSBhaskar Upadhaya 			"Can't support requested %s coalesce value [max supported value %d]\n",
2131a0d2d97dSBhaskar Upadhaya 			coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx"
2132a0d2d97dSBhaskar Upadhaya 								   : "tx",
2133a0d2d97dSBhaskar Upadhaya 			QED_COALESCE_MAX);
2134a0d2d97dSBhaskar Upadhaya 		return -EINVAL;
2135a0d2d97dSBhaskar Upadhaya 	}
2136a0d2d97dSBhaskar Upadhaya 
2137a0d2d97dSBhaskar Upadhaya 	rxc = (u16)coal->rx_coalesce_usecs;
2138a0d2d97dSBhaskar Upadhaya 	txc = (u16)coal->tx_coalesce_usecs;
2139a0d2d97dSBhaskar Upadhaya 
2140a0d2d97dSBhaskar Upadhaya 	__qede_lock(edev);
2141a0d2d97dSBhaskar Upadhaya 	if (queue >= edev->num_queues) {
2142a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Invalid queue\n");
2143a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2144a0d2d97dSBhaskar Upadhaya 		goto out;
2145a0d2d97dSBhaskar Upadhaya 	}
2146a0d2d97dSBhaskar Upadhaya 
2147a0d2d97dSBhaskar Upadhaya 	if (edev->state != QEDE_STATE_OPEN) {
2148a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2149a0d2d97dSBhaskar Upadhaya 		goto out;
2150a0d2d97dSBhaskar Upadhaya 	}
2151a0d2d97dSBhaskar Upadhaya 
2152a0d2d97dSBhaskar Upadhaya 	fp = &edev->fp_array[queue];
2153a0d2d97dSBhaskar Upadhaya 
2154a0d2d97dSBhaskar Upadhaya 	if (edev->fp_array[queue].type & QEDE_FASTPATH_RX) {
2155a0d2d97dSBhaskar Upadhaya 		rc = edev->ops->common->set_coalesce(edev->cdev,
2156a0d2d97dSBhaskar Upadhaya 						     rxc, 0,
2157a0d2d97dSBhaskar Upadhaya 						     fp->rxq->handle);
2158a0d2d97dSBhaskar Upadhaya 		if (rc) {
2159a0d2d97dSBhaskar Upadhaya 			DP_INFO(edev,
2160a0d2d97dSBhaskar Upadhaya 				"Set RX coalesce error, rc = %d\n", rc);
2161a0d2d97dSBhaskar Upadhaya 			goto out;
2162a0d2d97dSBhaskar Upadhaya 		}
2163b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].rxc = rxc;
2164b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].isvalid = true;
2165a0d2d97dSBhaskar Upadhaya 	}
2166a0d2d97dSBhaskar Upadhaya 
2167a0d2d97dSBhaskar Upadhaya 	if (edev->fp_array[queue].type & QEDE_FASTPATH_TX) {
2168a0d2d97dSBhaskar Upadhaya 		rc = edev->ops->common->set_coalesce(edev->cdev,
2169a0d2d97dSBhaskar Upadhaya 						     0, txc,
2170a0d2d97dSBhaskar Upadhaya 						     fp->txq->handle);
2171a0d2d97dSBhaskar Upadhaya 		if (rc) {
2172a0d2d97dSBhaskar Upadhaya 			DP_INFO(edev,
2173a0d2d97dSBhaskar Upadhaya 				"Set TX coalesce error, rc = %d\n", rc);
2174a0d2d97dSBhaskar Upadhaya 			goto out;
2175a0d2d97dSBhaskar Upadhaya 		}
2176b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].txc = txc;
2177b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].isvalid = true;
2178a0d2d97dSBhaskar Upadhaya 	}
2179a0d2d97dSBhaskar Upadhaya out:
2180a0d2d97dSBhaskar Upadhaya 	__qede_unlock(edev);
2181a0d2d97dSBhaskar Upadhaya 
2182a0d2d97dSBhaskar Upadhaya 	return rc;
2183a0d2d97dSBhaskar Upadhaya }
2184a0d2d97dSBhaskar Upadhaya 
2185a0d2d97dSBhaskar Upadhaya static int qede_get_per_coalesce(struct net_device *dev,
2186a0d2d97dSBhaskar Upadhaya 				 u32 queue,
2187a0d2d97dSBhaskar Upadhaya 				 struct ethtool_coalesce *coal)
2188a0d2d97dSBhaskar Upadhaya {
2189a0d2d97dSBhaskar Upadhaya 	void *rx_handle = NULL, *tx_handle = NULL;
2190a0d2d97dSBhaskar Upadhaya 	struct qede_dev *edev = netdev_priv(dev);
2191a0d2d97dSBhaskar Upadhaya 	struct qede_fastpath *fp;
2192a0d2d97dSBhaskar Upadhaya 	u16 rx_coal, tx_coal;
2193a0d2d97dSBhaskar Upadhaya 	int rc = 0;
2194a0d2d97dSBhaskar Upadhaya 
2195a0d2d97dSBhaskar Upadhaya 	rx_coal = QED_DEFAULT_RX_USECS;
2196a0d2d97dSBhaskar Upadhaya 	tx_coal = QED_DEFAULT_TX_USECS;
2197a0d2d97dSBhaskar Upadhaya 
2198a0d2d97dSBhaskar Upadhaya 	memset(coal, 0, sizeof(struct ethtool_coalesce));
2199a0d2d97dSBhaskar Upadhaya 
2200a0d2d97dSBhaskar Upadhaya 	__qede_lock(edev);
2201a0d2d97dSBhaskar Upadhaya 	if (queue >= edev->num_queues) {
2202a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Invalid queue\n");
2203a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2204a0d2d97dSBhaskar Upadhaya 		goto out;
2205a0d2d97dSBhaskar Upadhaya 	}
2206a0d2d97dSBhaskar Upadhaya 
2207a0d2d97dSBhaskar Upadhaya 	if (edev->state != QEDE_STATE_OPEN) {
2208a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2209a0d2d97dSBhaskar Upadhaya 		goto out;
2210a0d2d97dSBhaskar Upadhaya 	}
2211a0d2d97dSBhaskar Upadhaya 
2212a0d2d97dSBhaskar Upadhaya 	fp = &edev->fp_array[queue];
2213a0d2d97dSBhaskar Upadhaya 
2214a0d2d97dSBhaskar Upadhaya 	if (fp->type & QEDE_FASTPATH_RX)
2215a0d2d97dSBhaskar Upadhaya 		rx_handle = fp->rxq->handle;
2216a0d2d97dSBhaskar Upadhaya 
2217a0d2d97dSBhaskar Upadhaya 	rc = edev->ops->get_coalesce(edev->cdev, &rx_coal,
2218a0d2d97dSBhaskar Upadhaya 				     rx_handle);
2219a0d2d97dSBhaskar Upadhaya 	if (rc) {
2220a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Read Rx coalesce error\n");
2221a0d2d97dSBhaskar Upadhaya 		goto out;
2222a0d2d97dSBhaskar Upadhaya 	}
2223a0d2d97dSBhaskar Upadhaya 
2224a0d2d97dSBhaskar Upadhaya 	fp = &edev->fp_array[queue];
2225a0d2d97dSBhaskar Upadhaya 	if (fp->type & QEDE_FASTPATH_TX)
2226a0d2d97dSBhaskar Upadhaya 		tx_handle = fp->txq->handle;
2227a0d2d97dSBhaskar Upadhaya 
2228a0d2d97dSBhaskar Upadhaya 	rc = edev->ops->get_coalesce(edev->cdev, &tx_coal,
2229a0d2d97dSBhaskar Upadhaya 				      tx_handle);
2230a0d2d97dSBhaskar Upadhaya 	if (rc)
2231a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Read Tx coalesce error\n");
2232a0d2d97dSBhaskar Upadhaya 
2233a0d2d97dSBhaskar Upadhaya out:
2234a0d2d97dSBhaskar Upadhaya 	__qede_unlock(edev);
2235a0d2d97dSBhaskar Upadhaya 
2236a0d2d97dSBhaskar Upadhaya 	coal->rx_coalesce_usecs = rx_coal;
2237a0d2d97dSBhaskar Upadhaya 	coal->tx_coalesce_usecs = tx_coal;
2238a0d2d97dSBhaskar Upadhaya 
2239a0d2d97dSBhaskar Upadhaya 	return rc;
2240a0d2d97dSBhaskar Upadhaya }
2241a0d2d97dSBhaskar Upadhaya 
2242133fac0eSSudarsana Kalluru static const struct ethtool_ops qede_ethtool_ops = {
2243c9312022SJakub Kicinski 	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS,
2244054c67d1SSudarsana Reddy Kalluru 	.get_link_ksettings		= qede_get_link_ksettings,
2245054c67d1SSudarsana Reddy Kalluru 	.set_link_ksettings		= qede_set_link_ksettings,
2246133fac0eSSudarsana Kalluru 	.get_drvinfo			= qede_get_drvinfo,
2247e0971c83STomer Tayar 	.get_regs_len			= qede_get_regs_len,
2248e0971c83STomer Tayar 	.get_regs			= qede_get_regs,
224914d39648SMintz, Yuval 	.get_wol			= qede_get_wol,
225014d39648SMintz, Yuval 	.set_wol			= qede_set_wol,
2251133fac0eSSudarsana Kalluru 	.get_msglevel			= qede_get_msglevel,
2252133fac0eSSudarsana Kalluru 	.set_msglevel			= qede_set_msglevel,
225332a7a570SSudarsana Kalluru 	.nway_reset			= qede_nway_reset,
2254133fac0eSSudarsana Kalluru 	.get_link			= qede_get_link,
2255d552fa84SSudarsana Reddy Kalluru 	.get_coalesce			= qede_get_coalesce,
2256d552fa84SSudarsana Reddy Kalluru 	.set_coalesce			= qede_set_coalesce,
225701ef7e05SSudarsana Kalluru 	.get_ringparam			= qede_get_ringparam,
225801ef7e05SSudarsana Kalluru 	.set_ringparam			= qede_set_ringparam,
22590f7db144SSudarsana Kalluru 	.get_pauseparam			= qede_get_pauseparam,
22600f7db144SSudarsana Kalluru 	.set_pauseparam			= qede_set_pauseparam,
2261133fac0eSSudarsana Kalluru 	.get_strings			= qede_get_strings,
22623d971cbdSSudarsana Kalluru 	.set_phys_id			= qede_set_phys_id,
2263133fac0eSSudarsana Kalluru 	.get_ethtool_stats		= qede_get_ethtool_stats,
2264f3e72109SYuval Mintz 	.get_priv_flags			= qede_get_priv_flags,
22657d9acd87SIgor Russkikh 	.set_priv_flags			= qede_set_priv_flags,
2266133fac0eSSudarsana Kalluru 	.get_sset_count			= qede_get_sset_count,
2267961acdeaSSudarsana Reddy Kalluru 	.get_rxnfc			= qede_get_rxnfc,
2268961acdeaSSudarsana Reddy Kalluru 	.set_rxnfc			= qede_set_rxnfc,
2269961acdeaSSudarsana Reddy Kalluru 	.get_rxfh_indir_size		= qede_get_rxfh_indir_size,
2270961acdeaSSudarsana Reddy Kalluru 	.get_rxfh_key_size		= qede_get_rxfh_key_size,
2271961acdeaSSudarsana Reddy Kalluru 	.get_rxfh			= qede_get_rxfh,
2272961acdeaSSudarsana Reddy Kalluru 	.set_rxfh			= qede_set_rxfh,
22734c55215cSSudarsana Reddy Kalluru 	.get_ts_info			= qede_get_ts_info,
22748edf049dSSudarsana Kalluru 	.get_channels			= qede_get_channels,
22758edf049dSSudarsana Kalluru 	.set_channels			= qede_set_channels,
22763044a02eSSudarsana Reddy Kalluru 	.self_test			= qede_self_test,
227797df0d65SSudarsana Reddy Kalluru 	.get_module_info		= qede_get_module_info,
227897df0d65SSudarsana Reddy Kalluru 	.get_module_eeprom		= qede_get_module_eeprom,
2279c3dc48f7SSudarsana Reddy Kalluru 	.get_eee			= qede_get_eee,
2280c3dc48f7SSudarsana Reddy Kalluru 	.set_eee			= qede_set_eee,
22819bdca14aSAlexander Lobakin 	.get_fecparam			= qede_get_fecparam,
22829bdca14aSAlexander Lobakin 	.set_fecparam			= qede_set_fecparam,
22833d789994SManish Chopra 	.get_tunable			= qede_get_tunable,
22843d789994SManish Chopra 	.set_tunable			= qede_set_tunable,
2285a0d2d97dSBhaskar Upadhaya 	.get_per_queue_coalesce		= qede_get_per_coalesce,
2286a0d2d97dSBhaskar Upadhaya 	.set_per_queue_coalesce		= qede_set_per_coalesce,
2287ccfa110cSSudarsana Reddy Kalluru 	.flash_device			= qede_flash_device,
2288d44a3cedSSudarsana Reddy Kalluru 	.get_dump_flag			= qede_get_dump_flag,
2289d44a3cedSSudarsana Reddy Kalluru 	.get_dump_data			= qede_get_dump_data,
2290d44a3cedSSudarsana Reddy Kalluru 	.set_dump			= qede_set_dump,
2291133fac0eSSudarsana Kalluru };
2292133fac0eSSudarsana Kalluru 
2293fefb0202SYuval Mintz static const struct ethtool_ops qede_vf_ethtool_ops = {
2294c9312022SJakub Kicinski 	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS,
2295054c67d1SSudarsana Reddy Kalluru 	.get_link_ksettings		= qede_get_link_ksettings,
2296fefb0202SYuval Mintz 	.get_drvinfo			= qede_get_drvinfo,
2297fefb0202SYuval Mintz 	.get_msglevel			= qede_get_msglevel,
2298fefb0202SYuval Mintz 	.set_msglevel			= qede_set_msglevel,
2299fefb0202SYuval Mintz 	.get_link			= qede_get_link,
2300477f2d14SRahul Verma 	.get_coalesce			= qede_get_coalesce,
2301477f2d14SRahul Verma 	.set_coalesce			= qede_set_coalesce,
2302fefb0202SYuval Mintz 	.get_ringparam			= qede_get_ringparam,
2303fefb0202SYuval Mintz 	.set_ringparam			= qede_set_ringparam,
2304fefb0202SYuval Mintz 	.get_strings			= qede_get_strings,
2305fefb0202SYuval Mintz 	.get_ethtool_stats		= qede_get_ethtool_stats,
2306fefb0202SYuval Mintz 	.get_priv_flags			= qede_get_priv_flags,
2307fefb0202SYuval Mintz 	.get_sset_count			= qede_get_sset_count,
2308fefb0202SYuval Mintz 	.get_rxnfc			= qede_get_rxnfc,
2309fefb0202SYuval Mintz 	.set_rxnfc			= qede_set_rxnfc,
2310fefb0202SYuval Mintz 	.get_rxfh_indir_size		= qede_get_rxfh_indir_size,
2311fefb0202SYuval Mintz 	.get_rxfh_key_size		= qede_get_rxfh_key_size,
2312fefb0202SYuval Mintz 	.get_rxfh			= qede_get_rxfh,
2313fefb0202SYuval Mintz 	.set_rxfh			= qede_set_rxfh,
2314fefb0202SYuval Mintz 	.get_channels			= qede_get_channels,
2315fefb0202SYuval Mintz 	.set_channels			= qede_set_channels,
2316a0d2d97dSBhaskar Upadhaya 	.get_per_queue_coalesce		= qede_get_per_coalesce,
2317a0d2d97dSBhaskar Upadhaya 	.set_per_queue_coalesce		= qede_set_per_coalesce,
23183d789994SManish Chopra 	.get_tunable			= qede_get_tunable,
23193d789994SManish Chopra 	.set_tunable			= qede_set_tunable,
2320fefb0202SYuval Mintz };
2321fefb0202SYuval Mintz 
2322133fac0eSSudarsana Kalluru void qede_set_ethtool_ops(struct net_device *dev)
2323133fac0eSSudarsana Kalluru {
2324fefb0202SYuval Mintz 	struct qede_dev *edev = netdev_priv(dev);
2325fefb0202SYuval Mintz 
2326fefb0202SYuval Mintz 	if (IS_VF(edev))
2327fefb0202SYuval Mintz 		dev->ethtool_ops = &qede_vf_ethtool_ops;
2328fefb0202SYuval Mintz 	else
2329133fac0eSSudarsana Kalluru 		dev->ethtool_ops = &qede_ethtool_ops;
2330133fac0eSSudarsana Kalluru }
2331