1dee1ad47SJeff Kirsher /*******************************************************************************
2dee1ad47SJeff Kirsher 
3dee1ad47SJeff Kirsher   Intel 82599 Virtual Function driver
4dee1ad47SJeff Kirsher   Copyright(c) 1999 - 2009 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
16dee1ad47SJeff Kirsher   this program; if not, write to the Free Software Foundation, Inc.,
17dee1ad47SJeff Kirsher   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18dee1ad47SJeff Kirsher 
19dee1ad47SJeff Kirsher   The full GNU General Public License is included in this distribution in
20dee1ad47SJeff Kirsher   the file called "COPYING".
21dee1ad47SJeff Kirsher 
22dee1ad47SJeff Kirsher   Contact Information:
23dee1ad47SJeff Kirsher   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24dee1ad47SJeff Kirsher   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25dee1ad47SJeff Kirsher 
26dee1ad47SJeff Kirsher *******************************************************************************/
27dee1ad47SJeff Kirsher 
28dee1ad47SJeff Kirsher /* ethtool support for ixgbevf */
29dee1ad47SJeff Kirsher 
30dee1ad47SJeff Kirsher #include <linux/types.h>
31dee1ad47SJeff Kirsher #include <linux/module.h>
32dee1ad47SJeff Kirsher #include <linux/slab.h>
33dee1ad47SJeff Kirsher #include <linux/pci.h>
34dee1ad47SJeff Kirsher #include <linux/netdevice.h>
35dee1ad47SJeff Kirsher #include <linux/ethtool.h>
36dee1ad47SJeff Kirsher #include <linux/vmalloc.h>
37dee1ad47SJeff Kirsher #include <linux/if_vlan.h>
38dee1ad47SJeff Kirsher #include <linux/uaccess.h>
39dee1ad47SJeff Kirsher 
40dee1ad47SJeff Kirsher #include "ixgbevf.h"
41dee1ad47SJeff Kirsher 
42dee1ad47SJeff Kirsher #define IXGBE_ALL_RAR_ENTRIES 16
43dee1ad47SJeff Kirsher 
44dee1ad47SJeff Kirsher #ifdef ETHTOOL_GSTATS
45dee1ad47SJeff Kirsher struct ixgbe_stats {
46dee1ad47SJeff Kirsher 	char stat_string[ETH_GSTRING_LEN];
47dee1ad47SJeff Kirsher 	int sizeof_stat;
48dee1ad47SJeff Kirsher 	int stat_offset;
49dee1ad47SJeff Kirsher 	int base_stat_offset;
50dee1ad47SJeff Kirsher 	int saved_reset_offset;
51dee1ad47SJeff Kirsher };
52dee1ad47SJeff Kirsher 
53dee1ad47SJeff Kirsher #define IXGBEVF_STAT(m, b, r)  sizeof(((struct ixgbevf_adapter *)0)->m), \
54dee1ad47SJeff Kirsher 			    offsetof(struct ixgbevf_adapter, m),         \
55dee1ad47SJeff Kirsher 			    offsetof(struct ixgbevf_adapter, b),         \
56dee1ad47SJeff Kirsher 			    offsetof(struct ixgbevf_adapter, r)
57dee1ad47SJeff Kirsher static struct ixgbe_stats ixgbe_gstrings_stats[] = {
58dee1ad47SJeff Kirsher 	{"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
59dee1ad47SJeff Kirsher 				    stats.saved_reset_vfgprc)},
60dee1ad47SJeff Kirsher 	{"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
61dee1ad47SJeff Kirsher 				    stats.saved_reset_vfgptc)},
62dee1ad47SJeff Kirsher 	{"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc,
63dee1ad47SJeff Kirsher 				  stats.saved_reset_vfgorc)},
64dee1ad47SJeff Kirsher 	{"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc,
65dee1ad47SJeff Kirsher 				  stats.saved_reset_vfgotc)},
66dee1ad47SJeff Kirsher 	{"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)},
67dee1ad47SJeff Kirsher 	{"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc,
68dee1ad47SJeff Kirsher 				   stats.saved_reset_vfmprc)},
69dee1ad47SJeff Kirsher 	{"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base,
70dee1ad47SJeff Kirsher 					      zero_base)},
71dee1ad47SJeff Kirsher 	{"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base,
72dee1ad47SJeff Kirsher 						zero_base)},
73dee1ad47SJeff Kirsher 	{"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base,
74dee1ad47SJeff Kirsher 					      zero_base)},
75dee1ad47SJeff Kirsher 	{"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)},
76dee1ad47SJeff Kirsher };
77dee1ad47SJeff Kirsher 
78dee1ad47SJeff Kirsher #define IXGBE_QUEUE_STATS_LEN 0
79dee1ad47SJeff Kirsher #define IXGBE_GLOBAL_STATS_LEN	ARRAY_SIZE(ixgbe_gstrings_stats)
80dee1ad47SJeff Kirsher 
81dee1ad47SJeff Kirsher #define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
82dee1ad47SJeff Kirsher #endif /* ETHTOOL_GSTATS */
83dee1ad47SJeff Kirsher #ifdef ETHTOOL_TEST
84dee1ad47SJeff Kirsher static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
85dee1ad47SJeff Kirsher 	"Register test  (offline)",
86dee1ad47SJeff Kirsher 	"Link test   (on/offline)"
87dee1ad47SJeff Kirsher };
88dee1ad47SJeff Kirsher #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
89dee1ad47SJeff Kirsher #endif /* ETHTOOL_TEST */
90dee1ad47SJeff Kirsher 
91dee1ad47SJeff Kirsher static int ixgbevf_get_settings(struct net_device *netdev,
92dee1ad47SJeff Kirsher 				struct ethtool_cmd *ecmd)
93dee1ad47SJeff Kirsher {
94dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
95dee1ad47SJeff Kirsher 	struct ixgbe_hw *hw = &adapter->hw;
96dee1ad47SJeff Kirsher 	u32 link_speed = 0;
97dee1ad47SJeff Kirsher 	bool link_up;
98dee1ad47SJeff Kirsher 
99dee1ad47SJeff Kirsher 	ecmd->supported = SUPPORTED_10000baseT_Full;
100dee1ad47SJeff Kirsher 	ecmd->autoneg = AUTONEG_DISABLE;
101dee1ad47SJeff Kirsher 	ecmd->transceiver = XCVR_DUMMY1;
102dee1ad47SJeff Kirsher 	ecmd->port = -1;
103dee1ad47SJeff Kirsher 
104dee1ad47SJeff Kirsher 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
105dee1ad47SJeff Kirsher 
106dee1ad47SJeff Kirsher 	if (link_up) {
107dee1ad47SJeff Kirsher 		ethtool_cmd_speed_set(
108dee1ad47SJeff Kirsher 			ecmd,
109dee1ad47SJeff Kirsher 			(link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
110dee1ad47SJeff Kirsher 			SPEED_10000 : SPEED_1000);
111dee1ad47SJeff Kirsher 		ecmd->duplex = DUPLEX_FULL;
112dee1ad47SJeff Kirsher 	} else {
113dee1ad47SJeff Kirsher 		ethtool_cmd_speed_set(ecmd, -1);
114dee1ad47SJeff Kirsher 		ecmd->duplex = -1;
115dee1ad47SJeff Kirsher 	}
116dee1ad47SJeff Kirsher 
117dee1ad47SJeff Kirsher 	return 0;
118dee1ad47SJeff Kirsher }
119dee1ad47SJeff Kirsher 
120dee1ad47SJeff Kirsher static u32 ixgbevf_get_rx_csum(struct net_device *netdev)
121dee1ad47SJeff Kirsher {
122dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
123dee1ad47SJeff Kirsher 	return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
124dee1ad47SJeff Kirsher }
125dee1ad47SJeff Kirsher 
126dee1ad47SJeff Kirsher static int ixgbevf_set_rx_csum(struct net_device *netdev, u32 data)
127dee1ad47SJeff Kirsher {
128dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
129dee1ad47SJeff Kirsher 	if (data)
130dee1ad47SJeff Kirsher 		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
131dee1ad47SJeff Kirsher 	else
132dee1ad47SJeff Kirsher 		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
133dee1ad47SJeff Kirsher 
134dee1ad47SJeff Kirsher 	if (netif_running(netdev)) {
135dee1ad47SJeff Kirsher 		if (!adapter->dev_closed)
136dee1ad47SJeff Kirsher 			ixgbevf_reinit_locked(adapter);
137dee1ad47SJeff Kirsher 	} else {
138dee1ad47SJeff Kirsher 		ixgbevf_reset(adapter);
139dee1ad47SJeff Kirsher 	}
140dee1ad47SJeff Kirsher 
141dee1ad47SJeff Kirsher 	return 0;
142dee1ad47SJeff Kirsher }
143dee1ad47SJeff Kirsher 
144dee1ad47SJeff Kirsher static int ixgbevf_set_tso(struct net_device *netdev, u32 data)
145dee1ad47SJeff Kirsher {
146dee1ad47SJeff Kirsher 	if (data) {
147dee1ad47SJeff Kirsher 		netdev->features |= NETIF_F_TSO;
148dee1ad47SJeff Kirsher 		netdev->features |= NETIF_F_TSO6;
149dee1ad47SJeff Kirsher 	} else {
150dee1ad47SJeff Kirsher 		netif_tx_stop_all_queues(netdev);
151dee1ad47SJeff Kirsher 		netdev->features &= ~NETIF_F_TSO;
152dee1ad47SJeff Kirsher 		netdev->features &= ~NETIF_F_TSO6;
153dee1ad47SJeff Kirsher 		netif_tx_start_all_queues(netdev);
154dee1ad47SJeff Kirsher 	}
155dee1ad47SJeff Kirsher 	return 0;
156dee1ad47SJeff Kirsher }
157dee1ad47SJeff Kirsher 
158dee1ad47SJeff Kirsher static u32 ixgbevf_get_msglevel(struct net_device *netdev)
159dee1ad47SJeff Kirsher {
160dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
161dee1ad47SJeff Kirsher 	return adapter->msg_enable;
162dee1ad47SJeff Kirsher }
163dee1ad47SJeff Kirsher 
164dee1ad47SJeff Kirsher static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data)
165dee1ad47SJeff Kirsher {
166dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
167dee1ad47SJeff Kirsher 	adapter->msg_enable = data;
168dee1ad47SJeff Kirsher }
169dee1ad47SJeff Kirsher 
170dee1ad47SJeff Kirsher #define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_)
171dee1ad47SJeff Kirsher 
172dee1ad47SJeff Kirsher static char *ixgbevf_reg_names[] = {
173dee1ad47SJeff Kirsher 	"IXGBE_VFCTRL",
174dee1ad47SJeff Kirsher 	"IXGBE_VFSTATUS",
175dee1ad47SJeff Kirsher 	"IXGBE_VFLINKS",
176dee1ad47SJeff Kirsher 	"IXGBE_VFRXMEMWRAP",
177dee1ad47SJeff Kirsher 	"IXGBE_VFFRTIMER",
178dee1ad47SJeff Kirsher 	"IXGBE_VTEICR",
179dee1ad47SJeff Kirsher 	"IXGBE_VTEICS",
180dee1ad47SJeff Kirsher 	"IXGBE_VTEIMS",
181dee1ad47SJeff Kirsher 	"IXGBE_VTEIMC",
182dee1ad47SJeff Kirsher 	"IXGBE_VTEIAC",
183dee1ad47SJeff Kirsher 	"IXGBE_VTEIAM",
184dee1ad47SJeff Kirsher 	"IXGBE_VTEITR",
185dee1ad47SJeff Kirsher 	"IXGBE_VTIVAR",
186dee1ad47SJeff Kirsher 	"IXGBE_VTIVAR_MISC",
187dee1ad47SJeff Kirsher 	"IXGBE_VFRDBAL0",
188dee1ad47SJeff Kirsher 	"IXGBE_VFRDBAL1",
189dee1ad47SJeff Kirsher 	"IXGBE_VFRDBAH0",
190dee1ad47SJeff Kirsher 	"IXGBE_VFRDBAH1",
191dee1ad47SJeff Kirsher 	"IXGBE_VFRDLEN0",
192dee1ad47SJeff Kirsher 	"IXGBE_VFRDLEN1",
193dee1ad47SJeff Kirsher 	"IXGBE_VFRDH0",
194dee1ad47SJeff Kirsher 	"IXGBE_VFRDH1",
195dee1ad47SJeff Kirsher 	"IXGBE_VFRDT0",
196dee1ad47SJeff Kirsher 	"IXGBE_VFRDT1",
197dee1ad47SJeff Kirsher 	"IXGBE_VFRXDCTL0",
198dee1ad47SJeff Kirsher 	"IXGBE_VFRXDCTL1",
199dee1ad47SJeff Kirsher 	"IXGBE_VFSRRCTL0",
200dee1ad47SJeff Kirsher 	"IXGBE_VFSRRCTL1",
201dee1ad47SJeff Kirsher 	"IXGBE_VFPSRTYPE",
202dee1ad47SJeff Kirsher 	"IXGBE_VFTDBAL0",
203dee1ad47SJeff Kirsher 	"IXGBE_VFTDBAL1",
204dee1ad47SJeff Kirsher 	"IXGBE_VFTDBAH0",
205dee1ad47SJeff Kirsher 	"IXGBE_VFTDBAH1",
206dee1ad47SJeff Kirsher 	"IXGBE_VFTDLEN0",
207dee1ad47SJeff Kirsher 	"IXGBE_VFTDLEN1",
208dee1ad47SJeff Kirsher 	"IXGBE_VFTDH0",
209dee1ad47SJeff Kirsher 	"IXGBE_VFTDH1",
210dee1ad47SJeff Kirsher 	"IXGBE_VFTDT0",
211dee1ad47SJeff Kirsher 	"IXGBE_VFTDT1",
212dee1ad47SJeff Kirsher 	"IXGBE_VFTXDCTL0",
213dee1ad47SJeff Kirsher 	"IXGBE_VFTXDCTL1",
214dee1ad47SJeff Kirsher 	"IXGBE_VFTDWBAL0",
215dee1ad47SJeff Kirsher 	"IXGBE_VFTDWBAL1",
216dee1ad47SJeff Kirsher 	"IXGBE_VFTDWBAH0",
217dee1ad47SJeff Kirsher 	"IXGBE_VFTDWBAH1"
218dee1ad47SJeff Kirsher };
219dee1ad47SJeff Kirsher 
220dee1ad47SJeff Kirsher 
221dee1ad47SJeff Kirsher static int ixgbevf_get_regs_len(struct net_device *netdev)
222dee1ad47SJeff Kirsher {
223dee1ad47SJeff Kirsher 	return (ARRAY_SIZE(ixgbevf_reg_names)) * sizeof(u32);
224dee1ad47SJeff Kirsher }
225dee1ad47SJeff Kirsher 
226dee1ad47SJeff Kirsher static void ixgbevf_get_regs(struct net_device *netdev,
227dee1ad47SJeff Kirsher 			     struct ethtool_regs *regs,
228dee1ad47SJeff Kirsher 			     void *p)
229dee1ad47SJeff Kirsher {
230dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
231dee1ad47SJeff Kirsher 	struct ixgbe_hw *hw = &adapter->hw;
232dee1ad47SJeff Kirsher 	u32 *regs_buff = p;
233dee1ad47SJeff Kirsher 	u32 regs_len = ixgbevf_get_regs_len(netdev);
234dee1ad47SJeff Kirsher 	u8 i;
235dee1ad47SJeff Kirsher 
236dee1ad47SJeff Kirsher 	memset(p, 0, regs_len);
237dee1ad47SJeff Kirsher 
238dee1ad47SJeff Kirsher 	regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id;
239dee1ad47SJeff Kirsher 
240dee1ad47SJeff Kirsher 	/* General Registers */
241dee1ad47SJeff Kirsher 	regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL);
242dee1ad47SJeff Kirsher 	regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS);
243dee1ad47SJeff Kirsher 	regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
244dee1ad47SJeff Kirsher 	regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP);
245dee1ad47SJeff Kirsher 	regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER);
246dee1ad47SJeff Kirsher 
247dee1ad47SJeff Kirsher 	/* Interrupt */
248dee1ad47SJeff Kirsher 	/* don't read EICR because it can clear interrupt causes, instead
249dee1ad47SJeff Kirsher 	 * read EICS which is a shadow but doesn't clear EICR */
250dee1ad47SJeff Kirsher 	regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_VTEICS);
251dee1ad47SJeff Kirsher 	regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_VTEICS);
252dee1ad47SJeff Kirsher 	regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_VTEIMS);
253dee1ad47SJeff Kirsher 	regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_VTEIMC);
254dee1ad47SJeff Kirsher 	regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_VTEIAC);
255dee1ad47SJeff Kirsher 	regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_VTEIAM);
256dee1ad47SJeff Kirsher 	regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_VTEITR(0));
257dee1ad47SJeff Kirsher 	regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_VTIVAR(0));
258dee1ad47SJeff Kirsher 	regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
259dee1ad47SJeff Kirsher 
260dee1ad47SJeff Kirsher 	/* Receive DMA */
261dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
262dee1ad47SJeff Kirsher 		regs_buff[14 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAL(i));
263dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
264dee1ad47SJeff Kirsher 		regs_buff[16 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAH(i));
265dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
266dee1ad47SJeff Kirsher 		regs_buff[18 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDLEN(i));
267dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
268dee1ad47SJeff Kirsher 		regs_buff[20 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDH(i));
269dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
270dee1ad47SJeff Kirsher 		regs_buff[22 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDT(i));
271dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
272dee1ad47SJeff Kirsher 		regs_buff[24 + i] = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
273dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
274dee1ad47SJeff Kirsher 		regs_buff[26 + i] = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i));
275dee1ad47SJeff Kirsher 
276dee1ad47SJeff Kirsher 	/* Receive */
277dee1ad47SJeff Kirsher 	regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_VFPSRTYPE);
278dee1ad47SJeff Kirsher 
279dee1ad47SJeff Kirsher 	/* Transmit */
280dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
281dee1ad47SJeff Kirsher 		regs_buff[29 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAL(i));
282dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
283dee1ad47SJeff Kirsher 		regs_buff[31 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAH(i));
284dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
285dee1ad47SJeff Kirsher 		regs_buff[33 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDLEN(i));
286dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
287dee1ad47SJeff Kirsher 		regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDH(i));
288dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
289dee1ad47SJeff Kirsher 		regs_buff[37 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDT(i));
290dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
291dee1ad47SJeff Kirsher 		regs_buff[39 + i] = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i));
292dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
293dee1ad47SJeff Kirsher 		regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i));
294dee1ad47SJeff Kirsher 	for (i = 0; i < 2; i++)
295dee1ad47SJeff Kirsher 		regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i));
296dee1ad47SJeff Kirsher 
297dee1ad47SJeff Kirsher 	for (i = 0; i < ARRAY_SIZE(ixgbevf_reg_names); i++)
298dee1ad47SJeff Kirsher 		hw_dbg(hw, "%s\t%8.8x\n", ixgbevf_reg_names[i], regs_buff[i]);
299dee1ad47SJeff Kirsher }
300dee1ad47SJeff Kirsher 
301dee1ad47SJeff Kirsher static void ixgbevf_get_drvinfo(struct net_device *netdev,
302dee1ad47SJeff Kirsher 				struct ethtool_drvinfo *drvinfo)
303dee1ad47SJeff Kirsher {
304dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
305dee1ad47SJeff Kirsher 
306dee1ad47SJeff Kirsher 	strlcpy(drvinfo->driver, ixgbevf_driver_name, 32);
307dee1ad47SJeff Kirsher 	strlcpy(drvinfo->version, ixgbevf_driver_version, 32);
308dee1ad47SJeff Kirsher 
309dee1ad47SJeff Kirsher 	strlcpy(drvinfo->fw_version, "N/A", 4);
310dee1ad47SJeff Kirsher 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
311dee1ad47SJeff Kirsher }
312dee1ad47SJeff Kirsher 
313dee1ad47SJeff Kirsher static void ixgbevf_get_ringparam(struct net_device *netdev,
314dee1ad47SJeff Kirsher 				  struct ethtool_ringparam *ring)
315dee1ad47SJeff Kirsher {
316dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
317dee1ad47SJeff Kirsher 	struct ixgbevf_ring *tx_ring = adapter->tx_ring;
318dee1ad47SJeff Kirsher 	struct ixgbevf_ring *rx_ring = adapter->rx_ring;
319dee1ad47SJeff Kirsher 
320dee1ad47SJeff Kirsher 	ring->rx_max_pending = IXGBEVF_MAX_RXD;
321dee1ad47SJeff Kirsher 	ring->tx_max_pending = IXGBEVF_MAX_TXD;
322dee1ad47SJeff Kirsher 	ring->rx_mini_max_pending = 0;
323dee1ad47SJeff Kirsher 	ring->rx_jumbo_max_pending = 0;
324dee1ad47SJeff Kirsher 	ring->rx_pending = rx_ring->count;
325dee1ad47SJeff Kirsher 	ring->tx_pending = tx_ring->count;
326dee1ad47SJeff Kirsher 	ring->rx_mini_pending = 0;
327dee1ad47SJeff Kirsher 	ring->rx_jumbo_pending = 0;
328dee1ad47SJeff Kirsher }
329dee1ad47SJeff Kirsher 
330dee1ad47SJeff Kirsher static int ixgbevf_set_ringparam(struct net_device *netdev,
331dee1ad47SJeff Kirsher 				 struct ethtool_ringparam *ring)
332dee1ad47SJeff Kirsher {
333dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
334dee1ad47SJeff Kirsher 	struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
335dee1ad47SJeff Kirsher 	int i, err = 0;
336dee1ad47SJeff Kirsher 	u32 new_rx_count, new_tx_count;
337dee1ad47SJeff Kirsher 
338dee1ad47SJeff Kirsher 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
339dee1ad47SJeff Kirsher 		return -EINVAL;
340dee1ad47SJeff Kirsher 
341dee1ad47SJeff Kirsher 	new_rx_count = max(ring->rx_pending, (u32)IXGBEVF_MIN_RXD);
342dee1ad47SJeff Kirsher 	new_rx_count = min(new_rx_count, (u32)IXGBEVF_MAX_RXD);
343dee1ad47SJeff Kirsher 	new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE);
344dee1ad47SJeff Kirsher 
345dee1ad47SJeff Kirsher 	new_tx_count = max(ring->tx_pending, (u32)IXGBEVF_MIN_TXD);
346dee1ad47SJeff Kirsher 	new_tx_count = min(new_tx_count, (u32)IXGBEVF_MAX_TXD);
347dee1ad47SJeff Kirsher 	new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE);
348dee1ad47SJeff Kirsher 
349dee1ad47SJeff Kirsher 	if ((new_tx_count == adapter->tx_ring->count) &&
350dee1ad47SJeff Kirsher 	    (new_rx_count == adapter->rx_ring->count)) {
351dee1ad47SJeff Kirsher 		/* nothing to do */
352dee1ad47SJeff Kirsher 		return 0;
353dee1ad47SJeff Kirsher 	}
354dee1ad47SJeff Kirsher 
355dee1ad47SJeff Kirsher 	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
356dee1ad47SJeff Kirsher 		msleep(1);
357dee1ad47SJeff Kirsher 
358dee1ad47SJeff Kirsher 	/*
359dee1ad47SJeff Kirsher 	 * If the adapter isn't up and running then just set the
360dee1ad47SJeff Kirsher 	 * new parameters and scurry for the exits.
361dee1ad47SJeff Kirsher 	 */
362dee1ad47SJeff Kirsher 	if (!netif_running(adapter->netdev)) {
363dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_tx_queues; i++)
364dee1ad47SJeff Kirsher 			adapter->tx_ring[i].count = new_tx_count;
365dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_rx_queues; i++)
366dee1ad47SJeff Kirsher 			adapter->rx_ring[i].count = new_rx_count;
367dee1ad47SJeff Kirsher 		adapter->tx_ring_count = new_tx_count;
368dee1ad47SJeff Kirsher 		adapter->rx_ring_count = new_rx_count;
369dee1ad47SJeff Kirsher 		goto clear_reset;
370dee1ad47SJeff Kirsher 	}
371dee1ad47SJeff Kirsher 
372dee1ad47SJeff Kirsher 	tx_ring = kcalloc(adapter->num_tx_queues,
373dee1ad47SJeff Kirsher 			  sizeof(struct ixgbevf_ring), GFP_KERNEL);
374dee1ad47SJeff Kirsher 	if (!tx_ring) {
375dee1ad47SJeff Kirsher 		err = -ENOMEM;
376dee1ad47SJeff Kirsher 		goto clear_reset;
377dee1ad47SJeff Kirsher 	}
378dee1ad47SJeff Kirsher 
379dee1ad47SJeff Kirsher 	rx_ring = kcalloc(adapter->num_rx_queues,
380dee1ad47SJeff Kirsher 			  sizeof(struct ixgbevf_ring), GFP_KERNEL);
381dee1ad47SJeff Kirsher 	if (!rx_ring) {
382dee1ad47SJeff Kirsher 		err = -ENOMEM;
383dee1ad47SJeff Kirsher 		goto err_rx_setup;
384dee1ad47SJeff Kirsher 	}
385dee1ad47SJeff Kirsher 
386dee1ad47SJeff Kirsher 	ixgbevf_down(adapter);
387dee1ad47SJeff Kirsher 
388dee1ad47SJeff Kirsher 	memcpy(tx_ring, adapter->tx_ring,
389dee1ad47SJeff Kirsher 	       adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
390dee1ad47SJeff Kirsher 	for (i = 0; i < adapter->num_tx_queues; i++) {
391dee1ad47SJeff Kirsher 		tx_ring[i].count = new_tx_count;
392dee1ad47SJeff Kirsher 		err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]);
393dee1ad47SJeff Kirsher 		if (err) {
394dee1ad47SJeff Kirsher 			while (i) {
395dee1ad47SJeff Kirsher 				i--;
396dee1ad47SJeff Kirsher 				ixgbevf_free_tx_resources(adapter,
397dee1ad47SJeff Kirsher 							  &tx_ring[i]);
398dee1ad47SJeff Kirsher 			}
399dee1ad47SJeff Kirsher 			goto err_tx_ring_setup;
400dee1ad47SJeff Kirsher 		}
401dee1ad47SJeff Kirsher 		tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
402dee1ad47SJeff Kirsher 	}
403dee1ad47SJeff Kirsher 
404dee1ad47SJeff Kirsher 	memcpy(rx_ring, adapter->rx_ring,
405dee1ad47SJeff Kirsher 	       adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
406dee1ad47SJeff Kirsher 	for (i = 0; i < adapter->num_rx_queues; i++) {
407dee1ad47SJeff Kirsher 		rx_ring[i].count = new_rx_count;
408dee1ad47SJeff Kirsher 		err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]);
409dee1ad47SJeff Kirsher 		if (err) {
410dee1ad47SJeff Kirsher 			while (i) {
411dee1ad47SJeff Kirsher 				i--;
412dee1ad47SJeff Kirsher 				ixgbevf_free_rx_resources(adapter,
413dee1ad47SJeff Kirsher 							  &rx_ring[i]);
414dee1ad47SJeff Kirsher 			}
415dee1ad47SJeff Kirsher 				goto err_rx_ring_setup;
416dee1ad47SJeff Kirsher 		}
417dee1ad47SJeff Kirsher 		rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
418dee1ad47SJeff Kirsher 	}
419dee1ad47SJeff Kirsher 
420dee1ad47SJeff Kirsher 	/*
421dee1ad47SJeff Kirsher 	 * Only switch to new rings if all the prior allocations
422dee1ad47SJeff Kirsher 	 * and ring setups have succeeded.
423dee1ad47SJeff Kirsher 	 */
424dee1ad47SJeff Kirsher 	kfree(adapter->tx_ring);
425dee1ad47SJeff Kirsher 	adapter->tx_ring = tx_ring;
426dee1ad47SJeff Kirsher 	adapter->tx_ring_count = new_tx_count;
427dee1ad47SJeff Kirsher 
428dee1ad47SJeff Kirsher 	kfree(adapter->rx_ring);
429dee1ad47SJeff Kirsher 	adapter->rx_ring = rx_ring;
430dee1ad47SJeff Kirsher 	adapter->rx_ring_count = new_rx_count;
431dee1ad47SJeff Kirsher 
432dee1ad47SJeff Kirsher 	/* success! */
433dee1ad47SJeff Kirsher 	ixgbevf_up(adapter);
434dee1ad47SJeff Kirsher 
435dee1ad47SJeff Kirsher 	goto clear_reset;
436dee1ad47SJeff Kirsher 
437dee1ad47SJeff Kirsher err_rx_ring_setup:
438dee1ad47SJeff Kirsher 	for(i = 0; i < adapter->num_tx_queues; i++)
439dee1ad47SJeff Kirsher 		ixgbevf_free_tx_resources(adapter, &tx_ring[i]);
440dee1ad47SJeff Kirsher 
441dee1ad47SJeff Kirsher err_tx_ring_setup:
442dee1ad47SJeff Kirsher 	kfree(rx_ring);
443dee1ad47SJeff Kirsher 
444dee1ad47SJeff Kirsher err_rx_setup:
445dee1ad47SJeff Kirsher 	kfree(tx_ring);
446dee1ad47SJeff Kirsher 
447dee1ad47SJeff Kirsher clear_reset:
448dee1ad47SJeff Kirsher 	clear_bit(__IXGBEVF_RESETTING, &adapter->state);
449dee1ad47SJeff Kirsher 	return err;
450dee1ad47SJeff Kirsher }
451dee1ad47SJeff Kirsher 
452dee1ad47SJeff Kirsher static int ixgbevf_get_sset_count(struct net_device *dev, int stringset)
453dee1ad47SJeff Kirsher {
454dee1ad47SJeff Kirsher        switch (stringset) {
455dee1ad47SJeff Kirsher        case ETH_SS_TEST:
456dee1ad47SJeff Kirsher 	       return IXGBE_TEST_LEN;
457dee1ad47SJeff Kirsher        case ETH_SS_STATS:
458dee1ad47SJeff Kirsher 	       return IXGBE_GLOBAL_STATS_LEN;
459dee1ad47SJeff Kirsher        default:
460dee1ad47SJeff Kirsher 	       return -EINVAL;
461dee1ad47SJeff Kirsher        }
462dee1ad47SJeff Kirsher }
463dee1ad47SJeff Kirsher 
464dee1ad47SJeff Kirsher static void ixgbevf_get_ethtool_stats(struct net_device *netdev,
465dee1ad47SJeff Kirsher 				      struct ethtool_stats *stats, u64 *data)
466dee1ad47SJeff Kirsher {
467dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
468dee1ad47SJeff Kirsher 	int i;
469dee1ad47SJeff Kirsher 
470dee1ad47SJeff Kirsher 	ixgbevf_update_stats(adapter);
471dee1ad47SJeff Kirsher 	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
472dee1ad47SJeff Kirsher 		char *p = (char *)adapter +
473dee1ad47SJeff Kirsher 			ixgbe_gstrings_stats[i].stat_offset;
474dee1ad47SJeff Kirsher 		char *b = (char *)adapter +
475dee1ad47SJeff Kirsher 			ixgbe_gstrings_stats[i].base_stat_offset;
476dee1ad47SJeff Kirsher 		char *r = (char *)adapter +
477dee1ad47SJeff Kirsher 			ixgbe_gstrings_stats[i].saved_reset_offset;
478dee1ad47SJeff Kirsher 		data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat ==
479dee1ad47SJeff Kirsher 			    sizeof(u64)) ? *(u64 *)p : *(u32 *)p) -
480dee1ad47SJeff Kirsher 			  ((ixgbe_gstrings_stats[i].sizeof_stat ==
481dee1ad47SJeff Kirsher 			    sizeof(u64)) ? *(u64 *)b : *(u32 *)b) +
482dee1ad47SJeff Kirsher 			  ((ixgbe_gstrings_stats[i].sizeof_stat ==
483dee1ad47SJeff Kirsher 			    sizeof(u64)) ? *(u64 *)r : *(u32 *)r);
484dee1ad47SJeff Kirsher 	}
485dee1ad47SJeff Kirsher }
486dee1ad47SJeff Kirsher 
487dee1ad47SJeff Kirsher static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset,
488dee1ad47SJeff Kirsher 				u8 *data)
489dee1ad47SJeff Kirsher {
490dee1ad47SJeff Kirsher 	char *p = (char *)data;
491dee1ad47SJeff Kirsher 	int i;
492dee1ad47SJeff Kirsher 
493dee1ad47SJeff Kirsher 	switch (stringset) {
494dee1ad47SJeff Kirsher 	case ETH_SS_TEST:
495dee1ad47SJeff Kirsher 		memcpy(data, *ixgbe_gstrings_test,
496dee1ad47SJeff Kirsher 		       IXGBE_TEST_LEN * ETH_GSTRING_LEN);
497dee1ad47SJeff Kirsher 		break;
498dee1ad47SJeff Kirsher 	case ETH_SS_STATS:
499dee1ad47SJeff Kirsher 		for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
500dee1ad47SJeff Kirsher 			memcpy(p, ixgbe_gstrings_stats[i].stat_string,
501dee1ad47SJeff Kirsher 			       ETH_GSTRING_LEN);
502dee1ad47SJeff Kirsher 			p += ETH_GSTRING_LEN;
503dee1ad47SJeff Kirsher 		}
504dee1ad47SJeff Kirsher 		break;
505dee1ad47SJeff Kirsher 	}
506dee1ad47SJeff Kirsher }
507dee1ad47SJeff Kirsher 
508dee1ad47SJeff Kirsher static int ixgbevf_link_test(struct ixgbevf_adapter *adapter, u64 *data)
509dee1ad47SJeff Kirsher {
510dee1ad47SJeff Kirsher 	struct ixgbe_hw *hw = &adapter->hw;
511dee1ad47SJeff Kirsher 	bool link_up;
512dee1ad47SJeff Kirsher 	u32 link_speed = 0;
513dee1ad47SJeff Kirsher 	*data = 0;
514dee1ad47SJeff Kirsher 
515dee1ad47SJeff Kirsher 	hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
516dee1ad47SJeff Kirsher 	if (!link_up)
517dee1ad47SJeff Kirsher 		*data = 1;
518dee1ad47SJeff Kirsher 
519dee1ad47SJeff Kirsher 	return *data;
520dee1ad47SJeff Kirsher }
521dee1ad47SJeff Kirsher 
522dee1ad47SJeff Kirsher /* ethtool register test data */
523dee1ad47SJeff Kirsher struct ixgbevf_reg_test {
524dee1ad47SJeff Kirsher 	u16 reg;
525dee1ad47SJeff Kirsher 	u8  array_len;
526dee1ad47SJeff Kirsher 	u8  test_type;
527dee1ad47SJeff Kirsher 	u32 mask;
528dee1ad47SJeff Kirsher 	u32 write;
529dee1ad47SJeff Kirsher };
530dee1ad47SJeff Kirsher 
531dee1ad47SJeff Kirsher /* In the hardware, registers are laid out either singly, in arrays
532dee1ad47SJeff Kirsher  * spaced 0x40 bytes apart, or in contiguous tables.  We assume
533dee1ad47SJeff Kirsher  * most tests take place on arrays or single registers (handled
534dee1ad47SJeff Kirsher  * as a single-element array) and special-case the tables.
535dee1ad47SJeff Kirsher  * Table tests are always pattern tests.
536dee1ad47SJeff Kirsher  *
537dee1ad47SJeff Kirsher  * We also make provision for some required setup steps by specifying
538dee1ad47SJeff Kirsher  * registers to be written without any read-back testing.
539dee1ad47SJeff Kirsher  */
540dee1ad47SJeff Kirsher 
541dee1ad47SJeff Kirsher #define PATTERN_TEST	1
542dee1ad47SJeff Kirsher #define SET_READ_TEST	2
543dee1ad47SJeff Kirsher #define WRITE_NO_TEST	3
544dee1ad47SJeff Kirsher #define TABLE32_TEST	4
545dee1ad47SJeff Kirsher #define TABLE64_TEST_LO	5
546dee1ad47SJeff Kirsher #define TABLE64_TEST_HI	6
547dee1ad47SJeff Kirsher 
548dee1ad47SJeff Kirsher /* default VF register test */
549dee1ad47SJeff Kirsher static const struct ixgbevf_reg_test reg_test_vf[] = {
550dee1ad47SJeff Kirsher 	{ IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
551dee1ad47SJeff Kirsher 	{ IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
552dee1ad47SJeff Kirsher 	{ IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
553dee1ad47SJeff Kirsher 	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
554dee1ad47SJeff Kirsher 	{ IXGBE_VFRDT(0), 2, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
555dee1ad47SJeff Kirsher 	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, 0 },
556dee1ad47SJeff Kirsher 	{ IXGBE_VFTDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
557dee1ad47SJeff Kirsher 	{ IXGBE_VFTDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
558dee1ad47SJeff Kirsher 	{ IXGBE_VFTDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFF80 },
559dee1ad47SJeff Kirsher 	{ 0, 0, 0, 0 }
560dee1ad47SJeff Kirsher };
561dee1ad47SJeff Kirsher 
562dee1ad47SJeff Kirsher static const u32 register_test_patterns[] = {
563dee1ad47SJeff Kirsher 	0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
564dee1ad47SJeff Kirsher };
565dee1ad47SJeff Kirsher 
566dee1ad47SJeff Kirsher #define REG_PATTERN_TEST(R, M, W)                                             \
567dee1ad47SJeff Kirsher {                                                                             \
568dee1ad47SJeff Kirsher 	u32 pat, val, before;                                                 \
569dee1ad47SJeff Kirsher 	for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) {      \
570dee1ad47SJeff Kirsher 		before = readl(adapter->hw.hw_addr + R);                      \
571dee1ad47SJeff Kirsher 		writel((register_test_patterns[pat] & W),                     \
572dee1ad47SJeff Kirsher 		       (adapter->hw.hw_addr + R));                            \
573dee1ad47SJeff Kirsher 		val = readl(adapter->hw.hw_addr + R);                         \
574dee1ad47SJeff Kirsher 		if (val != (register_test_patterns[pat] & W & M)) {           \
575dee1ad47SJeff Kirsher 			hw_dbg(&adapter->hw,                                  \
576dee1ad47SJeff Kirsher 			"pattern test reg %04X failed: got "                  \
577dee1ad47SJeff Kirsher 			"0x%08X expected 0x%08X\n",                           \
578dee1ad47SJeff Kirsher 			R, val, (register_test_patterns[pat] & W & M));       \
579dee1ad47SJeff Kirsher 			*data = R;                                            \
580dee1ad47SJeff Kirsher 			writel(before, adapter->hw.hw_addr + R);              \
581dee1ad47SJeff Kirsher 			return 1;                                             \
582dee1ad47SJeff Kirsher 		}                                                             \
583dee1ad47SJeff Kirsher 		writel(before, adapter->hw.hw_addr + R);                      \
584dee1ad47SJeff Kirsher 	}                                                                     \
585dee1ad47SJeff Kirsher }
586dee1ad47SJeff Kirsher 
587dee1ad47SJeff Kirsher #define REG_SET_AND_CHECK(R, M, W)                                            \
588dee1ad47SJeff Kirsher {                                                                             \
589dee1ad47SJeff Kirsher 	u32 val, before;                                                      \
590dee1ad47SJeff Kirsher 	before = readl(adapter->hw.hw_addr + R);                              \
591dee1ad47SJeff Kirsher 	writel((W & M), (adapter->hw.hw_addr + R));                           \
592dee1ad47SJeff Kirsher 	val = readl(adapter->hw.hw_addr + R);                                 \
593dee1ad47SJeff Kirsher 	if ((W & M) != (val & M)) {                                           \
594dee1ad47SJeff Kirsher 		printk(KERN_ERR "set/check reg %04X test failed: got 0x%08X " \
595dee1ad47SJeff Kirsher 				 "expected 0x%08X\n", R, (val & M), (W & M)); \
596dee1ad47SJeff Kirsher 		*data = R;                                                    \
597dee1ad47SJeff Kirsher 		writel(before, (adapter->hw.hw_addr + R));                    \
598dee1ad47SJeff Kirsher 		return 1;                                                     \
599dee1ad47SJeff Kirsher 	}                                                                     \
600dee1ad47SJeff Kirsher 	writel(before, (adapter->hw.hw_addr + R));                            \
601dee1ad47SJeff Kirsher }
602dee1ad47SJeff Kirsher 
603dee1ad47SJeff Kirsher static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data)
604dee1ad47SJeff Kirsher {
605dee1ad47SJeff Kirsher 	const struct ixgbevf_reg_test *test;
606dee1ad47SJeff Kirsher 	u32 i;
607dee1ad47SJeff Kirsher 
608dee1ad47SJeff Kirsher 	test = reg_test_vf;
609dee1ad47SJeff Kirsher 
610dee1ad47SJeff Kirsher 	/*
611dee1ad47SJeff Kirsher 	 * Perform the register test, looping through the test table
612dee1ad47SJeff Kirsher 	 * until we either fail or reach the null entry.
613dee1ad47SJeff Kirsher 	 */
614dee1ad47SJeff Kirsher 	while (test->reg) {
615dee1ad47SJeff Kirsher 		for (i = 0; i < test->array_len; i++) {
616dee1ad47SJeff Kirsher 			switch (test->test_type) {
617dee1ad47SJeff Kirsher 			case PATTERN_TEST:
618dee1ad47SJeff Kirsher 				REG_PATTERN_TEST(test->reg + (i * 0x40),
619dee1ad47SJeff Kirsher 						test->mask,
620dee1ad47SJeff Kirsher 						test->write);
621dee1ad47SJeff Kirsher 				break;
622dee1ad47SJeff Kirsher 			case SET_READ_TEST:
623dee1ad47SJeff Kirsher 				REG_SET_AND_CHECK(test->reg + (i * 0x40),
624dee1ad47SJeff Kirsher 						test->mask,
625dee1ad47SJeff Kirsher 						test->write);
626dee1ad47SJeff Kirsher 				break;
627dee1ad47SJeff Kirsher 			case WRITE_NO_TEST:
628dee1ad47SJeff Kirsher 				writel(test->write,
629dee1ad47SJeff Kirsher 				       (adapter->hw.hw_addr + test->reg)
630dee1ad47SJeff Kirsher 				       + (i * 0x40));
631dee1ad47SJeff Kirsher 				break;
632dee1ad47SJeff Kirsher 			case TABLE32_TEST:
633dee1ad47SJeff Kirsher 				REG_PATTERN_TEST(test->reg + (i * 4),
634dee1ad47SJeff Kirsher 						test->mask,
635dee1ad47SJeff Kirsher 						test->write);
636dee1ad47SJeff Kirsher 				break;
637dee1ad47SJeff Kirsher 			case TABLE64_TEST_LO:
638dee1ad47SJeff Kirsher 				REG_PATTERN_TEST(test->reg + (i * 8),
639dee1ad47SJeff Kirsher 						test->mask,
640dee1ad47SJeff Kirsher 						test->write);
641dee1ad47SJeff Kirsher 				break;
642dee1ad47SJeff Kirsher 			case TABLE64_TEST_HI:
643dee1ad47SJeff Kirsher 				REG_PATTERN_TEST((test->reg + 4) + (i * 8),
644dee1ad47SJeff Kirsher 						test->mask,
645dee1ad47SJeff Kirsher 						test->write);
646dee1ad47SJeff Kirsher 				break;
647dee1ad47SJeff Kirsher 			}
648dee1ad47SJeff Kirsher 		}
649dee1ad47SJeff Kirsher 		test++;
650dee1ad47SJeff Kirsher 	}
651dee1ad47SJeff Kirsher 
652dee1ad47SJeff Kirsher 	*data = 0;
653dee1ad47SJeff Kirsher 	return *data;
654dee1ad47SJeff Kirsher }
655dee1ad47SJeff Kirsher 
656dee1ad47SJeff Kirsher static void ixgbevf_diag_test(struct net_device *netdev,
657dee1ad47SJeff Kirsher 			      struct ethtool_test *eth_test, u64 *data)
658dee1ad47SJeff Kirsher {
659dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
660dee1ad47SJeff Kirsher 	bool if_running = netif_running(netdev);
661dee1ad47SJeff Kirsher 
662dee1ad47SJeff Kirsher 	set_bit(__IXGBEVF_TESTING, &adapter->state);
663dee1ad47SJeff Kirsher 	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
664dee1ad47SJeff Kirsher 		/* Offline tests */
665dee1ad47SJeff Kirsher 
666dee1ad47SJeff Kirsher 		hw_dbg(&adapter->hw, "offline testing starting\n");
667dee1ad47SJeff Kirsher 
668dee1ad47SJeff Kirsher 		/* Link test performed before hardware reset so autoneg doesn't
669dee1ad47SJeff Kirsher 		 * interfere with test result */
670dee1ad47SJeff Kirsher 		if (ixgbevf_link_test(adapter, &data[1]))
671dee1ad47SJeff Kirsher 			eth_test->flags |= ETH_TEST_FL_FAILED;
672dee1ad47SJeff Kirsher 
673dee1ad47SJeff Kirsher 		if (if_running)
674dee1ad47SJeff Kirsher 			/* indicate we're in test mode */
675dee1ad47SJeff Kirsher 			dev_close(netdev);
676dee1ad47SJeff Kirsher 		else
677dee1ad47SJeff Kirsher 			ixgbevf_reset(adapter);
678dee1ad47SJeff Kirsher 
679dee1ad47SJeff Kirsher 		hw_dbg(&adapter->hw, "register testing starting\n");
680dee1ad47SJeff Kirsher 		if (ixgbevf_reg_test(adapter, &data[0]))
681dee1ad47SJeff Kirsher 			eth_test->flags |= ETH_TEST_FL_FAILED;
682dee1ad47SJeff Kirsher 
683dee1ad47SJeff Kirsher 		ixgbevf_reset(adapter);
684dee1ad47SJeff Kirsher 
685dee1ad47SJeff Kirsher 		clear_bit(__IXGBEVF_TESTING, &adapter->state);
686dee1ad47SJeff Kirsher 		if (if_running)
687dee1ad47SJeff Kirsher 			dev_open(netdev);
688dee1ad47SJeff Kirsher 	} else {
689dee1ad47SJeff Kirsher 		hw_dbg(&adapter->hw, "online testing starting\n");
690dee1ad47SJeff Kirsher 		/* Online tests */
691dee1ad47SJeff Kirsher 		if (ixgbevf_link_test(adapter, &data[1]))
692dee1ad47SJeff Kirsher 			eth_test->flags |= ETH_TEST_FL_FAILED;
693dee1ad47SJeff Kirsher 
694dee1ad47SJeff Kirsher 		/* Online tests aren't run; pass by default */
695dee1ad47SJeff Kirsher 		data[0] = 0;
696dee1ad47SJeff Kirsher 
697dee1ad47SJeff Kirsher 		clear_bit(__IXGBEVF_TESTING, &adapter->state);
698dee1ad47SJeff Kirsher 	}
699dee1ad47SJeff Kirsher 	msleep_interruptible(4 * 1000);
700dee1ad47SJeff Kirsher }
701dee1ad47SJeff Kirsher 
702dee1ad47SJeff Kirsher static int ixgbevf_nway_reset(struct net_device *netdev)
703dee1ad47SJeff Kirsher {
704dee1ad47SJeff Kirsher 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
705dee1ad47SJeff Kirsher 
706dee1ad47SJeff Kirsher 	if (netif_running(netdev)) {
707dee1ad47SJeff Kirsher 		if (!adapter->dev_closed)
708dee1ad47SJeff Kirsher 			ixgbevf_reinit_locked(adapter);
709dee1ad47SJeff Kirsher 	}
710dee1ad47SJeff Kirsher 
711dee1ad47SJeff Kirsher 	return 0;
712dee1ad47SJeff Kirsher }
713dee1ad47SJeff Kirsher 
714dee1ad47SJeff Kirsher static struct ethtool_ops ixgbevf_ethtool_ops = {
715dee1ad47SJeff Kirsher 	.get_settings           = ixgbevf_get_settings,
716dee1ad47SJeff Kirsher 	.get_drvinfo            = ixgbevf_get_drvinfo,
717dee1ad47SJeff Kirsher 	.get_regs_len           = ixgbevf_get_regs_len,
718dee1ad47SJeff Kirsher 	.get_regs               = ixgbevf_get_regs,
719dee1ad47SJeff Kirsher 	.nway_reset             = ixgbevf_nway_reset,
720dee1ad47SJeff Kirsher 	.get_link               = ethtool_op_get_link,
721dee1ad47SJeff Kirsher 	.get_ringparam          = ixgbevf_get_ringparam,
722dee1ad47SJeff Kirsher 	.set_ringparam          = ixgbevf_set_ringparam,
723dee1ad47SJeff Kirsher 	.get_rx_csum            = ixgbevf_get_rx_csum,
724dee1ad47SJeff Kirsher 	.set_rx_csum            = ixgbevf_set_rx_csum,
725dee1ad47SJeff Kirsher 	.get_tx_csum            = ethtool_op_get_tx_csum,
726dee1ad47SJeff Kirsher 	.set_tx_csum            = ethtool_op_set_tx_ipv6_csum,
727dee1ad47SJeff Kirsher 	.get_sg                 = ethtool_op_get_sg,
728dee1ad47SJeff Kirsher 	.set_sg                 = ethtool_op_set_sg,
729dee1ad47SJeff Kirsher 	.get_msglevel           = ixgbevf_get_msglevel,
730dee1ad47SJeff Kirsher 	.set_msglevel           = ixgbevf_set_msglevel,
731dee1ad47SJeff Kirsher 	.get_tso                = ethtool_op_get_tso,
732dee1ad47SJeff Kirsher 	.set_tso                = ixgbevf_set_tso,
733dee1ad47SJeff Kirsher 	.self_test              = ixgbevf_diag_test,
734dee1ad47SJeff Kirsher 	.get_sset_count         = ixgbevf_get_sset_count,
735dee1ad47SJeff Kirsher 	.get_strings            = ixgbevf_get_strings,
736dee1ad47SJeff Kirsher 	.get_ethtool_stats      = ixgbevf_get_ethtool_stats,
737dee1ad47SJeff Kirsher };
738dee1ad47SJeff Kirsher 
739dee1ad47SJeff Kirsher void ixgbevf_set_ethtool_ops(struct net_device *netdev)
740dee1ad47SJeff Kirsher {
741dee1ad47SJeff Kirsher 	SET_ETHTOOL_OPS(netdev, &ixgbevf_ethtool_ops);
742dee1ad47SJeff Kirsher }
743