1dee1ad47SJeff Kirsher /*******************************************************************************
2dee1ad47SJeff Kirsher 
3dee1ad47SJeff Kirsher   Intel 82599 Virtual Function driver
4dec0d8e4SJeff Kirsher   Copyright(c) 1999 - 2015 Intel Corporation.
5dee1ad47SJeff Kirsher 
6dee1ad47SJeff Kirsher   This program is free software; you can redistribute it and/or modify it
7dee1ad47SJeff Kirsher   under the terms and conditions of the GNU General Public License,
8dee1ad47SJeff Kirsher   version 2, as published by the Free Software Foundation.
9dee1ad47SJeff Kirsher 
10dee1ad47SJeff Kirsher   This program is distributed in the hope it will be useful, but WITHOUT
11dee1ad47SJeff Kirsher   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12dee1ad47SJeff Kirsher   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13dee1ad47SJeff Kirsher   more details.
14dee1ad47SJeff Kirsher 
15dee1ad47SJeff Kirsher   You should have received a copy of the GNU General Public License along with
16dec0d8e4SJeff Kirsher   this program; if not, see <http://www.gnu.org/licenses/>.
17dee1ad47SJeff Kirsher 
18dee1ad47SJeff Kirsher   The full GNU General Public License is included in this distribution in
19dee1ad47SJeff Kirsher   the file called "COPYING".
20dee1ad47SJeff Kirsher 
21dee1ad47SJeff Kirsher   Contact Information:
22dee1ad47SJeff Kirsher   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23dee1ad47SJeff Kirsher   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24dee1ad47SJeff Kirsher 
25dee1ad47SJeff Kirsher *******************************************************************************/
26dee1ad47SJeff Kirsher 
27dee1ad47SJeff Kirsher /* ethtool support for ixgbevf */
28dee1ad47SJeff Kirsher 
29dbd9636eSJeff Kirsher #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30dbd9636eSJeff Kirsher 
31dee1ad47SJeff Kirsher #include <linux/types.h>
32dee1ad47SJeff Kirsher #include <linux/module.h>
33dee1ad47SJeff Kirsher #include <linux/slab.h>
34dee1ad47SJeff Kirsher #include <linux/pci.h>
35dee1ad47SJeff Kirsher #include <linux/netdevice.h>
36dee1ad47SJeff Kirsher #include <linux/ethtool.h>
37dee1ad47SJeff Kirsher #include <linux/vmalloc.h>
38dee1ad47SJeff Kirsher #include <linux/if_vlan.h>
39dee1ad47SJeff Kirsher #include <linux/uaccess.h>
40dee1ad47SJeff Kirsher 
41dee1ad47SJeff Kirsher #include "ixgbevf.h"
42dee1ad47SJeff Kirsher 
43dee1ad47SJeff Kirsher #define IXGBE_ALL_RAR_ENTRIES 16
44dee1ad47SJeff Kirsher 
45d72d6c19SEmil Tantilov enum {NETDEV_STATS, IXGBEVF_STATS};
46d72d6c19SEmil Tantilov 
47dee1ad47SJeff Kirsher struct ixgbe_stats {
48dee1ad47SJeff Kirsher 	char stat_string[ETH_GSTRING_LEN];
49d72d6c19SEmil Tantilov 	int type;
50dee1ad47SJeff Kirsher 	int sizeof_stat;
51dee1ad47SJeff Kirsher 	int stat_offset;
5244bd741eSDon Skidmore };
53dee1ad47SJeff Kirsher 
54d72d6c19SEmil Tantilov #define IXGBEVF_STAT(_name, _stat) { \
55d72d6c19SEmil Tantilov 	.stat_string = _name, \
56d72d6c19SEmil Tantilov 	.type = IXGBEVF_STATS, \
57d72d6c19SEmil Tantilov 	.sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, _stat), \
58d72d6c19SEmil Tantilov 	.stat_offset = offsetof(struct ixgbevf_adapter, _stat) \
5944bd741eSDon Skidmore }
6044bd741eSDon Skidmore 
61d72d6c19SEmil Tantilov #define IXGBEVF_NETDEV_STAT(_net_stat) { \
62d72d6c19SEmil Tantilov 	.stat_string = #_net_stat, \
63d72d6c19SEmil Tantilov 	.type = NETDEV_STATS, \
64d72d6c19SEmil Tantilov 	.sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
65d72d6c19SEmil Tantilov 	.stat_offset = offsetof(struct net_device_stats, _net_stat) \
6644bd741eSDon Skidmore }
67b47aca13SStephen Hemminger 
68d72d6c19SEmil Tantilov static struct ixgbe_stats ixgbevf_gstrings_stats[] = {
69d72d6c19SEmil Tantilov 	IXGBEVF_NETDEV_STAT(rx_packets),
70d72d6c19SEmil Tantilov 	IXGBEVF_NETDEV_STAT(tx_packets),
71d72d6c19SEmil Tantilov 	IXGBEVF_NETDEV_STAT(rx_bytes),
72d72d6c19SEmil Tantilov 	IXGBEVF_NETDEV_STAT(tx_bytes),
73d72d6c19SEmil Tantilov 	IXGBEVF_STAT("tx_busy", tx_busy),
74d72d6c19SEmil Tantilov 	IXGBEVF_STAT("tx_restart_queue", restart_queue),
75d72d6c19SEmil Tantilov 	IXGBEVF_STAT("tx_timeout_count", tx_timeout_count),
76d72d6c19SEmil Tantilov 	IXGBEVF_NETDEV_STAT(multicast),
77d72d6c19SEmil Tantilov 	IXGBEVF_STAT("rx_csum_offload_errors", hw_csum_rx_error),
78dee1ad47SJeff Kirsher };
79dee1ad47SJeff Kirsher 
80d72d6c19SEmil Tantilov #define IXGBEVF_QUEUE_STATS_LEN ( \
81d72d6c19SEmil Tantilov 	(((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \
82d72d6c19SEmil Tantilov 	 ((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \
83d72d6c19SEmil Tantilov 	 (sizeof(struct ixgbe_stats) / sizeof(u64)))
84d72d6c19SEmil Tantilov #define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats)
85dee1ad47SJeff Kirsher 
86d72d6c19SEmil Tantilov #define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN)
87dee1ad47SJeff Kirsher static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
88dee1ad47SJeff Kirsher 	"Register test  (offline)",
89dee1ad47SJeff Kirsher 	"Link test   (on/offline)"
90dee1ad47SJeff Kirsher };
91dec0d8e4SJeff Kirsher 
92d72d6c19SEmil Tantilov #define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
93dee1ad47SJeff Kirsher 
94dee1ad47SJeff Kirsher static int ixgbevf_get_settings(struct net_device *netdev,
95dee1ad47SJeff Kirsher 				struct ethtool_cmd *ecmd)
96dee1ad47SJeff Kirsher {
97dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
98dee1ad47SJeff Kirsher 	struct ixgbe_hw *hw = &adapter->hw;
99dee1ad47SJeff Kirsher 	u32 link_speed = 0;
100dee1ad47SJeff Kirsher 	bool link_up;
101dee1ad47SJeff Kirsher 
102dee1ad47SJeff Kirsher 	ecmd->supported = SUPPORTED_10000baseT_Full;
103dee1ad47SJeff Kirsher 	ecmd->autoneg = AUTONEG_DISABLE;
104dee1ad47SJeff Kirsher 	ecmd->transceiver = XCVR_DUMMY1;
105dee1ad47SJeff Kirsher 	ecmd->port = -1;
106dee1ad47SJeff Kirsher 
107aa19c295SGreg Rose 	hw->mac.get_link_status = 1;
108dee1ad47SJeff Kirsher 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
109dee1ad47SJeff Kirsher 
110dee1ad47SJeff Kirsher 	if (link_up) {
11131a1b375SGreg Rose 		__u32 speed = SPEED_10000;
112dec0d8e4SJeff Kirsher 
11331a1b375SGreg Rose 		switch (link_speed) {
11431a1b375SGreg Rose 		case IXGBE_LINK_SPEED_10GB_FULL:
11531a1b375SGreg Rose 			speed = SPEED_10000;
11631a1b375SGreg Rose 			break;
11731a1b375SGreg Rose 		case IXGBE_LINK_SPEED_1GB_FULL:
11831a1b375SGreg Rose 			speed = SPEED_1000;
11931a1b375SGreg Rose 			break;
12031a1b375SGreg Rose 		case IXGBE_LINK_SPEED_100_FULL:
12131a1b375SGreg Rose 			speed = SPEED_100;
12231a1b375SGreg Rose 			break;
12331a1b375SGreg Rose 		}
12431a1b375SGreg Rose 
12531a1b375SGreg Rose 		ethtool_cmd_speed_set(ecmd, speed);
126dee1ad47SJeff Kirsher 		ecmd->duplex = DUPLEX_FULL;
127dee1ad47SJeff Kirsher 	} else {
128537fae01SJiri Pirko 		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
129537fae01SJiri Pirko 		ecmd->duplex = DUPLEX_UNKNOWN;
130dee1ad47SJeff Kirsher 	}
131dee1ad47SJeff Kirsher 
132dee1ad47SJeff Kirsher 	return 0;
133dee1ad47SJeff Kirsher }
134dee1ad47SJeff Kirsher 
135dee1ad47SJeff Kirsher static u32 ixgbevf_get_msglevel(struct net_device *netdev)
136dee1ad47SJeff Kirsher {
137dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
138dec0d8e4SJeff Kirsher 
139dee1ad47SJeff Kirsher 	return adapter->msg_enable;
140dee1ad47SJeff Kirsher }
141dee1ad47SJeff Kirsher 
142dee1ad47SJeff Kirsher static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data)
143dee1ad47SJeff Kirsher {
144dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
145dec0d8e4SJeff Kirsher 
146dee1ad47SJeff Kirsher 	adapter->msg_enable = data;
147dee1ad47SJeff Kirsher }
148dee1ad47SJeff Kirsher 
149dee1ad47SJeff Kirsher #define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_)
150dee1ad47SJeff Kirsher 
151dee1ad47SJeff Kirsher static int ixgbevf_get_regs_len(struct net_device *netdev)
152dee1ad47SJeff Kirsher {
153fa07f10dSJacob Keller #define IXGBE_REGS_LEN 45
154fa07f10dSJacob Keller 	return IXGBE_REGS_LEN * sizeof(u32);
155dee1ad47SJeff Kirsher }
156dee1ad47SJeff Kirsher 
157dee1ad47SJeff Kirsher static void ixgbevf_get_regs(struct net_device *netdev,
158dee1ad47SJeff Kirsher 			     struct ethtool_regs *regs,
159dee1ad47SJeff Kirsher 			     void *p)
160dee1ad47SJeff Kirsher {
161dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
162dee1ad47SJeff Kirsher 	struct ixgbe_hw *hw = &adapter->hw;
163dee1ad47SJeff Kirsher 	u32 *regs_buff = p;
164dee1ad47SJeff Kirsher 	u32 regs_len = ixgbevf_get_regs_len(netdev);
165dee1ad47SJeff Kirsher 	u8 i;
166dee1ad47SJeff Kirsher 
167dee1ad47SJeff Kirsher 	memset(p, 0, regs_len);
168dee1ad47SJeff Kirsher 
169dee1ad47SJeff Kirsher 	regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id;
170dee1ad47SJeff Kirsher 
171dee1ad47SJeff Kirsher 	/* General Registers */
172dee1ad47SJeff Kirsher 	regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL);
173dee1ad47SJeff Kirsher 	regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS);
174dee1ad47SJeff Kirsher 	regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
175dee1ad47SJeff Kirsher 	regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP);
176dee1ad47SJeff Kirsher 	regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER);
177dee1ad47SJeff Kirsher 
178dee1ad47SJeff Kirsher 	/* Interrupt */
179dee1ad47SJeff Kirsher 	/* don't read EICR because it can clear interrupt causes, instead
180dec0d8e4SJeff Kirsher 	 * read EICS which is a shadow but doesn't clear EICR
181dec0d8e4SJeff Kirsher 	 */
182dee1ad47SJeff Kirsher 	regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_VTEICS);
183dee1ad47SJeff Kirsher 	regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_VTEICS);
184dee1ad47SJeff Kirsher 	regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_VTEIMS);
185dee1ad47SJeff Kirsher 	regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_VTEIMC);
186dee1ad47SJeff Kirsher 	regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_VTEIAC);
187dee1ad47SJeff Kirsher 	regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_VTEIAM);
188dee1ad47SJeff Kirsher 	regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_VTEITR(0));
189dee1ad47SJeff Kirsher 	regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_VTIVAR(0));
190dee1ad47SJeff Kirsher 	regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
191dee1ad47SJeff Kirsher 
192dee1ad47SJeff Kirsher 	/* Receive DMA */
193dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
194dee1ad47SJeff Kirsher 		regs_buff[14 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAL(i));
195dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
196dee1ad47SJeff Kirsher 		regs_buff[16 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAH(i));
197dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
198dee1ad47SJeff Kirsher 		regs_buff[18 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDLEN(i));
199dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
200dee1ad47SJeff Kirsher 		regs_buff[20 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDH(i));
201dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
202dee1ad47SJeff Kirsher 		regs_buff[22 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDT(i));
203dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
204dee1ad47SJeff Kirsher 		regs_buff[24 + i] = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
205dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
206dee1ad47SJeff Kirsher 		regs_buff[26 + i] = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i));
207dee1ad47SJeff Kirsher 
208dee1ad47SJeff Kirsher 	/* Receive */
209dee1ad47SJeff Kirsher 	regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_VFPSRTYPE);
210dee1ad47SJeff Kirsher 
211dee1ad47SJeff Kirsher 	/* Transmit */
212dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
213dee1ad47SJeff Kirsher 		regs_buff[29 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAL(i));
214dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
215dee1ad47SJeff Kirsher 		regs_buff[31 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAH(i));
216dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
217dee1ad47SJeff Kirsher 		regs_buff[33 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDLEN(i));
218dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
219dee1ad47SJeff Kirsher 		regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDH(i));
220dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
221dee1ad47SJeff Kirsher 		regs_buff[37 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDT(i));
222dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
223dee1ad47SJeff Kirsher 		regs_buff[39 + i] = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i));
224dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
225dee1ad47SJeff Kirsher 		regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i));
226dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
227dee1ad47SJeff Kirsher 		regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i));
228dee1ad47SJeff Kirsher }
229dee1ad47SJeff Kirsher 
230dee1ad47SJeff Kirsher static void ixgbevf_get_drvinfo(struct net_device *netdev,
231dee1ad47SJeff Kirsher 				struct ethtool_drvinfo *drvinfo)
232dee1ad47SJeff Kirsher {
233dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
234dee1ad47SJeff Kirsher 
23584b40501SRick Jones 	strlcpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver));
23684b40501SRick Jones 	strlcpy(drvinfo->version, ixgbevf_driver_version,
23784b40501SRick Jones 		sizeof(drvinfo->version));
23884b40501SRick Jones 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
23984b40501SRick Jones 		sizeof(drvinfo->bus_info));
240dee1ad47SJeff Kirsher }
241dee1ad47SJeff Kirsher 
242dee1ad47SJeff Kirsher static void ixgbevf_get_ringparam(struct net_device *netdev,
243dee1ad47SJeff Kirsher 				  struct ethtool_ringparam *ring)
244dee1ad47SJeff Kirsher {
245dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
246dee1ad47SJeff Kirsher 
247dee1ad47SJeff Kirsher 	ring->rx_max_pending = IXGBEVF_MAX_RXD;
248dee1ad47SJeff Kirsher 	ring->tx_max_pending = IXGBEVF_MAX_TXD;
249eb022d05SAlexander Duyck 	ring->rx_pending = adapter->rx_ring_count;
250eb022d05SAlexander Duyck 	ring->tx_pending = adapter->tx_ring_count;
251dee1ad47SJeff Kirsher }
252dee1ad47SJeff Kirsher 
253dee1ad47SJeff Kirsher static int ixgbevf_set_ringparam(struct net_device *netdev,
254dee1ad47SJeff Kirsher 				 struct ethtool_ringparam *ring)
255dee1ad47SJeff Kirsher {
256dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
257dee1ad47SJeff Kirsher 	struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
258dee1ad47SJeff Kirsher 	u32 new_rx_count, new_tx_count;
259eb022d05SAlexander Duyck 	int i, err = 0;
260dee1ad47SJeff Kirsher 
261dee1ad47SJeff Kirsher 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
262dee1ad47SJeff Kirsher 		return -EINVAL;
263dee1ad47SJeff Kirsher 
264eb022d05SAlexander Duyck 	new_tx_count = max_t(u32, ring->tx_pending, IXGBEVF_MIN_TXD);
265eb022d05SAlexander Duyck 	new_tx_count = min_t(u32, new_tx_count, IXGBEVF_MAX_TXD);
266dee1ad47SJeff Kirsher 	new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE);
267dee1ad47SJeff Kirsher 
268eb022d05SAlexander Duyck 	new_rx_count = max_t(u32, ring->rx_pending, IXGBEVF_MIN_RXD);
269eb022d05SAlexander Duyck 	new_rx_count = min_t(u32, new_rx_count, IXGBEVF_MAX_RXD);
270eb022d05SAlexander Duyck 	new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE);
271eb022d05SAlexander Duyck 
272eb022d05SAlexander Duyck 	/* if nothing to do return success */
273eb022d05SAlexander Duyck 	if ((new_tx_count == adapter->tx_ring_count) &&
274eb022d05SAlexander Duyck 	    (new_rx_count == adapter->rx_ring_count))
275dee1ad47SJeff Kirsher 		return 0;
276dee1ad47SJeff Kirsher 
277dee1ad47SJeff Kirsher 	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
278eb022d05SAlexander Duyck 		usleep_range(1000, 2000);
279dee1ad47SJeff Kirsher 
280dee1ad47SJeff Kirsher 	if (!netif_running(adapter->netdev)) {
281dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_tx_queues; i++)
28287e70ab9SDon Skidmore 			adapter->tx_ring[i]->count = new_tx_count;
283dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_rx_queues; i++)
28487e70ab9SDon Skidmore 			adapter->rx_ring[i]->count = new_rx_count;
285dee1ad47SJeff Kirsher 		adapter->tx_ring_count = new_tx_count;
286dee1ad47SJeff Kirsher 		adapter->rx_ring_count = new_rx_count;
287dee1ad47SJeff Kirsher 		goto clear_reset;
288dee1ad47SJeff Kirsher 	}
289dee1ad47SJeff Kirsher 
290eb022d05SAlexander Duyck 	if (new_tx_count != adapter->tx_ring_count) {
291eb022d05SAlexander Duyck 		tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring));
292dee1ad47SJeff Kirsher 		if (!tx_ring) {
293dee1ad47SJeff Kirsher 			err = -ENOMEM;
294dee1ad47SJeff Kirsher 			goto clear_reset;
295dee1ad47SJeff Kirsher 		}
296dee1ad47SJeff Kirsher 
297dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_tx_queues; i++) {
298eb022d05SAlexander Duyck 			/* clone ring and setup updated count */
29987e70ab9SDon Skidmore 			tx_ring[i] = *adapter->tx_ring[i];
300dee1ad47SJeff Kirsher 			tx_ring[i].count = new_tx_count;
30105d063aaSEmil Tantilov 			err = ixgbevf_setup_tx_resources(&tx_ring[i]);
30205d063aaSEmil Tantilov 			if (err) {
303dee1ad47SJeff Kirsher 				while (i) {
304dee1ad47SJeff Kirsher 					i--;
30505d063aaSEmil Tantilov 					ixgbevf_free_tx_resources(&tx_ring[i]);
306dee1ad47SJeff Kirsher 				}
307eb022d05SAlexander Duyck 
308eb022d05SAlexander Duyck 				vfree(tx_ring);
309eb022d05SAlexander Duyck 				tx_ring = NULL;
310eb022d05SAlexander Duyck 
311eb022d05SAlexander Duyck 				goto clear_reset;
312dee1ad47SJeff Kirsher 			}
313dee1ad47SJeff Kirsher 		}
31405d063aaSEmil Tantilov 	}
315dee1ad47SJeff Kirsher 
316eb022d05SAlexander Duyck 	if (new_rx_count != adapter->rx_ring_count) {
317eb022d05SAlexander Duyck 		rx_ring = vmalloc(adapter->num_rx_queues * sizeof(*rx_ring));
318eb022d05SAlexander Duyck 		if (!rx_ring) {
319eb022d05SAlexander Duyck 			err = -ENOMEM;
320eb022d05SAlexander Duyck 			goto clear_reset;
321eb022d05SAlexander Duyck 		}
322eb022d05SAlexander Duyck 
323dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_rx_queues; i++) {
324eb022d05SAlexander Duyck 			/* clone ring and setup updated count */
32587e70ab9SDon Skidmore 			rx_ring[i] = *adapter->rx_ring[i];
326dee1ad47SJeff Kirsher 			rx_ring[i].count = new_rx_count;
32705d063aaSEmil Tantilov 			err = ixgbevf_setup_rx_resources(&rx_ring[i]);
32805d063aaSEmil Tantilov 			if (err) {
329dee1ad47SJeff Kirsher 				while (i) {
330dee1ad47SJeff Kirsher 					i--;
33105d063aaSEmil Tantilov 					ixgbevf_free_rx_resources(&rx_ring[i]);
332dee1ad47SJeff Kirsher 				}
333dee1ad47SJeff Kirsher 
334eb022d05SAlexander Duyck 				vfree(rx_ring);
335eb022d05SAlexander Duyck 				rx_ring = NULL;
336dee1ad47SJeff Kirsher 
337dee1ad47SJeff Kirsher 				goto clear_reset;
338eb022d05SAlexander Duyck 			}
339eb022d05SAlexander Duyck 		}
34005d063aaSEmil Tantilov 	}
341dee1ad47SJeff Kirsher 
342eb022d05SAlexander Duyck 	/* bring interface down to prepare for update */
343eb022d05SAlexander Duyck 	ixgbevf_down(adapter);
344dee1ad47SJeff Kirsher 
345eb022d05SAlexander Duyck 	/* Tx */
346eb022d05SAlexander Duyck 	if (tx_ring) {
347eb022d05SAlexander Duyck 		for (i = 0; i < adapter->num_tx_queues; i++) {
34805d063aaSEmil Tantilov 			ixgbevf_free_tx_resources(adapter->tx_ring[i]);
34987e70ab9SDon Skidmore 			*adapter->tx_ring[i] = tx_ring[i];
350eb022d05SAlexander Duyck 		}
351eb022d05SAlexander Duyck 		adapter->tx_ring_count = new_tx_count;
352dee1ad47SJeff Kirsher 
353eb022d05SAlexander Duyck 		vfree(tx_ring);
354eb022d05SAlexander Duyck 		tx_ring = NULL;
355eb022d05SAlexander Duyck 	}
356eb022d05SAlexander Duyck 
357eb022d05SAlexander Duyck 	/* Rx */
358eb022d05SAlexander Duyck 	if (rx_ring) {
359eb022d05SAlexander Duyck 		for (i = 0; i < adapter->num_rx_queues; i++) {
36005d063aaSEmil Tantilov 			ixgbevf_free_rx_resources(adapter->rx_ring[i]);
36187e70ab9SDon Skidmore 			*adapter->rx_ring[i] = rx_ring[i];
362eb022d05SAlexander Duyck 		}
363eb022d05SAlexander Duyck 		adapter->rx_ring_count = new_rx_count;
364eb022d05SAlexander Duyck 
365eb022d05SAlexander Duyck 		vfree(rx_ring);
366eb022d05SAlexander Duyck 		rx_ring = NULL;
367eb022d05SAlexander Duyck 	}
368eb022d05SAlexander Duyck 
369eb022d05SAlexander Duyck 	/* restore interface using new values */
370eb022d05SAlexander Duyck 	ixgbevf_up(adapter);
371dee1ad47SJeff Kirsher 
372dee1ad47SJeff Kirsher clear_reset:
373eb022d05SAlexander Duyck 	/* free Tx resources if Rx error is encountered */
374eb022d05SAlexander Duyck 	if (tx_ring) {
375eb022d05SAlexander Duyck 		for (i = 0; i < adapter->num_tx_queues; i++)
37605d063aaSEmil Tantilov 			ixgbevf_free_tx_resources(&tx_ring[i]);
377eb022d05SAlexander Duyck 		vfree(tx_ring);
378eb022d05SAlexander Duyck 	}
379eb022d05SAlexander Duyck 
380dee1ad47SJeff Kirsher 	clear_bit(__IXGBEVF_RESETTING, &adapter->state);
381dee1ad47SJeff Kirsher 	return err;
382dee1ad47SJeff Kirsher }
383dee1ad47SJeff Kirsher 
384a02a5a53SEmil Tantilov static int ixgbevf_get_sset_count(struct net_device *netdev, int stringset)
385dee1ad47SJeff Kirsher {
386dee1ad47SJeff Kirsher 	switch (stringset) {
387dee1ad47SJeff Kirsher 	case ETH_SS_TEST:
388d72d6c19SEmil Tantilov 		return IXGBEVF_TEST_LEN;
389dee1ad47SJeff Kirsher 	case ETH_SS_STATS:
390a02a5a53SEmil Tantilov 		return IXGBEVF_STATS_LEN;
391dee1ad47SJeff Kirsher 	default:
392dee1ad47SJeff Kirsher 		return -EINVAL;
393dee1ad47SJeff Kirsher 	}
394dee1ad47SJeff Kirsher }
395dee1ad47SJeff Kirsher 
396dee1ad47SJeff Kirsher static void ixgbevf_get_ethtool_stats(struct net_device *netdev,
397dee1ad47SJeff Kirsher 				      struct ethtool_stats *stats, u64 *data)
398dee1ad47SJeff Kirsher {
399dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
400d72d6c19SEmil Tantilov 	struct rtnl_link_stats64 temp;
401d72d6c19SEmil Tantilov 	const struct rtnl_link_stats64 *net_stats;
402a02a5a53SEmil Tantilov 	unsigned int start;
403a02a5a53SEmil Tantilov 	struct ixgbevf_ring *ring;
404a02a5a53SEmil Tantilov 	int i, j;
405d72d6c19SEmil Tantilov 	char *p;
406d72d6c19SEmil Tantilov 
407dee1ad47SJeff Kirsher 	ixgbevf_update_stats(adapter);
408d72d6c19SEmil Tantilov 	net_stats = dev_get_stats(netdev, &temp);
409d72d6c19SEmil Tantilov 	for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) {
410d72d6c19SEmil Tantilov 		switch (ixgbevf_gstrings_stats[i].type) {
411d72d6c19SEmil Tantilov 		case NETDEV_STATS:
412d72d6c19SEmil Tantilov 			p = (char *)net_stats +
413d72d6c19SEmil Tantilov 					ixgbevf_gstrings_stats[i].stat_offset;
414d72d6c19SEmil Tantilov 			break;
415d72d6c19SEmil Tantilov 		case IXGBEVF_STATS:
416d72d6c19SEmil Tantilov 			p = (char *)adapter +
417d72d6c19SEmil Tantilov 					ixgbevf_gstrings_stats[i].stat_offset;
418d72d6c19SEmil Tantilov 			break;
419d72d6c19SEmil Tantilov 		default:
420d72d6c19SEmil Tantilov 			data[i] = 0;
421d72d6c19SEmil Tantilov 			continue;
42244bd741eSDon Skidmore 		}
423d72d6c19SEmil Tantilov 
424d72d6c19SEmil Tantilov 		data[i] = (ixgbevf_gstrings_stats[i].sizeof_stat ==
425d72d6c19SEmil Tantilov 			   sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
426dee1ad47SJeff Kirsher 	}
427a02a5a53SEmil Tantilov 
428a02a5a53SEmil Tantilov 	/* populate Tx queue data */
429a02a5a53SEmil Tantilov 	for (j = 0; j < adapter->num_tx_queues; j++) {
430a02a5a53SEmil Tantilov 		ring = adapter->tx_ring[j];
431a02a5a53SEmil Tantilov 		if (!ring) {
432a02a5a53SEmil Tantilov 			data[i++] = 0;
433a02a5a53SEmil Tantilov 			data[i++] = 0;
434a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS
435a02a5a53SEmil Tantilov 			data[i++] = 0;
436a02a5a53SEmil Tantilov 			data[i++] = 0;
437a02a5a53SEmil Tantilov 			data[i++] = 0;
438a02a5a53SEmil Tantilov #endif
439a02a5a53SEmil Tantilov 			continue;
440a02a5a53SEmil Tantilov 		}
441a02a5a53SEmil Tantilov 
442a02a5a53SEmil Tantilov 		do {
443a02a5a53SEmil Tantilov 			start = u64_stats_fetch_begin_irq(&ring->syncp);
444a02a5a53SEmil Tantilov 			data[i]   = ring->stats.packets;
445a02a5a53SEmil Tantilov 			data[i + 1] = ring->stats.bytes;
446a02a5a53SEmil Tantilov 		} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
447a02a5a53SEmil Tantilov 		i += 2;
448a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS
449a02a5a53SEmil Tantilov 		data[i] = ring->stats.yields;
450a02a5a53SEmil Tantilov 		data[i + 1] = ring->stats.misses;
451a02a5a53SEmil Tantilov 		data[i + 2] = ring->stats.cleaned;
452a02a5a53SEmil Tantilov 		i += 3;
453a02a5a53SEmil Tantilov #endif
454a02a5a53SEmil Tantilov 	}
455a02a5a53SEmil Tantilov 
456a02a5a53SEmil Tantilov 	/* populate Rx queue data */
457a02a5a53SEmil Tantilov 	for (j = 0; j < adapter->num_rx_queues; j++) {
458a02a5a53SEmil Tantilov 		ring = adapter->rx_ring[j];
459a02a5a53SEmil Tantilov 		if (!ring) {
460a02a5a53SEmil Tantilov 			data[i++] = 0;
461a02a5a53SEmil Tantilov 			data[i++] = 0;
462a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS
463a02a5a53SEmil Tantilov 			data[i++] = 0;
464a02a5a53SEmil Tantilov 			data[i++] = 0;
465a02a5a53SEmil Tantilov 			data[i++] = 0;
466a02a5a53SEmil Tantilov #endif
467a02a5a53SEmil Tantilov 			continue;
468a02a5a53SEmil Tantilov 		}
469a02a5a53SEmil Tantilov 
470a02a5a53SEmil Tantilov 		do {
471a02a5a53SEmil Tantilov 			start = u64_stats_fetch_begin_irq(&ring->syncp);
472a02a5a53SEmil Tantilov 			data[i]   = ring->stats.packets;
473a02a5a53SEmil Tantilov 			data[i + 1] = ring->stats.bytes;
474a02a5a53SEmil Tantilov 		} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
475a02a5a53SEmil Tantilov 		i += 2;
476a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS
477a02a5a53SEmil Tantilov 		data[i] = ring->stats.yields;
478a02a5a53SEmil Tantilov 		data[i + 1] = ring->stats.misses;
479a02a5a53SEmil Tantilov 		data[i + 2] = ring->stats.cleaned;
480a02a5a53SEmil Tantilov 		i += 3;
481a02a5a53SEmil Tantilov #endif
482a02a5a53SEmil Tantilov 	}
483dee1ad47SJeff Kirsher }
484dee1ad47SJeff Kirsher 
485dee1ad47SJeff Kirsher static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset,
486dee1ad47SJeff Kirsher 				u8 *data)
487dee1ad47SJeff Kirsher {
488a02a5a53SEmil Tantilov 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
489dee1ad47SJeff Kirsher 	char *p = (char *)data;
490dee1ad47SJeff Kirsher 	int i;
491dee1ad47SJeff Kirsher 
492dee1ad47SJeff Kirsher 	switch (stringset) {
493dee1ad47SJeff Kirsher 	case ETH_SS_TEST:
494dee1ad47SJeff Kirsher 		memcpy(data, *ixgbe_gstrings_test,
495d72d6c19SEmil Tantilov 		       IXGBEVF_TEST_LEN * ETH_GSTRING_LEN);
496dee1ad47SJeff Kirsher 		break;
497dee1ad47SJeff Kirsher 	case ETH_SS_STATS:
498d72d6c19SEmil Tantilov 		for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) {
499d72d6c19SEmil Tantilov 			memcpy(p, ixgbevf_gstrings_stats[i].stat_string,
500dee1ad47SJeff Kirsher 			       ETH_GSTRING_LEN);
501dee1ad47SJeff Kirsher 			p += ETH_GSTRING_LEN;
502dee1ad47SJeff Kirsher 		}
503a02a5a53SEmil Tantilov 
504a02a5a53SEmil Tantilov 		for (i = 0; i < adapter->num_tx_queues; i++) {
505a02a5a53SEmil Tantilov 			sprintf(p, "tx_queue_%u_packets", i);
506a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
507a02a5a53SEmil Tantilov 			sprintf(p, "tx_queue_%u_bytes", i);
508a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
509a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS
510a02a5a53SEmil Tantilov 			sprintf(p, "tx_queue_%u_bp_napi_yield", i);
511a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
512a02a5a53SEmil Tantilov 			sprintf(p, "tx_queue_%u_bp_misses", i);
513a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
514a02a5a53SEmil Tantilov 			sprintf(p, "tx_queue_%u_bp_cleaned", i);
515a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
516a02a5a53SEmil Tantilov #endif /* BP_EXTENDED_STATS */
517a02a5a53SEmil Tantilov 		}
518a02a5a53SEmil Tantilov 		for (i = 0; i < adapter->num_rx_queues; i++) {
519a02a5a53SEmil Tantilov 			sprintf(p, "rx_queue_%u_packets", i);
520a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
521a02a5a53SEmil Tantilov 			sprintf(p, "rx_queue_%u_bytes", i);
522a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
523a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS
524a02a5a53SEmil Tantilov 			sprintf(p, "rx_queue_%u_bp_poll_yield", i);
525a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
526a02a5a53SEmil Tantilov 			sprintf(p, "rx_queue_%u_bp_misses", i);
527a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
528a02a5a53SEmil Tantilov 			sprintf(p, "rx_queue_%u_bp_cleaned", i);
529a02a5a53SEmil Tantilov 			p += ETH_GSTRING_LEN;
530a02a5a53SEmil Tantilov #endif /* BP_EXTENDED_STATS */
531a02a5a53SEmil Tantilov 		}
532dee1ad47SJeff Kirsher 		break;
533dee1ad47SJeff Kirsher 	}
534dee1ad47SJeff Kirsher }
535dee1ad47SJeff Kirsher 
536dee1ad47SJeff Kirsher static int ixgbevf_link_test(struct ixgbevf_adapter *adapter, u64 *data)
537dee1ad47SJeff Kirsher {
538dee1ad47SJeff Kirsher 	struct ixgbe_hw *hw = &adapter->hw;
539dee1ad47SJeff Kirsher 	bool link_up;
540dee1ad47SJeff Kirsher 	u32 link_speed = 0;
541dee1ad47SJeff Kirsher 	*data = 0;
542dee1ad47SJeff Kirsher 
543dee1ad47SJeff Kirsher 	hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
544dee1ad47SJeff Kirsher 	if (!link_up)
545dee1ad47SJeff Kirsher 		*data = 1;
546dee1ad47SJeff Kirsher 
547dee1ad47SJeff Kirsher 	return *data;
548dee1ad47SJeff Kirsher }
549dee1ad47SJeff Kirsher 
550dee1ad47SJeff Kirsher /* ethtool register test data */
551dee1ad47SJeff Kirsher struct ixgbevf_reg_test {
552dee1ad47SJeff Kirsher 	u16 reg;
553dee1ad47SJeff Kirsher 	u8  array_len;
554dee1ad47SJeff Kirsher 	u8  test_type;
555dee1ad47SJeff Kirsher 	u32 mask;
556dee1ad47SJeff Kirsher 	u32 write;
557dee1ad47SJeff Kirsher };
558dee1ad47SJeff Kirsher 
559dee1ad47SJeff Kirsher /* In the hardware, registers are laid out either singly, in arrays
560dee1ad47SJeff Kirsher  * spaced 0x40 bytes apart, or in contiguous tables.  We assume
561dee1ad47SJeff Kirsher  * most tests take place on arrays or single registers (handled
562dee1ad47SJeff Kirsher  * as a single-element array) and special-case the tables.
563dee1ad47SJeff Kirsher  * Table tests are always pattern tests.
564dee1ad47SJeff Kirsher  *
565dee1ad47SJeff Kirsher  * We also make provision for some required setup steps by specifying
566dee1ad47SJeff Kirsher  * registers to be written without any read-back testing.
567dee1ad47SJeff Kirsher  */
568dee1ad47SJeff Kirsher 
569dee1ad47SJeff Kirsher #define PATTERN_TEST	1
570dee1ad47SJeff Kirsher #define SET_READ_TEST	2
571dee1ad47SJeff Kirsher #define WRITE_NO_TEST	3
572dee1ad47SJeff Kirsher #define TABLE32_TEST	4
573dee1ad47SJeff Kirsher #define TABLE64_TEST_LO	5
574dee1ad47SJeff Kirsher #define TABLE64_TEST_HI	6
575dee1ad47SJeff Kirsher 
576dee1ad47SJeff Kirsher /* default VF register test */
577dee1ad47SJeff Kirsher static const struct ixgbevf_reg_test reg_test_vf[] = {
578dee1ad47SJeff Kirsher 	{ IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
579dee1ad47SJeff Kirsher 	{ IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
580dee1ad47SJeff Kirsher 	{ IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
581dee1ad47SJeff Kirsher 	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
582dee1ad47SJeff Kirsher 	{ IXGBE_VFRDT(0), 2, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
583dee1ad47SJeff Kirsher 	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, 0 },
584dee1ad47SJeff Kirsher 	{ IXGBE_VFTDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
585dee1ad47SJeff Kirsher 	{ IXGBE_VFTDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
586dee1ad47SJeff Kirsher 	{ IXGBE_VFTDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFF80 },
587db99d95cSMark Rustad 	{ .reg = 0 }
588dee1ad47SJeff Kirsher };
589dee1ad47SJeff Kirsher 
590dee1ad47SJeff Kirsher static const u32 register_test_patterns[] = {
591dee1ad47SJeff Kirsher 	0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
592dee1ad47SJeff Kirsher };
593dee1ad47SJeff Kirsher 
594388b2e4cSMark Rustad static bool reg_pattern_test(struct ixgbevf_adapter *adapter, u64 *data,
595388b2e4cSMark Rustad 			     int reg, u32 mask, u32 write)
596388b2e4cSMark Rustad {
597388b2e4cSMark Rustad 	u32 pat, val, before;
598388b2e4cSMark Rustad 
59926597802SMark Rustad 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) {
60026597802SMark Rustad 		*data = 1;
60126597802SMark Rustad 		return true;
60226597802SMark Rustad 	}
603388b2e4cSMark Rustad 	for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) {
60432c74949SMark Rustad 		before = ixgbevf_read_reg(&adapter->hw, reg);
605388b2e4cSMark Rustad 		ixgbe_write_reg(&adapter->hw, reg,
606388b2e4cSMark Rustad 				register_test_patterns[pat] & write);
60732c74949SMark Rustad 		val = ixgbevf_read_reg(&adapter->hw, reg);
608388b2e4cSMark Rustad 		if (val != (register_test_patterns[pat] & write & mask)) {
609388b2e4cSMark Rustad 			hw_dbg(&adapter->hw,
610388b2e4cSMark Rustad 			       "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n",
611388b2e4cSMark Rustad 			       reg, val,
612388b2e4cSMark Rustad 			       register_test_patterns[pat] & write & mask);
613388b2e4cSMark Rustad 			*data = reg;
614388b2e4cSMark Rustad 			ixgbe_write_reg(&adapter->hw, reg, before);
615388b2e4cSMark Rustad 			return true;
616388b2e4cSMark Rustad 		}
617388b2e4cSMark Rustad 		ixgbe_write_reg(&adapter->hw, reg, before);
618388b2e4cSMark Rustad 	}
619388b2e4cSMark Rustad 	return false;
620dee1ad47SJeff Kirsher }
621dee1ad47SJeff Kirsher 
622388b2e4cSMark Rustad static bool reg_set_and_check(struct ixgbevf_adapter *adapter, u64 *data,
623388b2e4cSMark Rustad 			      int reg, u32 mask, u32 write)
624388b2e4cSMark Rustad {
625388b2e4cSMark Rustad 	u32 val, before;
626388b2e4cSMark Rustad 
62726597802SMark Rustad 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) {
62826597802SMark Rustad 		*data = 1;
62926597802SMark Rustad 		return true;
63026597802SMark Rustad 	}
63132c74949SMark Rustad 	before = ixgbevf_read_reg(&adapter->hw, reg);
632388b2e4cSMark Rustad 	ixgbe_write_reg(&adapter->hw, reg, write & mask);
63332c74949SMark Rustad 	val = ixgbevf_read_reg(&adapter->hw, reg);
634388b2e4cSMark Rustad 	if ((write & mask) != (val & mask)) {
635388b2e4cSMark Rustad 		pr_err("set/check reg %04X test failed: got 0x%08X expected 0x%08X\n",
636388b2e4cSMark Rustad 		       reg, (val & mask), write & mask);
637388b2e4cSMark Rustad 		*data = reg;
638388b2e4cSMark Rustad 		ixgbe_write_reg(&adapter->hw, reg, before);
639388b2e4cSMark Rustad 		return true;
640388b2e4cSMark Rustad 	}
641388b2e4cSMark Rustad 	ixgbe_write_reg(&adapter->hw, reg, before);
642388b2e4cSMark Rustad 	return false;
643dee1ad47SJeff Kirsher }
644dee1ad47SJeff Kirsher 
645dee1ad47SJeff Kirsher static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data)
646dee1ad47SJeff Kirsher {
647dee1ad47SJeff Kirsher 	const struct ixgbevf_reg_test *test;
648dee1ad47SJeff Kirsher 	u32 i;
649dee1ad47SJeff Kirsher 
65026597802SMark Rustad 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) {
65126597802SMark Rustad 		dev_err(&adapter->pdev->dev,
65226597802SMark Rustad 			"Adapter removed - register test blocked\n");
65326597802SMark Rustad 		*data = 1;
65426597802SMark Rustad 		return 1;
65526597802SMark Rustad 	}
656dee1ad47SJeff Kirsher 	test = reg_test_vf;
657dee1ad47SJeff Kirsher 
658dec0d8e4SJeff Kirsher 	/* Perform the register test, looping through the test table
659dee1ad47SJeff Kirsher 	 * until we either fail or reach the null entry.
660dee1ad47SJeff Kirsher 	 */
661dee1ad47SJeff Kirsher 	while (test->reg) {
662dee1ad47SJeff Kirsher 		for (i = 0; i < test->array_len; i++) {
663388b2e4cSMark Rustad 			bool b = false;
664388b2e4cSMark Rustad 
665dee1ad47SJeff Kirsher 			switch (test->test_type) {
666dee1ad47SJeff Kirsher 			case PATTERN_TEST:
667388b2e4cSMark Rustad 				b = reg_pattern_test(adapter, data,
668388b2e4cSMark Rustad 						     test->reg + (i * 0x40),
669dee1ad47SJeff Kirsher 						     test->mask,
670dee1ad47SJeff Kirsher 						     test->write);
671dee1ad47SJeff Kirsher 				break;
672dee1ad47SJeff Kirsher 			case SET_READ_TEST:
673388b2e4cSMark Rustad 				b = reg_set_and_check(adapter, data,
674388b2e4cSMark Rustad 						      test->reg + (i * 0x40),
675dee1ad47SJeff Kirsher 						      test->mask,
676dee1ad47SJeff Kirsher 						      test->write);
677dee1ad47SJeff Kirsher 				break;
678dee1ad47SJeff Kirsher 			case WRITE_NO_TEST:
679388b2e4cSMark Rustad 				ixgbe_write_reg(&adapter->hw,
680388b2e4cSMark Rustad 						test->reg + (i * 0x40),
681388b2e4cSMark Rustad 						test->write);
682dee1ad47SJeff Kirsher 				break;
683dee1ad47SJeff Kirsher 			case TABLE32_TEST:
684388b2e4cSMark Rustad 				b = reg_pattern_test(adapter, data,
685388b2e4cSMark Rustad 						     test->reg + (i * 4),
686dee1ad47SJeff Kirsher 						     test->mask,
687dee1ad47SJeff Kirsher 						     test->write);
688dee1ad47SJeff Kirsher 				break;
689dee1ad47SJeff Kirsher 			case TABLE64_TEST_LO:
690388b2e4cSMark Rustad 				b = reg_pattern_test(adapter, data,
691388b2e4cSMark Rustad 						     test->reg + (i * 8),
692dee1ad47SJeff Kirsher 						     test->mask,
693dee1ad47SJeff Kirsher 						     test->write);
694dee1ad47SJeff Kirsher 				break;
695dee1ad47SJeff Kirsher 			case TABLE64_TEST_HI:
696388b2e4cSMark Rustad 				b = reg_pattern_test(adapter, data,
697388b2e4cSMark Rustad 						     test->reg + 4 + (i * 8),
698dee1ad47SJeff Kirsher 						     test->mask,
699dee1ad47SJeff Kirsher 						     test->write);
700dee1ad47SJeff Kirsher 				break;
701dee1ad47SJeff Kirsher 			}
702388b2e4cSMark Rustad 			if (b)
703388b2e4cSMark Rustad 				return 1;
704dee1ad47SJeff Kirsher 		}
705dee1ad47SJeff Kirsher 		test++;
706dee1ad47SJeff Kirsher 	}
707dee1ad47SJeff Kirsher 
708dee1ad47SJeff Kirsher 	*data = 0;
709dee1ad47SJeff Kirsher 	return *data;
710dee1ad47SJeff Kirsher }
711dee1ad47SJeff Kirsher 
712dee1ad47SJeff Kirsher static void ixgbevf_diag_test(struct net_device *netdev,
713dee1ad47SJeff Kirsher 			      struct ethtool_test *eth_test, u64 *data)
714dee1ad47SJeff Kirsher {
715dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
716dee1ad47SJeff Kirsher 	bool if_running = netif_running(netdev);
717dee1ad47SJeff Kirsher 
71826597802SMark Rustad 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) {
71926597802SMark Rustad 		dev_err(&adapter->pdev->dev,
72026597802SMark Rustad 			"Adapter removed - test blocked\n");
72126597802SMark Rustad 		data[0] = 1;
72226597802SMark Rustad 		data[1] = 1;
72326597802SMark Rustad 		eth_test->flags |= ETH_TEST_FL_FAILED;
72426597802SMark Rustad 		return;
72526597802SMark Rustad 	}
726dee1ad47SJeff Kirsher 	set_bit(__IXGBEVF_TESTING, &adapter->state);
727dee1ad47SJeff Kirsher 	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
728dee1ad47SJeff Kirsher 		/* Offline tests */
729dee1ad47SJeff Kirsher 
730dee1ad47SJeff Kirsher 		hw_dbg(&adapter->hw, "offline testing starting\n");
731dee1ad47SJeff Kirsher 
732dee1ad47SJeff Kirsher 		/* Link test performed before hardware reset so autoneg doesn't
733dec0d8e4SJeff Kirsher 		 * interfere with test result
734dec0d8e4SJeff Kirsher 		 */
735dee1ad47SJeff Kirsher 		if (ixgbevf_link_test(adapter, &data[1]))
736dee1ad47SJeff Kirsher 			eth_test->flags |= ETH_TEST_FL_FAILED;
737dee1ad47SJeff Kirsher 
738dee1ad47SJeff Kirsher 		if (if_running)
739dee1ad47SJeff Kirsher 			/* indicate we're in test mode */
740324d0867SStefan Assmann 			ixgbevf_close(netdev);
741dee1ad47SJeff Kirsher 		else
742dee1ad47SJeff Kirsher 			ixgbevf_reset(adapter);
743dee1ad47SJeff Kirsher 
744dee1ad47SJeff Kirsher 		hw_dbg(&adapter->hw, "register testing starting\n");
745dee1ad47SJeff Kirsher 		if (ixgbevf_reg_test(adapter, &data[0]))
746dee1ad47SJeff Kirsher 			eth_test->flags |= ETH_TEST_FL_FAILED;
747dee1ad47SJeff Kirsher 
748dee1ad47SJeff Kirsher 		ixgbevf_reset(adapter);
749dee1ad47SJeff Kirsher 
750dee1ad47SJeff Kirsher 		clear_bit(__IXGBEVF_TESTING, &adapter->state);
751dee1ad47SJeff Kirsher 		if (if_running)
752324d0867SStefan Assmann 			ixgbevf_open(netdev);
753dee1ad47SJeff Kirsher 	} else {
754dee1ad47SJeff Kirsher 		hw_dbg(&adapter->hw, "online testing starting\n");
755dee1ad47SJeff Kirsher 		/* Online tests */
756dee1ad47SJeff Kirsher 		if (ixgbevf_link_test(adapter, &data[1]))
757dee1ad47SJeff Kirsher 			eth_test->flags |= ETH_TEST_FL_FAILED;
758dee1ad47SJeff Kirsher 
759dee1ad47SJeff Kirsher 		/* Online tests aren't run; pass by default */
760dee1ad47SJeff Kirsher 		data[0] = 0;
761dee1ad47SJeff Kirsher 
762dee1ad47SJeff Kirsher 		clear_bit(__IXGBEVF_TESTING, &adapter->state);
763dee1ad47SJeff Kirsher 	}
764dee1ad47SJeff Kirsher 	msleep_interruptible(4 * 1000);
765dee1ad47SJeff Kirsher }
766dee1ad47SJeff Kirsher 
767dee1ad47SJeff Kirsher static int ixgbevf_nway_reset(struct net_device *netdev)
768dee1ad47SJeff Kirsher {
769dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
770dee1ad47SJeff Kirsher 
77177d5dfcaSAlexander Duyck 	if (netif_running(netdev))
772dee1ad47SJeff Kirsher 		ixgbevf_reinit_locked(adapter);
773dee1ad47SJeff Kirsher 
774dee1ad47SJeff Kirsher 	return 0;
775dee1ad47SJeff Kirsher }
776dee1ad47SJeff Kirsher 
7773849623eSJacob Keller static int ixgbevf_get_coalesce(struct net_device *netdev,
7783849623eSJacob Keller 				struct ethtool_coalesce *ec)
7793849623eSJacob Keller {
7803849623eSJacob Keller 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
7813849623eSJacob Keller 
7823849623eSJacob Keller 	/* only valid if in constant ITR mode */
7833849623eSJacob Keller 	if (adapter->rx_itr_setting <= 1)
7843849623eSJacob Keller 		ec->rx_coalesce_usecs = adapter->rx_itr_setting;
7853849623eSJacob Keller 	else
7863849623eSJacob Keller 		ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2;
7873849623eSJacob Keller 
788dec0d8e4SJeff Kirsher 	/* if in mixed Tx/Rx queues per vector mode, report only Rx settings */
7893849623eSJacob Keller 	if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count)
7903849623eSJacob Keller 		return 0;
7913849623eSJacob Keller 
7923849623eSJacob Keller 	/* only valid if in constant ITR mode */
7933849623eSJacob Keller 	if (adapter->tx_itr_setting <= 1)
7943849623eSJacob Keller 		ec->tx_coalesce_usecs = adapter->tx_itr_setting;
7953849623eSJacob Keller 	else
7963849623eSJacob Keller 		ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2;
7973849623eSJacob Keller 
7983849623eSJacob Keller 	return 0;
7993849623eSJacob Keller }
8003849623eSJacob Keller 
8013849623eSJacob Keller static int ixgbevf_set_coalesce(struct net_device *netdev,
8023849623eSJacob Keller 				struct ethtool_coalesce *ec)
8033849623eSJacob Keller {
8043849623eSJacob Keller 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
8053849623eSJacob Keller 	struct ixgbevf_q_vector *q_vector;
8063849623eSJacob Keller 	int num_vectors, i;
8073849623eSJacob Keller 	u16 tx_itr_param, rx_itr_param;
8083849623eSJacob Keller 
809dec0d8e4SJeff Kirsher 	/* don't accept Tx specific changes if we've got mixed RxTx vectors */
810dec0d8e4SJeff Kirsher 	if (adapter->q_vector[0]->tx.count &&
811dec0d8e4SJeff Kirsher 	    adapter->q_vector[0]->rx.count && ec->tx_coalesce_usecs)
8123849623eSJacob Keller 		return -EINVAL;
8133849623eSJacob Keller 
8143849623eSJacob Keller 	if ((ec->rx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)) ||
8153849623eSJacob Keller 	    (ec->tx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)))
8163849623eSJacob Keller 		return -EINVAL;
8173849623eSJacob Keller 
8183849623eSJacob Keller 	if (ec->rx_coalesce_usecs > 1)
8193849623eSJacob Keller 		adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2;
8203849623eSJacob Keller 	else
8213849623eSJacob Keller 		adapter->rx_itr_setting = ec->rx_coalesce_usecs;
8223849623eSJacob Keller 
8233849623eSJacob Keller 	if (adapter->rx_itr_setting == 1)
8243849623eSJacob Keller 		rx_itr_param = IXGBE_20K_ITR;
8253849623eSJacob Keller 	else
8263849623eSJacob Keller 		rx_itr_param = adapter->rx_itr_setting;
8273849623eSJacob Keller 
8283849623eSJacob Keller 	if (ec->tx_coalesce_usecs > 1)
8293849623eSJacob Keller 		adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2;
8303849623eSJacob Keller 	else
8313849623eSJacob Keller 		adapter->tx_itr_setting = ec->tx_coalesce_usecs;
8323849623eSJacob Keller 
8333849623eSJacob Keller 	if (adapter->tx_itr_setting == 1)
8348a9ca110SAlexander Duyck 		tx_itr_param = IXGBE_12K_ITR;
8353849623eSJacob Keller 	else
8363849623eSJacob Keller 		tx_itr_param = adapter->tx_itr_setting;
8373849623eSJacob Keller 
8383849623eSJacob Keller 	num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
8393849623eSJacob Keller 
8403849623eSJacob Keller 	for (i = 0; i < num_vectors; i++) {
8413849623eSJacob Keller 		q_vector = adapter->q_vector[i];
8423849623eSJacob Keller 		if (q_vector->tx.count && !q_vector->rx.count)
843dec0d8e4SJeff Kirsher 			/* Tx only */
8443849623eSJacob Keller 			q_vector->itr = tx_itr_param;
8453849623eSJacob Keller 		else
846dec0d8e4SJeff Kirsher 			/* Rx only or mixed */
8473849623eSJacob Keller 			q_vector->itr = rx_itr_param;
8483849623eSJacob Keller 		ixgbevf_write_eitr(q_vector);
8493849623eSJacob Keller 	}
8503849623eSJacob Keller 
8513849623eSJacob Keller 	return 0;
8523849623eSJacob Keller }
8533849623eSJacob Keller 
854b6411739SVlad Zolotarov static int ixgbevf_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
855b6411739SVlad Zolotarov 			     u32 *rules __always_unused)
856b6411739SVlad Zolotarov {
857b6411739SVlad Zolotarov 	struct ixgbevf_adapter *adapter = netdev_priv(dev);
858b6411739SVlad Zolotarov 
859b6411739SVlad Zolotarov 	switch (info->cmd) {
860b6411739SVlad Zolotarov 	case ETHTOOL_GRXRINGS:
861b6411739SVlad Zolotarov 		info->data = adapter->num_rx_queues;
862b6411739SVlad Zolotarov 		return 0;
863b6411739SVlad Zolotarov 	default:
864b6411739SVlad Zolotarov 		hw_dbg(&adapter->hw, "Command parameters not supported\n");
865b6411739SVlad Zolotarov 		return -EOPNOTSUPP;
866b6411739SVlad Zolotarov 	}
867b6411739SVlad Zolotarov }
868b6411739SVlad Zolotarov 
869b6411739SVlad Zolotarov static u32 ixgbevf_get_rxfh_indir_size(struct net_device *netdev)
870b6411739SVlad Zolotarov {
871b6411739SVlad Zolotarov 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
872b6411739SVlad Zolotarov 
8739cba434fSEmil Tantilov 	if (adapter->hw.mac.type >= ixgbe_mac_X550_vf)
8749cba434fSEmil Tantilov 		return IXGBEVF_X550_VFRETA_SIZE;
875b6411739SVlad Zolotarov 
8769cba434fSEmil Tantilov 	return IXGBEVF_82599_RETA_SIZE;
877b6411739SVlad Zolotarov }
878b6411739SVlad Zolotarov 
879b6411739SVlad Zolotarov static u32 ixgbevf_get_rxfh_key_size(struct net_device *netdev)
880b6411739SVlad Zolotarov {
881b6411739SVlad Zolotarov 	return IXGBEVF_RSS_HASH_KEY_SIZE;
882b6411739SVlad Zolotarov }
883b6411739SVlad Zolotarov 
884b6411739SVlad Zolotarov static int ixgbevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
885b6411739SVlad Zolotarov 			    u8 *hfunc)
886b6411739SVlad Zolotarov {
887b6411739SVlad Zolotarov 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
888b6411739SVlad Zolotarov 	int err = 0;
889b6411739SVlad Zolotarov 
890b6411739SVlad Zolotarov 	if (hfunc)
891b6411739SVlad Zolotarov 		*hfunc = ETH_RSS_HASH_TOP;
892b6411739SVlad Zolotarov 
8939cba434fSEmil Tantilov 	if (adapter->hw.mac.type >= ixgbe_mac_X550_vf) {
8949cba434fSEmil Tantilov 		if (key)
8959cba434fSEmil Tantilov 			memcpy(key, adapter->rss_key, sizeof(adapter->rss_key));
8969cba434fSEmil Tantilov 
8979cba434fSEmil Tantilov 		if (indir) {
8989cba434fSEmil Tantilov 			int i;
8999cba434fSEmil Tantilov 
9009cba434fSEmil Tantilov 			for (i = 0; i < IXGBEVF_X550_VFRETA_SIZE; i++)
9019cba434fSEmil Tantilov 				indir[i] = adapter->rss_indir_tbl[i];
9029cba434fSEmil Tantilov 		}
9039cba434fSEmil Tantilov 	} else {
9049cba434fSEmil Tantilov 		/* If neither indirection table nor hash key was requested
9059cba434fSEmil Tantilov 		 *  - just return a success avoiding taking any locks.
906b6411739SVlad Zolotarov 		 */
907b6411739SVlad Zolotarov 		if (!indir && !key)
908b6411739SVlad Zolotarov 			return 0;
909b6411739SVlad Zolotarov 
910b6411739SVlad Zolotarov 		spin_lock_bh(&adapter->mbx_lock);
911b6411739SVlad Zolotarov 		if (indir)
912b6411739SVlad Zolotarov 			err = ixgbevf_get_reta_locked(&adapter->hw, indir,
913b6411739SVlad Zolotarov 						      adapter->num_rx_queues);
914b6411739SVlad Zolotarov 
915b6411739SVlad Zolotarov 		if (!err && key)
916b6411739SVlad Zolotarov 			err = ixgbevf_get_rss_key_locked(&adapter->hw, key);
917b6411739SVlad Zolotarov 
918b6411739SVlad Zolotarov 		spin_unlock_bh(&adapter->mbx_lock);
9199cba434fSEmil Tantilov 	}
920b6411739SVlad Zolotarov 
921b6411739SVlad Zolotarov 	return err;
922b6411739SVlad Zolotarov }
923b6411739SVlad Zolotarov 
924b47aca13SStephen Hemminger static const struct ethtool_ops ixgbevf_ethtool_ops = {
925dee1ad47SJeff Kirsher 	.get_settings		= ixgbevf_get_settings,
926dee1ad47SJeff Kirsher 	.get_drvinfo		= ixgbevf_get_drvinfo,
927dee1ad47SJeff Kirsher 	.get_regs_len		= ixgbevf_get_regs_len,
928dee1ad47SJeff Kirsher 	.get_regs		= ixgbevf_get_regs,
929dee1ad47SJeff Kirsher 	.nway_reset		= ixgbevf_nway_reset,
930dee1ad47SJeff Kirsher 	.get_link		= ethtool_op_get_link,
931dee1ad47SJeff Kirsher 	.get_ringparam		= ixgbevf_get_ringparam,
932dee1ad47SJeff Kirsher 	.set_ringparam		= ixgbevf_set_ringparam,
933dee1ad47SJeff Kirsher 	.get_msglevel		= ixgbevf_get_msglevel,
934dee1ad47SJeff Kirsher 	.set_msglevel		= ixgbevf_set_msglevel,
935dee1ad47SJeff Kirsher 	.self_test		= ixgbevf_diag_test,
936dee1ad47SJeff Kirsher 	.get_sset_count		= ixgbevf_get_sset_count,
937dee1ad47SJeff Kirsher 	.get_strings		= ixgbevf_get_strings,
938dee1ad47SJeff Kirsher 	.get_ethtool_stats	= ixgbevf_get_ethtool_stats,
9393849623eSJacob Keller 	.get_coalesce		= ixgbevf_get_coalesce,
9403849623eSJacob Keller 	.set_coalesce		= ixgbevf_set_coalesce,
941b6411739SVlad Zolotarov 	.get_rxnfc		= ixgbevf_get_rxnfc,
942b6411739SVlad Zolotarov 	.get_rxfh_indir_size	= ixgbevf_get_rxfh_indir_size,
943b6411739SVlad Zolotarov 	.get_rxfh_key_size	= ixgbevf_get_rxfh_key_size,
944b6411739SVlad Zolotarov 	.get_rxfh		= ixgbevf_get_rxfh,
945dee1ad47SJeff Kirsher };
946dee1ad47SJeff Kirsher 
947dee1ad47SJeff Kirsher void ixgbevf_set_ethtool_ops(struct net_device *netdev)
948dee1ad47SJeff Kirsher {
9497ad24ea4SWilfried Klaebe 	netdev->ethtool_ops = &ixgbevf_ethtool_ops;
950dee1ad47SJeff Kirsher }
951