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/types.h>
8133fac0eSSudarsana Kalluru #include <linux/netdevice.h>
916f46bf0SSudarsana Reddy Kalluru #include <linux/etherdevice.h>
10133fac0eSSudarsana Kalluru #include <linux/ethtool.h>
11133fac0eSSudarsana Kalluru #include <linux/string.h>
12133fac0eSSudarsana Kalluru #include <linux/pci.h>
13133fac0eSSudarsana Kalluru #include <linux/capability.h>
14f29ffdb6SMintz, Yuval #include <linux/vmalloc.h>
15bdb5d8ecSAlexander Lobakin #include <linux/phylink.h>
16bdb5d8ecSAlexander Lobakin 
17133fac0eSSudarsana Kalluru #include "qede.h"
184c55215cSSudarsana Reddy Kalluru #include "qede_ptp.h"
19133fac0eSSudarsana Kalluru 
20133fac0eSSudarsana Kalluru #define QEDE_RQSTAT_OFFSET(stat_name) \
21133fac0eSSudarsana Kalluru 	 (offsetof(struct qede_rx_queue, stat_name))
22133fac0eSSudarsana Kalluru #define QEDE_RQSTAT_STRING(stat_name) (#stat_name)
23133fac0eSSudarsana Kalluru #define QEDE_RQSTAT(stat_name) \
24133fac0eSSudarsana Kalluru 	 {QEDE_RQSTAT_OFFSET(stat_name), QEDE_RQSTAT_STRING(stat_name)}
2516f46bf0SSudarsana Reddy Kalluru 
2616f46bf0SSudarsana Reddy Kalluru #define QEDE_SELFTEST_POLL_COUNT 100
27d44a3cedSSudarsana Reddy Kalluru #define QEDE_DUMP_VERSION	0x1
28d44a3cedSSudarsana Reddy Kalluru #define QEDE_DUMP_NVM_ARG_COUNT	2
2916f46bf0SSudarsana Reddy Kalluru 
30133fac0eSSudarsana Kalluru static const struct {
31133fac0eSSudarsana Kalluru 	u64 offset;
32133fac0eSSudarsana Kalluru 	char string[ETH_GSTRING_LEN];
33133fac0eSSudarsana Kalluru } qede_rqstats_arr[] = {
3468db9ec2SSudarsana Reddy Kalluru 	QEDE_RQSTAT(rcv_pkts),
35133fac0eSSudarsana Kalluru 	QEDE_RQSTAT(rx_hw_errors),
36133fac0eSSudarsana Kalluru 	QEDE_RQSTAT(rx_alloc_errors),
37c72a6125SManish Chopra 	QEDE_RQSTAT(rx_ip_frags),
38496e0517SMintz, Yuval 	QEDE_RQSTAT(xdp_no_pass),
39133fac0eSSudarsana Kalluru };
40133fac0eSSudarsana Kalluru 
41133fac0eSSudarsana Kalluru #define QEDE_NUM_RQSTATS ARRAY_SIZE(qede_rqstats_arr)
4268db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT_OFFSET(stat_name) \
4368db9ec2SSudarsana Reddy Kalluru 	(offsetof(struct qede_tx_queue, stat_name))
4468db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT_STRING(stat_name) (#stat_name)
4568db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT(stat_name) \
4668db9ec2SSudarsana Reddy Kalluru 	{QEDE_TQSTAT_OFFSET(stat_name), QEDE_TQSTAT_STRING(stat_name)}
4768db9ec2SSudarsana Reddy Kalluru #define QEDE_NUM_TQSTATS ARRAY_SIZE(qede_tqstats_arr)
4868db9ec2SSudarsana Reddy Kalluru static const struct {
4968db9ec2SSudarsana Reddy Kalluru 	u64 offset;
5068db9ec2SSudarsana Reddy Kalluru 	char string[ETH_GSTRING_LEN];
5168db9ec2SSudarsana Reddy Kalluru } qede_tqstats_arr[] = {
5268db9ec2SSudarsana Reddy Kalluru 	QEDE_TQSTAT(xmit_pkts),
5368db9ec2SSudarsana Reddy Kalluru 	QEDE_TQSTAT(stopped_cnt),
54dcc6abaeSMichael Shteinbok 	QEDE_TQSTAT(tx_mem_alloc_err),
5568db9ec2SSudarsana Reddy Kalluru };
5668db9ec2SSudarsana Reddy Kalluru 
579c79ddaaSMintz, Yuval #define QEDE_STAT_OFFSET(stat_name, type, base) \
589c79ddaaSMintz, Yuval 	(offsetof(type, stat_name) + (base))
594dbcd640SMintz, Yuval #define QEDE_STAT_STRING(stat_name)	(#stat_name)
609c79ddaaSMintz, Yuval #define _QEDE_STAT(stat_name, type, base, attr) \
619c79ddaaSMintz, Yuval 	{QEDE_STAT_OFFSET(stat_name, type, base), \
629c79ddaaSMintz, Yuval 	 QEDE_STAT_STRING(stat_name), \
639c79ddaaSMintz, Yuval 	 attr}
649c79ddaaSMintz, Yuval #define QEDE_STAT(stat_name) \
659c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_common, 0, 0x0)
669c79ddaaSMintz, Yuval #define QEDE_PF_STAT(stat_name) \
679c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_common, 0, \
689c79ddaaSMintz, Yuval 		   BIT(QEDE_STAT_PF_ONLY))
699c79ddaaSMintz, Yuval #define QEDE_PF_BB_STAT(stat_name) \
709c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_bb, \
719c79ddaaSMintz, Yuval 		   offsetof(struct qede_stats, bb), \
729c79ddaaSMintz, Yuval 		   BIT(QEDE_STAT_PF_ONLY) | BIT(QEDE_STAT_BB_ONLY))
739c79ddaaSMintz, Yuval #define QEDE_PF_AH_STAT(stat_name) \
749c79ddaaSMintz, Yuval 	_QEDE_STAT(stat_name, struct qede_stats_ah, \
759c79ddaaSMintz, Yuval 		   offsetof(struct qede_stats, ah), \
769c79ddaaSMintz, Yuval 		   BIT(QEDE_STAT_PF_ONLY) | BIT(QEDE_STAT_AH_ONLY))
77133fac0eSSudarsana Kalluru static const struct {
78133fac0eSSudarsana Kalluru 	u64 offset;
79133fac0eSSudarsana Kalluru 	char string[ETH_GSTRING_LEN];
809c79ddaaSMintz, Yuval 	unsigned long attr;
819c79ddaaSMintz, Yuval #define QEDE_STAT_PF_ONLY	0
829c79ddaaSMintz, Yuval #define QEDE_STAT_BB_ONLY	1
839c79ddaaSMintz, Yuval #define QEDE_STAT_AH_ONLY	2
84133fac0eSSudarsana Kalluru } qede_stats_arr[] = {
85133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_ucast_bytes),
86133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_mcast_bytes),
87133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_bcast_bytes),
88133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_ucast_pkts),
89133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_mcast_pkts),
90133fac0eSSudarsana Kalluru 	QEDE_STAT(rx_bcast_pkts),
91133fac0eSSudarsana Kalluru 
92133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_ucast_bytes),
93133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_mcast_bytes),
94133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_bcast_bytes),
95133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_ucast_pkts),
96133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_mcast_pkts),
97133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_bcast_pkts),
98133fac0eSSudarsana Kalluru 
99133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_64_byte_packets),
100d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_65_to_127_byte_packets),
101d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_128_to_255_byte_packets),
102d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_256_to_511_byte_packets),
103d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_512_to_1023_byte_packets),
104d4967cf3SYuval Mintz 	QEDE_PF_STAT(rx_1024_to_1518_byte_packets),
1059c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_1519_to_1522_byte_packets),
1069c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_1519_to_2047_byte_packets),
1079c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_2048_to_4095_byte_packets),
1089c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_4096_to_9216_byte_packets),
1099c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(rx_9217_to_16383_byte_packets),
1109c79ddaaSMintz, Yuval 	QEDE_PF_AH_STAT(rx_1519_to_max_byte_packets),
111133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_64_byte_packets),
112133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_65_to_127_byte_packets),
113133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_128_to_255_byte_packets),
114133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_256_to_511_byte_packets),
115133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_512_to_1023_byte_packets),
116133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_1024_to_1518_byte_packets),
1179c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_1519_to_2047_byte_packets),
1189c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_2048_to_4095_byte_packets),
1199c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_4096_to_9216_byte_packets),
1209c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_9217_to_16383_byte_packets),
1219c79ddaaSMintz, Yuval 	QEDE_PF_AH_STAT(tx_1519_to_max_byte_packets),
122133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_mac_crtl_frames),
123133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_mac_ctrl_frames),
124133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_pause_frames),
125133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_pause_frames),
126133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_pfc_frames),
127133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(tx_pfc_frames),
128133fac0eSSudarsana Kalluru 
129133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_crc_errors),
130133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_align_errors),
131133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_carrier_errors),
132133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_oversize_packets),
133133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_jabbers),
134133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_undersize_packets),
135133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(rx_fragments),
1369c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_lpi_entry_count),
1379c79ddaaSMintz, Yuval 	QEDE_PF_BB_STAT(tx_total_collisions),
138133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(brb_truncates),
139133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(brb_discards),
140133fac0eSSudarsana Kalluru 	QEDE_STAT(no_buff_discards),
141133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(mftag_filter_discards),
142133fac0eSSudarsana Kalluru 	QEDE_PF_STAT(mac_filter_discards),
143608e00d0SManish Chopra 	QEDE_PF_STAT(gft_filter_drop),
144133fac0eSSudarsana Kalluru 	QEDE_STAT(tx_err_drop_pkts),
1451a5a366fSSudarsana Reddy Kalluru 	QEDE_STAT(ttl0_discard),
1461a5a366fSSudarsana Reddy Kalluru 	QEDE_STAT(packet_too_big_discard),
147133fac0eSSudarsana Kalluru 
148133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_pkts),
149133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_events),
150133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_aborts_num),
151133fac0eSSudarsana Kalluru 	QEDE_STAT(non_coalesced_pkts),
152133fac0eSSudarsana Kalluru 	QEDE_STAT(coalesced_bytes),
15332d26a68SSudarsana Reddy Kalluru 
15432d26a68SSudarsana Reddy Kalluru 	QEDE_STAT(link_change_count),
1559adebac3SSudarsana Reddy Kalluru 	QEDE_STAT(ptp_skip_txts),
156133fac0eSSudarsana Kalluru };
157133fac0eSSudarsana Kalluru 
158133fac0eSSudarsana Kalluru #define QEDE_NUM_STATS	ARRAY_SIZE(qede_stats_arr)
1599c79ddaaSMintz, Yuval #define QEDE_STAT_IS_PF_ONLY(i) \
1609c79ddaaSMintz, Yuval 	test_bit(QEDE_STAT_PF_ONLY, &qede_stats_arr[i].attr)
1619c79ddaaSMintz, Yuval #define QEDE_STAT_IS_BB_ONLY(i) \
1629c79ddaaSMintz, Yuval 	test_bit(QEDE_STAT_BB_ONLY, &qede_stats_arr[i].attr)
1639c79ddaaSMintz, Yuval #define QEDE_STAT_IS_AH_ONLY(i) \
1649c79ddaaSMintz, Yuval 	test_bit(QEDE_STAT_AH_ONLY, &qede_stats_arr[i].attr)
165133fac0eSSudarsana Kalluru 
166f3e72109SYuval Mintz enum {
167f3e72109SYuval Mintz 	QEDE_PRI_FLAG_CMT,
168f15cff04SSudarsana Reddy Kalluru 	QEDE_PRI_FLAG_SMART_AN_SUPPORT, /* MFW supports SmartAN */
1697d9acd87SIgor Russkikh 	QEDE_PRI_FLAG_RECOVER_ON_ERROR,
170823163baSManish Chopra 	QEDE_PRI_FLAG_ESL_SUPPORT, /* MFW supports Enhanced System Lockdown */
171823163baSManish Chopra 	QEDE_PRI_FLAG_ESL_ACTIVE, /* Enhanced System Lockdown Active status */
172f3e72109SYuval Mintz 	QEDE_PRI_FLAG_LEN,
173f3e72109SYuval Mintz };
174f3e72109SYuval Mintz 
175f3e72109SYuval Mintz static const char qede_private_arr[QEDE_PRI_FLAG_LEN][ETH_GSTRING_LEN] = {
176f3e72109SYuval Mintz 	"Coupled-Function",
177f15cff04SSudarsana Reddy Kalluru 	"SmartAN capable",
1787d9acd87SIgor Russkikh 	"Recover on error",
179823163baSManish Chopra 	"ESL capable",
180823163baSManish Chopra 	"ESL active",
181f3e72109SYuval Mintz };
182f3e72109SYuval Mintz 
1833044a02eSSudarsana Reddy Kalluru enum qede_ethtool_tests {
18416f46bf0SSudarsana Reddy Kalluru 	QEDE_ETHTOOL_INT_LOOPBACK,
1853044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_INTERRUPT_TEST,
1863044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_MEMORY_TEST,
1873044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_REGISTER_TEST,
1883044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_CLOCK_TEST,
1897a4b21b7SMintz, Yuval 	QEDE_ETHTOOL_NVRAM_TEST,
1903044a02eSSudarsana Reddy Kalluru 	QEDE_ETHTOOL_TEST_MAX
1913044a02eSSudarsana Reddy Kalluru };
1923044a02eSSudarsana Reddy Kalluru 
1933044a02eSSudarsana Reddy Kalluru static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = {
19416f46bf0SSudarsana Reddy Kalluru 	"Internal loopback (offline)",
1953044a02eSSudarsana Reddy Kalluru 	"Interrupt (online)\t",
1963044a02eSSudarsana Reddy Kalluru 	"Memory (online)\t\t",
1973044a02eSSudarsana Reddy Kalluru 	"Register (online)\t",
1983044a02eSSudarsana Reddy Kalluru 	"Clock (online)\t\t",
1997a4b21b7SMintz, Yuval 	"Nvram (online)\t\t",
2003044a02eSSudarsana Reddy Kalluru };
2013044a02eSSudarsana Reddy Kalluru 
2021d4e4eccSAlexander Lobakin /* Forced speed capabilities maps */
2031d4e4eccSAlexander Lobakin 
2041d4e4eccSAlexander Lobakin struct qede_forced_speed_map {
2051d4e4eccSAlexander Lobakin 	u32		speed;
2061d4e4eccSAlexander Lobakin 	__ETHTOOL_DECLARE_LINK_MODE_MASK(caps);
2071d4e4eccSAlexander Lobakin 
2081d4e4eccSAlexander Lobakin 	const u32	*cap_arr;
2091d4e4eccSAlexander Lobakin 	u32		arr_size;
2101d4e4eccSAlexander Lobakin };
2111d4e4eccSAlexander Lobakin 
2121d4e4eccSAlexander Lobakin #define QEDE_FORCED_SPEED_MAP(value)					\
2131d4e4eccSAlexander Lobakin {									\
2141d4e4eccSAlexander Lobakin 	.speed		= SPEED_##value,				\
2151d4e4eccSAlexander Lobakin 	.cap_arr	= qede_forced_speed_##value,			\
2161d4e4eccSAlexander Lobakin 	.arr_size	= ARRAY_SIZE(qede_forced_speed_##value),	\
2171d4e4eccSAlexander Lobakin }
2181d4e4eccSAlexander Lobakin 
2191d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_1000[] __initconst = {
2201d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
2211d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2221d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
2231d4e4eccSAlexander Lobakin };
2241d4e4eccSAlexander Lobakin 
2251d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_10000[] __initconst = {
2261d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
2271d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
2281d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
2291d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
2301d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
2311d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
2321d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
2331d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
2341d4e4eccSAlexander Lobakin };
2351d4e4eccSAlexander Lobakin 
2361d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_20000[] __initconst = {
2371d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
2381d4e4eccSAlexander Lobakin };
2391d4e4eccSAlexander Lobakin 
2401d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_25000[] __initconst = {
2411d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
2421d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
2431d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
2441d4e4eccSAlexander Lobakin };
2451d4e4eccSAlexander Lobakin 
2461d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_40000[] __initconst = {
2471d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
2481d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
2491d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
2501d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
2511d4e4eccSAlexander Lobakin };
2521d4e4eccSAlexander Lobakin 
2531d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_50000[] __initconst = {
2541d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
2551d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
2561d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
2571d4e4eccSAlexander Lobakin };
2581d4e4eccSAlexander Lobakin 
2591d4e4eccSAlexander Lobakin static const u32 qede_forced_speed_100000[] __initconst = {
2601d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
2611d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
2621d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
2631d4e4eccSAlexander Lobakin 	ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
2641d4e4eccSAlexander Lobakin };
2651d4e4eccSAlexander Lobakin 
2661d4e4eccSAlexander Lobakin static struct qede_forced_speed_map qede_forced_speed_maps[] __ro_after_init = {
2671d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(1000),
2681d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(10000),
2691d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(20000),
2701d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(25000),
2711d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(40000),
2721d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(50000),
2731d4e4eccSAlexander Lobakin 	QEDE_FORCED_SPEED_MAP(100000),
2741d4e4eccSAlexander Lobakin };
2751d4e4eccSAlexander Lobakin 
qede_forced_speed_maps_init(void)2761d4e4eccSAlexander Lobakin void __init qede_forced_speed_maps_init(void)
2771d4e4eccSAlexander Lobakin {
2781d4e4eccSAlexander Lobakin 	struct qede_forced_speed_map *map;
2791d4e4eccSAlexander Lobakin 	u32 i;
2801d4e4eccSAlexander Lobakin 
2811d4e4eccSAlexander Lobakin 	for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
2821d4e4eccSAlexander Lobakin 		map = qede_forced_speed_maps + i;
2831d4e4eccSAlexander Lobakin 
2841d4e4eccSAlexander Lobakin 		linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps);
2851d4e4eccSAlexander Lobakin 		map->cap_arr = NULL;
2861d4e4eccSAlexander Lobakin 		map->arr_size = 0;
2871d4e4eccSAlexander Lobakin 	}
2881d4e4eccSAlexander Lobakin }
2891d4e4eccSAlexander Lobakin 
2901d4e4eccSAlexander Lobakin /* Ethtool callbacks */
2911d4e4eccSAlexander Lobakin 
qede_get_strings_stats_txq(struct qede_dev * edev,struct qede_tx_queue * txq,u8 ** buf)2924dbcd640SMintz, Yuval static void qede_get_strings_stats_txq(struct qede_dev *edev,
2934dbcd640SMintz, Yuval 				       struct qede_tx_queue *txq, u8 **buf)
2944dbcd640SMintz, Yuval {
2954dbcd640SMintz, Yuval 	int i;
2964dbcd640SMintz, Yuval 
2974dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_TQSTATS; i++) {
298cb6aeb07SMintz, Yuval 		if (txq->is_xdp)
299cb6aeb07SMintz, Yuval 			sprintf(*buf, "%d [XDP]: %s",
300cb6aeb07SMintz, Yuval 				QEDE_TXQ_XDP_TO_IDX(edev, txq),
301cb6aeb07SMintz, Yuval 				qede_tqstats_arr[i].string);
302cb6aeb07SMintz, Yuval 		else
3035e7baf0fSManish Chopra 			sprintf(*buf, "%d_%d: %s", txq->index, txq->cos,
3044dbcd640SMintz, Yuval 				qede_tqstats_arr[i].string);
3054dbcd640SMintz, Yuval 		*buf += ETH_GSTRING_LEN;
3064dbcd640SMintz, Yuval 	}
3074dbcd640SMintz, Yuval }
3084dbcd640SMintz, Yuval 
qede_get_strings_stats_rxq(struct qede_dev * edev,struct qede_rx_queue * rxq,u8 ** buf)3094dbcd640SMintz, Yuval static void qede_get_strings_stats_rxq(struct qede_dev *edev,
3104dbcd640SMintz, Yuval 				       struct qede_rx_queue *rxq, u8 **buf)
3114dbcd640SMintz, Yuval {
3124dbcd640SMintz, Yuval 	int i;
3134dbcd640SMintz, Yuval 
3144dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_RQSTATS; i++) {
3154dbcd640SMintz, Yuval 		sprintf(*buf, "%d: %s", rxq->rxq_id,
3164dbcd640SMintz, Yuval 			qede_rqstats_arr[i].string);
3174dbcd640SMintz, Yuval 		*buf += ETH_GSTRING_LEN;
3184dbcd640SMintz, Yuval 	}
3194dbcd640SMintz, Yuval }
3204dbcd640SMintz, Yuval 
qede_is_irrelevant_stat(struct qede_dev * edev,int stat_index)3219c79ddaaSMintz, Yuval static bool qede_is_irrelevant_stat(struct qede_dev *edev, int stat_index)
3229c79ddaaSMintz, Yuval {
3239c79ddaaSMintz, Yuval 	return (IS_VF(edev) && QEDE_STAT_IS_PF_ONLY(stat_index)) ||
3249c79ddaaSMintz, Yuval 	       (QEDE_IS_BB(edev) && QEDE_STAT_IS_AH_ONLY(stat_index)) ||
3259c79ddaaSMintz, Yuval 	       (QEDE_IS_AH(edev) && QEDE_STAT_IS_BB_ONLY(stat_index));
3269c79ddaaSMintz, Yuval }
3279c79ddaaSMintz, Yuval 
qede_get_strings_stats(struct qede_dev * edev,u8 * buf)328133fac0eSSudarsana Kalluru static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf)
329133fac0eSSudarsana Kalluru {
3304dbcd640SMintz, Yuval 	struct qede_fastpath *fp;
3314dbcd640SMintz, Yuval 	int i;
332133fac0eSSudarsana Kalluru 
3334dbcd640SMintz, Yuval 	/* Account for queue statistics */
3344dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_QUEUE_CNT(edev); i++) {
3354dbcd640SMintz, Yuval 		fp = &edev->fp_array[i];
33668db9ec2SSudarsana Reddy Kalluru 
3374dbcd640SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_RX)
3384dbcd640SMintz, Yuval 			qede_get_strings_stats_rxq(edev, fp->rxq, &buf);
3394dbcd640SMintz, Yuval 
340cb6aeb07SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_XDP)
341cb6aeb07SMintz, Yuval 			qede_get_strings_stats_txq(edev, fp->xdp_tx, &buf);
342cb6aeb07SMintz, Yuval 
3435e7baf0fSManish Chopra 		if (fp->type & QEDE_FASTPATH_TX) {
3445e7baf0fSManish Chopra 			int cos;
3455e7baf0fSManish Chopra 
3465e7baf0fSManish Chopra 			for_each_cos_in_txq(edev, cos)
3475e7baf0fSManish Chopra 				qede_get_strings_stats_txq(edev,
3485e7baf0fSManish Chopra 							   &fp->txq[cos], &buf);
3495e7baf0fSManish Chopra 		}
350cbbf049aSMintz, Yuval 	}
351cbbf049aSMintz, Yuval 
3524dbcd640SMintz, Yuval 	/* Account for non-queue statistics */
3534dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_STATS; i++) {
3549c79ddaaSMintz, Yuval 		if (qede_is_irrelevant_stat(edev, i))
355fefb0202SYuval Mintz 			continue;
3564dbcd640SMintz, Yuval 		strcpy(buf, qede_stats_arr[i].string);
3574dbcd640SMintz, Yuval 		buf += ETH_GSTRING_LEN;
358133fac0eSSudarsana Kalluru 	}
359133fac0eSSudarsana Kalluru }
360133fac0eSSudarsana Kalluru 
qede_get_strings(struct net_device * dev,u32 stringset,u8 * buf)361133fac0eSSudarsana Kalluru static void qede_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
362133fac0eSSudarsana Kalluru {
363133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
364133fac0eSSudarsana Kalluru 
365133fac0eSSudarsana Kalluru 	switch (stringset) {
366133fac0eSSudarsana Kalluru 	case ETH_SS_STATS:
367133fac0eSSudarsana Kalluru 		qede_get_strings_stats(edev, buf);
368133fac0eSSudarsana Kalluru 		break;
369f3e72109SYuval Mintz 	case ETH_SS_PRIV_FLAGS:
370f3e72109SYuval Mintz 		memcpy(buf, qede_private_arr,
371f3e72109SYuval Mintz 		       ETH_GSTRING_LEN * QEDE_PRI_FLAG_LEN);
372f3e72109SYuval Mintz 		break;
3733044a02eSSudarsana Reddy Kalluru 	case ETH_SS_TEST:
3743044a02eSSudarsana Reddy Kalluru 		memcpy(buf, qede_tests_str_arr,
3753044a02eSSudarsana Reddy Kalluru 		       ETH_GSTRING_LEN * QEDE_ETHTOOL_TEST_MAX);
3763044a02eSSudarsana Reddy Kalluru 		break;
377133fac0eSSudarsana Kalluru 	default:
378133fac0eSSudarsana Kalluru 		DP_VERBOSE(edev, QED_MSG_DEBUG,
379133fac0eSSudarsana Kalluru 			   "Unsupported stringset 0x%08x\n", stringset);
380133fac0eSSudarsana Kalluru 	}
381133fac0eSSudarsana Kalluru }
382133fac0eSSudarsana Kalluru 
qede_get_ethtool_stats_txq(struct qede_tx_queue * txq,u64 ** buf)3834dbcd640SMintz, Yuval static void qede_get_ethtool_stats_txq(struct qede_tx_queue *txq, u64 **buf)
3844dbcd640SMintz, Yuval {
3854dbcd640SMintz, Yuval 	int i;
3864dbcd640SMintz, Yuval 
3874dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_TQSTATS; i++) {
3884dbcd640SMintz, Yuval 		**buf = *((u64 *)(((void *)txq) + qede_tqstats_arr[i].offset));
3894dbcd640SMintz, Yuval 		(*buf)++;
3904dbcd640SMintz, Yuval 	}
3914dbcd640SMintz, Yuval }
3924dbcd640SMintz, Yuval 
qede_get_ethtool_stats_rxq(struct qede_rx_queue * rxq,u64 ** buf)3934dbcd640SMintz, Yuval static void qede_get_ethtool_stats_rxq(struct qede_rx_queue *rxq, u64 **buf)
3944dbcd640SMintz, Yuval {
3954dbcd640SMintz, Yuval 	int i;
3964dbcd640SMintz, Yuval 
3974dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_RQSTATS; i++) {
3984dbcd640SMintz, Yuval 		**buf = *((u64 *)(((void *)rxq) + qede_rqstats_arr[i].offset));
3994dbcd640SMintz, Yuval 		(*buf)++;
4004dbcd640SMintz, Yuval 	}
4014dbcd640SMintz, Yuval }
4024dbcd640SMintz, Yuval 
qede_get_ethtool_stats(struct net_device * dev,struct ethtool_stats * stats,u64 * buf)403133fac0eSSudarsana Kalluru static void qede_get_ethtool_stats(struct net_device *dev,
404133fac0eSSudarsana Kalluru 				   struct ethtool_stats *stats, u64 *buf)
405133fac0eSSudarsana Kalluru {
406133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
4074dbcd640SMintz, Yuval 	struct qede_fastpath *fp;
4084dbcd640SMintz, Yuval 	int i;
409133fac0eSSudarsana Kalluru 
410133fac0eSSudarsana Kalluru 	qede_fill_by_demand_stats(edev);
411133fac0eSSudarsana Kalluru 
412567b3c12SMintz, Yuval 	/* Need to protect the access to the fastpath array */
413567b3c12SMintz, Yuval 	__qede_lock(edev);
414567b3c12SMintz, Yuval 
4154dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_QUEUE_CNT(edev); i++) {
4164dbcd640SMintz, Yuval 		fp = &edev->fp_array[i];
417133fac0eSSudarsana Kalluru 
4184dbcd640SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_RX)
4194dbcd640SMintz, Yuval 			qede_get_ethtool_stats_rxq(fp->rxq, &buf);
42068db9ec2SSudarsana Reddy Kalluru 
421cb6aeb07SMintz, Yuval 		if (fp->type & QEDE_FASTPATH_XDP)
422cb6aeb07SMintz, Yuval 			qede_get_ethtool_stats_txq(fp->xdp_tx, &buf);
423cb6aeb07SMintz, Yuval 
4245e7baf0fSManish Chopra 		if (fp->type & QEDE_FASTPATH_TX) {
4255e7baf0fSManish Chopra 			int cos;
4265e7baf0fSManish Chopra 
4275e7baf0fSManish Chopra 			for_each_cos_in_txq(edev, cos)
4285e7baf0fSManish Chopra 				qede_get_ethtool_stats_txq(&fp->txq[cos], &buf);
4295e7baf0fSManish Chopra 		}
43068db9ec2SSudarsana Reddy Kalluru 	}
43168db9ec2SSudarsana Reddy Kalluru 
432*42510dffSManish Chopra 	spin_lock(&edev->stats_lock);
433*42510dffSManish Chopra 
4344dbcd640SMintz, Yuval 	for (i = 0; i < QEDE_NUM_STATS; i++) {
4359c79ddaaSMintz, Yuval 		if (qede_is_irrelevant_stat(edev, i))
436fefb0202SYuval Mintz 			continue;
4374dbcd640SMintz, Yuval 		*buf = *((u64 *)(((void *)&edev->stats) +
4384dbcd640SMintz, Yuval 				 qede_stats_arr[i].offset));
4394dbcd640SMintz, Yuval 
4404dbcd640SMintz, Yuval 		buf++;
441fefb0202SYuval Mintz 	}
442133fac0eSSudarsana Kalluru 
443*42510dffSManish Chopra 	spin_unlock(&edev->stats_lock);
444*42510dffSManish Chopra 
445567b3c12SMintz, Yuval 	__qede_unlock(edev);
446133fac0eSSudarsana Kalluru }
447133fac0eSSudarsana Kalluru 
qede_get_sset_count(struct net_device * dev,int stringset)448133fac0eSSudarsana Kalluru static int qede_get_sset_count(struct net_device *dev, int stringset)
449133fac0eSSudarsana Kalluru {
450133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
4519c79ddaaSMintz, Yuval 	int num_stats = QEDE_NUM_STATS, i;
452133fac0eSSudarsana Kalluru 
453133fac0eSSudarsana Kalluru 	switch (stringset) {
454133fac0eSSudarsana Kalluru 	case ETH_SS_STATS:
455fefb0202SYuval Mintz 		for (i = 0; i < QEDE_NUM_STATS; i++)
4569c79ddaaSMintz, Yuval 			if (qede_is_irrelevant_stat(edev, i))
457fefb0202SYuval Mintz 				num_stats--;
4584dbcd640SMintz, Yuval 
4594dbcd640SMintz, Yuval 		/* Account for the Regular Tx statistics */
4605e7baf0fSManish Chopra 		num_stats += QEDE_TSS_COUNT(edev) * QEDE_NUM_TQSTATS *
4615e7baf0fSManish Chopra 				edev->dev_info.num_tc;
4624dbcd640SMintz, Yuval 
4634dbcd640SMintz, Yuval 		/* Account for the Regular Rx statistics */
4644dbcd640SMintz, Yuval 		num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_RQSTATS;
4654dbcd640SMintz, Yuval 
466cb6aeb07SMintz, Yuval 		/* Account for XDP statistics [if needed] */
467cb6aeb07SMintz, Yuval 		if (edev->xdp_prog)
468cb6aeb07SMintz, Yuval 			num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_TQSTATS;
4694dbcd640SMintz, Yuval 		return num_stats;
4704dbcd640SMintz, Yuval 
471f3e72109SYuval Mintz 	case ETH_SS_PRIV_FLAGS:
472f3e72109SYuval Mintz 		return QEDE_PRI_FLAG_LEN;
4733044a02eSSudarsana Reddy Kalluru 	case ETH_SS_TEST:
4746ecb0a0cSYuval Mintz 		if (!IS_VF(edev))
4753044a02eSSudarsana Reddy Kalluru 			return QEDE_ETHTOOL_TEST_MAX;
4766ecb0a0cSYuval Mintz 		else
4776ecb0a0cSYuval Mintz 			return 0;
478133fac0eSSudarsana Kalluru 	default:
479133fac0eSSudarsana Kalluru 		DP_VERBOSE(edev, QED_MSG_DEBUG,
480133fac0eSSudarsana Kalluru 			   "Unsupported stringset 0x%08x\n", stringset);
481133fac0eSSudarsana Kalluru 		return -EINVAL;
482133fac0eSSudarsana Kalluru 	}
483133fac0eSSudarsana Kalluru }
484133fac0eSSudarsana Kalluru 
qede_get_priv_flags(struct net_device * dev)485f3e72109SYuval Mintz static u32 qede_get_priv_flags(struct net_device *dev)
486f3e72109SYuval Mintz {
487f3e72109SYuval Mintz 	struct qede_dev *edev = netdev_priv(dev);
488823163baSManish Chopra 	bool esl_active;
489f15cff04SSudarsana Reddy Kalluru 	u32 flags = 0;
490f3e72109SYuval Mintz 
491f15cff04SSudarsana Reddy Kalluru 	if (edev->dev_info.common.num_hwfns > 1)
492f15cff04SSudarsana Reddy Kalluru 		flags |= BIT(QEDE_PRI_FLAG_CMT);
493f15cff04SSudarsana Reddy Kalluru 
494f15cff04SSudarsana Reddy Kalluru 	if (edev->dev_info.common.smart_an)
495f15cff04SSudarsana Reddy Kalluru 		flags |= BIT(QEDE_PRI_FLAG_SMART_AN_SUPPORT);
496f15cff04SSudarsana Reddy Kalluru 
4977d9acd87SIgor Russkikh 	if (edev->err_flags & BIT(QEDE_ERR_IS_RECOVERABLE))
4987d9acd87SIgor Russkikh 		flags |= BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR);
4997d9acd87SIgor Russkikh 
500823163baSManish Chopra 	if (edev->dev_info.common.esl)
501823163baSManish Chopra 		flags |= BIT(QEDE_PRI_FLAG_ESL_SUPPORT);
502823163baSManish Chopra 
503823163baSManish Chopra 	edev->ops->common->get_esl_status(edev->cdev, &esl_active);
504823163baSManish Chopra 
505823163baSManish Chopra 	if (esl_active)
506823163baSManish Chopra 		flags |= BIT(QEDE_PRI_FLAG_ESL_ACTIVE);
507823163baSManish Chopra 
508f15cff04SSudarsana Reddy Kalluru 	return flags;
509f3e72109SYuval Mintz }
510f3e72109SYuval Mintz 
qede_set_priv_flags(struct net_device * dev,u32 flags)5117d9acd87SIgor Russkikh static int qede_set_priv_flags(struct net_device *dev, u32 flags)
5127d9acd87SIgor Russkikh {
5137d9acd87SIgor Russkikh 	struct qede_dev *edev = netdev_priv(dev);
5147d9acd87SIgor Russkikh 	u32 cflags = qede_get_priv_flags(dev);
5157d9acd87SIgor Russkikh 	u32 dflags = flags ^ cflags;
5167d9acd87SIgor Russkikh 
5177d9acd87SIgor Russkikh 	/* can only change RECOVER_ON_ERROR flag */
5187d9acd87SIgor Russkikh 	if (dflags & ~BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR))
5197d9acd87SIgor Russkikh 		return -EINVAL;
5207d9acd87SIgor Russkikh 
5217d9acd87SIgor Russkikh 	if (flags & BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR))
5227d9acd87SIgor Russkikh 		set_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags);
5237d9acd87SIgor Russkikh 	else
5247d9acd87SIgor Russkikh 		clear_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags);
5257d9acd87SIgor Russkikh 
5267d9acd87SIgor Russkikh 	return 0;
5277d9acd87SIgor Russkikh }
5287d9acd87SIgor Russkikh 
qede_get_link_ksettings(struct net_device * dev,struct ethtool_link_ksettings * cmd)529054c67d1SSudarsana Reddy Kalluru static int qede_get_link_ksettings(struct net_device *dev,
530054c67d1SSudarsana Reddy Kalluru 				   struct ethtool_link_ksettings *cmd)
531133fac0eSSudarsana Kalluru {
532bdb5d8ecSAlexander Lobakin 	typeof(cmd->link_modes) *link_modes = &cmd->link_modes;
533054c67d1SSudarsana Reddy Kalluru 	struct ethtool_link_settings *base = &cmd->base;
534133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
535133fac0eSSudarsana Kalluru 	struct qed_link_output current_link;
536133fac0eSSudarsana Kalluru 
537567b3c12SMintz, Yuval 	__qede_lock(edev);
538567b3c12SMintz, Yuval 
539133fac0eSSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
540133fac0eSSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
541133fac0eSSudarsana Kalluru 
542bdb5d8ecSAlexander Lobakin 	linkmode_copy(link_modes->supported, current_link.supported_caps);
543bdb5d8ecSAlexander Lobakin 	linkmode_copy(link_modes->advertising, current_link.advertised_caps);
544bdb5d8ecSAlexander Lobakin 	linkmode_copy(link_modes->lp_advertising, current_link.lp_caps);
545054c67d1SSudarsana Reddy Kalluru 
546133fac0eSSudarsana Kalluru 	if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) {
547054c67d1SSudarsana Reddy Kalluru 		base->speed = current_link.speed;
548054c67d1SSudarsana Reddy Kalluru 		base->duplex = current_link.duplex;
549133fac0eSSudarsana Kalluru 	} else {
550054c67d1SSudarsana Reddy Kalluru 		base->speed = SPEED_UNKNOWN;
551054c67d1SSudarsana Reddy Kalluru 		base->duplex = DUPLEX_UNKNOWN;
552133fac0eSSudarsana Kalluru 	}
553567b3c12SMintz, Yuval 
554567b3c12SMintz, Yuval 	__qede_unlock(edev);
555567b3c12SMintz, Yuval 
556054c67d1SSudarsana Reddy Kalluru 	base->port = current_link.port;
557054c67d1SSudarsana Reddy Kalluru 	base->autoneg = (current_link.autoneg) ? AUTONEG_ENABLE :
558133fac0eSSudarsana Kalluru 			AUTONEG_DISABLE;
559133fac0eSSudarsana Kalluru 
560133fac0eSSudarsana Kalluru 	return 0;
561133fac0eSSudarsana Kalluru }
562133fac0eSSudarsana Kalluru 
qede_set_link_ksettings(struct net_device * dev,const struct ethtool_link_ksettings * cmd)563054c67d1SSudarsana Reddy Kalluru static int qede_set_link_ksettings(struct net_device *dev,
564054c67d1SSudarsana Reddy Kalluru 				   const struct ethtool_link_ksettings *cmd)
565133fac0eSSudarsana Kalluru {
566054c67d1SSudarsana Reddy Kalluru 	const struct ethtool_link_settings *base = &cmd->base;
567133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
5681d4e4eccSAlexander Lobakin 	const struct qede_forced_speed_map *map;
569133fac0eSSudarsana Kalluru 	struct qed_link_output current_link;
570133fac0eSSudarsana Kalluru 	struct qed_link_params params;
5711d4e4eccSAlexander Lobakin 	u32 i;
572133fac0eSSudarsana Kalluru 
573fe7cd2bfSYuval Mintz 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
574054c67d1SSudarsana Reddy Kalluru 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
575133fac0eSSudarsana Kalluru 		return -EOPNOTSUPP;
576133fac0eSSudarsana Kalluru 	}
577133fac0eSSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
578133fac0eSSudarsana Kalluru 	memset(&params, 0, sizeof(params));
579133fac0eSSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
580133fac0eSSudarsana Kalluru 
581133fac0eSSudarsana Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS;
582133fac0eSSudarsana Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG;
583bdb5d8ecSAlexander Lobakin 
584054c67d1SSudarsana Reddy Kalluru 	if (base->autoneg == AUTONEG_ENABLE) {
585bdb5d8ecSAlexander Lobakin 		if (!phylink_test(current_link.supported_caps, Autoneg)) {
586161adb04Ssudarsana.kalluru@cavium.com 			DP_INFO(edev, "Auto negotiation is not supported\n");
587161adb04Ssudarsana.kalluru@cavium.com 			return -EOPNOTSUPP;
588161adb04Ssudarsana.kalluru@cavium.com 		}
589161adb04Ssudarsana.kalluru@cavium.com 
590133fac0eSSudarsana Kalluru 		params.autoneg = true;
591133fac0eSSudarsana Kalluru 		params.forced_speed = 0;
592bdb5d8ecSAlexander Lobakin 
593bdb5d8ecSAlexander Lobakin 		linkmode_copy(params.adv_speeds, cmd->link_modes.advertising);
594133fac0eSSudarsana Kalluru 	} else {		/* forced speed */
595133fac0eSSudarsana Kalluru 		params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED;
596133fac0eSSudarsana Kalluru 		params.autoneg = false;
597054c67d1SSudarsana Reddy Kalluru 		params.forced_speed = base->speed;
598bdb5d8ecSAlexander Lobakin 
5991d4e4eccSAlexander Lobakin 		for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
6001d4e4eccSAlexander Lobakin 			map = qede_forced_speed_maps + i;
601bdb5d8ecSAlexander Lobakin 
6021d4e4eccSAlexander Lobakin 			if (base->speed != map->speed ||
6031d4e4eccSAlexander Lobakin 			    !linkmode_intersects(current_link.supported_caps,
6041d4e4eccSAlexander Lobakin 						 map->caps))
6051d4e4eccSAlexander Lobakin 				continue;
6061d4e4eccSAlexander Lobakin 
6071d4e4eccSAlexander Lobakin 			linkmode_and(params.adv_speeds,
6081d4e4eccSAlexander Lobakin 				     current_link.supported_caps, map->caps);
6091d4e4eccSAlexander Lobakin 			goto set_link;
6101d4e4eccSAlexander Lobakin 		}
6111d4e4eccSAlexander Lobakin 
612054c67d1SSudarsana Reddy Kalluru 		DP_INFO(edev, "Unsupported speed %u\n", base->speed);
613133fac0eSSudarsana Kalluru 		return -EINVAL;
614133fac0eSSudarsana Kalluru 	}
615bdb5d8ecSAlexander Lobakin 
6161d4e4eccSAlexander Lobakin set_link:
617133fac0eSSudarsana Kalluru 	params.link_up = true;
618133fac0eSSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &params);
619133fac0eSSudarsana Kalluru 
620133fac0eSSudarsana Kalluru 	return 0;
621133fac0eSSudarsana Kalluru }
622133fac0eSSudarsana Kalluru 
qede_get_drvinfo(struct net_device * ndev,struct ethtool_drvinfo * info)623133fac0eSSudarsana Kalluru static void qede_get_drvinfo(struct net_device *ndev,
624133fac0eSSudarsana Kalluru 			     struct ethtool_drvinfo *info)
625133fac0eSSudarsana Kalluru {
626133fac0eSSudarsana Kalluru 	char mfw[ETHTOOL_FWVERS_LEN], storm[ETHTOOL_FWVERS_LEN];
627133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
628a88381deSSudarsana Reddy Kalluru 	char mbi[ETHTOOL_FWVERS_LEN];
629133fac0eSSudarsana Kalluru 
630f029c781SWolfram Sang 	strscpy(info->driver, "qede", sizeof(info->driver));
631133fac0eSSudarsana Kalluru 
632133fac0eSSudarsana Kalluru 	snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",
633133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_major,
634133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_minor,
635133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_rev,
636133fac0eSSudarsana Kalluru 		 edev->dev_info.common.fw_eng);
637133fac0eSSudarsana Kalluru 
638133fac0eSSudarsana Kalluru 	snprintf(mfw, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",
639133fac0eSSudarsana Kalluru 		 (edev->dev_info.common.mfw_rev >> 24) & 0xFF,
640133fac0eSSudarsana Kalluru 		 (edev->dev_info.common.mfw_rev >> 16) & 0xFF,
641133fac0eSSudarsana Kalluru 		 (edev->dev_info.common.mfw_rev >> 8) & 0xFF,
642133fac0eSSudarsana Kalluru 		 edev->dev_info.common.mfw_rev & 0xFF);
643133fac0eSSudarsana Kalluru 
64488ea96f8SShai Malin 	if ((strlen(storm) + strlen("[storm]")) <
645a88381deSSudarsana Reddy Kalluru 	    sizeof(info->version))
646a88381deSSudarsana Reddy Kalluru 		snprintf(info->version, sizeof(info->version),
64788ea96f8SShai Malin 			 "[storm %s]", storm);
648a88381deSSudarsana Reddy Kalluru 	else
649a88381deSSudarsana Reddy Kalluru 		snprintf(info->version, sizeof(info->version),
65088ea96f8SShai Malin 			 "%s", storm);
651a88381deSSudarsana Reddy Kalluru 
652a88381deSSudarsana Reddy Kalluru 	if (edev->dev_info.common.mbi_version) {
653a88381deSSudarsana Reddy Kalluru 		snprintf(mbi, ETHTOOL_FWVERS_LEN, "%d.%d.%d",
654a88381deSSudarsana Reddy Kalluru 			 (edev->dev_info.common.mbi_version &
655a88381deSSudarsana Reddy Kalluru 			  QED_MBI_VERSION_2_MASK) >> QED_MBI_VERSION_2_OFFSET,
656a88381deSSudarsana Reddy Kalluru 			 (edev->dev_info.common.mbi_version &
657a88381deSSudarsana Reddy Kalluru 			  QED_MBI_VERSION_1_MASK) >> QED_MBI_VERSION_1_OFFSET,
658a88381deSSudarsana Reddy Kalluru 			 (edev->dev_info.common.mbi_version &
659a88381deSSudarsana Reddy Kalluru 			  QED_MBI_VERSION_0_MASK) >> QED_MBI_VERSION_0_OFFSET);
660133fac0eSSudarsana Kalluru 		snprintf(info->fw_version, sizeof(info->fw_version),
661a88381deSSudarsana Reddy Kalluru 			 "mbi %s [mfw %s]", mbi, mfw);
662133fac0eSSudarsana Kalluru 	} else {
663133fac0eSSudarsana Kalluru 		snprintf(info->fw_version, sizeof(info->fw_version),
664a88381deSSudarsana Reddy Kalluru 			 "mfw %s", mfw);
665133fac0eSSudarsana Kalluru 	}
666133fac0eSSudarsana Kalluru 
667f029c781SWolfram Sang 	strscpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info));
668133fac0eSSudarsana Kalluru }
669133fac0eSSudarsana Kalluru 
qede_get_wol(struct net_device * ndev,struct ethtool_wolinfo * wol)67014d39648SMintz, Yuval static void qede_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
67114d39648SMintz, Yuval {
67214d39648SMintz, Yuval 	struct qede_dev *edev = netdev_priv(ndev);
67314d39648SMintz, Yuval 
67414d39648SMintz, Yuval 	if (edev->dev_info.common.wol_support) {
67514d39648SMintz, Yuval 		wol->supported = WAKE_MAGIC;
67614d39648SMintz, Yuval 		wol->wolopts = edev->wol_enabled ? WAKE_MAGIC : 0;
67714d39648SMintz, Yuval 	}
67814d39648SMintz, Yuval }
67914d39648SMintz, Yuval 
qede_set_wol(struct net_device * ndev,struct ethtool_wolinfo * wol)68014d39648SMintz, Yuval static int qede_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
68114d39648SMintz, Yuval {
68214d39648SMintz, Yuval 	struct qede_dev *edev = netdev_priv(ndev);
68314d39648SMintz, Yuval 	bool wol_requested;
68414d39648SMintz, Yuval 	int rc;
68514d39648SMintz, Yuval 
68614d39648SMintz, Yuval 	if (wol->wolopts & ~WAKE_MAGIC) {
68714d39648SMintz, Yuval 		DP_INFO(edev,
68814d39648SMintz, Yuval 			"Can't support WoL options other than magic-packet\n");
68914d39648SMintz, Yuval 		return -EINVAL;
69014d39648SMintz, Yuval 	}
69114d39648SMintz, Yuval 
69214d39648SMintz, Yuval 	wol_requested = !!(wol->wolopts & WAKE_MAGIC);
69314d39648SMintz, Yuval 	if (wol_requested == edev->wol_enabled)
69414d39648SMintz, Yuval 		return 0;
69514d39648SMintz, Yuval 
69614d39648SMintz, Yuval 	/* Need to actually change configuration */
69714d39648SMintz, Yuval 	if (!edev->dev_info.common.wol_support) {
69814d39648SMintz, Yuval 		DP_INFO(edev, "Device doesn't support WoL\n");
69914d39648SMintz, Yuval 		return -EINVAL;
70014d39648SMintz, Yuval 	}
70114d39648SMintz, Yuval 
70214d39648SMintz, Yuval 	rc = edev->ops->common->update_wol(edev->cdev, wol_requested);
70314d39648SMintz, Yuval 	if (!rc)
70414d39648SMintz, Yuval 		edev->wol_enabled = wol_requested;
70514d39648SMintz, Yuval 
70614d39648SMintz, Yuval 	return rc;
70714d39648SMintz, Yuval }
70814d39648SMintz, Yuval 
qede_get_msglevel(struct net_device * ndev)709133fac0eSSudarsana Kalluru static u32 qede_get_msglevel(struct net_device *ndev)
710133fac0eSSudarsana Kalluru {
711133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
712133fac0eSSudarsana Kalluru 
7131a635e48SYuval Mintz 	return ((u32)edev->dp_level << QED_LOG_LEVEL_SHIFT) | edev->dp_module;
714133fac0eSSudarsana Kalluru }
715133fac0eSSudarsana Kalluru 
qede_set_msglevel(struct net_device * ndev,u32 level)716133fac0eSSudarsana Kalluru static void qede_set_msglevel(struct net_device *ndev, u32 level)
717133fac0eSSudarsana Kalluru {
718133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
719133fac0eSSudarsana Kalluru 	u32 dp_module = 0;
720133fac0eSSudarsana Kalluru 	u8 dp_level = 0;
721133fac0eSSudarsana Kalluru 
722133fac0eSSudarsana Kalluru 	qede_config_debug(level, &dp_module, &dp_level);
723133fac0eSSudarsana Kalluru 
724133fac0eSSudarsana Kalluru 	edev->dp_level = dp_level;
725133fac0eSSudarsana Kalluru 	edev->dp_module = dp_module;
726133fac0eSSudarsana Kalluru 	edev->ops->common->update_msglvl(edev->cdev,
727133fac0eSSudarsana Kalluru 					 dp_module, dp_level);
728133fac0eSSudarsana Kalluru }
729133fac0eSSudarsana Kalluru 
qede_nway_reset(struct net_device * dev)73032a7a570SSudarsana Kalluru static int qede_nway_reset(struct net_device *dev)
73132a7a570SSudarsana Kalluru {
73232a7a570SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
73332a7a570SSudarsana Kalluru 	struct qed_link_output current_link;
73432a7a570SSudarsana Kalluru 	struct qed_link_params link_params;
73532a7a570SSudarsana Kalluru 
736fe7cd2bfSYuval Mintz 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
7371a635e48SYuval Mintz 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
738fe7cd2bfSYuval Mintz 		return -EOPNOTSUPP;
739fe7cd2bfSYuval Mintz 	}
740fe7cd2bfSYuval Mintz 
74132a7a570SSudarsana Kalluru 	if (!netif_running(dev))
74232a7a570SSudarsana Kalluru 		return 0;
74332a7a570SSudarsana Kalluru 
74432a7a570SSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
74532a7a570SSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
74632a7a570SSudarsana Kalluru 	if (!current_link.link_up)
74732a7a570SSudarsana Kalluru 		return 0;
74832a7a570SSudarsana Kalluru 
74932a7a570SSudarsana Kalluru 	/* Toggle the link */
75032a7a570SSudarsana Kalluru 	memset(&link_params, 0, sizeof(link_params));
75132a7a570SSudarsana Kalluru 	link_params.link_up = false;
75232a7a570SSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
75332a7a570SSudarsana Kalluru 	link_params.link_up = true;
75432a7a570SSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
75532a7a570SSudarsana Kalluru 
75632a7a570SSudarsana Kalluru 	return 0;
75732a7a570SSudarsana Kalluru }
75832a7a570SSudarsana Kalluru 
qede_get_link(struct net_device * dev)759133fac0eSSudarsana Kalluru static u32 qede_get_link(struct net_device *dev)
760133fac0eSSudarsana Kalluru {
761133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
762133fac0eSSudarsana Kalluru 	struct qed_link_output current_link;
763133fac0eSSudarsana Kalluru 
764133fac0eSSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
765133fac0eSSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
766133fac0eSSudarsana Kalluru 
767133fac0eSSudarsana Kalluru 	return current_link.link_up;
768133fac0eSSudarsana Kalluru }
769133fac0eSSudarsana Kalluru 
qede_flash_device(struct net_device * dev,struct ethtool_flash * flash)770ccfa110cSSudarsana Reddy Kalluru static int qede_flash_device(struct net_device *dev,
771ccfa110cSSudarsana Reddy Kalluru 			     struct ethtool_flash *flash)
772ccfa110cSSudarsana Reddy Kalluru {
773ccfa110cSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
774ccfa110cSSudarsana Reddy Kalluru 
775ccfa110cSSudarsana Reddy Kalluru 	return edev->ops->common->nvm_flash(edev->cdev, flash->data);
776ccfa110cSSudarsana Reddy Kalluru }
777ccfa110cSSudarsana Reddy Kalluru 
qede_get_coalesce(struct net_device * dev,struct ethtool_coalesce * coal,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)778d552fa84SSudarsana Reddy Kalluru static int qede_get_coalesce(struct net_device *dev,
779f3ccfda1SYufeng Mo 			     struct ethtool_coalesce *coal,
780f3ccfda1SYufeng Mo 			     struct kernel_ethtool_coalesce *kernel_coal,
781f3ccfda1SYufeng Mo 			     struct netlink_ext_ack *extack)
782d552fa84SSudarsana Reddy Kalluru {
783bf5a94bfSRahul Verma 	void *rx_handle = NULL, *tx_handle = NULL;
784d552fa84SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
785bf5a94bfSRahul Verma 	u16 rx_coal, tx_coal, i, rc = 0;
786bf5a94bfSRahul Verma 	struct qede_fastpath *fp;
787bf5a94bfSRahul Verma 
788bf5a94bfSRahul Verma 	rx_coal = QED_DEFAULT_RX_USECS;
789bf5a94bfSRahul Verma 	tx_coal = QED_DEFAULT_TX_USECS;
790d552fa84SSudarsana Reddy Kalluru 
791d552fa84SSudarsana Reddy Kalluru 	memset(coal, 0, sizeof(struct ethtool_coalesce));
792d2890deaSSudarsana Reddy Kalluru 
793bf5a94bfSRahul Verma 	__qede_lock(edev);
794bf5a94bfSRahul Verma 	if (edev->state == QEDE_STATE_OPEN) {
795bf5a94bfSRahul Verma 		for_each_queue(i) {
796bf5a94bfSRahul Verma 			fp = &edev->fp_array[i];
797d552fa84SSudarsana Reddy Kalluru 
798bf5a94bfSRahul Verma 			if (fp->type & QEDE_FASTPATH_RX) {
799bf5a94bfSRahul Verma 				rx_handle = fp->rxq->handle;
800bf5a94bfSRahul Verma 				break;
801bf5a94bfSRahul Verma 			}
802bf5a94bfSRahul Verma 		}
803bf5a94bfSRahul Verma 
804bf5a94bfSRahul Verma 		rc = edev->ops->get_coalesce(edev->cdev, &rx_coal, rx_handle);
805bf5a94bfSRahul Verma 		if (rc) {
806bf5a94bfSRahul Verma 			DP_INFO(edev, "Read Rx coalesce error\n");
807bf5a94bfSRahul Verma 			goto out;
808bf5a94bfSRahul Verma 		}
809bf5a94bfSRahul Verma 
810bf5a94bfSRahul Verma 		for_each_queue(i) {
8115e7baf0fSManish Chopra 			struct qede_tx_queue *txq;
8125e7baf0fSManish Chopra 
813bf5a94bfSRahul Verma 			fp = &edev->fp_array[i];
8145e7baf0fSManish Chopra 
8155e7baf0fSManish Chopra 			/* All TX queues of given fastpath uses same
8165e7baf0fSManish Chopra 			 * coalescing value, so no need to iterate over
8175e7baf0fSManish Chopra 			 * all TCs, TC0 txq should suffice.
8185e7baf0fSManish Chopra 			 */
819bf5a94bfSRahul Verma 			if (fp->type & QEDE_FASTPATH_TX) {
8205e7baf0fSManish Chopra 				txq = QEDE_FP_TC0_TXQ(fp);
8215e7baf0fSManish Chopra 				tx_handle = txq->handle;
822bf5a94bfSRahul Verma 				break;
823bf5a94bfSRahul Verma 			}
824bf5a94bfSRahul Verma 		}
825bf5a94bfSRahul Verma 
826bf5a94bfSRahul Verma 		rc = edev->ops->get_coalesce(edev->cdev, &tx_coal, tx_handle);
827bf5a94bfSRahul Verma 		if (rc)
828bf5a94bfSRahul Verma 			DP_INFO(edev, "Read Tx coalesce error\n");
829bf5a94bfSRahul Verma 	}
830bf5a94bfSRahul Verma 
831bf5a94bfSRahul Verma out:
832bf5a94bfSRahul Verma 	__qede_unlock(edev);
833bf5a94bfSRahul Verma 
834bf5a94bfSRahul Verma 	coal->rx_coalesce_usecs = rx_coal;
835bf5a94bfSRahul Verma 	coal->tx_coalesce_usecs = tx_coal;
836*42510dffSManish Chopra 	coal->stats_block_coalesce_usecs = edev->stats_coal_usecs;
837bf5a94bfSRahul Verma 
838bf5a94bfSRahul Verma 	return rc;
839d552fa84SSudarsana Reddy Kalluru }
840d552fa84SSudarsana Reddy Kalluru 
qede_set_coalesce(struct net_device * dev,struct ethtool_coalesce * coal,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)841f3ccfda1SYufeng Mo int qede_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal,
842f3ccfda1SYufeng Mo 		      struct kernel_ethtool_coalesce *kernel_coal,
843f3ccfda1SYufeng Mo 		      struct netlink_ext_ack *extack)
844d552fa84SSudarsana Reddy Kalluru {
845d552fa84SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
846477f2d14SRahul Verma 	struct qede_fastpath *fp;
847d552fa84SSudarsana Reddy Kalluru 	int i, rc = 0;
848477f2d14SRahul Verma 	u16 rxc, txc;
849d552fa84SSudarsana Reddy Kalluru 
850*42510dffSManish Chopra 	if (edev->stats_coal_usecs != coal->stats_block_coalesce_usecs) {
851*42510dffSManish Chopra 		edev->stats_coal_usecs = coal->stats_block_coalesce_usecs;
852*42510dffSManish Chopra 		if (edev->stats_coal_usecs) {
853*42510dffSManish Chopra 			edev->stats_coal_ticks = usecs_to_jiffies(edev->stats_coal_usecs);
854*42510dffSManish Chopra 			schedule_delayed_work(&edev->periodic_task, 0);
855*42510dffSManish Chopra 
856*42510dffSManish Chopra 			DP_INFO(edev, "Configured stats coal ticks=%lu jiffies\n",
857*42510dffSManish Chopra 				edev->stats_coal_ticks);
858*42510dffSManish Chopra 		} else {
859*42510dffSManish Chopra 			cancel_delayed_work_sync(&edev->periodic_task);
860*42510dffSManish Chopra 		}
861*42510dffSManish Chopra 	}
862*42510dffSManish Chopra 
863d552fa84SSudarsana Reddy Kalluru 	if (!netif_running(dev)) {
864d552fa84SSudarsana Reddy Kalluru 		DP_INFO(edev, "Interface is down\n");
865d552fa84SSudarsana Reddy Kalluru 		return -EINVAL;
866d552fa84SSudarsana Reddy Kalluru 	}
867d552fa84SSudarsana Reddy Kalluru 
868d552fa84SSudarsana Reddy Kalluru 	if (coal->rx_coalesce_usecs > QED_COALESCE_MAX ||
869d552fa84SSudarsana Reddy Kalluru 	    coal->tx_coalesce_usecs > QED_COALESCE_MAX) {
870d552fa84SSudarsana Reddy Kalluru 		DP_INFO(edev,
871d552fa84SSudarsana Reddy Kalluru 			"Can't support requested %s coalesce value [max supported value %d]\n",
872477f2d14SRahul Verma 			coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx" :
873477f2d14SRahul Verma 			"tx", QED_COALESCE_MAX);
874d552fa84SSudarsana Reddy Kalluru 		return -EINVAL;
875d552fa84SSudarsana Reddy Kalluru 	}
876d552fa84SSudarsana Reddy Kalluru 
877d552fa84SSudarsana Reddy Kalluru 	rxc = (u16)coal->rx_coalesce_usecs;
878d552fa84SSudarsana Reddy Kalluru 	txc = (u16)coal->tx_coalesce_usecs;
8799a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
880477f2d14SRahul Verma 		fp = &edev->fp_array[i];
881477f2d14SRahul Verma 
882477f2d14SRahul Verma 		if (edev->fp_array[i].type & QEDE_FASTPATH_RX) {
883477f2d14SRahul Verma 			rc = edev->ops->common->set_coalesce(edev->cdev,
884477f2d14SRahul Verma 							     rxc, 0,
885477f2d14SRahul Verma 							     fp->rxq->handle);
886d552fa84SSudarsana Reddy Kalluru 			if (rc) {
887477f2d14SRahul Verma 				DP_INFO(edev,
888477f2d14SRahul Verma 					"Set RX coalesce error, rc = %d\n", rc);
889d552fa84SSudarsana Reddy Kalluru 				return rc;
890d552fa84SSudarsana Reddy Kalluru 			}
891b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].rxc = rxc;
892b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].isvalid = true;
893d552fa84SSudarsana Reddy Kalluru 		}
894d552fa84SSudarsana Reddy Kalluru 
895477f2d14SRahul Verma 		if (edev->fp_array[i].type & QEDE_FASTPATH_TX) {
8965e7baf0fSManish Chopra 			struct qede_tx_queue *txq;
8975e7baf0fSManish Chopra 
8985e7baf0fSManish Chopra 			/* All TX queues of given fastpath uses same
8995e7baf0fSManish Chopra 			 * coalescing value, so no need to iterate over
9005e7baf0fSManish Chopra 			 * all TCs, TC0 txq should suffice.
9015e7baf0fSManish Chopra 			 */
9025e7baf0fSManish Chopra 			txq = QEDE_FP_TC0_TXQ(fp);
9035e7baf0fSManish Chopra 
904477f2d14SRahul Verma 			rc = edev->ops->common->set_coalesce(edev->cdev,
905477f2d14SRahul Verma 							     0, txc,
9065e7baf0fSManish Chopra 							     txq->handle);
907477f2d14SRahul Verma 			if (rc) {
908477f2d14SRahul Verma 				DP_INFO(edev,
909477f2d14SRahul Verma 					"Set TX coalesce error, rc = %d\n", rc);
910477f2d14SRahul Verma 				return rc;
911477f2d14SRahul Verma 			}
912b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].txc = txc;
913b0ec5489SBhaskar Upadhaya 			edev->coal_entry[i].isvalid = true;
914477f2d14SRahul Verma 		}
915477f2d14SRahul Verma 	}
916477f2d14SRahul Verma 
917d552fa84SSudarsana Reddy Kalluru 	return rc;
918d552fa84SSudarsana Reddy Kalluru }
919d552fa84SSudarsana Reddy Kalluru 
qede_get_ringparam(struct net_device * dev,struct ethtool_ringparam * ering,struct kernel_ethtool_ringparam * kernel_ering,struct netlink_ext_ack * extack)92001ef7e05SSudarsana Kalluru static void qede_get_ringparam(struct net_device *dev,
92174624944SHao Chen 			       struct ethtool_ringparam *ering,
92274624944SHao Chen 			       struct kernel_ethtool_ringparam *kernel_ering,
92374624944SHao Chen 			       struct netlink_ext_ack *extack)
92401ef7e05SSudarsana Kalluru {
92501ef7e05SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
92601ef7e05SSudarsana Kalluru 
92701ef7e05SSudarsana Kalluru 	ering->rx_max_pending = NUM_RX_BDS_MAX;
92801ef7e05SSudarsana Kalluru 	ering->rx_pending = edev->q_num_rx_buffers;
92901ef7e05SSudarsana Kalluru 	ering->tx_max_pending = NUM_TX_BDS_MAX;
93001ef7e05SSudarsana Kalluru 	ering->tx_pending = edev->q_num_tx_buffers;
93101ef7e05SSudarsana Kalluru }
93201ef7e05SSudarsana Kalluru 
qede_set_ringparam(struct net_device * dev,struct ethtool_ringparam * ering,struct kernel_ethtool_ringparam * kernel_ering,struct netlink_ext_ack * extack)93301ef7e05SSudarsana Kalluru static int qede_set_ringparam(struct net_device *dev,
93474624944SHao Chen 			      struct ethtool_ringparam *ering,
93574624944SHao Chen 			      struct kernel_ethtool_ringparam *kernel_ering,
93674624944SHao Chen 			      struct netlink_ext_ack *extack)
93701ef7e05SSudarsana Kalluru {
93801ef7e05SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
93901ef7e05SSudarsana Kalluru 
94001ef7e05SSudarsana Kalluru 	DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
94101ef7e05SSudarsana Kalluru 		   "Set ring params command parameters: rx_pending = %d, tx_pending = %d\n",
94201ef7e05SSudarsana Kalluru 		   ering->rx_pending, ering->tx_pending);
94301ef7e05SSudarsana Kalluru 
94401ef7e05SSudarsana Kalluru 	/* Validate legality of configuration */
94501ef7e05SSudarsana Kalluru 	if (ering->rx_pending > NUM_RX_BDS_MAX ||
94601ef7e05SSudarsana Kalluru 	    ering->rx_pending < NUM_RX_BDS_MIN ||
94701ef7e05SSudarsana Kalluru 	    ering->tx_pending > NUM_TX_BDS_MAX ||
94801ef7e05SSudarsana Kalluru 	    ering->tx_pending < NUM_TX_BDS_MIN) {
94901ef7e05SSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
95001ef7e05SSudarsana Kalluru 			   "Can only support Rx Buffer size [0%08x,...,0x%08x] and Tx Buffer size [0x%08x,...,0x%08x]\n",
95101ef7e05SSudarsana Kalluru 			   NUM_RX_BDS_MIN, NUM_RX_BDS_MAX,
95201ef7e05SSudarsana Kalluru 			   NUM_TX_BDS_MIN, NUM_TX_BDS_MAX);
95301ef7e05SSudarsana Kalluru 		return -EINVAL;
95401ef7e05SSudarsana Kalluru 	}
95501ef7e05SSudarsana Kalluru 
95601ef7e05SSudarsana Kalluru 	/* Change ring size and re-load */
95701ef7e05SSudarsana Kalluru 	edev->q_num_rx_buffers = ering->rx_pending;
95801ef7e05SSudarsana Kalluru 	edev->q_num_tx_buffers = ering->tx_pending;
95901ef7e05SSudarsana Kalluru 
960567b3c12SMintz, Yuval 	qede_reload(edev, NULL, false);
96101ef7e05SSudarsana Kalluru 
96201ef7e05SSudarsana Kalluru 	return 0;
96301ef7e05SSudarsana Kalluru }
96401ef7e05SSudarsana Kalluru 
qede_get_pauseparam(struct net_device * dev,struct ethtool_pauseparam * epause)9650f7db144SSudarsana Kalluru static void qede_get_pauseparam(struct net_device *dev,
9660f7db144SSudarsana Kalluru 				struct ethtool_pauseparam *epause)
9670f7db144SSudarsana Kalluru {
9680f7db144SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
9690f7db144SSudarsana Kalluru 	struct qed_link_output current_link;
9700f7db144SSudarsana Kalluru 
9710f7db144SSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
9720f7db144SSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
9730f7db144SSudarsana Kalluru 
9740f7db144SSudarsana Kalluru 	if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
9750f7db144SSudarsana Kalluru 		epause->autoneg = true;
9760f7db144SSudarsana Kalluru 	if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE)
9770f7db144SSudarsana Kalluru 		epause->rx_pause = true;
9780f7db144SSudarsana Kalluru 	if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE)
9790f7db144SSudarsana Kalluru 		epause->tx_pause = true;
9800f7db144SSudarsana Kalluru 
9810f7db144SSudarsana Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
9820f7db144SSudarsana Kalluru 		   "ethtool_pauseparam: cmd %d  autoneg %d  rx_pause %d  tx_pause %d\n",
9830f7db144SSudarsana Kalluru 		   epause->cmd, epause->autoneg, epause->rx_pause,
9840f7db144SSudarsana Kalluru 		   epause->tx_pause);
9850f7db144SSudarsana Kalluru }
9860f7db144SSudarsana Kalluru 
qede_set_pauseparam(struct net_device * dev,struct ethtool_pauseparam * epause)9870f7db144SSudarsana Kalluru static int qede_set_pauseparam(struct net_device *dev,
9880f7db144SSudarsana Kalluru 			       struct ethtool_pauseparam *epause)
9890f7db144SSudarsana Kalluru {
9900f7db144SSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
9910f7db144SSudarsana Kalluru 	struct qed_link_params params;
9920f7db144SSudarsana Kalluru 	struct qed_link_output current_link;
9930f7db144SSudarsana Kalluru 
994fe7cd2bfSYuval Mintz 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
9950f7db144SSudarsana Kalluru 		DP_INFO(edev,
996fe7cd2bfSYuval Mintz 			"Pause settings are not allowed to be changed\n");
9970f7db144SSudarsana Kalluru 		return -EOPNOTSUPP;
9980f7db144SSudarsana Kalluru 	}
9990f7db144SSudarsana Kalluru 
10000f7db144SSudarsana Kalluru 	memset(&current_link, 0, sizeof(current_link));
10010f7db144SSudarsana Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
10020f7db144SSudarsana Kalluru 
10030f7db144SSudarsana Kalluru 	memset(&params, 0, sizeof(params));
10040f7db144SSudarsana Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG;
1005bdb5d8ecSAlexander Lobakin 
10060f7db144SSudarsana Kalluru 	if (epause->autoneg) {
1007bdb5d8ecSAlexander Lobakin 		if (!phylink_test(current_link.supported_caps, Autoneg)) {
10080f7db144SSudarsana Kalluru 			DP_INFO(edev, "autoneg not supported\n");
10090f7db144SSudarsana Kalluru 			return -EINVAL;
10100f7db144SSudarsana Kalluru 		}
1011bdb5d8ecSAlexander Lobakin 
10120f7db144SSudarsana Kalluru 		params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
10130f7db144SSudarsana Kalluru 	}
1014bdb5d8ecSAlexander Lobakin 
10150f7db144SSudarsana Kalluru 	if (epause->rx_pause)
10160f7db144SSudarsana Kalluru 		params.pause_config |= QED_LINK_PAUSE_RX_ENABLE;
10170f7db144SSudarsana Kalluru 	if (epause->tx_pause)
10180f7db144SSudarsana Kalluru 		params.pause_config |= QED_LINK_PAUSE_TX_ENABLE;
10190f7db144SSudarsana Kalluru 
10200f7db144SSudarsana Kalluru 	params.link_up = true;
10210f7db144SSudarsana Kalluru 	edev->ops->common->set_link(edev->cdev, &params);
10220f7db144SSudarsana Kalluru 
10230f7db144SSudarsana Kalluru 	return 0;
10240f7db144SSudarsana Kalluru }
10250f7db144SSudarsana Kalluru 
qede_get_regs(struct net_device * ndev,struct ethtool_regs * regs,void * buffer)1026e0971c83STomer Tayar static void qede_get_regs(struct net_device *ndev,
1027e0971c83STomer Tayar 			  struct ethtool_regs *regs, void *buffer)
1028e0971c83STomer Tayar {
1029e0971c83STomer Tayar 	struct qede_dev *edev = netdev_priv(ndev);
1030e0971c83STomer Tayar 
1031e0971c83STomer Tayar 	regs->version = 0;
1032e0971c83STomer Tayar 	memset(buffer, 0, regs->len);
1033e0971c83STomer Tayar 
1034e0971c83STomer Tayar 	if (edev->ops && edev->ops->common)
1035e0971c83STomer Tayar 		edev->ops->common->dbg_all_data(edev->cdev, buffer);
1036e0971c83STomer Tayar }
1037e0971c83STomer Tayar 
qede_get_regs_len(struct net_device * ndev)1038e0971c83STomer Tayar static int qede_get_regs_len(struct net_device *ndev)
1039e0971c83STomer Tayar {
1040e0971c83STomer Tayar 	struct qede_dev *edev = netdev_priv(ndev);
1041e0971c83STomer Tayar 
1042e0971c83STomer Tayar 	if (edev->ops && edev->ops->common)
1043e0971c83STomer Tayar 		return edev->ops->common->dbg_all_data_size(edev->cdev);
1044e0971c83STomer Tayar 	else
1045e0971c83STomer Tayar 		return -EINVAL;
1046e0971c83STomer Tayar }
1047e0971c83STomer Tayar 
qede_update_mtu(struct qede_dev * edev,struct qede_reload_args * args)1048567b3c12SMintz, Yuval static void qede_update_mtu(struct qede_dev *edev,
1049567b3c12SMintz, Yuval 			    struct qede_reload_args *args)
1050133fac0eSSudarsana Kalluru {
1051567b3c12SMintz, Yuval 	edev->ndev->mtu = args->u.mtu;
1052133fac0eSSudarsana Kalluru }
1053133fac0eSSudarsana Kalluru 
1054133fac0eSSudarsana Kalluru /* Netdevice NDOs */
qede_change_mtu(struct net_device * ndev,int new_mtu)1055133fac0eSSudarsana Kalluru int qede_change_mtu(struct net_device *ndev, int new_mtu)
1056133fac0eSSudarsana Kalluru {
1057133fac0eSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(ndev);
1058567b3c12SMintz, Yuval 	struct qede_reload_args args;
1059133fac0eSSudarsana Kalluru 
1060133fac0eSSudarsana Kalluru 	DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
1061133fac0eSSudarsana Kalluru 		   "Configuring MTU size of %d\n", new_mtu);
1062133fac0eSSudarsana Kalluru 
106318c602deSMichael Chan 	if (new_mtu > PAGE_SIZE)
106418c602deSMichael Chan 		ndev->features &= ~NETIF_F_GRO_HW;
106518c602deSMichael Chan 
1066133fac0eSSudarsana Kalluru 	/* Set the mtu field and re-start the interface if needed */
1067567b3c12SMintz, Yuval 	args.u.mtu = new_mtu;
1068567b3c12SMintz, Yuval 	args.func = &qede_update_mtu;
1069567b3c12SMintz, Yuval 	qede_reload(edev, &args, false);
107097fb3e33SMichal Kalderon #if IS_ENABLED(CONFIG_QED_RDMA)
107197fb3e33SMichal Kalderon 	qede_rdma_event_change_mtu(edev);
107297fb3e33SMichal Kalderon #endif
1073567b3c12SMintz, Yuval 	edev->ops->common->update_mtu(edev->cdev, new_mtu);
10740fefbfbaSSudarsana Kalluru 
1075133fac0eSSudarsana Kalluru 	return 0;
1076133fac0eSSudarsana Kalluru }
1077133fac0eSSudarsana Kalluru 
qede_get_channels(struct net_device * dev,struct ethtool_channels * channels)10788edf049dSSudarsana Kalluru static void qede_get_channels(struct net_device *dev,
10798edf049dSSudarsana Kalluru 			      struct ethtool_channels *channels)
10808edf049dSSudarsana Kalluru {
10818edf049dSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
10828edf049dSSudarsana Kalluru 
10838edf049dSSudarsana Kalluru 	channels->max_combined = QEDE_MAX_RSS_CNT(edev);
1084bdc8cbd3SSudarsana Reddy Kalluru 	channels->max_rx = QEDE_MAX_RSS_CNT(edev);
1085bdc8cbd3SSudarsana Reddy Kalluru 	channels->max_tx = QEDE_MAX_RSS_CNT(edev);
10869a4d7e86SSudarsana Reddy Kalluru 	channels->combined_count = QEDE_QUEUE_CNT(edev) - edev->fp_num_tx -
10879a4d7e86SSudarsana Reddy Kalluru 					edev->fp_num_rx;
10889a4d7e86SSudarsana Reddy Kalluru 	channels->tx_count = edev->fp_num_tx;
10899a4d7e86SSudarsana Reddy Kalluru 	channels->rx_count = edev->fp_num_rx;
10908edf049dSSudarsana Kalluru }
10918edf049dSSudarsana Kalluru 
qede_set_channels(struct net_device * dev,struct ethtool_channels * channels)10928edf049dSSudarsana Kalluru static int qede_set_channels(struct net_device *dev,
10938edf049dSSudarsana Kalluru 			     struct ethtool_channels *channels)
10948edf049dSSudarsana Kalluru {
10958edf049dSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
10969a4d7e86SSudarsana Reddy Kalluru 	u32 count;
10978edf049dSSudarsana Kalluru 
10988edf049dSSudarsana Kalluru 	DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
10998edf049dSSudarsana Kalluru 		   "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n",
11008edf049dSSudarsana Kalluru 		   channels->rx_count, channels->tx_count,
11018edf049dSSudarsana Kalluru 		   channels->other_count, channels->combined_count);
11028edf049dSSudarsana Kalluru 
11039a4d7e86SSudarsana Reddy Kalluru 	count = channels->rx_count + channels->tx_count +
11049a4d7e86SSudarsana Reddy Kalluru 			channels->combined_count;
11059a4d7e86SSudarsana Reddy Kalluru 
11069a4d7e86SSudarsana Reddy Kalluru 	/* We don't support `other' channels */
11079a4d7e86SSudarsana Reddy Kalluru 	if (channels->other_count) {
11088edf049dSSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11098edf049dSSudarsana Kalluru 			   "command parameters not supported\n");
11108edf049dSSudarsana Kalluru 		return -EINVAL;
11118edf049dSSudarsana Kalluru 	}
11128edf049dSSudarsana Kalluru 
11139a4d7e86SSudarsana Reddy Kalluru 	if (!(channels->combined_count || (channels->rx_count &&
11149a4d7e86SSudarsana Reddy Kalluru 					   channels->tx_count))) {
11159a4d7e86SSudarsana Reddy Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11169a4d7e86SSudarsana Reddy Kalluru 			   "need to request at least one transmit and one receive channel\n");
11179a4d7e86SSudarsana Reddy Kalluru 		return -EINVAL;
11189a4d7e86SSudarsana Reddy Kalluru 	}
11199a4d7e86SSudarsana Reddy Kalluru 
11209a4d7e86SSudarsana Reddy Kalluru 	if (count > QEDE_MAX_RSS_CNT(edev)) {
11219a4d7e86SSudarsana Reddy Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11229a4d7e86SSudarsana Reddy Kalluru 			   "requested channels = %d max supported channels = %d\n",
11239a4d7e86SSudarsana Reddy Kalluru 			   count, QEDE_MAX_RSS_CNT(edev));
11249a4d7e86SSudarsana Reddy Kalluru 		return -EINVAL;
11259a4d7e86SSudarsana Reddy Kalluru 	}
11269a4d7e86SSudarsana Reddy Kalluru 
11278edf049dSSudarsana Kalluru 	/* Check if there was a change in the active parameters */
11289a4d7e86SSudarsana Reddy Kalluru 	if ((count == QEDE_QUEUE_CNT(edev)) &&
11299a4d7e86SSudarsana Reddy Kalluru 	    (channels->tx_count == edev->fp_num_tx) &&
11309a4d7e86SSudarsana Reddy Kalluru 	    (channels->rx_count == edev->fp_num_rx)) {
11318edf049dSSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11328edf049dSSudarsana Kalluru 			   "No change in active parameters\n");
11338edf049dSSudarsana Kalluru 		return 0;
11348edf049dSSudarsana Kalluru 	}
11358edf049dSSudarsana Kalluru 
11368edf049dSSudarsana Kalluru 	/* We need the number of queues to be divisible between the hwfns */
11379a4d7e86SSudarsana Reddy Kalluru 	if ((count % edev->dev_info.common.num_hwfns) ||
11389a4d7e86SSudarsana Reddy Kalluru 	    (channels->tx_count % edev->dev_info.common.num_hwfns) ||
11399a4d7e86SSudarsana Reddy Kalluru 	    (channels->rx_count % edev->dev_info.common.num_hwfns)) {
11408edf049dSSudarsana Kalluru 		DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
11419a4d7e86SSudarsana Reddy Kalluru 			   "Number of channels must be divisible by %04x\n",
11428edf049dSSudarsana Kalluru 			   edev->dev_info.common.num_hwfns);
11438edf049dSSudarsana Kalluru 		return -EINVAL;
11448edf049dSSudarsana Kalluru 	}
11458edf049dSSudarsana Kalluru 
11468edf049dSSudarsana Kalluru 	/* Set number of queues and reload if necessary */
11479a4d7e86SSudarsana Reddy Kalluru 	edev->req_queues = count;
11489a4d7e86SSudarsana Reddy Kalluru 	edev->req_num_tx = channels->tx_count;
11499a4d7e86SSudarsana Reddy Kalluru 	edev->req_num_rx = channels->rx_count;
1150ed0dd915SSudarsana Reddy Kalluru 	/* Reset the indirection table if rx queue count is updated */
1151ed0dd915SSudarsana Reddy Kalluru 	if ((edev->req_queues - edev->req_num_tx) != QEDE_RSS_COUNT(edev)) {
1152ed0dd915SSudarsana Reddy Kalluru 		edev->rss_params_inited &= ~QEDE_RSS_INDIR_INITED;
1153f29ffdb6SMintz, Yuval 		memset(edev->rss_ind_table, 0, sizeof(edev->rss_ind_table));
1154ed0dd915SSudarsana Reddy Kalluru 	}
1155ed0dd915SSudarsana Reddy Kalluru 
1156567b3c12SMintz, Yuval 	qede_reload(edev, NULL, false);
11578edf049dSSudarsana Kalluru 
11588edf049dSSudarsana Kalluru 	return 0;
11598edf049dSSudarsana Kalluru }
11608edf049dSSudarsana Kalluru 
qede_get_ts_info(struct net_device * dev,struct ethtool_ts_info * info)11614c55215cSSudarsana Reddy Kalluru static int qede_get_ts_info(struct net_device *dev,
11624c55215cSSudarsana Reddy Kalluru 			    struct ethtool_ts_info *info)
11634c55215cSSudarsana Reddy Kalluru {
11644c55215cSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
11654c55215cSSudarsana Reddy Kalluru 
11664c55215cSSudarsana Reddy Kalluru 	return qede_ptp_get_ts_info(edev, info);
11674c55215cSSudarsana Reddy Kalluru }
11684c55215cSSudarsana Reddy Kalluru 
qede_set_phys_id(struct net_device * dev,enum ethtool_phys_id_state state)11693d971cbdSSudarsana Kalluru static int qede_set_phys_id(struct net_device *dev,
11703d971cbdSSudarsana Kalluru 			    enum ethtool_phys_id_state state)
11713d971cbdSSudarsana Kalluru {
11723d971cbdSSudarsana Kalluru 	struct qede_dev *edev = netdev_priv(dev);
11733d971cbdSSudarsana Kalluru 	u8 led_state = 0;
11743d971cbdSSudarsana Kalluru 
11753d971cbdSSudarsana Kalluru 	switch (state) {
11763d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_ACTIVE:
11773d971cbdSSudarsana Kalluru 		return 1;	/* cycle on/off once per second */
11783d971cbdSSudarsana Kalluru 
11793d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_ON:
11803d971cbdSSudarsana Kalluru 		led_state = QED_LED_MODE_ON;
11813d971cbdSSudarsana Kalluru 		break;
11823d971cbdSSudarsana Kalluru 
11833d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_OFF:
11843d971cbdSSudarsana Kalluru 		led_state = QED_LED_MODE_OFF;
11853d971cbdSSudarsana Kalluru 		break;
11863d971cbdSSudarsana Kalluru 
11873d971cbdSSudarsana Kalluru 	case ETHTOOL_ID_INACTIVE:
11883d971cbdSSudarsana Kalluru 		led_state = QED_LED_MODE_RESTORE;
11893d971cbdSSudarsana Kalluru 		break;
11903d971cbdSSudarsana Kalluru 	}
11913d971cbdSSudarsana Kalluru 
11923d971cbdSSudarsana Kalluru 	edev->ops->common->set_led(edev->cdev, led_state);
11933d971cbdSSudarsana Kalluru 
11943d971cbdSSudarsana Kalluru 	return 0;
11953d971cbdSSudarsana Kalluru }
11963d971cbdSSudarsana Kalluru 
qede_get_rss_flags(struct qede_dev * edev,struct ethtool_rxnfc * info)1197961acdeaSSudarsana Reddy Kalluru static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
1198961acdeaSSudarsana Reddy Kalluru {
1199961acdeaSSudarsana Reddy Kalluru 	info->data = RXH_IP_SRC | RXH_IP_DST;
1200961acdeaSSudarsana Reddy Kalluru 
1201961acdeaSSudarsana Reddy Kalluru 	switch (info->flow_type) {
1202961acdeaSSudarsana Reddy Kalluru 	case TCP_V4_FLOW:
1203961acdeaSSudarsana Reddy Kalluru 	case TCP_V6_FLOW:
1204961acdeaSSudarsana Reddy Kalluru 		info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1205961acdeaSSudarsana Reddy Kalluru 		break;
1206961acdeaSSudarsana Reddy Kalluru 	case UDP_V4_FLOW:
1207f29ffdb6SMintz, Yuval 		if (edev->rss_caps & QED_RSS_IPV4_UDP)
1208961acdeaSSudarsana Reddy Kalluru 			info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1209961acdeaSSudarsana Reddy Kalluru 		break;
1210961acdeaSSudarsana Reddy Kalluru 	case UDP_V6_FLOW:
1211f29ffdb6SMintz, Yuval 		if (edev->rss_caps & QED_RSS_IPV6_UDP)
1212961acdeaSSudarsana Reddy Kalluru 			info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1213961acdeaSSudarsana Reddy Kalluru 		break;
1214961acdeaSSudarsana Reddy Kalluru 	case IPV4_FLOW:
1215961acdeaSSudarsana Reddy Kalluru 	case IPV6_FLOW:
1216961acdeaSSudarsana Reddy Kalluru 		break;
1217961acdeaSSudarsana Reddy Kalluru 	default:
1218961acdeaSSudarsana Reddy Kalluru 		info->data = 0;
1219961acdeaSSudarsana Reddy Kalluru 		break;
1220961acdeaSSudarsana Reddy Kalluru 	}
1221961acdeaSSudarsana Reddy Kalluru 
1222961acdeaSSudarsana Reddy Kalluru 	return 0;
1223961acdeaSSudarsana Reddy Kalluru }
1224961acdeaSSudarsana Reddy Kalluru 
qede_get_rxnfc(struct net_device * dev,struct ethtool_rxnfc * info,u32 * rule_locs)1225961acdeaSSudarsana Reddy Kalluru static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
1226ec9b8dbdSChopra, Manish 			  u32 *rule_locs)
1227961acdeaSSudarsana Reddy Kalluru {
1228961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1229ec9b8dbdSChopra, Manish 	int rc = 0;
1230961acdeaSSudarsana Reddy Kalluru 
1231961acdeaSSudarsana Reddy Kalluru 	switch (info->cmd) {
1232961acdeaSSudarsana Reddy Kalluru 	case ETHTOOL_GRXRINGS:
12339a4d7e86SSudarsana Reddy Kalluru 		info->data = QEDE_RSS_COUNT(edev);
1234ec9b8dbdSChopra, Manish 		break;
1235961acdeaSSudarsana Reddy Kalluru 	case ETHTOOL_GRXFH:
1236ec9b8dbdSChopra, Manish 		rc = qede_get_rss_flags(edev, info);
1237ec9b8dbdSChopra, Manish 		break;
1238ec9b8dbdSChopra, Manish 	case ETHTOOL_GRXCLSRLCNT:
1239ec9b8dbdSChopra, Manish 		info->rule_cnt = qede_get_arfs_filter_count(edev);
1240ec9b8dbdSChopra, Manish 		info->data = QEDE_RFS_MAX_FLTR;
1241ec9b8dbdSChopra, Manish 		break;
1242ec9b8dbdSChopra, Manish 	case ETHTOOL_GRXCLSRULE:
1243ec9b8dbdSChopra, Manish 		rc = qede_get_cls_rule_entry(edev, info);
1244ec9b8dbdSChopra, Manish 		break;
1245ec9b8dbdSChopra, Manish 	case ETHTOOL_GRXCLSRLALL:
1246ec9b8dbdSChopra, Manish 		rc = qede_get_cls_rule_all(edev, info, rule_locs);
1247ec9b8dbdSChopra, Manish 		break;
1248961acdeaSSudarsana Reddy Kalluru 	default:
1249961acdeaSSudarsana Reddy Kalluru 		DP_ERR(edev, "Command parameters not supported\n");
1250ec9b8dbdSChopra, Manish 		rc = -EOPNOTSUPP;
1251961acdeaSSudarsana Reddy Kalluru 	}
1252ec9b8dbdSChopra, Manish 
1253ec9b8dbdSChopra, Manish 	return rc;
1254961acdeaSSudarsana Reddy Kalluru }
1255961acdeaSSudarsana Reddy Kalluru 
qede_set_rss_flags(struct qede_dev * edev,struct ethtool_rxnfc * info)1256961acdeaSSudarsana Reddy Kalluru static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
1257961acdeaSSudarsana Reddy Kalluru {
1258f29ffdb6SMintz, Yuval 	struct qed_update_vport_params *vport_update_params;
1259961acdeaSSudarsana Reddy Kalluru 	u8 set_caps = 0, clr_caps = 0;
1260f29ffdb6SMintz, Yuval 	int rc = 0;
1261961acdeaSSudarsana Reddy Kalluru 
1262961acdeaSSudarsana Reddy Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
1263961acdeaSSudarsana Reddy Kalluru 		   "Set rss flags command parameters: flow type = %d, data = %llu\n",
1264961acdeaSSudarsana Reddy Kalluru 		   info->flow_type, info->data);
1265961acdeaSSudarsana Reddy Kalluru 
1266961acdeaSSudarsana Reddy Kalluru 	switch (info->flow_type) {
1267961acdeaSSudarsana Reddy Kalluru 	case TCP_V4_FLOW:
1268961acdeaSSudarsana Reddy Kalluru 	case TCP_V6_FLOW:
1269961acdeaSSudarsana Reddy Kalluru 		/* For TCP only 4-tuple hash is supported */
1270961acdeaSSudarsana Reddy Kalluru 		if (info->data ^ (RXH_IP_SRC | RXH_IP_DST |
1271961acdeaSSudarsana Reddy Kalluru 				  RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1272961acdeaSSudarsana Reddy Kalluru 			DP_INFO(edev, "Command parameters not supported\n");
1273961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1274961acdeaSSudarsana Reddy Kalluru 		}
1275961acdeaSSudarsana Reddy Kalluru 		return 0;
1276961acdeaSSudarsana Reddy Kalluru 	case UDP_V4_FLOW:
1277961acdeaSSudarsana Reddy Kalluru 		/* For UDP either 2-tuple hash or 4-tuple hash is supported */
1278961acdeaSSudarsana Reddy Kalluru 		if (info->data == (RXH_IP_SRC | RXH_IP_DST |
1279961acdeaSSudarsana Reddy Kalluru 				   RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1280961acdeaSSudarsana Reddy Kalluru 			set_caps = QED_RSS_IPV4_UDP;
1281961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1282961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple enabled\n");
1283961acdeaSSudarsana Reddy Kalluru 		} else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
1284961acdeaSSudarsana Reddy Kalluru 			clr_caps = QED_RSS_IPV4_UDP;
1285961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1286961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple disabled\n");
1287961acdeaSSudarsana Reddy Kalluru 		} else {
1288961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1289961acdeaSSudarsana Reddy Kalluru 		}
1290961acdeaSSudarsana Reddy Kalluru 		break;
1291961acdeaSSudarsana Reddy Kalluru 	case UDP_V6_FLOW:
1292961acdeaSSudarsana Reddy Kalluru 		/* For UDP either 2-tuple hash or 4-tuple hash is supported */
1293961acdeaSSudarsana Reddy Kalluru 		if (info->data == (RXH_IP_SRC | RXH_IP_DST |
1294961acdeaSSudarsana Reddy Kalluru 				   RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1295961acdeaSSudarsana Reddy Kalluru 			set_caps = QED_RSS_IPV6_UDP;
1296961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1297961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple enabled\n");
1298961acdeaSSudarsana Reddy Kalluru 		} else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
1299961acdeaSSudarsana Reddy Kalluru 			clr_caps = QED_RSS_IPV6_UDP;
1300961acdeaSSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
1301961acdeaSSudarsana Reddy Kalluru 				   "UDP 4-tuple disabled\n");
1302961acdeaSSudarsana Reddy Kalluru 		} else {
1303961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1304961acdeaSSudarsana Reddy Kalluru 		}
1305961acdeaSSudarsana Reddy Kalluru 		break;
1306961acdeaSSudarsana Reddy Kalluru 	case IPV4_FLOW:
1307961acdeaSSudarsana Reddy Kalluru 	case IPV6_FLOW:
1308961acdeaSSudarsana Reddy Kalluru 		/* For IP only 2-tuple hash is supported */
1309961acdeaSSudarsana Reddy Kalluru 		if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) {
1310961acdeaSSudarsana Reddy Kalluru 			DP_INFO(edev, "Command parameters not supported\n");
1311961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1312961acdeaSSudarsana Reddy Kalluru 		}
1313961acdeaSSudarsana Reddy Kalluru 		return 0;
1314961acdeaSSudarsana Reddy Kalluru 	case SCTP_V4_FLOW:
1315961acdeaSSudarsana Reddy Kalluru 	case AH_ESP_V4_FLOW:
1316961acdeaSSudarsana Reddy Kalluru 	case AH_V4_FLOW:
1317961acdeaSSudarsana Reddy Kalluru 	case ESP_V4_FLOW:
1318961acdeaSSudarsana Reddy Kalluru 	case SCTP_V6_FLOW:
1319961acdeaSSudarsana Reddy Kalluru 	case AH_ESP_V6_FLOW:
1320961acdeaSSudarsana Reddy Kalluru 	case AH_V6_FLOW:
1321961acdeaSSudarsana Reddy Kalluru 	case ESP_V6_FLOW:
1322961acdeaSSudarsana Reddy Kalluru 	case IP_USER_FLOW:
1323961acdeaSSudarsana Reddy Kalluru 	case ETHER_FLOW:
1324961acdeaSSudarsana Reddy Kalluru 		/* RSS is not supported for these protocols */
1325961acdeaSSudarsana Reddy Kalluru 		if (info->data) {
1326961acdeaSSudarsana Reddy Kalluru 			DP_INFO(edev, "Command parameters not supported\n");
1327961acdeaSSudarsana Reddy Kalluru 			return -EINVAL;
1328961acdeaSSudarsana Reddy Kalluru 		}
1329961acdeaSSudarsana Reddy Kalluru 		return 0;
1330961acdeaSSudarsana Reddy Kalluru 	default:
1331961acdeaSSudarsana Reddy Kalluru 		return -EINVAL;
1332961acdeaSSudarsana Reddy Kalluru 	}
1333961acdeaSSudarsana Reddy Kalluru 
1334961acdeaSSudarsana Reddy Kalluru 	/* No action is needed if there is no change in the rss capability */
1335f29ffdb6SMintz, Yuval 	if (edev->rss_caps == ((edev->rss_caps & ~clr_caps) | set_caps))
1336961acdeaSSudarsana Reddy Kalluru 		return 0;
1337961acdeaSSudarsana Reddy Kalluru 
1338961acdeaSSudarsana Reddy Kalluru 	/* Update internal configuration */
1339f29ffdb6SMintz, Yuval 	edev->rss_caps = ((edev->rss_caps & ~clr_caps) | set_caps);
1340961acdeaSSudarsana Reddy Kalluru 	edev->rss_params_inited |= QEDE_RSS_CAPS_INITED;
1341961acdeaSSudarsana Reddy Kalluru 
1342961acdeaSSudarsana Reddy Kalluru 	/* Re-configure if possible */
1343f29ffdb6SMintz, Yuval 	__qede_lock(edev);
1344f29ffdb6SMintz, Yuval 	if (edev->state == QEDE_STATE_OPEN) {
1345f29ffdb6SMintz, Yuval 		vport_update_params = vzalloc(sizeof(*vport_update_params));
1346f29ffdb6SMintz, Yuval 		if (!vport_update_params) {
1347f29ffdb6SMintz, Yuval 			__qede_unlock(edev);
1348f29ffdb6SMintz, Yuval 			return -ENOMEM;
1349961acdeaSSudarsana Reddy Kalluru 		}
1350f29ffdb6SMintz, Yuval 		qede_fill_rss_params(edev, &vport_update_params->rss_params,
1351f29ffdb6SMintz, Yuval 				     &vport_update_params->update_rss_flg);
1352f29ffdb6SMintz, Yuval 		rc = edev->ops->vport_update(edev->cdev, vport_update_params);
1353f29ffdb6SMintz, Yuval 		vfree(vport_update_params);
1354f29ffdb6SMintz, Yuval 	}
1355f29ffdb6SMintz, Yuval 	__qede_unlock(edev);
1356961acdeaSSudarsana Reddy Kalluru 
1357f29ffdb6SMintz, Yuval 	return rc;
1358961acdeaSSudarsana Reddy Kalluru }
1359961acdeaSSudarsana Reddy Kalluru 
qede_set_rxnfc(struct net_device * dev,struct ethtool_rxnfc * info)1360961acdeaSSudarsana Reddy Kalluru static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
1361961acdeaSSudarsana Reddy Kalluru {
1362961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
13633f2a2b8bSChopra, Manish 	int rc;
1364961acdeaSSudarsana Reddy Kalluru 
1365961acdeaSSudarsana Reddy Kalluru 	switch (info->cmd) {
1366961acdeaSSudarsana Reddy Kalluru 	case ETHTOOL_SRXFH:
13673f2a2b8bSChopra, Manish 		rc = qede_set_rss_flags(edev, info);
13683f2a2b8bSChopra, Manish 		break;
13693f2a2b8bSChopra, Manish 	case ETHTOOL_SRXCLSRLINS:
13703f2a2b8bSChopra, Manish 		rc = qede_add_cls_rule(edev, info);
13713f2a2b8bSChopra, Manish 		break;
13723f2a2b8bSChopra, Manish 	case ETHTOOL_SRXCLSRLDEL:
13732ce9c93eSManish Chopra 		rc = qede_delete_flow_filter(edev, info->fs.location);
13743f2a2b8bSChopra, Manish 		break;
1375961acdeaSSudarsana Reddy Kalluru 	default:
1376961acdeaSSudarsana Reddy Kalluru 		DP_INFO(edev, "Command parameters not supported\n");
13773f2a2b8bSChopra, Manish 		rc = -EOPNOTSUPP;
1378961acdeaSSudarsana Reddy Kalluru 	}
13793f2a2b8bSChopra, Manish 
13803f2a2b8bSChopra, Manish 	return rc;
1381961acdeaSSudarsana Reddy Kalluru }
1382961acdeaSSudarsana Reddy Kalluru 
qede_get_rxfh_indir_size(struct net_device * dev)1383961acdeaSSudarsana Reddy Kalluru static u32 qede_get_rxfh_indir_size(struct net_device *dev)
1384961acdeaSSudarsana Reddy Kalluru {
1385961acdeaSSudarsana Reddy Kalluru 	return QED_RSS_IND_TABLE_SIZE;
1386961acdeaSSudarsana Reddy Kalluru }
1387961acdeaSSudarsana Reddy Kalluru 
qede_get_rxfh_key_size(struct net_device * dev)1388961acdeaSSudarsana Reddy Kalluru static u32 qede_get_rxfh_key_size(struct net_device *dev)
1389961acdeaSSudarsana Reddy Kalluru {
1390961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1391961acdeaSSudarsana Reddy Kalluru 
1392f29ffdb6SMintz, Yuval 	return sizeof(edev->rss_key);
1393961acdeaSSudarsana Reddy Kalluru }
1394961acdeaSSudarsana Reddy Kalluru 
qede_get_rxfh(struct net_device * dev,u32 * indir,u8 * key,u8 * hfunc)1395961acdeaSSudarsana Reddy Kalluru static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
1396961acdeaSSudarsana Reddy Kalluru {
1397961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1398961acdeaSSudarsana Reddy Kalluru 	int i;
1399961acdeaSSudarsana Reddy Kalluru 
1400961acdeaSSudarsana Reddy Kalluru 	if (hfunc)
1401961acdeaSSudarsana Reddy Kalluru 		*hfunc = ETH_RSS_HASH_TOP;
1402961acdeaSSudarsana Reddy Kalluru 
1403961acdeaSSudarsana Reddy Kalluru 	if (!indir)
1404961acdeaSSudarsana Reddy Kalluru 		return 0;
1405961acdeaSSudarsana Reddy Kalluru 
1406961acdeaSSudarsana Reddy Kalluru 	for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
1407f29ffdb6SMintz, Yuval 		indir[i] = edev->rss_ind_table[i];
1408961acdeaSSudarsana Reddy Kalluru 
1409961acdeaSSudarsana Reddy Kalluru 	if (key)
1410f29ffdb6SMintz, Yuval 		memcpy(key, edev->rss_key, qede_get_rxfh_key_size(dev));
1411961acdeaSSudarsana Reddy Kalluru 
1412961acdeaSSudarsana Reddy Kalluru 	return 0;
1413961acdeaSSudarsana Reddy Kalluru }
1414961acdeaSSudarsana Reddy Kalluru 
qede_set_rxfh(struct net_device * dev,const u32 * indir,const u8 * key,const u8 hfunc)1415961acdeaSSudarsana Reddy Kalluru static int qede_set_rxfh(struct net_device *dev, const u32 *indir,
1416961acdeaSSudarsana Reddy Kalluru 			 const u8 *key, const u8 hfunc)
1417961acdeaSSudarsana Reddy Kalluru {
1418f29ffdb6SMintz, Yuval 	struct qed_update_vport_params *vport_update_params;
1419961acdeaSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1420f29ffdb6SMintz, Yuval 	int i, rc = 0;
1421961acdeaSSudarsana Reddy Kalluru 
1422ba300ce3SSudarsana Reddy Kalluru 	if (edev->dev_info.common.num_hwfns > 1) {
1423ba300ce3SSudarsana Reddy Kalluru 		DP_INFO(edev,
1424ba300ce3SSudarsana Reddy Kalluru 			"RSS configuration is not supported for 100G devices\n");
1425ba300ce3SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1426ba300ce3SSudarsana Reddy Kalluru 	}
1427ba300ce3SSudarsana Reddy Kalluru 
1428961acdeaSSudarsana Reddy Kalluru 	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1429961acdeaSSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1430961acdeaSSudarsana Reddy Kalluru 
1431961acdeaSSudarsana Reddy Kalluru 	if (!indir && !key)
1432961acdeaSSudarsana Reddy Kalluru 		return 0;
1433961acdeaSSudarsana Reddy Kalluru 
1434961acdeaSSudarsana Reddy Kalluru 	if (indir) {
1435961acdeaSSudarsana Reddy Kalluru 		for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
1436f29ffdb6SMintz, Yuval 			edev->rss_ind_table[i] = indir[i];
1437961acdeaSSudarsana Reddy Kalluru 		edev->rss_params_inited |= QEDE_RSS_INDIR_INITED;
1438961acdeaSSudarsana Reddy Kalluru 	}
1439961acdeaSSudarsana Reddy Kalluru 
1440961acdeaSSudarsana Reddy Kalluru 	if (key) {
1441f29ffdb6SMintz, Yuval 		memcpy(&edev->rss_key, key, qede_get_rxfh_key_size(dev));
1442961acdeaSSudarsana Reddy Kalluru 		edev->rss_params_inited |= QEDE_RSS_KEY_INITED;
1443961acdeaSSudarsana Reddy Kalluru 	}
1444961acdeaSSudarsana Reddy Kalluru 
1445f29ffdb6SMintz, Yuval 	__qede_lock(edev);
1446f29ffdb6SMintz, Yuval 	if (edev->state == QEDE_STATE_OPEN) {
1447f29ffdb6SMintz, Yuval 		vport_update_params = vzalloc(sizeof(*vport_update_params));
1448f29ffdb6SMintz, Yuval 		if (!vport_update_params) {
1449f29ffdb6SMintz, Yuval 			__qede_unlock(edev);
1450f29ffdb6SMintz, Yuval 			return -ENOMEM;
1451961acdeaSSudarsana Reddy Kalluru 		}
1452f29ffdb6SMintz, Yuval 		qede_fill_rss_params(edev, &vport_update_params->rss_params,
1453f29ffdb6SMintz, Yuval 				     &vport_update_params->update_rss_flg);
1454f29ffdb6SMintz, Yuval 		rc = edev->ops->vport_update(edev->cdev, vport_update_params);
1455f29ffdb6SMintz, Yuval 		vfree(vport_update_params);
1456f29ffdb6SMintz, Yuval 	}
1457f29ffdb6SMintz, Yuval 	__qede_unlock(edev);
1458961acdeaSSudarsana Reddy Kalluru 
1459f29ffdb6SMintz, Yuval 	return rc;
1460961acdeaSSudarsana Reddy Kalluru }
1461961acdeaSSudarsana Reddy Kalluru 
146216f46bf0SSudarsana Reddy Kalluru /* This function enables the interrupt generation and the NAPI on the device */
qede_netif_start(struct qede_dev * edev)146316f46bf0SSudarsana Reddy Kalluru static void qede_netif_start(struct qede_dev *edev)
146416f46bf0SSudarsana Reddy Kalluru {
146516f46bf0SSudarsana Reddy Kalluru 	int i;
146616f46bf0SSudarsana Reddy Kalluru 
146716f46bf0SSudarsana Reddy Kalluru 	if (!netif_running(edev->ndev))
146816f46bf0SSudarsana Reddy Kalluru 		return;
146916f46bf0SSudarsana Reddy Kalluru 
14709a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
147116f46bf0SSudarsana Reddy Kalluru 		/* Update and reenable interrupts */
147216f46bf0SSudarsana Reddy Kalluru 		qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_ENABLE, 1);
147316f46bf0SSudarsana Reddy Kalluru 		napi_enable(&edev->fp_array[i].napi);
147416f46bf0SSudarsana Reddy Kalluru 	}
147516f46bf0SSudarsana Reddy Kalluru }
147616f46bf0SSudarsana Reddy Kalluru 
147716f46bf0SSudarsana Reddy Kalluru /* This function disables the NAPI and the interrupt generation on the device */
qede_netif_stop(struct qede_dev * edev)147816f46bf0SSudarsana Reddy Kalluru static void qede_netif_stop(struct qede_dev *edev)
147916f46bf0SSudarsana Reddy Kalluru {
148016f46bf0SSudarsana Reddy Kalluru 	int i;
148116f46bf0SSudarsana Reddy Kalluru 
14829a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
148316f46bf0SSudarsana Reddy Kalluru 		napi_disable(&edev->fp_array[i].napi);
148416f46bf0SSudarsana Reddy Kalluru 		/* Disable interrupts */
148516f46bf0SSudarsana Reddy Kalluru 		qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_DISABLE, 0);
148616f46bf0SSudarsana Reddy Kalluru 	}
148716f46bf0SSudarsana Reddy Kalluru }
148816f46bf0SSudarsana Reddy Kalluru 
qede_selftest_transmit_traffic(struct qede_dev * edev,struct sk_buff * skb)148916f46bf0SSudarsana Reddy Kalluru static int qede_selftest_transmit_traffic(struct qede_dev *edev,
149016f46bf0SSudarsana Reddy Kalluru 					  struct sk_buff *skb)
149116f46bf0SSudarsana Reddy Kalluru {
14929a4d7e86SSudarsana Reddy Kalluru 	struct qede_tx_queue *txq = NULL;
149316f46bf0SSudarsana Reddy Kalluru 	struct eth_tx_1st_bd *first_bd;
149416f46bf0SSudarsana Reddy Kalluru 	dma_addr_t mapping;
149548848a06SManish Chopra 	int i, idx;
149648848a06SManish Chopra 	u16 val;
149716f46bf0SSudarsana Reddy Kalluru 
14989a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
14995e7baf0fSManish Chopra 		struct qede_fastpath *fp = &edev->fp_array[i];
15005e7baf0fSManish Chopra 
15015e7baf0fSManish Chopra 		if (fp->type & QEDE_FASTPATH_TX) {
15025e7baf0fSManish Chopra 			txq = QEDE_FP_TC0_TXQ(fp);
15039a4d7e86SSudarsana Reddy Kalluru 			break;
15049a4d7e86SSudarsana Reddy Kalluru 		}
15059a4d7e86SSudarsana Reddy Kalluru 	}
15069a4d7e86SSudarsana Reddy Kalluru 
15079a4d7e86SSudarsana Reddy Kalluru 	if (!txq) {
15089a4d7e86SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Tx path is not available\n");
15099a4d7e86SSudarsana Reddy Kalluru 		return -1;
15109a4d7e86SSudarsana Reddy Kalluru 	}
15119a4d7e86SSudarsana Reddy Kalluru 
151216f46bf0SSudarsana Reddy Kalluru 	/* Fill the entry in the SW ring and the BDs in the FW ring */
15135a052d62SSudarsana Reddy Kalluru 	idx = txq->sw_tx_prod;
1514cb6aeb07SMintz, Yuval 	txq->sw_tx_ring.skbs[idx].skb = skb;
151516f46bf0SSudarsana Reddy Kalluru 	first_bd = qed_chain_produce(&txq->tx_pbl);
151616f46bf0SSudarsana Reddy Kalluru 	memset(first_bd, 0, sizeof(*first_bd));
151716f46bf0SSudarsana Reddy Kalluru 	val = 1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT;
151816f46bf0SSudarsana Reddy Kalluru 	first_bd->data.bd_flags.bitfields = val;
1519351a4dedSYuval Mintz 	val = skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK;
152048848a06SManish Chopra 	val = val << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT;
152148848a06SManish Chopra 	first_bd->data.bitfields |= cpu_to_le16(val);
152216f46bf0SSudarsana Reddy Kalluru 
152316f46bf0SSudarsana Reddy Kalluru 	/* Map skb linear data for DMA and set in the first BD */
152416f46bf0SSudarsana Reddy Kalluru 	mapping = dma_map_single(&edev->pdev->dev, skb->data,
152516f46bf0SSudarsana Reddy Kalluru 				 skb_headlen(skb), DMA_TO_DEVICE);
152616f46bf0SSudarsana Reddy Kalluru 	if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) {
152716f46bf0SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "SKB mapping failed\n");
152816f46bf0SSudarsana Reddy Kalluru 		return -ENOMEM;
152916f46bf0SSudarsana Reddy Kalluru 	}
153016f46bf0SSudarsana Reddy Kalluru 	BD_SET_UNMAP_ADDR_LEN(first_bd, mapping, skb_headlen(skb));
153116f46bf0SSudarsana Reddy Kalluru 
153216f46bf0SSudarsana Reddy Kalluru 	/* update the first BD with the actual num BDs */
153316f46bf0SSudarsana Reddy Kalluru 	first_bd->data.nbds = 1;
15345a052d62SSudarsana Reddy Kalluru 	txq->sw_tx_prod = (txq->sw_tx_prod + 1) % txq->num_tx_buffers;
153516f46bf0SSudarsana Reddy Kalluru 	/* 'next page' entries are counted in the producer value */
153648848a06SManish Chopra 	val = qed_chain_get_prod_idx(&txq->tx_pbl);
153748848a06SManish Chopra 	txq->tx_db.data.bd_prod = cpu_to_le16(val);
153816f46bf0SSudarsana Reddy Kalluru 
153916f46bf0SSudarsana Reddy Kalluru 	/* wmb makes sure that the BDs data is updated before updating the
154016f46bf0SSudarsana Reddy Kalluru 	 * producer, otherwise FW may read old data from the BDs.
154116f46bf0SSudarsana Reddy Kalluru 	 */
154216f46bf0SSudarsana Reddy Kalluru 	wmb();
154316f46bf0SSudarsana Reddy Kalluru 	barrier();
154416f46bf0SSudarsana Reddy Kalluru 	writel(txq->tx_db.raw, txq->doorbell_addr);
154516f46bf0SSudarsana Reddy Kalluru 
154616f46bf0SSudarsana Reddy Kalluru 	for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) {
154716f46bf0SSudarsana Reddy Kalluru 		if (qede_txq_has_work(txq))
154816f46bf0SSudarsana Reddy Kalluru 			break;
154916f46bf0SSudarsana Reddy Kalluru 		usleep_range(100, 200);
155016f46bf0SSudarsana Reddy Kalluru 	}
155116f46bf0SSudarsana Reddy Kalluru 
155216f46bf0SSudarsana Reddy Kalluru 	if (!qede_txq_has_work(txq)) {
155316f46bf0SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Tx completion didn't happen\n");
155416f46bf0SSudarsana Reddy Kalluru 		return -1;
155516f46bf0SSudarsana Reddy Kalluru 	}
155616f46bf0SSudarsana Reddy Kalluru 
155716f46bf0SSudarsana Reddy Kalluru 	first_bd = (struct eth_tx_1st_bd *)qed_chain_consume(&txq->tx_pbl);
1558fabd545cSManish Chopra 	dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
155916f46bf0SSudarsana Reddy Kalluru 			 BD_UNMAP_LEN(first_bd), DMA_TO_DEVICE);
15605a052d62SSudarsana Reddy Kalluru 	txq->sw_tx_cons = (txq->sw_tx_cons + 1) % txq->num_tx_buffers;
1561cb6aeb07SMintz, Yuval 	txq->sw_tx_ring.skbs[idx].skb = NULL;
156216f46bf0SSudarsana Reddy Kalluru 
156316f46bf0SSudarsana Reddy Kalluru 	return 0;
156416f46bf0SSudarsana Reddy Kalluru }
156516f46bf0SSudarsana Reddy Kalluru 
qede_selftest_receive_traffic(struct qede_dev * edev)156616f46bf0SSudarsana Reddy Kalluru static int qede_selftest_receive_traffic(struct qede_dev *edev)
156716f46bf0SSudarsana Reddy Kalluru {
156810ee4b87SZheng Zengkai 	u16 sw_rx_index, len;
156916f46bf0SSudarsana Reddy Kalluru 	struct eth_fast_path_rx_reg_cqe *fp_cqe;
15709a4d7e86SSudarsana Reddy Kalluru 	struct qede_rx_queue *rxq = NULL;
157116f46bf0SSudarsana Reddy Kalluru 	struct sw_rx_data *sw_rx_data;
157216f46bf0SSudarsana Reddy Kalluru 	union eth_rx_cqe *cqe;
1573afe981d6SSudarsana Reddy Kalluru 	int i, iter, rc = 0;
157416f46bf0SSudarsana Reddy Kalluru 	u8 *data_ptr;
157516f46bf0SSudarsana Reddy Kalluru 
15769a4d7e86SSudarsana Reddy Kalluru 	for_each_queue(i) {
15779a4d7e86SSudarsana Reddy Kalluru 		if (edev->fp_array[i].type & QEDE_FASTPATH_RX) {
15789a4d7e86SSudarsana Reddy Kalluru 			rxq = edev->fp_array[i].rxq;
15799a4d7e86SSudarsana Reddy Kalluru 			break;
15809a4d7e86SSudarsana Reddy Kalluru 		}
15819a4d7e86SSudarsana Reddy Kalluru 	}
15829a4d7e86SSudarsana Reddy Kalluru 
15839a4d7e86SSudarsana Reddy Kalluru 	if (!rxq) {
15849a4d7e86SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Rx path is not available\n");
15859a4d7e86SSudarsana Reddy Kalluru 		return -1;
15869a4d7e86SSudarsana Reddy Kalluru 	}
15879a4d7e86SSudarsana Reddy Kalluru 
158816f46bf0SSudarsana Reddy Kalluru 	/* The packet is expected to receive on rx-queue 0 even though RSS is
158916f46bf0SSudarsana Reddy Kalluru 	 * enabled. This is because the queue 0 is configured as the default
159016f46bf0SSudarsana Reddy Kalluru 	 * queue and that the loopback traffic is not IP.
159116f46bf0SSudarsana Reddy Kalluru 	 */
1592afe981d6SSudarsana Reddy Kalluru 	for (iter = 0; iter < QEDE_SELFTEST_POLL_COUNT; iter++) {
159316f46bf0SSudarsana Reddy Kalluru 		if (!qede_has_rx_work(rxq)) {
1594837d4eb6SSudarsana Reddy Kalluru 			usleep_range(100, 200);
1595837d4eb6SSudarsana Reddy Kalluru 			continue;
159616f46bf0SSudarsana Reddy Kalluru 		}
159716f46bf0SSudarsana Reddy Kalluru 
159816f46bf0SSudarsana Reddy Kalluru 		/* Get the CQE from the completion ring */
159916f46bf0SSudarsana Reddy Kalluru 		cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring);
160016f46bf0SSudarsana Reddy Kalluru 
160116f46bf0SSudarsana Reddy Kalluru 		/* Get the data from the SW ring */
160216f46bf0SSudarsana Reddy Kalluru 		sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
160316f46bf0SSudarsana Reddy Kalluru 		sw_rx_data = &rxq->sw_rx_ring[sw_rx_index];
160416f46bf0SSudarsana Reddy Kalluru 		fp_cqe = &cqe->fast_path_regular;
160516f46bf0SSudarsana Reddy Kalluru 		len =  le16_to_cpu(fp_cqe->len_on_first_bd);
160616f46bf0SSudarsana Reddy Kalluru 		data_ptr = (u8 *)(page_address(sw_rx_data->data) +
1607837d4eb6SSudarsana Reddy Kalluru 				  fp_cqe->placement_offset +
16088a863397SManish Chopra 				  sw_rx_data->page_offset +
16098a863397SManish Chopra 				  rxq->rx_headroom);
1610837d4eb6SSudarsana Reddy Kalluru 		if (ether_addr_equal(data_ptr,  edev->ndev->dev_addr) &&
1611837d4eb6SSudarsana Reddy Kalluru 		    ether_addr_equal(data_ptr + ETH_ALEN,
1612837d4eb6SSudarsana Reddy Kalluru 				     edev->ndev->dev_addr)) {
161316f46bf0SSudarsana Reddy Kalluru 			for (i = ETH_HLEN; i < len; i++)
161416f46bf0SSudarsana Reddy Kalluru 				if (data_ptr[i] != (unsigned char)(i & 0xff)) {
1615837d4eb6SSudarsana Reddy Kalluru 					rc = -1;
1616837d4eb6SSudarsana Reddy Kalluru 					break;
161716f46bf0SSudarsana Reddy Kalluru 				}
161816f46bf0SSudarsana Reddy Kalluru 
16199eb22357SMintz, Yuval 			qede_recycle_rx_bd_ring(rxq, 1);
1620837d4eb6SSudarsana Reddy Kalluru 			qed_chain_recycle_consumed(&rxq->rx_comp_ring);
1621837d4eb6SSudarsana Reddy Kalluru 			break;
1622837d4eb6SSudarsana Reddy Kalluru 		}
162316f46bf0SSudarsana Reddy Kalluru 
1624837d4eb6SSudarsana Reddy Kalluru 		DP_INFO(edev, "Not the transmitted packet\n");
16259eb22357SMintz, Yuval 		qede_recycle_rx_bd_ring(rxq, 1);
1626837d4eb6SSudarsana Reddy Kalluru 		qed_chain_recycle_consumed(&rxq->rx_comp_ring);
1627837d4eb6SSudarsana Reddy Kalluru 	}
1628837d4eb6SSudarsana Reddy Kalluru 
1629afe981d6SSudarsana Reddy Kalluru 	if (iter == QEDE_SELFTEST_POLL_COUNT) {
1630837d4eb6SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Failed to receive the traffic\n");
1631837d4eb6SSudarsana Reddy Kalluru 		return -1;
1632837d4eb6SSudarsana Reddy Kalluru 	}
1633837d4eb6SSudarsana Reddy Kalluru 
1634837d4eb6SSudarsana Reddy Kalluru 	qede_update_rx_prod(edev, rxq);
1635837d4eb6SSudarsana Reddy Kalluru 
1636837d4eb6SSudarsana Reddy Kalluru 	return rc;
163716f46bf0SSudarsana Reddy Kalluru }
163816f46bf0SSudarsana Reddy Kalluru 
qede_selftest_run_loopback(struct qede_dev * edev,u32 loopback_mode)163916f46bf0SSudarsana Reddy Kalluru static int qede_selftest_run_loopback(struct qede_dev *edev, u32 loopback_mode)
164016f46bf0SSudarsana Reddy Kalluru {
164116f46bf0SSudarsana Reddy Kalluru 	struct qed_link_params link_params;
164216f46bf0SSudarsana Reddy Kalluru 	struct sk_buff *skb = NULL;
164316f46bf0SSudarsana Reddy Kalluru 	int rc = 0, i;
164416f46bf0SSudarsana Reddy Kalluru 	u32 pkt_size;
164516f46bf0SSudarsana Reddy Kalluru 	u8 *packet;
164616f46bf0SSudarsana Reddy Kalluru 
164716f46bf0SSudarsana Reddy Kalluru 	if (!netif_running(edev->ndev)) {
164816f46bf0SSudarsana Reddy Kalluru 		DP_NOTICE(edev, "Interface is down\n");
164916f46bf0SSudarsana Reddy Kalluru 		return -EINVAL;
165016f46bf0SSudarsana Reddy Kalluru 	}
165116f46bf0SSudarsana Reddy Kalluru 
165216f46bf0SSudarsana Reddy Kalluru 	qede_netif_stop(edev);
165316f46bf0SSudarsana Reddy Kalluru 
165416f46bf0SSudarsana Reddy Kalluru 	/* Bring up the link in Loopback mode */
165516f46bf0SSudarsana Reddy Kalluru 	memset(&link_params, 0, sizeof(link_params));
165616f46bf0SSudarsana Reddy Kalluru 	link_params.link_up = true;
165716f46bf0SSudarsana Reddy Kalluru 	link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE;
165816f46bf0SSudarsana Reddy Kalluru 	link_params.loopback_mode = loopback_mode;
165916f46bf0SSudarsana Reddy Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
166016f46bf0SSudarsana Reddy Kalluru 
166116f46bf0SSudarsana Reddy Kalluru 	/* Wait for loopback configuration to apply */
166216f46bf0SSudarsana Reddy Kalluru 	msleep_interruptible(500);
166316f46bf0SSudarsana Reddy Kalluru 
1664b89869daSSudarsana Reddy Kalluru 	/* Setting max packet size to 1.5K to avoid data being split over
1665b89869daSSudarsana Reddy Kalluru 	 * multiple BDs in cases where MTU > PAGE_SIZE.
1666b89869daSSudarsana Reddy Kalluru 	 */
1667b89869daSSudarsana Reddy Kalluru 	pkt_size = (((edev->ndev->mtu < ETH_DATA_LEN) ?
1668b89869daSSudarsana Reddy Kalluru 		     edev->ndev->mtu : ETH_DATA_LEN) + ETH_HLEN);
166916f46bf0SSudarsana Reddy Kalluru 
167016f46bf0SSudarsana Reddy Kalluru 	skb = netdev_alloc_skb(edev->ndev, pkt_size);
167116f46bf0SSudarsana Reddy Kalluru 	if (!skb) {
167216f46bf0SSudarsana Reddy Kalluru 		DP_INFO(edev, "Can't allocate skb\n");
167316f46bf0SSudarsana Reddy Kalluru 		rc = -ENOMEM;
167416f46bf0SSudarsana Reddy Kalluru 		goto test_loopback_exit;
167516f46bf0SSudarsana Reddy Kalluru 	}
167616f46bf0SSudarsana Reddy Kalluru 	packet = skb_put(skb, pkt_size);
167716f46bf0SSudarsana Reddy Kalluru 	ether_addr_copy(packet, edev->ndev->dev_addr);
167816f46bf0SSudarsana Reddy Kalluru 	ether_addr_copy(packet + ETH_ALEN, edev->ndev->dev_addr);
167916f46bf0SSudarsana Reddy Kalluru 	memset(packet + (2 * ETH_ALEN), 0x77, (ETH_HLEN - (2 * ETH_ALEN)));
168016f46bf0SSudarsana Reddy Kalluru 	for (i = ETH_HLEN; i < pkt_size; i++)
168116f46bf0SSudarsana Reddy Kalluru 		packet[i] = (unsigned char)(i & 0xff);
168216f46bf0SSudarsana Reddy Kalluru 
168316f46bf0SSudarsana Reddy Kalluru 	rc = qede_selftest_transmit_traffic(edev, skb);
168416f46bf0SSudarsana Reddy Kalluru 	if (rc)
168516f46bf0SSudarsana Reddy Kalluru 		goto test_loopback_exit;
168616f46bf0SSudarsana Reddy Kalluru 
168716f46bf0SSudarsana Reddy Kalluru 	rc = qede_selftest_receive_traffic(edev);
168816f46bf0SSudarsana Reddy Kalluru 	if (rc)
168916f46bf0SSudarsana Reddy Kalluru 		goto test_loopback_exit;
169016f46bf0SSudarsana Reddy Kalluru 
169116f46bf0SSudarsana Reddy Kalluru 	DP_VERBOSE(edev, NETIF_MSG_RX_STATUS, "Loopback test successful\n");
169216f46bf0SSudarsana Reddy Kalluru 
169316f46bf0SSudarsana Reddy Kalluru test_loopback_exit:
169416f46bf0SSudarsana Reddy Kalluru 	dev_kfree_skb(skb);
169516f46bf0SSudarsana Reddy Kalluru 
169616f46bf0SSudarsana Reddy Kalluru 	/* Bring up the link in Normal mode */
169716f46bf0SSudarsana Reddy Kalluru 	memset(&link_params, 0, sizeof(link_params));
169816f46bf0SSudarsana Reddy Kalluru 	link_params.link_up = true;
169916f46bf0SSudarsana Reddy Kalluru 	link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE;
170016f46bf0SSudarsana Reddy Kalluru 	link_params.loopback_mode = QED_LINK_LOOPBACK_NONE;
170116f46bf0SSudarsana Reddy Kalluru 	edev->ops->common->set_link(edev->cdev, &link_params);
170216f46bf0SSudarsana Reddy Kalluru 
170316f46bf0SSudarsana Reddy Kalluru 	/* Wait for loopback configuration to apply */
170416f46bf0SSudarsana Reddy Kalluru 	msleep_interruptible(500);
170516f46bf0SSudarsana Reddy Kalluru 
170616f46bf0SSudarsana Reddy Kalluru 	qede_netif_start(edev);
170716f46bf0SSudarsana Reddy Kalluru 
170816f46bf0SSudarsana Reddy Kalluru 	return rc;
170916f46bf0SSudarsana Reddy Kalluru }
171016f46bf0SSudarsana Reddy Kalluru 
qede_self_test(struct net_device * dev,struct ethtool_test * etest,u64 * buf)17113044a02eSSudarsana Reddy Kalluru static void qede_self_test(struct net_device *dev,
17123044a02eSSudarsana Reddy Kalluru 			   struct ethtool_test *etest, u64 *buf)
17133044a02eSSudarsana Reddy Kalluru {
17143044a02eSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
17153044a02eSSudarsana Reddy Kalluru 
17163044a02eSSudarsana Reddy Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
17173044a02eSSudarsana Reddy Kalluru 		   "Self-test command parameters: offline = %d, external_lb = %d\n",
17183044a02eSSudarsana Reddy Kalluru 		   (etest->flags & ETH_TEST_FL_OFFLINE),
17193044a02eSSudarsana Reddy Kalluru 		   (etest->flags & ETH_TEST_FL_EXTERNAL_LB) >> 2);
17203044a02eSSudarsana Reddy Kalluru 
17213044a02eSSudarsana Reddy Kalluru 	memset(buf, 0, sizeof(u64) * QEDE_ETHTOOL_TEST_MAX);
17223044a02eSSudarsana Reddy Kalluru 
172316f46bf0SSudarsana Reddy Kalluru 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
172416f46bf0SSudarsana Reddy Kalluru 		if (qede_selftest_run_loopback(edev,
172516f46bf0SSudarsana Reddy Kalluru 					       QED_LINK_LOOPBACK_INT_PHY)) {
172616f46bf0SSudarsana Reddy Kalluru 			buf[QEDE_ETHTOOL_INT_LOOPBACK] = 1;
172716f46bf0SSudarsana Reddy Kalluru 			etest->flags |= ETH_TEST_FL_FAILED;
172816f46bf0SSudarsana Reddy Kalluru 		}
172916f46bf0SSudarsana Reddy Kalluru 	}
173016f46bf0SSudarsana Reddy Kalluru 
17313044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_interrupt(edev->cdev)) {
17323044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_INTERRUPT_TEST] = 1;
17333044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17343044a02eSSudarsana Reddy Kalluru 	}
17353044a02eSSudarsana Reddy Kalluru 
17363044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_memory(edev->cdev)) {
17373044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_MEMORY_TEST] = 1;
17383044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17393044a02eSSudarsana Reddy Kalluru 	}
17403044a02eSSudarsana Reddy Kalluru 
17413044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_register(edev->cdev)) {
17423044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_REGISTER_TEST] = 1;
17433044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17443044a02eSSudarsana Reddy Kalluru 	}
17453044a02eSSudarsana Reddy Kalluru 
17463044a02eSSudarsana Reddy Kalluru 	if (edev->ops->common->selftest->selftest_clock(edev->cdev)) {
17473044a02eSSudarsana Reddy Kalluru 		buf[QEDE_ETHTOOL_CLOCK_TEST] = 1;
17483044a02eSSudarsana Reddy Kalluru 		etest->flags |= ETH_TEST_FL_FAILED;
17493044a02eSSudarsana Reddy Kalluru 	}
17507a4b21b7SMintz, Yuval 
17517a4b21b7SMintz, Yuval 	if (edev->ops->common->selftest->selftest_nvram(edev->cdev)) {
17527a4b21b7SMintz, Yuval 		buf[QEDE_ETHTOOL_NVRAM_TEST] = 1;
17537a4b21b7SMintz, Yuval 		etest->flags |= ETH_TEST_FL_FAILED;
17547a4b21b7SMintz, Yuval 	}
17553044a02eSSudarsana Reddy Kalluru }
17563044a02eSSudarsana Reddy Kalluru 
qede_set_tunable(struct net_device * dev,const struct ethtool_tunable * tuna,const void * data)17573d789994SManish Chopra static int qede_set_tunable(struct net_device *dev,
17583d789994SManish Chopra 			    const struct ethtool_tunable *tuna,
17593d789994SManish Chopra 			    const void *data)
17603d789994SManish Chopra {
17613d789994SManish Chopra 	struct qede_dev *edev = netdev_priv(dev);
17623d789994SManish Chopra 	u32 val;
17633d789994SManish Chopra 
17643d789994SManish Chopra 	switch (tuna->id) {
17653d789994SManish Chopra 	case ETHTOOL_RX_COPYBREAK:
17663d789994SManish Chopra 		val = *(u32 *)data;
17673d789994SManish Chopra 		if (val < QEDE_MIN_PKT_LEN || val > QEDE_RX_HDR_SIZE) {
17683d789994SManish Chopra 			DP_VERBOSE(edev, QED_MSG_DEBUG,
17693d789994SManish Chopra 				   "Invalid rx copy break value, range is [%u, %u]",
17703d789994SManish Chopra 				   QEDE_MIN_PKT_LEN, QEDE_RX_HDR_SIZE);
17713d789994SManish Chopra 			return -EINVAL;
17723d789994SManish Chopra 		}
17733d789994SManish Chopra 
17743d789994SManish Chopra 		edev->rx_copybreak = *(u32 *)data;
17753d789994SManish Chopra 		break;
17763d789994SManish Chopra 	default:
17773d789994SManish Chopra 		return -EOPNOTSUPP;
17783d789994SManish Chopra 	}
17793d789994SManish Chopra 
17803d789994SManish Chopra 	return 0;
17813d789994SManish Chopra }
17823d789994SManish Chopra 
qede_get_tunable(struct net_device * dev,const struct ethtool_tunable * tuna,void * data)17833d789994SManish Chopra static int qede_get_tunable(struct net_device *dev,
17843d789994SManish Chopra 			    const struct ethtool_tunable *tuna, void *data)
17853d789994SManish Chopra {
17863d789994SManish Chopra 	struct qede_dev *edev = netdev_priv(dev);
17873d789994SManish Chopra 
17883d789994SManish Chopra 	switch (tuna->id) {
17893d789994SManish Chopra 	case ETHTOOL_RX_COPYBREAK:
17903d789994SManish Chopra 		*(u32 *)data = edev->rx_copybreak;
17913d789994SManish Chopra 		break;
17923d789994SManish Chopra 	default:
17933d789994SManish Chopra 		return -EOPNOTSUPP;
17943d789994SManish Chopra 	}
17953d789994SManish Chopra 
17963d789994SManish Chopra 	return 0;
17973d789994SManish Chopra }
17983d789994SManish Chopra 
qede_get_eee(struct net_device * dev,struct ethtool_eee * edata)1799c3dc48f7SSudarsana Reddy Kalluru static int qede_get_eee(struct net_device *dev, struct ethtool_eee *edata)
1800c3dc48f7SSudarsana Reddy Kalluru {
1801c3dc48f7SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1802c3dc48f7SSudarsana Reddy Kalluru 	struct qed_link_output current_link;
1803c3dc48f7SSudarsana Reddy Kalluru 
1804c3dc48f7SSudarsana Reddy Kalluru 	memset(&current_link, 0, sizeof(current_link));
1805c3dc48f7SSudarsana Reddy Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
1806c3dc48f7SSudarsana Reddy Kalluru 
1807c3dc48f7SSudarsana Reddy Kalluru 	if (!current_link.eee_supported) {
1808c3dc48f7SSudarsana Reddy Kalluru 		DP_INFO(edev, "EEE is not supported\n");
1809c3dc48f7SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1810c3dc48f7SSudarsana Reddy Kalluru 	}
1811c3dc48f7SSudarsana Reddy Kalluru 
1812c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.adv_caps & QED_EEE_1G_ADV)
1813c3dc48f7SSudarsana Reddy Kalluru 		edata->advertised = ADVERTISED_1000baseT_Full;
1814c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.adv_caps & QED_EEE_10G_ADV)
1815c3dc48f7SSudarsana Reddy Kalluru 		edata->advertised |= ADVERTISED_10000baseT_Full;
1816c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.sup_caps & QED_EEE_1G_ADV)
1817c3dc48f7SSudarsana Reddy Kalluru 		edata->supported = ADVERTISED_1000baseT_Full;
1818c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.sup_caps & QED_EEE_10G_ADV)
1819c3dc48f7SSudarsana Reddy Kalluru 		edata->supported |= ADVERTISED_10000baseT_Full;
1820c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.lp_adv_caps & QED_EEE_1G_ADV)
1821c3dc48f7SSudarsana Reddy Kalluru 		edata->lp_advertised = ADVERTISED_1000baseT_Full;
1822c3dc48f7SSudarsana Reddy Kalluru 	if (current_link.eee.lp_adv_caps & QED_EEE_10G_ADV)
1823c3dc48f7SSudarsana Reddy Kalluru 		edata->lp_advertised |= ADVERTISED_10000baseT_Full;
1824c3dc48f7SSudarsana Reddy Kalluru 
1825c3dc48f7SSudarsana Reddy Kalluru 	edata->tx_lpi_timer = current_link.eee.tx_lpi_timer;
1826c3dc48f7SSudarsana Reddy Kalluru 	edata->eee_enabled = current_link.eee.enable;
1827c3dc48f7SSudarsana Reddy Kalluru 	edata->tx_lpi_enabled = current_link.eee.tx_lpi_enable;
1828c3dc48f7SSudarsana Reddy Kalluru 	edata->eee_active = current_link.eee_active;
1829c3dc48f7SSudarsana Reddy Kalluru 
1830c3dc48f7SSudarsana Reddy Kalluru 	return 0;
1831c3dc48f7SSudarsana Reddy Kalluru }
1832c3dc48f7SSudarsana Reddy Kalluru 
qede_set_eee(struct net_device * dev,struct ethtool_eee * edata)1833c3dc48f7SSudarsana Reddy Kalluru static int qede_set_eee(struct net_device *dev, struct ethtool_eee *edata)
1834c3dc48f7SSudarsana Reddy Kalluru {
1835c3dc48f7SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
1836c3dc48f7SSudarsana Reddy Kalluru 	struct qed_link_output current_link;
1837c3dc48f7SSudarsana Reddy Kalluru 	struct qed_link_params params;
1838c3dc48f7SSudarsana Reddy Kalluru 
1839c3dc48f7SSudarsana Reddy Kalluru 	if (!edev->ops->common->can_link_change(edev->cdev)) {
1840c3dc48f7SSudarsana Reddy Kalluru 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
1841c3dc48f7SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1842c3dc48f7SSudarsana Reddy Kalluru 	}
1843c3dc48f7SSudarsana Reddy Kalluru 
1844c3dc48f7SSudarsana Reddy Kalluru 	memset(&current_link, 0, sizeof(current_link));
1845c3dc48f7SSudarsana Reddy Kalluru 	edev->ops->common->get_link(edev->cdev, &current_link);
1846c3dc48f7SSudarsana Reddy Kalluru 
1847c3dc48f7SSudarsana Reddy Kalluru 	if (!current_link.eee_supported) {
1848c3dc48f7SSudarsana Reddy Kalluru 		DP_INFO(edev, "EEE is not supported\n");
1849c3dc48f7SSudarsana Reddy Kalluru 		return -EOPNOTSUPP;
1850c3dc48f7SSudarsana Reddy Kalluru 	}
1851c3dc48f7SSudarsana Reddy Kalluru 
1852c3dc48f7SSudarsana Reddy Kalluru 	memset(&params, 0, sizeof(params));
1853c3dc48f7SSudarsana Reddy Kalluru 	params.override_flags |= QED_LINK_OVERRIDE_EEE_CONFIG;
1854c3dc48f7SSudarsana Reddy Kalluru 
1855c3dc48f7SSudarsana Reddy Kalluru 	if (!(edata->advertised & (ADVERTISED_1000baseT_Full |
1856c3dc48f7SSudarsana Reddy Kalluru 				   ADVERTISED_10000baseT_Full)) ||
1857c3dc48f7SSudarsana Reddy Kalluru 	    ((edata->advertised & (ADVERTISED_1000baseT_Full |
1858c3dc48f7SSudarsana Reddy Kalluru 				   ADVERTISED_10000baseT_Full)) !=
1859c3dc48f7SSudarsana Reddy Kalluru 	     edata->advertised)) {
1860c3dc48f7SSudarsana Reddy Kalluru 		DP_VERBOSE(edev, QED_MSG_DEBUG,
1861c3dc48f7SSudarsana Reddy Kalluru 			   "Invalid advertised capabilities %d\n",
1862c3dc48f7SSudarsana Reddy Kalluru 			   edata->advertised);
1863c3dc48f7SSudarsana Reddy Kalluru 		return -EINVAL;
1864c3dc48f7SSudarsana Reddy Kalluru 	}
1865c3dc48f7SSudarsana Reddy Kalluru 
1866c3dc48f7SSudarsana Reddy Kalluru 	if (edata->advertised & ADVERTISED_1000baseT_Full)
1867c3dc48f7SSudarsana Reddy Kalluru 		params.eee.adv_caps = QED_EEE_1G_ADV;
1868c3dc48f7SSudarsana Reddy Kalluru 	if (edata->advertised & ADVERTISED_10000baseT_Full)
1869c3dc48f7SSudarsana Reddy Kalluru 		params.eee.adv_caps |= QED_EEE_10G_ADV;
1870c3dc48f7SSudarsana Reddy Kalluru 	params.eee.enable = edata->eee_enabled;
1871c3dc48f7SSudarsana Reddy Kalluru 	params.eee.tx_lpi_enable = edata->tx_lpi_enabled;
1872c3dc48f7SSudarsana Reddy Kalluru 	params.eee.tx_lpi_timer = edata->tx_lpi_timer;
1873c3dc48f7SSudarsana Reddy Kalluru 
1874c3dc48f7SSudarsana Reddy Kalluru 	params.link_up = true;
1875c3dc48f7SSudarsana Reddy Kalluru 	edev->ops->common->set_link(edev->cdev, &params);
1876c3dc48f7SSudarsana Reddy Kalluru 
1877c3dc48f7SSudarsana Reddy Kalluru 	return 0;
1878c3dc48f7SSudarsana Reddy Kalluru }
1879c3dc48f7SSudarsana Reddy Kalluru 
qede_link_to_ethtool_fec(u32 link_fec)18809bdca14aSAlexander Lobakin static u32 qede_link_to_ethtool_fec(u32 link_fec)
18819bdca14aSAlexander Lobakin {
18829bdca14aSAlexander Lobakin 	u32 eth_fec = 0;
18839bdca14aSAlexander Lobakin 
18849bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_NONE)
18859bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_OFF;
18869bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_FIRECODE)
18879bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_BASER;
18889bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_RS)
18899bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_RS;
18909bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_AUTO)
18919bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_AUTO;
18929bdca14aSAlexander Lobakin 	if (link_fec & QED_FEC_MODE_UNSUPPORTED)
18939bdca14aSAlexander Lobakin 		eth_fec |= ETHTOOL_FEC_NONE;
18949bdca14aSAlexander Lobakin 
18959bdca14aSAlexander Lobakin 	return eth_fec;
18969bdca14aSAlexander Lobakin }
18979bdca14aSAlexander Lobakin 
qede_ethtool_to_link_fec(u32 eth_fec)18989bdca14aSAlexander Lobakin static u32 qede_ethtool_to_link_fec(u32 eth_fec)
18999bdca14aSAlexander Lobakin {
19009bdca14aSAlexander Lobakin 	u32 link_fec = 0;
19019bdca14aSAlexander Lobakin 
19029bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_OFF)
19039bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_NONE;
19049bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_BASER)
19059bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_FIRECODE;
19069bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_RS)
19079bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_RS;
19089bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_AUTO)
19099bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_AUTO;
19109bdca14aSAlexander Lobakin 	if (eth_fec & ETHTOOL_FEC_NONE)
19119bdca14aSAlexander Lobakin 		link_fec |= QED_FEC_MODE_UNSUPPORTED;
19129bdca14aSAlexander Lobakin 
19139bdca14aSAlexander Lobakin 	return link_fec;
19149bdca14aSAlexander Lobakin }
19159bdca14aSAlexander Lobakin 
qede_get_fecparam(struct net_device * dev,struct ethtool_fecparam * fecparam)19169bdca14aSAlexander Lobakin static int qede_get_fecparam(struct net_device *dev,
19179bdca14aSAlexander Lobakin 			     struct ethtool_fecparam *fecparam)
19189bdca14aSAlexander Lobakin {
19199bdca14aSAlexander Lobakin 	struct qede_dev *edev = netdev_priv(dev);
19209bdca14aSAlexander Lobakin 	struct qed_link_output curr_link;
19219bdca14aSAlexander Lobakin 
19229bdca14aSAlexander Lobakin 	memset(&curr_link, 0, sizeof(curr_link));
19239bdca14aSAlexander Lobakin 	edev->ops->common->get_link(edev->cdev, &curr_link);
19249bdca14aSAlexander Lobakin 
19259bdca14aSAlexander Lobakin 	fecparam->active_fec = qede_link_to_ethtool_fec(curr_link.active_fec);
19269bdca14aSAlexander Lobakin 	fecparam->fec = qede_link_to_ethtool_fec(curr_link.sup_fec);
19279bdca14aSAlexander Lobakin 
19289bdca14aSAlexander Lobakin 	return 0;
19299bdca14aSAlexander Lobakin }
19309bdca14aSAlexander Lobakin 
qede_set_fecparam(struct net_device * dev,struct ethtool_fecparam * fecparam)19319bdca14aSAlexander Lobakin static int qede_set_fecparam(struct net_device *dev,
19329bdca14aSAlexander Lobakin 			     struct ethtool_fecparam *fecparam)
19339bdca14aSAlexander Lobakin {
19349bdca14aSAlexander Lobakin 	struct qede_dev *edev = netdev_priv(dev);
19359bdca14aSAlexander Lobakin 	struct qed_link_params params;
19369bdca14aSAlexander Lobakin 
19379bdca14aSAlexander Lobakin 	if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
19389bdca14aSAlexander Lobakin 		DP_INFO(edev, "Link settings are not allowed to be changed\n");
19399bdca14aSAlexander Lobakin 		return -EOPNOTSUPP;
19409bdca14aSAlexander Lobakin 	}
19419bdca14aSAlexander Lobakin 
19429bdca14aSAlexander Lobakin 	memset(&params, 0, sizeof(params));
19439bdca14aSAlexander Lobakin 	params.override_flags |= QED_LINK_OVERRIDE_FEC_CONFIG;
19449bdca14aSAlexander Lobakin 	params.fec = qede_ethtool_to_link_fec(fecparam->fec);
19459bdca14aSAlexander Lobakin 	params.link_up = true;
19469bdca14aSAlexander Lobakin 
19479bdca14aSAlexander Lobakin 	edev->ops->common->set_link(edev->cdev, &params);
19489bdca14aSAlexander Lobakin 
19499bdca14aSAlexander Lobakin 	return 0;
19509bdca14aSAlexander Lobakin }
19519bdca14aSAlexander Lobakin 
qede_get_module_info(struct net_device * dev,struct ethtool_modinfo * modinfo)195297df0d65SSudarsana Reddy Kalluru static int qede_get_module_info(struct net_device *dev,
195397df0d65SSudarsana Reddy Kalluru 				struct ethtool_modinfo *modinfo)
195497df0d65SSudarsana Reddy Kalluru {
195597df0d65SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
195697df0d65SSudarsana Reddy Kalluru 	u8 buf[4];
195797df0d65SSudarsana Reddy Kalluru 	int rc;
195897df0d65SSudarsana Reddy Kalluru 
195997df0d65SSudarsana Reddy Kalluru 	/* Read first 4 bytes to find the sfp type */
196097df0d65SSudarsana Reddy Kalluru 	rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
196197df0d65SSudarsana Reddy Kalluru 						   QED_I2C_DEV_ADDR_A0, 0, 4);
196297df0d65SSudarsana Reddy Kalluru 	if (rc) {
196397df0d65SSudarsana Reddy Kalluru 		DP_ERR(edev, "Failed reading EEPROM data %d\n", rc);
196497df0d65SSudarsana Reddy Kalluru 		return rc;
196597df0d65SSudarsana Reddy Kalluru 	}
196697df0d65SSudarsana Reddy Kalluru 
196797df0d65SSudarsana Reddy Kalluru 	switch (buf[0]) {
196897df0d65SSudarsana Reddy Kalluru 	case 0x3: /* SFP, SFP+, SFP-28 */
196997df0d65SSudarsana Reddy Kalluru 		modinfo->type = ETH_MODULE_SFF_8472;
197097df0d65SSudarsana Reddy Kalluru 		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
197197df0d65SSudarsana Reddy Kalluru 		break;
197297df0d65SSudarsana Reddy Kalluru 	case 0xc: /* QSFP */
197397df0d65SSudarsana Reddy Kalluru 	case 0xd: /* QSFP+ */
197497df0d65SSudarsana Reddy Kalluru 		modinfo->type = ETH_MODULE_SFF_8436;
197597df0d65SSudarsana Reddy Kalluru 		modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
197697df0d65SSudarsana Reddy Kalluru 		break;
197797df0d65SSudarsana Reddy Kalluru 	case 0x11: /* QSFP-28 */
197897df0d65SSudarsana Reddy Kalluru 		modinfo->type = ETH_MODULE_SFF_8636;
197997df0d65SSudarsana Reddy Kalluru 		modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
198097df0d65SSudarsana Reddy Kalluru 		break;
198197df0d65SSudarsana Reddy Kalluru 	default:
198297df0d65SSudarsana Reddy Kalluru 		DP_ERR(edev, "Unknown transceiver type 0x%x\n", buf[0]);
198397df0d65SSudarsana Reddy Kalluru 		return -EINVAL;
198497df0d65SSudarsana Reddy Kalluru 	}
198597df0d65SSudarsana Reddy Kalluru 
198697df0d65SSudarsana Reddy Kalluru 	return 0;
198797df0d65SSudarsana Reddy Kalluru }
198897df0d65SSudarsana Reddy Kalluru 
qede_get_module_eeprom(struct net_device * dev,struct ethtool_eeprom * ee,u8 * data)198997df0d65SSudarsana Reddy Kalluru static int qede_get_module_eeprom(struct net_device *dev,
199097df0d65SSudarsana Reddy Kalluru 				  struct ethtool_eeprom *ee, u8 *data)
199197df0d65SSudarsana Reddy Kalluru {
199297df0d65SSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
199397df0d65SSudarsana Reddy Kalluru 	u32 start_addr = ee->offset, size = 0;
199497df0d65SSudarsana Reddy Kalluru 	u8 *buf = data;
199597df0d65SSudarsana Reddy Kalluru 	int rc = 0;
199697df0d65SSudarsana Reddy Kalluru 
199797df0d65SSudarsana Reddy Kalluru 	/* Read A0 section */
199897df0d65SSudarsana Reddy Kalluru 	if (ee->offset < ETH_MODULE_SFF_8079_LEN) {
199997df0d65SSudarsana Reddy Kalluru 		/* Limit transfer size to the A0 section boundary */
200097df0d65SSudarsana Reddy Kalluru 		if (ee->offset + ee->len > ETH_MODULE_SFF_8079_LEN)
200197df0d65SSudarsana Reddy Kalluru 			size = ETH_MODULE_SFF_8079_LEN - ee->offset;
200297df0d65SSudarsana Reddy Kalluru 		else
200397df0d65SSudarsana Reddy Kalluru 			size = ee->len;
200497df0d65SSudarsana Reddy Kalluru 
200597df0d65SSudarsana Reddy Kalluru 		rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
200697df0d65SSudarsana Reddy Kalluru 							   QED_I2C_DEV_ADDR_A0,
200797df0d65SSudarsana Reddy Kalluru 							   start_addr, size);
200897df0d65SSudarsana Reddy Kalluru 		if (rc) {
200997df0d65SSudarsana Reddy Kalluru 			DP_ERR(edev, "Failed reading A0 section  %d\n", rc);
201097df0d65SSudarsana Reddy Kalluru 			return rc;
201197df0d65SSudarsana Reddy Kalluru 		}
201297df0d65SSudarsana Reddy Kalluru 
201397df0d65SSudarsana Reddy Kalluru 		buf += size;
201497df0d65SSudarsana Reddy Kalluru 		start_addr += size;
201597df0d65SSudarsana Reddy Kalluru 	}
201697df0d65SSudarsana Reddy Kalluru 
201797df0d65SSudarsana Reddy Kalluru 	/* Read A2 section */
201897df0d65SSudarsana Reddy Kalluru 	if (start_addr >= ETH_MODULE_SFF_8079_LEN &&
201997df0d65SSudarsana Reddy Kalluru 	    start_addr < ETH_MODULE_SFF_8472_LEN) {
202097df0d65SSudarsana Reddy Kalluru 		size = ee->len - size;
202197df0d65SSudarsana Reddy Kalluru 		/* Limit transfer size to the A2 section boundary */
202297df0d65SSudarsana Reddy Kalluru 		if (start_addr + size > ETH_MODULE_SFF_8472_LEN)
202397df0d65SSudarsana Reddy Kalluru 			size = ETH_MODULE_SFF_8472_LEN - start_addr;
202497df0d65SSudarsana Reddy Kalluru 		start_addr -= ETH_MODULE_SFF_8079_LEN;
202597df0d65SSudarsana Reddy Kalluru 		rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
202697df0d65SSudarsana Reddy Kalluru 							   QED_I2C_DEV_ADDR_A2,
202797df0d65SSudarsana Reddy Kalluru 							   start_addr, size);
202897df0d65SSudarsana Reddy Kalluru 		if (rc) {
202997df0d65SSudarsana Reddy Kalluru 			DP_VERBOSE(edev, QED_MSG_DEBUG,
203097df0d65SSudarsana Reddy Kalluru 				   "Failed reading A2 section %d\n", rc);
203197df0d65SSudarsana Reddy Kalluru 			return 0;
203297df0d65SSudarsana Reddy Kalluru 		}
203397df0d65SSudarsana Reddy Kalluru 	}
203497df0d65SSudarsana Reddy Kalluru 
203597df0d65SSudarsana Reddy Kalluru 	return rc;
203697df0d65SSudarsana Reddy Kalluru }
203797df0d65SSudarsana Reddy Kalluru 
qede_set_dump(struct net_device * dev,struct ethtool_dump * val)2038d44a3cedSSudarsana Reddy Kalluru static int qede_set_dump(struct net_device *dev, struct ethtool_dump *val)
2039d44a3cedSSudarsana Reddy Kalluru {
2040d44a3cedSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
2041d44a3cedSSudarsana Reddy Kalluru 	int rc = 0;
2042d44a3cedSSudarsana Reddy Kalluru 
2043d44a3cedSSudarsana Reddy Kalluru 	if (edev->dump_info.cmd == QEDE_DUMP_CMD_NONE) {
2044d44a3cedSSudarsana Reddy Kalluru 		if (val->flag > QEDE_DUMP_CMD_MAX) {
2045d44a3cedSSudarsana Reddy Kalluru 			DP_ERR(edev, "Invalid command %d\n", val->flag);
2046d44a3cedSSudarsana Reddy Kalluru 			return -EINVAL;
2047d44a3cedSSudarsana Reddy Kalluru 		}
2048d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.cmd = val->flag;
2049d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.num_args = 0;
2050d44a3cedSSudarsana Reddy Kalluru 		return 0;
2051d44a3cedSSudarsana Reddy Kalluru 	}
2052d44a3cedSSudarsana Reddy Kalluru 
2053d44a3cedSSudarsana Reddy Kalluru 	if (edev->dump_info.num_args == QEDE_DUMP_MAX_ARGS) {
2054d44a3cedSSudarsana Reddy Kalluru 		DP_ERR(edev, "Arg count = %d\n", edev->dump_info.num_args);
2055d44a3cedSSudarsana Reddy Kalluru 		return -EINVAL;
2056d44a3cedSSudarsana Reddy Kalluru 	}
2057d44a3cedSSudarsana Reddy Kalluru 
2058d44a3cedSSudarsana Reddy Kalluru 	switch (edev->dump_info.cmd) {
2059d44a3cedSSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_NVM_CFG:
2060d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.args[edev->dump_info.num_args] = val->flag;
2061d44a3cedSSudarsana Reddy Kalluru 		edev->dump_info.num_args++;
2062d44a3cedSSudarsana Reddy Kalluru 		break;
2063849dbf09SSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_GRCDUMP:
2064849dbf09SSudarsana Reddy Kalluru 		rc = edev->ops->common->set_grc_config(edev->cdev,
2065849dbf09SSudarsana Reddy Kalluru 						       val->flag, 1);
2066849dbf09SSudarsana Reddy Kalluru 		break;
2067d44a3cedSSudarsana Reddy Kalluru 	default:
2068d44a3cedSSudarsana Reddy Kalluru 		break;
2069d44a3cedSSudarsana Reddy Kalluru 	}
2070d44a3cedSSudarsana Reddy Kalluru 
2071d44a3cedSSudarsana Reddy Kalluru 	return rc;
2072d44a3cedSSudarsana Reddy Kalluru }
2073d44a3cedSSudarsana Reddy Kalluru 
qede_get_dump_flag(struct net_device * dev,struct ethtool_dump * dump)2074d44a3cedSSudarsana Reddy Kalluru static int qede_get_dump_flag(struct net_device *dev,
2075d44a3cedSSudarsana Reddy Kalluru 			      struct ethtool_dump *dump)
2076d44a3cedSSudarsana Reddy Kalluru {
2077d44a3cedSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
2078d44a3cedSSudarsana Reddy Kalluru 
2079849dbf09SSudarsana Reddy Kalluru 	if (!edev->ops || !edev->ops->common) {
2080849dbf09SSudarsana Reddy Kalluru 		DP_ERR(edev, "Edev ops not populated\n");
2081849dbf09SSudarsana Reddy Kalluru 		return -EINVAL;
2082849dbf09SSudarsana Reddy Kalluru 	}
2083849dbf09SSudarsana Reddy Kalluru 
2084d44a3cedSSudarsana Reddy Kalluru 	dump->version = QEDE_DUMP_VERSION;
2085d44a3cedSSudarsana Reddy Kalluru 	switch (edev->dump_info.cmd) {
2086d44a3cedSSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_NVM_CFG:
2087d44a3cedSSudarsana Reddy Kalluru 		dump->flag = QEDE_DUMP_CMD_NVM_CFG;
20889e54ba7cSSudarsana Reddy Kalluru 		dump->len = edev->ops->common->read_nvm_cfg_len(edev->cdev,
20899e54ba7cSSudarsana Reddy Kalluru 						edev->dump_info.args[0]);
2090d44a3cedSSudarsana Reddy Kalluru 		break;
2091849dbf09SSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_GRCDUMP:
2092849dbf09SSudarsana Reddy Kalluru 		dump->flag = QEDE_DUMP_CMD_GRCDUMP;
2093849dbf09SSudarsana Reddy Kalluru 		dump->len = edev->ops->common->dbg_all_data_size(edev->cdev);
2094d44a3cedSSudarsana Reddy Kalluru 		break;
2095849dbf09SSudarsana Reddy Kalluru 	default:
2096849dbf09SSudarsana Reddy Kalluru 		DP_ERR(edev, "Invalid cmd = %d\n", edev->dump_info.cmd);
2097849dbf09SSudarsana Reddy Kalluru 		return -EINVAL;
2098d44a3cedSSudarsana Reddy Kalluru 	}
2099d44a3cedSSudarsana Reddy Kalluru 
2100d44a3cedSSudarsana Reddy Kalluru 	DP_VERBOSE(edev, QED_MSG_DEBUG,
2101d44a3cedSSudarsana Reddy Kalluru 		   "dump->version = 0x%x dump->flag = %d dump->len = %d\n",
2102d44a3cedSSudarsana Reddy Kalluru 		   dump->version, dump->flag, dump->len);
2103d44a3cedSSudarsana Reddy Kalluru 	return 0;
2104d44a3cedSSudarsana Reddy Kalluru }
2105d44a3cedSSudarsana Reddy Kalluru 
qede_get_dump_data(struct net_device * dev,struct ethtool_dump * dump,void * buf)2106d44a3cedSSudarsana Reddy Kalluru static int qede_get_dump_data(struct net_device *dev,
2107d44a3cedSSudarsana Reddy Kalluru 			      struct ethtool_dump *dump, void *buf)
2108d44a3cedSSudarsana Reddy Kalluru {
2109d44a3cedSSudarsana Reddy Kalluru 	struct qede_dev *edev = netdev_priv(dev);
2110849dbf09SSudarsana Reddy Kalluru 	int rc = 0;
2111849dbf09SSudarsana Reddy Kalluru 
2112849dbf09SSudarsana Reddy Kalluru 	if (!edev->ops || !edev->ops->common) {
2113849dbf09SSudarsana Reddy Kalluru 		DP_ERR(edev, "Edev ops not populated\n");
21149e54ba7cSSudarsana Reddy Kalluru 		rc = -EINVAL;
21159e54ba7cSSudarsana Reddy Kalluru 		goto err;
2116849dbf09SSudarsana Reddy Kalluru 	}
2117d44a3cedSSudarsana Reddy Kalluru 
2118d44a3cedSSudarsana Reddy Kalluru 	switch (edev->dump_info.cmd) {
2119d44a3cedSSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_NVM_CFG:
2120d44a3cedSSudarsana Reddy Kalluru 		if (edev->dump_info.num_args != QEDE_DUMP_NVM_ARG_COUNT) {
2121d44a3cedSSudarsana Reddy Kalluru 			DP_ERR(edev, "Arg count = %d required = %d\n",
2122d44a3cedSSudarsana Reddy Kalluru 			       edev->dump_info.num_args,
2123d44a3cedSSudarsana Reddy Kalluru 			       QEDE_DUMP_NVM_ARG_COUNT);
21249e54ba7cSSudarsana Reddy Kalluru 			rc = -EINVAL;
21259e54ba7cSSudarsana Reddy Kalluru 			goto err;
2126d44a3cedSSudarsana Reddy Kalluru 		}
2127d44a3cedSSudarsana Reddy Kalluru 		rc =  edev->ops->common->read_nvm_cfg(edev->cdev, (u8 **)&buf,
2128d44a3cedSSudarsana Reddy Kalluru 						      edev->dump_info.args[0],
2129d44a3cedSSudarsana Reddy Kalluru 						      edev->dump_info.args[1]);
2130d44a3cedSSudarsana Reddy Kalluru 		break;
2131849dbf09SSudarsana Reddy Kalluru 	case QEDE_DUMP_CMD_GRCDUMP:
2132849dbf09SSudarsana Reddy Kalluru 		memset(buf, 0, dump->len);
2133849dbf09SSudarsana Reddy Kalluru 		rc = edev->ops->common->dbg_all_data(edev->cdev, buf);
2134849dbf09SSudarsana Reddy Kalluru 		break;
2135d44a3cedSSudarsana Reddy Kalluru 	default:
2136d44a3cedSSudarsana Reddy Kalluru 		DP_ERR(edev, "Invalid cmd = %d\n", edev->dump_info.cmd);
2137d44a3cedSSudarsana Reddy Kalluru 		rc = -EINVAL;
2138d44a3cedSSudarsana Reddy Kalluru 		break;
2139d44a3cedSSudarsana Reddy Kalluru 	}
2140d44a3cedSSudarsana Reddy Kalluru 
21419e54ba7cSSudarsana Reddy Kalluru err:
2142d44a3cedSSudarsana Reddy Kalluru 	edev->dump_info.cmd = QEDE_DUMP_CMD_NONE;
2143d44a3cedSSudarsana Reddy Kalluru 	edev->dump_info.num_args = 0;
21449e54ba7cSSudarsana Reddy Kalluru 	memset(edev->dump_info.args, 0, sizeof(edev->dump_info.args));
2145d44a3cedSSudarsana Reddy Kalluru 
2146d44a3cedSSudarsana Reddy Kalluru 	return rc;
2147d44a3cedSSudarsana Reddy Kalluru }
2148d44a3cedSSudarsana Reddy Kalluru 
qede_set_per_coalesce(struct net_device * dev,u32 queue,struct ethtool_coalesce * coal)2149b0ec5489SBhaskar Upadhaya int qede_set_per_coalesce(struct net_device *dev, u32 queue,
2150a0d2d97dSBhaskar Upadhaya 			  struct ethtool_coalesce *coal)
2151a0d2d97dSBhaskar Upadhaya {
2152a0d2d97dSBhaskar Upadhaya 	struct qede_dev *edev = netdev_priv(dev);
2153a0d2d97dSBhaskar Upadhaya 	struct qede_fastpath *fp;
2154a0d2d97dSBhaskar Upadhaya 	u16 rxc, txc;
2155a0d2d97dSBhaskar Upadhaya 	int rc = 0;
2156a0d2d97dSBhaskar Upadhaya 
2157a0d2d97dSBhaskar Upadhaya 	if (coal->rx_coalesce_usecs > QED_COALESCE_MAX ||
2158a0d2d97dSBhaskar Upadhaya 	    coal->tx_coalesce_usecs > QED_COALESCE_MAX) {
2159a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev,
2160a0d2d97dSBhaskar Upadhaya 			"Can't support requested %s coalesce value [max supported value %d]\n",
2161a0d2d97dSBhaskar Upadhaya 			coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx"
2162a0d2d97dSBhaskar Upadhaya 								   : "tx",
2163a0d2d97dSBhaskar Upadhaya 			QED_COALESCE_MAX);
2164a0d2d97dSBhaskar Upadhaya 		return -EINVAL;
2165a0d2d97dSBhaskar Upadhaya 	}
2166a0d2d97dSBhaskar Upadhaya 
2167a0d2d97dSBhaskar Upadhaya 	rxc = (u16)coal->rx_coalesce_usecs;
2168a0d2d97dSBhaskar Upadhaya 	txc = (u16)coal->tx_coalesce_usecs;
2169a0d2d97dSBhaskar Upadhaya 
2170a0d2d97dSBhaskar Upadhaya 	__qede_lock(edev);
2171a0d2d97dSBhaskar Upadhaya 	if (queue >= edev->num_queues) {
2172a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Invalid queue\n");
2173a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2174a0d2d97dSBhaskar Upadhaya 		goto out;
2175a0d2d97dSBhaskar Upadhaya 	}
2176a0d2d97dSBhaskar Upadhaya 
2177a0d2d97dSBhaskar Upadhaya 	if (edev->state != QEDE_STATE_OPEN) {
2178a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2179a0d2d97dSBhaskar Upadhaya 		goto out;
2180a0d2d97dSBhaskar Upadhaya 	}
2181a0d2d97dSBhaskar Upadhaya 
2182a0d2d97dSBhaskar Upadhaya 	fp = &edev->fp_array[queue];
2183a0d2d97dSBhaskar Upadhaya 
2184a0d2d97dSBhaskar Upadhaya 	if (edev->fp_array[queue].type & QEDE_FASTPATH_RX) {
2185a0d2d97dSBhaskar Upadhaya 		rc = edev->ops->common->set_coalesce(edev->cdev,
2186a0d2d97dSBhaskar Upadhaya 						     rxc, 0,
2187a0d2d97dSBhaskar Upadhaya 						     fp->rxq->handle);
2188a0d2d97dSBhaskar Upadhaya 		if (rc) {
2189a0d2d97dSBhaskar Upadhaya 			DP_INFO(edev,
2190a0d2d97dSBhaskar Upadhaya 				"Set RX coalesce error, rc = %d\n", rc);
2191a0d2d97dSBhaskar Upadhaya 			goto out;
2192a0d2d97dSBhaskar Upadhaya 		}
2193b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].rxc = rxc;
2194b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].isvalid = true;
2195a0d2d97dSBhaskar Upadhaya 	}
2196a0d2d97dSBhaskar Upadhaya 
2197a0d2d97dSBhaskar Upadhaya 	if (edev->fp_array[queue].type & QEDE_FASTPATH_TX) {
2198a0d2d97dSBhaskar Upadhaya 		rc = edev->ops->common->set_coalesce(edev->cdev,
2199a0d2d97dSBhaskar Upadhaya 						     0, txc,
2200a0d2d97dSBhaskar Upadhaya 						     fp->txq->handle);
2201a0d2d97dSBhaskar Upadhaya 		if (rc) {
2202a0d2d97dSBhaskar Upadhaya 			DP_INFO(edev,
2203a0d2d97dSBhaskar Upadhaya 				"Set TX coalesce error, rc = %d\n", rc);
2204a0d2d97dSBhaskar Upadhaya 			goto out;
2205a0d2d97dSBhaskar Upadhaya 		}
2206b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].txc = txc;
2207b0ec5489SBhaskar Upadhaya 		edev->coal_entry[queue].isvalid = true;
2208a0d2d97dSBhaskar Upadhaya 	}
2209a0d2d97dSBhaskar Upadhaya out:
2210a0d2d97dSBhaskar Upadhaya 	__qede_unlock(edev);
2211a0d2d97dSBhaskar Upadhaya 
2212a0d2d97dSBhaskar Upadhaya 	return rc;
2213a0d2d97dSBhaskar Upadhaya }
2214a0d2d97dSBhaskar Upadhaya 
qede_get_per_coalesce(struct net_device * dev,u32 queue,struct ethtool_coalesce * coal)2215a0d2d97dSBhaskar Upadhaya static int qede_get_per_coalesce(struct net_device *dev,
2216a0d2d97dSBhaskar Upadhaya 				 u32 queue,
2217a0d2d97dSBhaskar Upadhaya 				 struct ethtool_coalesce *coal)
2218a0d2d97dSBhaskar Upadhaya {
2219a0d2d97dSBhaskar Upadhaya 	void *rx_handle = NULL, *tx_handle = NULL;
2220a0d2d97dSBhaskar Upadhaya 	struct qede_dev *edev = netdev_priv(dev);
2221a0d2d97dSBhaskar Upadhaya 	struct qede_fastpath *fp;
2222a0d2d97dSBhaskar Upadhaya 	u16 rx_coal, tx_coal;
2223a0d2d97dSBhaskar Upadhaya 	int rc = 0;
2224a0d2d97dSBhaskar Upadhaya 
2225a0d2d97dSBhaskar Upadhaya 	rx_coal = QED_DEFAULT_RX_USECS;
2226a0d2d97dSBhaskar Upadhaya 	tx_coal = QED_DEFAULT_TX_USECS;
2227a0d2d97dSBhaskar Upadhaya 
2228a0d2d97dSBhaskar Upadhaya 	memset(coal, 0, sizeof(struct ethtool_coalesce));
2229a0d2d97dSBhaskar Upadhaya 
2230a0d2d97dSBhaskar Upadhaya 	__qede_lock(edev);
2231a0d2d97dSBhaskar Upadhaya 	if (queue >= edev->num_queues) {
2232a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Invalid queue\n");
2233a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2234a0d2d97dSBhaskar Upadhaya 		goto out;
2235a0d2d97dSBhaskar Upadhaya 	}
2236a0d2d97dSBhaskar Upadhaya 
2237a0d2d97dSBhaskar Upadhaya 	if (edev->state != QEDE_STATE_OPEN) {
2238a0d2d97dSBhaskar Upadhaya 		rc = -EINVAL;
2239a0d2d97dSBhaskar Upadhaya 		goto out;
2240a0d2d97dSBhaskar Upadhaya 	}
2241a0d2d97dSBhaskar Upadhaya 
2242a0d2d97dSBhaskar Upadhaya 	fp = &edev->fp_array[queue];
2243a0d2d97dSBhaskar Upadhaya 
2244a0d2d97dSBhaskar Upadhaya 	if (fp->type & QEDE_FASTPATH_RX)
2245a0d2d97dSBhaskar Upadhaya 		rx_handle = fp->rxq->handle;
2246a0d2d97dSBhaskar Upadhaya 
2247a0d2d97dSBhaskar Upadhaya 	rc = edev->ops->get_coalesce(edev->cdev, &rx_coal,
2248a0d2d97dSBhaskar Upadhaya 				     rx_handle);
2249a0d2d97dSBhaskar Upadhaya 	if (rc) {
2250a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Read Rx coalesce error\n");
2251a0d2d97dSBhaskar Upadhaya 		goto out;
2252a0d2d97dSBhaskar Upadhaya 	}
2253a0d2d97dSBhaskar Upadhaya 
2254a0d2d97dSBhaskar Upadhaya 	fp = &edev->fp_array[queue];
2255a0d2d97dSBhaskar Upadhaya 	if (fp->type & QEDE_FASTPATH_TX)
2256a0d2d97dSBhaskar Upadhaya 		tx_handle = fp->txq->handle;
2257a0d2d97dSBhaskar Upadhaya 
2258a0d2d97dSBhaskar Upadhaya 	rc = edev->ops->get_coalesce(edev->cdev, &tx_coal,
2259a0d2d97dSBhaskar Upadhaya 				      tx_handle);
2260a0d2d97dSBhaskar Upadhaya 	if (rc)
2261a0d2d97dSBhaskar Upadhaya 		DP_INFO(edev, "Read Tx coalesce error\n");
2262a0d2d97dSBhaskar Upadhaya 
2263a0d2d97dSBhaskar Upadhaya out:
2264a0d2d97dSBhaskar Upadhaya 	__qede_unlock(edev);
2265a0d2d97dSBhaskar Upadhaya 
2266a0d2d97dSBhaskar Upadhaya 	coal->rx_coalesce_usecs = rx_coal;
2267a0d2d97dSBhaskar Upadhaya 	coal->tx_coalesce_usecs = tx_coal;
2268a0d2d97dSBhaskar Upadhaya 
2269a0d2d97dSBhaskar Upadhaya 	return rc;
2270a0d2d97dSBhaskar Upadhaya }
2271a0d2d97dSBhaskar Upadhaya 
2272133fac0eSSudarsana Kalluru static const struct ethtool_ops qede_ethtool_ops = {
2273*42510dffSManish Chopra 	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS |
2274*42510dffSManish Chopra 					  ETHTOOL_COALESCE_STATS_BLOCK_USECS,
2275054c67d1SSudarsana Reddy Kalluru 	.get_link_ksettings		= qede_get_link_ksettings,
2276054c67d1SSudarsana Reddy Kalluru 	.set_link_ksettings		= qede_set_link_ksettings,
2277133fac0eSSudarsana Kalluru 	.get_drvinfo			= qede_get_drvinfo,
2278e0971c83STomer Tayar 	.get_regs_len			= qede_get_regs_len,
2279e0971c83STomer Tayar 	.get_regs			= qede_get_regs,
228014d39648SMintz, Yuval 	.get_wol			= qede_get_wol,
228114d39648SMintz, Yuval 	.set_wol			= qede_set_wol,
2282133fac0eSSudarsana Kalluru 	.get_msglevel			= qede_get_msglevel,
2283133fac0eSSudarsana Kalluru 	.set_msglevel			= qede_set_msglevel,
228432a7a570SSudarsana Kalluru 	.nway_reset			= qede_nway_reset,
2285133fac0eSSudarsana Kalluru 	.get_link			= qede_get_link,
2286d552fa84SSudarsana Reddy Kalluru 	.get_coalesce			= qede_get_coalesce,
2287d552fa84SSudarsana Reddy Kalluru 	.set_coalesce			= qede_set_coalesce,
228801ef7e05SSudarsana Kalluru 	.get_ringparam			= qede_get_ringparam,
228901ef7e05SSudarsana Kalluru 	.set_ringparam			= qede_set_ringparam,
22900f7db144SSudarsana Kalluru 	.get_pauseparam			= qede_get_pauseparam,
22910f7db144SSudarsana Kalluru 	.set_pauseparam			= qede_set_pauseparam,
2292133fac0eSSudarsana Kalluru 	.get_strings			= qede_get_strings,
22933d971cbdSSudarsana Kalluru 	.set_phys_id			= qede_set_phys_id,
2294133fac0eSSudarsana Kalluru 	.get_ethtool_stats		= qede_get_ethtool_stats,
2295f3e72109SYuval Mintz 	.get_priv_flags			= qede_get_priv_flags,
22967d9acd87SIgor Russkikh 	.set_priv_flags			= qede_set_priv_flags,
2297133fac0eSSudarsana Kalluru 	.get_sset_count			= qede_get_sset_count,
2298961acdeaSSudarsana Reddy Kalluru 	.get_rxnfc			= qede_get_rxnfc,
2299961acdeaSSudarsana Reddy Kalluru 	.set_rxnfc			= qede_set_rxnfc,
2300961acdeaSSudarsana Reddy Kalluru 	.get_rxfh_indir_size		= qede_get_rxfh_indir_size,
2301961acdeaSSudarsana Reddy Kalluru 	.get_rxfh_key_size		= qede_get_rxfh_key_size,
2302961acdeaSSudarsana Reddy Kalluru 	.get_rxfh			= qede_get_rxfh,
2303961acdeaSSudarsana Reddy Kalluru 	.set_rxfh			= qede_set_rxfh,
23044c55215cSSudarsana Reddy Kalluru 	.get_ts_info			= qede_get_ts_info,
23058edf049dSSudarsana Kalluru 	.get_channels			= qede_get_channels,
23068edf049dSSudarsana Kalluru 	.set_channels			= qede_set_channels,
23073044a02eSSudarsana Reddy Kalluru 	.self_test			= qede_self_test,
230897df0d65SSudarsana Reddy Kalluru 	.get_module_info		= qede_get_module_info,
230997df0d65SSudarsana Reddy Kalluru 	.get_module_eeprom		= qede_get_module_eeprom,
2310c3dc48f7SSudarsana Reddy Kalluru 	.get_eee			= qede_get_eee,
2311c3dc48f7SSudarsana Reddy Kalluru 	.set_eee			= qede_set_eee,
23129bdca14aSAlexander Lobakin 	.get_fecparam			= qede_get_fecparam,
23139bdca14aSAlexander Lobakin 	.set_fecparam			= qede_set_fecparam,
23143d789994SManish Chopra 	.get_tunable			= qede_get_tunable,
23153d789994SManish Chopra 	.set_tunable			= qede_set_tunable,
2316a0d2d97dSBhaskar Upadhaya 	.get_per_queue_coalesce		= qede_get_per_coalesce,
2317a0d2d97dSBhaskar Upadhaya 	.set_per_queue_coalesce		= qede_set_per_coalesce,
2318ccfa110cSSudarsana Reddy Kalluru 	.flash_device			= qede_flash_device,
2319d44a3cedSSudarsana Reddy Kalluru 	.get_dump_flag			= qede_get_dump_flag,
2320d44a3cedSSudarsana Reddy Kalluru 	.get_dump_data			= qede_get_dump_data,
2321d44a3cedSSudarsana Reddy Kalluru 	.set_dump			= qede_set_dump,
2322133fac0eSSudarsana Kalluru };
2323133fac0eSSudarsana Kalluru 
2324fefb0202SYuval Mintz static const struct ethtool_ops qede_vf_ethtool_ops = {
2325*42510dffSManish Chopra 	.supported_coalesce_params	= ETHTOOL_COALESCE_USECS |
2326*42510dffSManish Chopra 					  ETHTOOL_COALESCE_STATS_BLOCK_USECS,
2327054c67d1SSudarsana Reddy Kalluru 	.get_link_ksettings		= qede_get_link_ksettings,
2328fefb0202SYuval Mintz 	.get_drvinfo			= qede_get_drvinfo,
2329fefb0202SYuval Mintz 	.get_msglevel			= qede_get_msglevel,
2330fefb0202SYuval Mintz 	.set_msglevel			= qede_set_msglevel,
2331fefb0202SYuval Mintz 	.get_link			= qede_get_link,
2332477f2d14SRahul Verma 	.get_coalesce			= qede_get_coalesce,
2333477f2d14SRahul Verma 	.set_coalesce			= qede_set_coalesce,
2334fefb0202SYuval Mintz 	.get_ringparam			= qede_get_ringparam,
2335fefb0202SYuval Mintz 	.set_ringparam			= qede_set_ringparam,
2336fefb0202SYuval Mintz 	.get_strings			= qede_get_strings,
2337fefb0202SYuval Mintz 	.get_ethtool_stats		= qede_get_ethtool_stats,
2338fefb0202SYuval Mintz 	.get_priv_flags			= qede_get_priv_flags,
2339fefb0202SYuval Mintz 	.get_sset_count			= qede_get_sset_count,
2340fefb0202SYuval Mintz 	.get_rxnfc			= qede_get_rxnfc,
2341fefb0202SYuval Mintz 	.set_rxnfc			= qede_set_rxnfc,
2342fefb0202SYuval Mintz 	.get_rxfh_indir_size		= qede_get_rxfh_indir_size,
2343fefb0202SYuval Mintz 	.get_rxfh_key_size		= qede_get_rxfh_key_size,
2344fefb0202SYuval Mintz 	.get_rxfh			= qede_get_rxfh,
2345fefb0202SYuval Mintz 	.set_rxfh			= qede_set_rxfh,
2346fefb0202SYuval Mintz 	.get_channels			= qede_get_channels,
2347fefb0202SYuval Mintz 	.set_channels			= qede_set_channels,
2348a0d2d97dSBhaskar Upadhaya 	.get_per_queue_coalesce		= qede_get_per_coalesce,
2349a0d2d97dSBhaskar Upadhaya 	.set_per_queue_coalesce		= qede_set_per_coalesce,
23503d789994SManish Chopra 	.get_tunable			= qede_get_tunable,
23513d789994SManish Chopra 	.set_tunable			= qede_set_tunable,
2352fefb0202SYuval Mintz };
2353fefb0202SYuval Mintz 
qede_set_ethtool_ops(struct net_device * dev)2354133fac0eSSudarsana Kalluru void qede_set_ethtool_ops(struct net_device *dev)
2355133fac0eSSudarsana Kalluru {
2356fefb0202SYuval Mintz 	struct qede_dev *edev = netdev_priv(dev);
2357fefb0202SYuval Mintz 
2358fefb0202SYuval Mintz 	if (IS_VF(edev))
2359fefb0202SYuval Mintz 		dev->ethtool_ops = &qede_vf_ethtool_ops;
2360fefb0202SYuval Mintz 	else
2361133fac0eSSudarsana Kalluru 		dev->ethtool_ops = &qede_ethtool_ops;
2362133fac0eSSudarsana Kalluru }
2363