blob: 681a9e81ff512aa874406d6e549485815c29a55d [file] [log] [blame]
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
Greg Rosedc641b72013-12-18 13:45:51 +00004 * Copyright(c) 2013 - 2014 Intel Corporation.
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00005 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
Greg Rosedc641b72013-12-18 13:45:51 +000015 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +000017 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 ******************************************************************************/
26
27/* ethtool support for i40e */
28
29#include "i40e.h"
30#include "i40e_diag.h"
31
32struct i40e_stats {
33 char stat_string[ETH_GSTRING_LEN];
34 int sizeof_stat;
35 int stat_offset;
36};
37
38#define I40E_STAT(_type, _name, _stat) { \
39 .stat_string = _name, \
40 .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
41 .stat_offset = offsetof(_type, _stat) \
42}
43#define I40E_NETDEV_STAT(_net_stat) \
44 I40E_STAT(struct net_device_stats, #_net_stat, _net_stat)
45#define I40E_PF_STAT(_name, _stat) \
46 I40E_STAT(struct i40e_pf, _name, _stat)
47#define I40E_VSI_STAT(_name, _stat) \
48 I40E_STAT(struct i40e_vsi, _name, _stat)
Shannon Nelson8eab9cf2014-04-23 04:49:55 +000049#define I40E_VEB_STAT(_name, _stat) \
50 I40E_STAT(struct i40e_veb, _name, _stat)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +000051
52static const struct i40e_stats i40e_gstrings_net_stats[] = {
53 I40E_NETDEV_STAT(rx_packets),
54 I40E_NETDEV_STAT(tx_packets),
55 I40E_NETDEV_STAT(rx_bytes),
56 I40E_NETDEV_STAT(tx_bytes),
57 I40E_NETDEV_STAT(rx_errors),
58 I40E_NETDEV_STAT(tx_errors),
59 I40E_NETDEV_STAT(rx_dropped),
60 I40E_NETDEV_STAT(tx_dropped),
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +000061 I40E_NETDEV_STAT(collisions),
62 I40E_NETDEV_STAT(rx_length_errors),
63 I40E_NETDEV_STAT(rx_crc_errors),
64};
65
Shannon Nelson8eab9cf2014-04-23 04:49:55 +000066static const struct i40e_stats i40e_gstrings_veb_stats[] = {
67 I40E_VEB_STAT("rx_bytes", stats.rx_bytes),
68 I40E_VEB_STAT("tx_bytes", stats.tx_bytes),
69 I40E_VEB_STAT("rx_unicast", stats.rx_unicast),
70 I40E_VEB_STAT("tx_unicast", stats.tx_unicast),
71 I40E_VEB_STAT("rx_multicast", stats.rx_multicast),
72 I40E_VEB_STAT("tx_multicast", stats.tx_multicast),
73 I40E_VEB_STAT("rx_broadcast", stats.rx_broadcast),
74 I40E_VEB_STAT("tx_broadcast", stats.tx_broadcast),
75 I40E_VEB_STAT("rx_discards", stats.rx_discards),
76 I40E_VEB_STAT("tx_discards", stats.tx_discards),
77 I40E_VEB_STAT("tx_errors", stats.tx_errors),
78 I40E_VEB_STAT("rx_unknown_protocol", stats.rx_unknown_protocol),
79};
80
Shannon Nelson41a9e552014-04-23 04:50:20 +000081static const struct i40e_stats i40e_gstrings_misc_stats[] = {
Shannon Nelson418631d2014-04-23 04:50:07 +000082 I40E_VSI_STAT("rx_unicast", eth_stats.rx_unicast),
83 I40E_VSI_STAT("tx_unicast", eth_stats.tx_unicast),
84 I40E_VSI_STAT("rx_multicast", eth_stats.rx_multicast),
85 I40E_VSI_STAT("tx_multicast", eth_stats.tx_multicast),
Shannon Nelson41a9e552014-04-23 04:50:20 +000086 I40E_VSI_STAT("rx_broadcast", eth_stats.rx_broadcast),
87 I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
Shannon Nelson418631d2014-04-23 04:50:07 +000088 I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
Shannon Nelson41a9e552014-04-23 04:50:20 +000089};
90
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +000091static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
92 struct ethtool_rxnfc *cmd);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +000093
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +000094/* These PF_STATs might look like duplicates of some NETDEV_STATs,
95 * but they are separate. This device supports Virtualization, and
96 * as such might have several netdevs supporting VMDq and FCoE going
97 * through a single port. The NETDEV_STATs are for individual netdevs
98 * seen at the top of the stack, and the PF_STATs are for the physical
99 * function at the bottom of the stack hosting those netdevs.
100 *
101 * The PF_STATs are appended to the netdev stats only when ethtool -S
102 * is queried on the base PF netdev, not on the VMDq or FCoE netdev.
103 */
104static struct i40e_stats i40e_gstrings_stats[] = {
105 I40E_PF_STAT("rx_bytes", stats.eth.rx_bytes),
106 I40E_PF_STAT("tx_bytes", stats.eth.tx_bytes),
Shannon Nelson532d2832014-04-23 04:50:09 +0000107 I40E_PF_STAT("rx_unicast", stats.eth.rx_unicast),
108 I40E_PF_STAT("tx_unicast", stats.eth.tx_unicast),
109 I40E_PF_STAT("rx_multicast", stats.eth.rx_multicast),
110 I40E_PF_STAT("tx_multicast", stats.eth.tx_multicast),
111 I40E_PF_STAT("rx_broadcast", stats.eth.rx_broadcast),
112 I40E_PF_STAT("tx_broadcast", stats.eth.tx_broadcast),
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000113 I40E_PF_STAT("tx_errors", stats.eth.tx_errors),
114 I40E_PF_STAT("rx_dropped", stats.eth.rx_discards),
115 I40E_PF_STAT("tx_dropped", stats.eth.tx_discards),
116 I40E_PF_STAT("tx_dropped_link_down", stats.tx_dropped_link_down),
117 I40E_PF_STAT("crc_errors", stats.crc_errors),
118 I40E_PF_STAT("illegal_bytes", stats.illegal_bytes),
119 I40E_PF_STAT("mac_local_faults", stats.mac_local_faults),
120 I40E_PF_STAT("mac_remote_faults", stats.mac_remote_faults),
Jesse Brandeburga47a15f2014-02-06 05:51:09 +0000121 I40E_PF_STAT("tx_timeout", tx_timeout_count),
Jesse Brandeburg8a3c91c2014-05-20 08:01:43 +0000122 I40E_PF_STAT("rx_csum_bad", hw_csum_rx_error),
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000123 I40E_PF_STAT("rx_length_errors", stats.rx_length_errors),
124 I40E_PF_STAT("link_xon_rx", stats.link_xon_rx),
125 I40E_PF_STAT("link_xoff_rx", stats.link_xoff_rx),
126 I40E_PF_STAT("link_xon_tx", stats.link_xon_tx),
127 I40E_PF_STAT("link_xoff_tx", stats.link_xoff_tx),
128 I40E_PF_STAT("rx_size_64", stats.rx_size_64),
129 I40E_PF_STAT("rx_size_127", stats.rx_size_127),
130 I40E_PF_STAT("rx_size_255", stats.rx_size_255),
131 I40E_PF_STAT("rx_size_511", stats.rx_size_511),
132 I40E_PF_STAT("rx_size_1023", stats.rx_size_1023),
133 I40E_PF_STAT("rx_size_1522", stats.rx_size_1522),
134 I40E_PF_STAT("rx_size_big", stats.rx_size_big),
135 I40E_PF_STAT("tx_size_64", stats.tx_size_64),
136 I40E_PF_STAT("tx_size_127", stats.tx_size_127),
137 I40E_PF_STAT("tx_size_255", stats.tx_size_255),
138 I40E_PF_STAT("tx_size_511", stats.tx_size_511),
139 I40E_PF_STAT("tx_size_1023", stats.tx_size_1023),
140 I40E_PF_STAT("tx_size_1522", stats.tx_size_1522),
141 I40E_PF_STAT("tx_size_big", stats.tx_size_big),
142 I40E_PF_STAT("rx_undersize", stats.rx_undersize),
143 I40E_PF_STAT("rx_fragments", stats.rx_fragments),
144 I40E_PF_STAT("rx_oversize", stats.rx_oversize),
145 I40E_PF_STAT("rx_jabber", stats.rx_jabber),
146 I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests),
Jacob Kellerbeb0dff2014-01-11 05:43:19 +0000147 I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
Anjali Singhai Jain433c47d2014-05-22 06:32:17 +0000148 I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match),
149 I40E_PF_STAT("fdir_sb_match", stats.fd_sb_match),
150
Anjali Singhai Jainbee5af72014-03-06 08:59:50 +0000151 /* LPI stats */
152 I40E_PF_STAT("tx_lpi_status", stats.tx_lpi_status),
153 I40E_PF_STAT("rx_lpi_status", stats.rx_lpi_status),
154 I40E_PF_STAT("tx_lpi_count", stats.tx_lpi_count),
155 I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000156};
157
Vasu Dev38e00432014-08-01 13:27:03 -0700158#ifdef I40E_FCOE
159static const struct i40e_stats i40e_gstrings_fcoe_stats[] = {
160 I40E_VSI_STAT("fcoe_bad_fccrc", fcoe_stats.fcoe_bad_fccrc),
161 I40E_VSI_STAT("rx_fcoe_dropped", fcoe_stats.rx_fcoe_dropped),
162 I40E_VSI_STAT("rx_fcoe_packets", fcoe_stats.rx_fcoe_packets),
163 I40E_VSI_STAT("rx_fcoe_dwords", fcoe_stats.rx_fcoe_dwords),
164 I40E_VSI_STAT("fcoe_ddp_count", fcoe_stats.fcoe_ddp_count),
165 I40E_VSI_STAT("fcoe_last_error", fcoe_stats.fcoe_last_error),
166 I40E_VSI_STAT("tx_fcoe_packets", fcoe_stats.tx_fcoe_packets),
167 I40E_VSI_STAT("tx_fcoe_dwords", fcoe_stats.tx_fcoe_dwords),
168};
169
170#endif /* I40E_FCOE */
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000171#define I40E_QUEUE_STATS_LEN(n) \
Shannon Nelson31cd8402014-04-04 04:43:12 +0000172 (((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \
173 * 2 /* Tx and Rx together */ \
174 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000175#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
176#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
Shannon Nelson41a9e552014-04-23 04:50:20 +0000177#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
Vasu Dev38e00432014-08-01 13:27:03 -0700178#ifdef I40E_FCOE
179#define I40E_FCOE_STATS_LEN ARRAY_SIZE(i40e_gstrings_fcoe_stats)
180#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
181 I40E_FCOE_STATS_LEN + \
182 I40E_MISC_STATS_LEN + \
183 I40E_QUEUE_STATS_LEN((n)))
184#else
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000185#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
Shannon Nelson41a9e552014-04-23 04:50:20 +0000186 I40E_MISC_STATS_LEN + \
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000187 I40E_QUEUE_STATS_LEN((n)))
Vasu Dev38e00432014-08-01 13:27:03 -0700188#endif /* I40E_FCOE */
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000189#define I40E_PFC_STATS_LEN ( \
190 (FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \
191 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \
192 FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_tx) + \
193 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
194 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
195 / sizeof(u64))
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000196#define I40E_VEB_STATS_LEN ARRAY_SIZE(i40e_gstrings_veb_stats)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000197#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
198 I40E_PFC_STATS_LEN + \
199 I40E_VSI_STATS_LEN((n)))
200
201enum i40e_ethtool_test_id {
202 I40E_ETH_TEST_REG = 0,
203 I40E_ETH_TEST_EEPROM,
204 I40E_ETH_TEST_INTR,
205 I40E_ETH_TEST_LOOPBACK,
206 I40E_ETH_TEST_LINK,
207};
208
209static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
210 "Register test (offline)",
211 "Eeprom test (offline)",
212 "Interrupt test (offline)",
213 "Loopback test (offline)",
214 "Link test (on/offline)"
215};
216
217#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)
218
219/**
220 * i40e_get_settings - Get Link Speed and Duplex settings
221 * @netdev: network interface device structure
222 * @ecmd: ethtool command
223 *
224 * Reports speed/duplex settings based on media_type
225 **/
226static int i40e_get_settings(struct net_device *netdev,
227 struct ethtool_cmd *ecmd)
228{
229 struct i40e_netdev_priv *np = netdev_priv(netdev);
230 struct i40e_pf *pf = np->vsi->back;
231 struct i40e_hw *hw = &pf->hw;
232 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
233 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
234 u32 link_speed = hw_link_info->link_speed;
235
236 /* hardware is either in 40G mode or 10G mode
237 * NOTE: this section initializes supported and advertising
238 */
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000239 if (!link_up) {
240 /* link is down and the driver needs to fall back on
241 * device ID to determine what kinds of info to display,
242 * it's mostly a guess that may change when link is up
243 */
244 switch (hw->device_id) {
245 case I40E_DEV_ID_QSFP_A:
246 case I40E_DEV_ID_QSFP_B:
247 case I40E_DEV_ID_QSFP_C:
248 /* pluggable QSFP */
249 ecmd->supported = SUPPORTED_40000baseSR4_Full |
250 SUPPORTED_40000baseCR4_Full |
251 SUPPORTED_40000baseLR4_Full;
252 ecmd->advertising = ADVERTISED_40000baseSR4_Full |
253 ADVERTISED_40000baseCR4_Full |
254 ADVERTISED_40000baseLR4_Full;
255 break;
256 case I40E_DEV_ID_KX_B:
257 /* backplane 40G */
258 ecmd->supported = SUPPORTED_40000baseKR4_Full;
259 ecmd->advertising = ADVERTISED_40000baseKR4_Full;
260 break;
261 case I40E_DEV_ID_KX_C:
262 /* backplane 10G */
263 ecmd->supported = SUPPORTED_10000baseKR_Full;
264 ecmd->advertising = ADVERTISED_10000baseKR_Full;
265 break;
266 default:
267 /* all the rest are 10G/1G */
268 ecmd->supported = SUPPORTED_10000baseT_Full |
269 SUPPORTED_1000baseT_Full;
270 ecmd->advertising = ADVERTISED_10000baseT_Full |
271 ADVERTISED_1000baseT_Full;
272 break;
273 }
274
275 /* skip phy_type use as it is zero when link is down */
276 goto no_valid_phy_type;
277 }
278
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000279 switch (hw_link_info->phy_type) {
280 case I40E_PHY_TYPE_40GBASE_CR4:
281 case I40E_PHY_TYPE_40GBASE_CR4_CU:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000282 ecmd->supported = SUPPORTED_Autoneg |
283 SUPPORTED_40000baseCR4_Full;
284 ecmd->advertising = ADVERTISED_Autoneg |
285 ADVERTISED_40000baseCR4_Full;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000286 break;
287 case I40E_PHY_TYPE_40GBASE_KR4:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000288 ecmd->supported = SUPPORTED_Autoneg |
289 SUPPORTED_40000baseKR4_Full;
290 ecmd->advertising = ADVERTISED_Autoneg |
291 ADVERTISED_40000baseKR4_Full;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000292 break;
293 case I40E_PHY_TYPE_40GBASE_SR4:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000294 case I40E_PHY_TYPE_XLPPI:
295 case I40E_PHY_TYPE_XLAUI:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000296 ecmd->supported = SUPPORTED_40000baseSR4_Full;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000297 break;
298 case I40E_PHY_TYPE_40GBASE_LR4:
299 ecmd->supported = SUPPORTED_40000baseLR4_Full;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000300 break;
301 case I40E_PHY_TYPE_10GBASE_KX4:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000302 ecmd->supported = SUPPORTED_Autoneg |
303 SUPPORTED_10000baseKX4_Full;
304 ecmd->advertising = ADVERTISED_Autoneg |
305 ADVERTISED_10000baseKX4_Full;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000306 break;
307 case I40E_PHY_TYPE_10GBASE_KR:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000308 ecmd->supported = SUPPORTED_Autoneg |
309 SUPPORTED_10000baseKR_Full;
310 ecmd->advertising = ADVERTISED_Autoneg |
311 ADVERTISED_10000baseKR_Full;
312 break;
313 case I40E_PHY_TYPE_10GBASE_SR:
314 case I40E_PHY_TYPE_10GBASE_LR:
315 ecmd->supported = SUPPORTED_10000baseT_Full;
316 break;
317 case I40E_PHY_TYPE_10GBASE_CR1_CU:
318 case I40E_PHY_TYPE_10GBASE_CR1:
319 case I40E_PHY_TYPE_10GBASE_T:
320 ecmd->supported = SUPPORTED_Autoneg |
321 SUPPORTED_10000baseT_Full;
322 ecmd->advertising = ADVERTISED_Autoneg |
323 ADVERTISED_10000baseT_Full;
324 break;
325 case I40E_PHY_TYPE_XAUI:
326 case I40E_PHY_TYPE_XFI:
327 case I40E_PHY_TYPE_SFI:
328 case I40E_PHY_TYPE_10GBASE_SFPP_CU:
329 ecmd->supported = SUPPORTED_10000baseT_Full;
330 break;
331 case I40E_PHY_TYPE_1000BASE_KX:
332 case I40E_PHY_TYPE_1000BASE_T:
333 ecmd->supported = SUPPORTED_Autoneg |
334 SUPPORTED_1000baseT_Full;
335 ecmd->advertising = ADVERTISED_Autoneg |
336 ADVERTISED_1000baseT_Full;
337 break;
338 case I40E_PHY_TYPE_100BASE_TX:
339 ecmd->supported = SUPPORTED_Autoneg |
340 SUPPORTED_100baseT_Full;
341 ecmd->advertising = ADVERTISED_Autoneg |
342 ADVERTISED_100baseT_Full;
343 break;
344 case I40E_PHY_TYPE_SGMII:
345 ecmd->supported = SUPPORTED_Autoneg |
346 SUPPORTED_1000baseT_Full |
347 SUPPORTED_100baseT_Full;
348 ecmd->advertising = ADVERTISED_Autoneg |
349 ADVERTISED_1000baseT_Full |
350 ADVERTISED_100baseT_Full;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000351 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000352 default:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000353 /* if we got here and link is up something bad is afoot */
354 WARN_ON(link_up);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000355 }
356
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000357no_valid_phy_type:
358 /* this is if autoneg is enabled or disabled */
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000359 ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
360 AUTONEG_ENABLE : AUTONEG_DISABLE);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000361
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000362 switch (hw->phy.media_type) {
363 case I40E_MEDIA_TYPE_BACKPLANE:
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000364 ecmd->supported |= SUPPORTED_Autoneg |
365 SUPPORTED_Backplane;
366 ecmd->advertising |= ADVERTISED_Autoneg |
367 ADVERTISED_Backplane;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000368 ecmd->port = PORT_NONE;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000369 break;
370 case I40E_MEDIA_TYPE_BASET:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000371 ecmd->supported |= SUPPORTED_TP;
372 ecmd->advertising |= ADVERTISED_TP;
373 ecmd->port = PORT_TP;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000374 break;
375 case I40E_MEDIA_TYPE_DA:
376 case I40E_MEDIA_TYPE_CX4:
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +0000377 ecmd->supported |= SUPPORTED_FIBRE;
378 ecmd->advertising |= ADVERTISED_FIBRE;
379 ecmd->port = PORT_DA;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000380 break;
381 case I40E_MEDIA_TYPE_FIBER:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000382 ecmd->supported |= SUPPORTED_FIBRE;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000383 ecmd->port = PORT_FIBRE;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000384 break;
385 case I40E_MEDIA_TYPE_UNKNOWN:
386 default:
387 ecmd->port = PORT_OTHER;
388 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000389 }
390
391 ecmd->transceiver = XCVR_EXTERNAL;
392
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000393 ecmd->supported |= SUPPORTED_Pause;
394
395 switch (hw->fc.current_mode) {
396 case I40E_FC_FULL:
397 ecmd->advertising |= ADVERTISED_Pause;
398 break;
399 case I40E_FC_TX_PAUSE:
400 ecmd->advertising |= ADVERTISED_Asym_Pause;
401 break;
402 case I40E_FC_RX_PAUSE:
403 ecmd->advertising |= (ADVERTISED_Pause |
404 ADVERTISED_Asym_Pause);
405 break;
406 default:
407 ecmd->advertising &= ~(ADVERTISED_Pause |
408 ADVERTISED_Asym_Pause);
409 break;
410 }
411
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000412 if (link_up) {
413 switch (link_speed) {
414 case I40E_LINK_SPEED_40GB:
415 /* need a SPEED_40000 in ethtool.h */
416 ethtool_cmd_speed_set(ecmd, 40000);
417 break;
418 case I40E_LINK_SPEED_10GB:
419 ethtool_cmd_speed_set(ecmd, SPEED_10000);
420 break;
Jesse Brandeburg4e91bcd2014-06-04 08:45:23 +0000421 case I40E_LINK_SPEED_1GB:
422 ethtool_cmd_speed_set(ecmd, SPEED_1000);
423 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000424 default:
425 break;
426 }
427 ecmd->duplex = DUPLEX_FULL;
428 } else {
429 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
430 ecmd->duplex = DUPLEX_UNKNOWN;
431 }
432
433 return 0;
434}
435
Catherine Sullivanbf9c7142014-06-04 08:45:28 +0000436/**
437 * i40e_set_settings - Set Speed and Duplex
438 * @netdev: network interface device structure
439 * @ecmd: ethtool command
440 *
441 * Set speed/duplex per media_types advertised/forced
442 **/
443static int i40e_set_settings(struct net_device *netdev,
444 struct ethtool_cmd *ecmd)
445{
446 struct i40e_netdev_priv *np = netdev_priv(netdev);
447 struct i40e_aq_get_phy_abilities_resp abilities;
448 struct i40e_aq_set_phy_config config;
449 struct i40e_pf *pf = np->vsi->back;
450 struct i40e_vsi *vsi = np->vsi;
451 struct i40e_hw *hw = &pf->hw;
452 struct ethtool_cmd safe_ecmd;
453 i40e_status status = 0;
454 bool change = false;
455 int err = 0;
456 u8 autoneg;
457 u32 advertise;
458
459 if (vsi != pf->vsi[pf->lan_vsi])
460 return -EOPNOTSUPP;
461
462 if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
463 hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
464 hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE)
465 return -EOPNOTSUPP;
466
467 /* get our own copy of the bits to check against */
468 memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
469 i40e_get_settings(netdev, &safe_ecmd);
470
471 /* save autoneg and speed out of ecmd */
472 autoneg = ecmd->autoneg;
473 advertise = ecmd->advertising;
474
475 /* set autoneg and speed back to what they currently are */
476 ecmd->autoneg = safe_ecmd.autoneg;
477 ecmd->advertising = safe_ecmd.advertising;
478
479 ecmd->cmd = safe_ecmd.cmd;
480 /* If ecmd and safe_ecmd are not the same now, then they are
481 * trying to set something that we do not support
482 */
483 if (memcmp(ecmd, &safe_ecmd, sizeof(struct ethtool_cmd)))
484 return -EOPNOTSUPP;
485
486 while (test_bit(__I40E_CONFIG_BUSY, &vsi->state))
487 usleep_range(1000, 2000);
488
489 /* Get the current phy config */
490 status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
491 NULL);
492 if (status)
493 return -EAGAIN;
494
495 /* Copy link_speed and abilities to config in case they are not
496 * set below
497 */
498 memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
499 config.link_speed = abilities.link_speed;
500 config.abilities = abilities.abilities;
501
502 /* Check autoneg */
503 if (autoneg == AUTONEG_ENABLE) {
504 /* If autoneg is not supported, return error */
505 if (!(safe_ecmd.supported & SUPPORTED_Autoneg)) {
506 netdev_info(netdev, "Autoneg not supported on this phy\n");
507 return -EINVAL;
508 }
509 /* If autoneg was not already enabled */
510 if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
511 config.abilities = abilities.abilities |
512 I40E_AQ_PHY_ENABLE_AN;
513 change = true;
514 }
515 } else {
516 /* If autoneg is supported 10GBASE_T is the only phy that
517 * can disable it, so otherwise return error
518 */
519 if (safe_ecmd.supported & SUPPORTED_Autoneg &&
520 hw->phy.link_info.phy_type != I40E_PHY_TYPE_10GBASE_T) {
521 netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
522 return -EINVAL;
523 }
524 /* If autoneg is currently enabled */
525 if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
526 config.abilities = abilities.abilities |
527 ~I40E_AQ_PHY_ENABLE_AN;
528 change = true;
529 }
530 }
531
532 if (advertise & ~safe_ecmd.supported)
533 return -EINVAL;
534
535 if (advertise & ADVERTISED_100baseT_Full)
536 if (!(abilities.link_speed & I40E_LINK_SPEED_100MB)) {
537 config.link_speed |= I40E_LINK_SPEED_100MB;
538 change = true;
539 }
540 if (advertise & ADVERTISED_1000baseT_Full ||
541 advertise & ADVERTISED_1000baseKX_Full)
542 if (!(abilities.link_speed & I40E_LINK_SPEED_1GB)) {
543 config.link_speed |= I40E_LINK_SPEED_1GB;
544 change = true;
545 }
546 if (advertise & ADVERTISED_10000baseT_Full ||
547 advertise & ADVERTISED_10000baseKX4_Full ||
548 advertise & ADVERTISED_10000baseKR_Full)
549 if (!(abilities.link_speed & I40E_LINK_SPEED_10GB)) {
550 config.link_speed |= I40E_LINK_SPEED_10GB;
551 change = true;
552 }
553 if (advertise & ADVERTISED_40000baseKR4_Full ||
554 advertise & ADVERTISED_40000baseCR4_Full ||
555 advertise & ADVERTISED_40000baseSR4_Full ||
556 advertise & ADVERTISED_40000baseLR4_Full)
557 if (!(abilities.link_speed & I40E_LINK_SPEED_40GB)) {
558 config.link_speed |= I40E_LINK_SPEED_40GB;
559 change = true;
560 }
561
562 if (change) {
563 /* copy over the rest of the abilities */
564 config.phy_type = abilities.phy_type;
565 config.eee_capability = abilities.eee_capability;
566 config.eeer = abilities.eeer_val;
567 config.low_power_ctrl = abilities.d3_lpan;
568
569 /* If link is up set link and an so changes take effect */
570 if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
571 config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
572
573 /* make the aq call */
574 status = i40e_aq_set_phy_config(hw, &config, NULL);
575 if (status) {
576 netdev_info(netdev, "Set phy config failed with error %d.\n",
577 status);
578 return -EAGAIN;
579 }
580
581 status = i40e_update_link_info(hw, true);
582 if (status)
583 netdev_info(netdev, "Updating link info failed with error %d\n",
584 status);
585
586 } else {
587 netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
588 }
589
590 return err;
591}
592
Jesse Brandeburga6599722014-06-04 08:45:25 +0000593static int i40e_nway_reset(struct net_device *netdev)
594{
595 /* restart autonegotiation */
596 struct i40e_netdev_priv *np = netdev_priv(netdev);
597 struct i40e_pf *pf = np->vsi->back;
598 struct i40e_hw *hw = &pf->hw;
599 bool link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
600 i40e_status ret = 0;
601
602 ret = i40e_aq_set_link_restart_an(hw, link_up, NULL);
603 if (ret) {
604 netdev_info(netdev, "link restart failed, aq_err=%d\n",
605 pf->hw.aq.asq_last_status);
606 return -EIO;
607 }
608
609 return 0;
610}
611
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000612/**
613 * i40e_get_pauseparam - Get Flow Control status
614 * Return tx/rx-pause status
615 **/
616static void i40e_get_pauseparam(struct net_device *netdev,
617 struct ethtool_pauseparam *pause)
618{
619 struct i40e_netdev_priv *np = netdev_priv(netdev);
620 struct i40e_pf *pf = np->vsi->back;
621 struct i40e_hw *hw = &pf->hw;
622 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
623
624 pause->autoneg =
625 ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
626 AUTONEG_ENABLE : AUTONEG_DISABLE);
627
Jesse Brandeburgd52c20b2013-11-26 10:49:15 +0000628 if (hw->fc.current_mode == I40E_FC_RX_PAUSE) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000629 pause->rx_pause = 1;
Jesse Brandeburgd52c20b2013-11-26 10:49:15 +0000630 } else if (hw->fc.current_mode == I40E_FC_TX_PAUSE) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000631 pause->tx_pause = 1;
Jesse Brandeburgd52c20b2013-11-26 10:49:15 +0000632 } else if (hw->fc.current_mode == I40E_FC_FULL) {
633 pause->rx_pause = 1;
634 pause->tx_pause = 1;
635 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000636}
637
Catherine Sullivan2becc352014-06-04 08:45:27 +0000638/**
639 * i40e_set_pauseparam - Set Flow Control parameter
640 * @netdev: network interface device structure
641 * @pause: return tx/rx flow control status
642 **/
643static int i40e_set_pauseparam(struct net_device *netdev,
644 struct ethtool_pauseparam *pause)
645{
646 struct i40e_netdev_priv *np = netdev_priv(netdev);
647 struct i40e_pf *pf = np->vsi->back;
648 struct i40e_vsi *vsi = np->vsi;
649 struct i40e_hw *hw = &pf->hw;
650 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
651 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
652 i40e_status status;
653 u8 aq_failures;
Catherine Sullivan7d62dac2014-07-09 07:46:18 +0000654 int err = 0;
Catherine Sullivan2becc352014-06-04 08:45:27 +0000655
656 if (vsi != pf->vsi[pf->lan_vsi])
657 return -EOPNOTSUPP;
658
659 if (pause->autoneg != ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
660 AUTONEG_ENABLE : AUTONEG_DISABLE)) {
661 netdev_info(netdev, "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
662 return -EOPNOTSUPP;
663 }
664
665 /* If we have link and don't have autoneg */
666 if (!test_bit(__I40E_DOWN, &pf->state) &&
667 !(hw_link_info->an_info & I40E_AQ_AN_COMPLETED)) {
668 /* Send message that it might not necessarily work*/
669 netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n");
670 }
671
672 if (hw->fc.current_mode == I40E_FC_PFC) {
673 netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n");
674 return -EOPNOTSUPP;
675 }
676
677 if (pause->rx_pause && pause->tx_pause)
678 hw->fc.requested_mode = I40E_FC_FULL;
679 else if (pause->rx_pause && !pause->tx_pause)
680 hw->fc.requested_mode = I40E_FC_RX_PAUSE;
681 else if (!pause->rx_pause && pause->tx_pause)
682 hw->fc.requested_mode = I40E_FC_TX_PAUSE;
683 else if (!pause->rx_pause && !pause->tx_pause)
684 hw->fc.requested_mode = I40E_FC_NONE;
685 else
686 return -EINVAL;
687
688 /* Set the fc mode and only restart an if link is up*/
689 status = i40e_set_fc(hw, &aq_failures, link_up);
690
691 if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) {
692 netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with error %d and status %d\n",
693 status, hw->aq.asq_last_status);
694 err = -EAGAIN;
695 }
696 if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) {
697 netdev_info(netdev, "Set fc failed on the set_phy_config call with error %d and status %d\n",
698 status, hw->aq.asq_last_status);
699 err = -EAGAIN;
700 }
701 if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) {
702 netdev_info(netdev, "Set fc failed on the update_link_info call with error %d and status %d\n",
703 status, hw->aq.asq_last_status);
704 err = -EAGAIN;
705 }
706
Catherine Sullivan7d62dac2014-07-09 07:46:18 +0000707 if (!test_bit(__I40E_DOWN, &pf->state)) {
708 /* Give it a little more time to try to come back */
709 msleep(75);
710 if (!test_bit(__I40E_DOWN, &pf->state))
711 return i40e_nway_reset(netdev);
712 }
Catherine Sullivan2becc352014-06-04 08:45:27 +0000713
714 return err;
715}
716
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000717static u32 i40e_get_msglevel(struct net_device *netdev)
718{
719 struct i40e_netdev_priv *np = netdev_priv(netdev);
720 struct i40e_pf *pf = np->vsi->back;
721
722 return pf->msg_enable;
723}
724
725static void i40e_set_msglevel(struct net_device *netdev, u32 data)
726{
727 struct i40e_netdev_priv *np = netdev_priv(netdev);
728 struct i40e_pf *pf = np->vsi->back;
729
730 if (I40E_DEBUG_USER & data)
731 pf->hw.debug_mask = data;
732 pf->msg_enable = data;
733}
734
735static int i40e_get_regs_len(struct net_device *netdev)
736{
737 int reg_count = 0;
738 int i;
739
740 for (i = 0; i40e_reg_list[i].offset != 0; i++)
741 reg_count += i40e_reg_list[i].elements;
742
743 return reg_count * sizeof(u32);
744}
745
746static void i40e_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
747 void *p)
748{
749 struct i40e_netdev_priv *np = netdev_priv(netdev);
750 struct i40e_pf *pf = np->vsi->back;
751 struct i40e_hw *hw = &pf->hw;
752 u32 *reg_buf = p;
753 int i, j, ri;
754 u32 reg;
755
756 /* Tell ethtool which driver-version-specific regs output we have.
757 *
758 * At some point, if we have ethtool doing special formatting of
759 * this data, it will rely on this version number to know how to
760 * interpret things. Hence, this needs to be updated if/when the
761 * diags register table is changed.
762 */
763 regs->version = 1;
764
765 /* loop through the diags reg table for what to print */
766 ri = 0;
767 for (i = 0; i40e_reg_list[i].offset != 0; i++) {
768 for (j = 0; j < i40e_reg_list[i].elements; j++) {
769 reg = i40e_reg_list[i].offset
770 + (j * i40e_reg_list[i].stride);
771 reg_buf[ri++] = rd32(hw, reg);
772 }
773 }
774
775}
776
777static int i40e_get_eeprom(struct net_device *netdev,
778 struct ethtool_eeprom *eeprom, u8 *bytes)
779{
780 struct i40e_netdev_priv *np = netdev_priv(netdev);
781 struct i40e_hw *hw = &np->vsi->back->hw;
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000782 struct i40e_pf *pf = np->vsi->back;
783 int ret_val = 0, len;
784 u8 *eeprom_buff;
785 u16 i, sectors;
786 bool last;
Shannon Nelsoncd552cb2014-07-09 07:46:09 +0000787 u32 magic;
788
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000789#define I40E_NVM_SECTOR_SIZE 4096
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000790 if (eeprom->len == 0)
791 return -EINVAL;
792
Shannon Nelsoncd552cb2014-07-09 07:46:09 +0000793 /* check for NVMUpdate access method */
794 magic = hw->vendor_id | (hw->device_id << 16);
795 if (eeprom->magic && eeprom->magic != magic) {
796 int errno;
797
798 /* make sure it is the right magic for NVMUpdate */
799 if ((eeprom->magic >> 16) != hw->device_id)
800 return -EINVAL;
801
802 ret_val = i40e_nvmupd_command(hw,
803 (struct i40e_nvm_access *)eeprom,
804 bytes, &errno);
805 if (ret_val)
806 dev_info(&pf->pdev->dev,
807 "NVMUpdate read failed err=%d status=0x%x\n",
808 ret_val, hw->aq.asq_last_status);
809
810 return errno;
811 }
812
813 /* normal ethtool get_eeprom support */
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000814 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
815
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000816 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000817 if (!eeprom_buff)
818 return -ENOMEM;
819
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000820 ret_val = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
821 if (ret_val) {
822 dev_info(&pf->pdev->dev,
823 "Failed Acquiring NVM resource for read err=%d status=0x%x\n",
824 ret_val, hw->aq.asq_last_status);
825 goto free_buff;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000826 }
827
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000828 sectors = eeprom->len / I40E_NVM_SECTOR_SIZE;
829 sectors += (eeprom->len % I40E_NVM_SECTOR_SIZE) ? 1 : 0;
830 len = I40E_NVM_SECTOR_SIZE;
831 last = false;
832 for (i = 0; i < sectors; i++) {
833 if (i == (sectors - 1)) {
834 len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i);
835 last = true;
836 }
837 ret_val = i40e_aq_read_nvm(hw, 0x0,
838 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
839 len,
Shannon Nelsoncd552cb2014-07-09 07:46:09 +0000840 (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000841 last, NULL);
842 if (ret_val) {
843 dev_info(&pf->pdev->dev,
844 "read NVM failed err=%d status=0x%x\n",
845 ret_val, hw->aq.asq_last_status);
846 goto release_nvm;
847 }
848 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000849
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000850release_nvm:
851 i40e_release_nvm(hw);
Shannon Nelsoncd552cb2014-07-09 07:46:09 +0000852 memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000853free_buff:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000854 kfree(eeprom_buff);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000855 return ret_val;
856}
857
858static int i40e_get_eeprom_len(struct net_device *netdev)
859{
860 struct i40e_netdev_priv *np = netdev_priv(netdev);
861 struct i40e_hw *hw = &np->vsi->back->hw;
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000862 u32 val;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000863
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000864 val = (rd32(hw, I40E_GLPCI_LBARCTRL)
865 & I40E_GLPCI_LBARCTRL_FL_SIZE_MASK)
866 >> I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT;
867 /* register returns value in power of 2, 64Kbyte chunks. */
868 val = (64 * 1024) * (1 << val);
869 return val;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000870}
871
Shannon Nelsoncd552cb2014-07-09 07:46:09 +0000872static int i40e_set_eeprom(struct net_device *netdev,
873 struct ethtool_eeprom *eeprom, u8 *bytes)
874{
875 struct i40e_netdev_priv *np = netdev_priv(netdev);
876 struct i40e_hw *hw = &np->vsi->back->hw;
877 struct i40e_pf *pf = np->vsi->back;
878 int ret_val = 0;
879 int errno;
880 u32 magic;
881
882 /* normal ethtool set_eeprom is not supported */
883 magic = hw->vendor_id | (hw->device_id << 16);
884 if (eeprom->magic == magic)
885 return -EOPNOTSUPP;
886
887 /* check for NVMUpdate access method */
888 if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
889 return -EINVAL;
890
891 if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
892 test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
893 return -EBUSY;
894
895 ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom,
896 bytes, &errno);
897 if (ret_val)
898 dev_info(&pf->pdev->dev,
899 "NVMUpdate write failed err=%d status=0x%x\n",
900 ret_val, hw->aq.asq_last_status);
901
902 return errno;
903}
904
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000905static void i40e_get_drvinfo(struct net_device *netdev,
906 struct ethtool_drvinfo *drvinfo)
907{
908 struct i40e_netdev_priv *np = netdev_priv(netdev);
909 struct i40e_vsi *vsi = np->vsi;
910 struct i40e_pf *pf = vsi->back;
911
912 strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
913 strlcpy(drvinfo->version, i40e_driver_version_str,
914 sizeof(drvinfo->version));
915 strlcpy(drvinfo->fw_version, i40e_fw_version_str(&pf->hw),
916 sizeof(drvinfo->fw_version));
917 strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
918 sizeof(drvinfo->bus_info));
919}
920
921static void i40e_get_ringparam(struct net_device *netdev,
922 struct ethtool_ringparam *ring)
923{
924 struct i40e_netdev_priv *np = netdev_priv(netdev);
925 struct i40e_pf *pf = np->vsi->back;
926 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
927
928 ring->rx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
929 ring->tx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
930 ring->rx_mini_max_pending = 0;
931 ring->rx_jumbo_max_pending = 0;
Alexander Duyck9f65e152013-09-28 06:00:58 +0000932 ring->rx_pending = vsi->rx_rings[0]->count;
933 ring->tx_pending = vsi->tx_rings[0]->count;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000934 ring->rx_mini_pending = 0;
935 ring->rx_jumbo_pending = 0;
936}
937
938static int i40e_set_ringparam(struct net_device *netdev,
939 struct ethtool_ringparam *ring)
940{
941 struct i40e_ring *tx_rings = NULL, *rx_rings = NULL;
942 struct i40e_netdev_priv *np = netdev_priv(netdev);
943 struct i40e_vsi *vsi = np->vsi;
944 struct i40e_pf *pf = vsi->back;
945 u32 new_rx_count, new_tx_count;
946 int i, err = 0;
947
948 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
949 return -EINVAL;
950
Shannon Nelson1fa18372013-11-20 10:03:08 +0000951 if (ring->tx_pending > I40E_MAX_NUM_DESCRIPTORS ||
952 ring->tx_pending < I40E_MIN_NUM_DESCRIPTORS ||
953 ring->rx_pending > I40E_MAX_NUM_DESCRIPTORS ||
954 ring->rx_pending < I40E_MIN_NUM_DESCRIPTORS) {
955 netdev_info(netdev,
956 "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n",
957 ring->tx_pending, ring->rx_pending,
958 I40E_MIN_NUM_DESCRIPTORS, I40E_MAX_NUM_DESCRIPTORS);
959 return -EINVAL;
960 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000961
Shannon Nelson1fa18372013-11-20 10:03:08 +0000962 new_tx_count = ALIGN(ring->tx_pending, I40E_REQ_DESCRIPTOR_MULTIPLE);
963 new_rx_count = ALIGN(ring->rx_pending, I40E_REQ_DESCRIPTOR_MULTIPLE);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000964
965 /* if nothing to do return success */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000966 if ((new_tx_count == vsi->tx_rings[0]->count) &&
967 (new_rx_count == vsi->rx_rings[0]->count))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000968 return 0;
969
970 while (test_and_set_bit(__I40E_CONFIG_BUSY, &pf->state))
971 usleep_range(1000, 2000);
972
973 if (!netif_running(vsi->netdev)) {
974 /* simple case - set for the next time the netdev is started */
975 for (i = 0; i < vsi->num_queue_pairs; i++) {
Alexander Duyck9f65e152013-09-28 06:00:58 +0000976 vsi->tx_rings[i]->count = new_tx_count;
977 vsi->rx_rings[i]->count = new_rx_count;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000978 }
979 goto done;
980 }
981
982 /* We can't just free everything and then setup again,
983 * because the ISRs in MSI-X mode get passed pointers
984 * to the Tx and Rx ring structs.
985 */
986
987 /* alloc updated Tx resources */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000988 if (new_tx_count != vsi->tx_rings[0]->count) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000989 netdev_info(netdev,
990 "Changing Tx descriptor count from %d to %d.\n",
Alexander Duyck9f65e152013-09-28 06:00:58 +0000991 vsi->tx_rings[0]->count, new_tx_count);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000992 tx_rings = kcalloc(vsi->alloc_queue_pairs,
993 sizeof(struct i40e_ring), GFP_KERNEL);
994 if (!tx_rings) {
995 err = -ENOMEM;
996 goto done;
997 }
998
999 for (i = 0; i < vsi->num_queue_pairs; i++) {
1000 /* clone ring and setup updated count */
Alexander Duyck9f65e152013-09-28 06:00:58 +00001001 tx_rings[i] = *vsi->tx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001002 tx_rings[i].count = new_tx_count;
1003 err = i40e_setup_tx_descriptors(&tx_rings[i]);
1004 if (err) {
1005 while (i) {
1006 i--;
1007 i40e_free_tx_resources(&tx_rings[i]);
1008 }
1009 kfree(tx_rings);
1010 tx_rings = NULL;
1011
1012 goto done;
1013 }
1014 }
1015 }
1016
1017 /* alloc updated Rx resources */
Alexander Duyck9f65e152013-09-28 06:00:58 +00001018 if (new_rx_count != vsi->rx_rings[0]->count) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001019 netdev_info(netdev,
1020 "Changing Rx descriptor count from %d to %d\n",
Alexander Duyck9f65e152013-09-28 06:00:58 +00001021 vsi->rx_rings[0]->count, new_rx_count);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001022 rx_rings = kcalloc(vsi->alloc_queue_pairs,
1023 sizeof(struct i40e_ring), GFP_KERNEL);
1024 if (!rx_rings) {
1025 err = -ENOMEM;
1026 goto free_tx;
1027 }
1028
1029 for (i = 0; i < vsi->num_queue_pairs; i++) {
1030 /* clone ring and setup updated count */
Alexander Duyck9f65e152013-09-28 06:00:58 +00001031 rx_rings[i] = *vsi->rx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001032 rx_rings[i].count = new_rx_count;
1033 err = i40e_setup_rx_descriptors(&rx_rings[i]);
1034 if (err) {
1035 while (i) {
1036 i--;
1037 i40e_free_rx_resources(&rx_rings[i]);
1038 }
1039 kfree(rx_rings);
1040 rx_rings = NULL;
1041
1042 goto free_tx;
1043 }
1044 }
1045 }
1046
1047 /* Bring interface down, copy in the new ring info,
1048 * then restore the interface
1049 */
1050 i40e_down(vsi);
1051
1052 if (tx_rings) {
1053 for (i = 0; i < vsi->num_queue_pairs; i++) {
Alexander Duyck9f65e152013-09-28 06:00:58 +00001054 i40e_free_tx_resources(vsi->tx_rings[i]);
1055 *vsi->tx_rings[i] = tx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001056 }
1057 kfree(tx_rings);
1058 tx_rings = NULL;
1059 }
1060
1061 if (rx_rings) {
1062 for (i = 0; i < vsi->num_queue_pairs; i++) {
Alexander Duyck9f65e152013-09-28 06:00:58 +00001063 i40e_free_rx_resources(vsi->rx_rings[i]);
1064 *vsi->rx_rings[i] = rx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001065 }
1066 kfree(rx_rings);
1067 rx_rings = NULL;
1068 }
1069
1070 i40e_up(vsi);
1071
1072free_tx:
1073 /* error cleanup if the Rx allocations failed after getting Tx */
1074 if (tx_rings) {
1075 for (i = 0; i < vsi->num_queue_pairs; i++)
1076 i40e_free_tx_resources(&tx_rings[i]);
1077 kfree(tx_rings);
1078 tx_rings = NULL;
1079 }
1080
1081done:
1082 clear_bit(__I40E_CONFIG_BUSY, &pf->state);
1083
1084 return err;
1085}
1086
1087static int i40e_get_sset_count(struct net_device *netdev, int sset)
1088{
1089 struct i40e_netdev_priv *np = netdev_priv(netdev);
1090 struct i40e_vsi *vsi = np->vsi;
1091 struct i40e_pf *pf = vsi->back;
1092
1093 switch (sset) {
1094 case ETH_SS_TEST:
1095 return I40E_TEST_LEN;
1096 case ETH_SS_STATS:
Shannon Nelson8eab9cf2014-04-23 04:49:55 +00001097 if (vsi == pf->vsi[pf->lan_vsi]) {
1098 int len = I40E_PF_STATS_LEN(netdev);
1099
1100 if (pf->lan_veb != I40E_NO_VEB)
1101 len += I40E_VEB_STATS_LEN;
1102 return len;
1103 } else {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001104 return I40E_VSI_STATS_LEN(netdev);
Shannon Nelson8eab9cf2014-04-23 04:49:55 +00001105 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001106 default:
1107 return -EOPNOTSUPP;
1108 }
1109}
1110
1111static void i40e_get_ethtool_stats(struct net_device *netdev,
1112 struct ethtool_stats *stats, u64 *data)
1113{
1114 struct i40e_netdev_priv *np = netdev_priv(netdev);
Akeem G Abodunrine7046ee2014-04-09 05:58:58 +00001115 struct i40e_ring *tx_ring, *rx_ring;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001116 struct i40e_vsi *vsi = np->vsi;
1117 struct i40e_pf *pf = vsi->back;
1118 int i = 0;
1119 char *p;
1120 int j;
1121 struct rtnl_link_stats64 *net_stats = i40e_get_vsi_stats_struct(vsi);
Alexander Duyck980e9b12013-09-28 06:01:03 +00001122 unsigned int start;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001123
1124 i40e_update_stats(vsi);
1125
1126 for (j = 0; j < I40E_NETDEV_STATS_LEN; j++) {
1127 p = (char *)net_stats + i40e_gstrings_net_stats[j].stat_offset;
1128 data[i++] = (i40e_gstrings_net_stats[j].sizeof_stat ==
1129 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1130 }
Shannon Nelson41a9e552014-04-23 04:50:20 +00001131 for (j = 0; j < I40E_MISC_STATS_LEN; j++) {
1132 p = (char *)vsi + i40e_gstrings_misc_stats[j].stat_offset;
1133 data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat ==
1134 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1135 }
Vasu Dev38e00432014-08-01 13:27:03 -07001136#ifdef I40E_FCOE
1137 for (j = 0; j < I40E_FCOE_STATS_LEN; j++) {
1138 p = (char *)vsi + i40e_gstrings_fcoe_stats[j].stat_offset;
1139 data[i++] = (i40e_gstrings_fcoe_stats[j].sizeof_stat ==
1140 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1141 }
1142#endif
Alexander Duyck980e9b12013-09-28 06:01:03 +00001143 rcu_read_lock();
Catherine Sullivan99c472a2014-03-14 07:32:30 +00001144 for (j = 0; j < vsi->num_queue_pairs; j++) {
Akeem G Abodunrine7046ee2014-04-09 05:58:58 +00001145 tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
Alexander Duyck980e9b12013-09-28 06:01:03 +00001146
1147 if (!tx_ring)
1148 continue;
1149
1150 /* process Tx ring statistics */
1151 do {
Eric W. Biederman57a77442014-03-13 21:26:42 -07001152 start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
Alexander Duyck980e9b12013-09-28 06:01:03 +00001153 data[i] = tx_ring->stats.packets;
1154 data[i + 1] = tx_ring->stats.bytes;
Eric W. Biederman57a77442014-03-13 21:26:42 -07001155 } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
Catherine Sullivan99c472a2014-03-14 07:32:30 +00001156 i += 2;
Alexander Duyck980e9b12013-09-28 06:01:03 +00001157
1158 /* Rx ring is the 2nd half of the queue pair */
1159 rx_ring = &tx_ring[1];
1160 do {
Eric W. Biederman57a77442014-03-13 21:26:42 -07001161 start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
Catherine Sullivan99c472a2014-03-14 07:32:30 +00001162 data[i] = rx_ring->stats.packets;
1163 data[i + 1] = rx_ring->stats.bytes;
Eric W. Biederman57a77442014-03-13 21:26:42 -07001164 } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
Catherine Sullivan99c472a2014-03-14 07:32:30 +00001165 i += 2;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001166 }
Alexander Duyck980e9b12013-09-28 06:01:03 +00001167 rcu_read_unlock();
Shannon Nelson8eab9cf2014-04-23 04:49:55 +00001168 if (vsi != pf->vsi[pf->lan_vsi])
1169 return;
1170
1171 if (pf->lan_veb != I40E_NO_VEB) {
1172 struct i40e_veb *veb = pf->veb[pf->lan_veb];
1173 for (j = 0; j < I40E_VEB_STATS_LEN; j++) {
1174 p = (char *)veb;
1175 p += i40e_gstrings_veb_stats[j].stat_offset;
1176 data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat ==
1177 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001178 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001179 }
Shannon Nelson8eab9cf2014-04-23 04:49:55 +00001180 for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
1181 p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
1182 data[i++] = (i40e_gstrings_stats[j].sizeof_stat ==
1183 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1184 }
1185 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
1186 data[i++] = pf->stats.priority_xon_tx[j];
1187 data[i++] = pf->stats.priority_xoff_tx[j];
1188 }
1189 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
1190 data[i++] = pf->stats.priority_xon_rx[j];
1191 data[i++] = pf->stats.priority_xoff_rx[j];
1192 }
1193 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++)
1194 data[i++] = pf->stats.priority_xon_2_xoff[j];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001195}
1196
1197static void i40e_get_strings(struct net_device *netdev, u32 stringset,
1198 u8 *data)
1199{
1200 struct i40e_netdev_priv *np = netdev_priv(netdev);
1201 struct i40e_vsi *vsi = np->vsi;
1202 struct i40e_pf *pf = vsi->back;
1203 char *p = (char *)data;
1204 int i;
1205
1206 switch (stringset) {
1207 case ETH_SS_TEST:
1208 for (i = 0; i < I40E_TEST_LEN; i++) {
1209 memcpy(data, i40e_gstrings_test[i], ETH_GSTRING_LEN);
1210 data += ETH_GSTRING_LEN;
1211 }
1212 break;
1213 case ETH_SS_STATS:
1214 for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
1215 snprintf(p, ETH_GSTRING_LEN, "%s",
1216 i40e_gstrings_net_stats[i].stat_string);
1217 p += ETH_GSTRING_LEN;
1218 }
Shannon Nelson41a9e552014-04-23 04:50:20 +00001219 for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
1220 snprintf(p, ETH_GSTRING_LEN, "%s",
1221 i40e_gstrings_misc_stats[i].stat_string);
1222 p += ETH_GSTRING_LEN;
1223 }
Vasu Dev38e00432014-08-01 13:27:03 -07001224#ifdef I40E_FCOE
1225 for (i = 0; i < I40E_FCOE_STATS_LEN; i++) {
1226 snprintf(p, ETH_GSTRING_LEN, "%s",
1227 i40e_gstrings_fcoe_stats[i].stat_string);
1228 p += ETH_GSTRING_LEN;
1229 }
1230#endif
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001231 for (i = 0; i < vsi->num_queue_pairs; i++) {
1232 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
1233 p += ETH_GSTRING_LEN;
1234 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
1235 p += ETH_GSTRING_LEN;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001236 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
1237 p += ETH_GSTRING_LEN;
1238 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
1239 p += ETH_GSTRING_LEN;
1240 }
Shannon Nelson8eab9cf2014-04-23 04:49:55 +00001241 if (vsi != pf->vsi[pf->lan_vsi])
1242 return;
1243
1244 if (pf->lan_veb != I40E_NO_VEB) {
1245 for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
1246 snprintf(p, ETH_GSTRING_LEN, "veb.%s",
1247 i40e_gstrings_veb_stats[i].stat_string);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001248 p += ETH_GSTRING_LEN;
1249 }
Shannon Nelson8eab9cf2014-04-23 04:49:55 +00001250 }
1251 for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
1252 snprintf(p, ETH_GSTRING_LEN, "port.%s",
1253 i40e_gstrings_stats[i].stat_string);
1254 p += ETH_GSTRING_LEN;
1255 }
1256 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
1257 snprintf(p, ETH_GSTRING_LEN,
1258 "port.tx_priority_%u_xon", i);
1259 p += ETH_GSTRING_LEN;
1260 snprintf(p, ETH_GSTRING_LEN,
1261 "port.tx_priority_%u_xoff", i);
1262 p += ETH_GSTRING_LEN;
1263 }
1264 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
1265 snprintf(p, ETH_GSTRING_LEN,
1266 "port.rx_priority_%u_xon", i);
1267 p += ETH_GSTRING_LEN;
1268 snprintf(p, ETH_GSTRING_LEN,
1269 "port.rx_priority_%u_xoff", i);
1270 p += ETH_GSTRING_LEN;
1271 }
1272 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
1273 snprintf(p, ETH_GSTRING_LEN,
1274 "port.rx_priority_%u_xon_2_xoff", i);
1275 p += ETH_GSTRING_LEN;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001276 }
1277 /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
1278 break;
1279 }
1280}
1281
1282static int i40e_get_ts_info(struct net_device *dev,
1283 struct ethtool_ts_info *info)
1284{
Jacob Kellerbeb0dff2014-01-11 05:43:19 +00001285 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
1286
1287 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
1288 SOF_TIMESTAMPING_RX_SOFTWARE |
1289 SOF_TIMESTAMPING_SOFTWARE |
1290 SOF_TIMESTAMPING_TX_HARDWARE |
1291 SOF_TIMESTAMPING_RX_HARDWARE |
1292 SOF_TIMESTAMPING_RAW_HARDWARE;
1293
1294 if (pf->ptp_clock)
1295 info->phc_index = ptp_clock_index(pf->ptp_clock);
1296 else
1297 info->phc_index = -1;
1298
1299 info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
1300
1301 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
1302 (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
1303 (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
1304 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
1305 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
1306 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
1307 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
1308 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
1309 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
1310 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
1311 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
1312 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
1313
1314 return 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001315}
1316
Shannon Nelson7b086392013-11-20 10:02:59 +00001317static int i40e_link_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001318{
Shannon Nelson7b086392013-11-20 10:02:59 +00001319 struct i40e_netdev_priv *np = netdev_priv(netdev);
1320 struct i40e_pf *pf = np->vsi->back;
1321
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001322 netif_info(pf, hw, netdev, "link test\n");
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001323 if (i40e_get_link_status(&pf->hw))
1324 *data = 0;
1325 else
1326 *data = 1;
1327
1328 return *data;
1329}
1330
Shannon Nelson7b086392013-11-20 10:02:59 +00001331static int i40e_reg_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001332{
Shannon Nelson7b086392013-11-20 10:02:59 +00001333 struct i40e_netdev_priv *np = netdev_priv(netdev);
1334 struct i40e_pf *pf = np->vsi->back;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001335
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001336 netif_info(pf, hw, netdev, "register test\n");
Shannon Nelson7b086392013-11-20 10:02:59 +00001337 *data = i40e_diag_reg_test(&pf->hw);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001338
Shannon Nelson7b086392013-11-20 10:02:59 +00001339 return *data;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001340}
1341
Shannon Nelson7b086392013-11-20 10:02:59 +00001342static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001343{
Shannon Nelson7b086392013-11-20 10:02:59 +00001344 struct i40e_netdev_priv *np = netdev_priv(netdev);
1345 struct i40e_pf *pf = np->vsi->back;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001346
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001347 netif_info(pf, hw, netdev, "eeprom test\n");
Shannon Nelson7b086392013-11-20 10:02:59 +00001348 *data = i40e_diag_eeprom_test(&pf->hw);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001349
Shannon Nelson7b086392013-11-20 10:02:59 +00001350 return *data;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001351}
1352
Shannon Nelson7b086392013-11-20 10:02:59 +00001353static int i40e_intr_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001354{
Shannon Nelson7b086392013-11-20 10:02:59 +00001355 struct i40e_netdev_priv *np = netdev_priv(netdev);
1356 struct i40e_pf *pf = np->vsi->back;
Shannon Nelsoncd92e722013-11-16 10:00:44 +00001357 u16 swc_old = pf->sw_int_count;
1358
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001359 netif_info(pf, hw, netdev, "interrupt test\n");
Shannon Nelsoncd92e722013-11-16 10:00:44 +00001360 wr32(&pf->hw, I40E_PFINT_DYN_CTL0,
1361 (I40E_PFINT_DYN_CTL0_INTENA_MASK |
1362 I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK));
1363 usleep_range(1000, 2000);
1364 *data = (swc_old == pf->sw_int_count);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001365
1366 return *data;
1367}
1368
Shannon Nelson7b086392013-11-20 10:02:59 +00001369static int i40e_loopback_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001370{
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001371 struct i40e_netdev_priv *np = netdev_priv(netdev);
1372 struct i40e_pf *pf = np->vsi->back;
1373
1374 netif_info(pf, hw, netdev, "loopback test not implemented\n");
Shannon Nelsoncd92e722013-11-16 10:00:44 +00001375 *data = 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001376
1377 return *data;
1378}
1379
1380static void i40e_diag_test(struct net_device *netdev,
1381 struct ethtool_test *eth_test, u64 *data)
1382{
1383 struct i40e_netdev_priv *np = netdev_priv(netdev);
1384 struct i40e_pf *pf = np->vsi->back;
1385
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001386 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
1387 /* Offline tests */
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001388 netif_info(pf, drv, netdev, "offline testing starting\n");
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001389
Shannon Nelsonf551b432013-11-26 10:49:12 +00001390 set_bit(__I40E_TESTING, &pf->state);
1391
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001392 /* Link test performed before hardware reset
1393 * so autoneg doesn't interfere with test result
1394 */
Shannon Nelson7b086392013-11-20 10:02:59 +00001395 if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001396 eth_test->flags |= ETH_TEST_FL_FAILED;
1397
Shannon Nelson7b086392013-11-20 10:02:59 +00001398 if (i40e_eeprom_test(netdev, &data[I40E_ETH_TEST_EEPROM]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001399 eth_test->flags |= ETH_TEST_FL_FAILED;
1400
Shannon Nelson7b086392013-11-20 10:02:59 +00001401 if (i40e_intr_test(netdev, &data[I40E_ETH_TEST_INTR]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001402 eth_test->flags |= ETH_TEST_FL_FAILED;
1403
Shannon Nelson7b086392013-11-20 10:02:59 +00001404 if (i40e_loopback_test(netdev, &data[I40E_ETH_TEST_LOOPBACK]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001405 eth_test->flags |= ETH_TEST_FL_FAILED;
1406
Shannon Nelsonf551b432013-11-26 10:49:12 +00001407 /* run reg test last, a reset is required after it */
1408 if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
1409 eth_test->flags |= ETH_TEST_FL_FAILED;
1410
1411 clear_bit(__I40E_TESTING, &pf->state);
1412 i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001413 } else {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001414 /* Online tests */
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001415 netif_info(pf, drv, netdev, "online testing starting\n");
1416
Shannon Nelson7b086392013-11-20 10:02:59 +00001417 if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001418 eth_test->flags |= ETH_TEST_FL_FAILED;
1419
1420 /* Offline only tests, not run in online; pass by default */
1421 data[I40E_ETH_TEST_REG] = 0;
1422 data[I40E_ETH_TEST_EEPROM] = 0;
1423 data[I40E_ETH_TEST_INTR] = 0;
1424 data[I40E_ETH_TEST_LOOPBACK] = 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001425 }
Shannon Nelsonc140c172013-11-20 10:02:58 +00001426
Shannon Nelsonb03aaa92013-11-20 10:03:06 +00001427 netif_info(pf, drv, netdev, "testing finished\n");
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001428}
1429
1430static void i40e_get_wol(struct net_device *netdev,
1431 struct ethtool_wolinfo *wol)
1432{
Shannon Nelson8e2773a2013-11-28 06:39:22 +00001433 struct i40e_netdev_priv *np = netdev_priv(netdev);
1434 struct i40e_pf *pf = np->vsi->back;
1435 struct i40e_hw *hw = &pf->hw;
1436 u16 wol_nvm_bits;
1437
1438 /* NVM bit on means WoL disabled for the port */
1439 i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
1440 if ((1 << hw->port) & wol_nvm_bits) {
1441 wol->supported = 0;
1442 wol->wolopts = 0;
1443 } else {
1444 wol->supported = WAKE_MAGIC;
1445 wol->wolopts = (pf->wol_en ? WAKE_MAGIC : 0);
1446 }
1447}
1448
1449static int i40e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1450{
1451 struct i40e_netdev_priv *np = netdev_priv(netdev);
1452 struct i40e_pf *pf = np->vsi->back;
1453 struct i40e_hw *hw = &pf->hw;
1454 u16 wol_nvm_bits;
1455
1456 /* NVM bit on means WoL disabled for the port */
1457 i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
1458 if (((1 << hw->port) & wol_nvm_bits))
1459 return -EOPNOTSUPP;
1460
1461 /* only magic packet is supported */
1462 if (wol->wolopts && (wol->wolopts != WAKE_MAGIC))
1463 return -EOPNOTSUPP;
1464
1465 /* is this a new value? */
1466 if (pf->wol_en != !!wol->wolopts) {
1467 pf->wol_en = !!wol->wolopts;
1468 device_set_wakeup_enable(&pf->pdev->dev, pf->wol_en);
1469 }
1470
1471 return 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001472}
1473
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001474static int i40e_set_phys_id(struct net_device *netdev,
1475 enum ethtool_phys_id_state state)
1476{
1477 struct i40e_netdev_priv *np = netdev_priv(netdev);
1478 struct i40e_pf *pf = np->vsi->back;
1479 struct i40e_hw *hw = &pf->hw;
1480 int blink_freq = 2;
1481
1482 switch (state) {
1483 case ETHTOOL_ID_ACTIVE:
1484 pf->led_status = i40e_led_get(hw);
1485 return blink_freq;
1486 case ETHTOOL_ID_ON:
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001487 i40e_led_set(hw, 0xF, false);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001488 break;
1489 case ETHTOOL_ID_OFF:
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001490 i40e_led_set(hw, 0x0, false);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001491 break;
1492 case ETHTOOL_ID_INACTIVE:
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001493 i40e_led_set(hw, pf->led_status, false);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001494 break;
1495 }
1496
1497 return 0;
1498}
1499
1500/* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
1501 * Throttle Rate (ITR) ie. ITR(1) = 2us ITR(10) = 20 us, and also
1502 * 125us (8000 interrupts per second) == ITR(62)
1503 */
1504
1505static int i40e_get_coalesce(struct net_device *netdev,
1506 struct ethtool_coalesce *ec)
1507{
1508 struct i40e_netdev_priv *np = netdev_priv(netdev);
1509 struct i40e_vsi *vsi = np->vsi;
1510
1511 ec->tx_max_coalesced_frames_irq = vsi->work_limit;
1512 ec->rx_max_coalesced_frames_irq = vsi->work_limit;
1513
1514 if (ITR_IS_DYNAMIC(vsi->rx_itr_setting))
Mitch Williams32f5f542014-04-04 04:43:10 +00001515 ec->use_adaptive_rx_coalesce = 1;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001516
1517 if (ITR_IS_DYNAMIC(vsi->tx_itr_setting))
Mitch Williams32f5f542014-04-04 04:43:10 +00001518 ec->use_adaptive_tx_coalesce = 1;
1519
1520 ec->rx_coalesce_usecs = vsi->rx_itr_setting & ~I40E_ITR_DYNAMIC;
1521 ec->tx_coalesce_usecs = vsi->tx_itr_setting & ~I40E_ITR_DYNAMIC;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001522
1523 return 0;
1524}
1525
1526static int i40e_set_coalesce(struct net_device *netdev,
1527 struct ethtool_coalesce *ec)
1528{
1529 struct i40e_netdev_priv *np = netdev_priv(netdev);
1530 struct i40e_q_vector *q_vector;
1531 struct i40e_vsi *vsi = np->vsi;
1532 struct i40e_pf *pf = vsi->back;
1533 struct i40e_hw *hw = &pf->hw;
1534 u16 vector;
1535 int i;
1536
1537 if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
1538 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
1539
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001540 vector = vsi->base_vector;
Mitch Williams32f5f542014-04-04 04:43:10 +00001541 if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001542 (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1))) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001543 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001544 } else if (ec->rx_coalesce_usecs == 0) {
1545 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
1546 i40e_irq_dynamic_disable(vsi, vector);
1547 if (ec->use_adaptive_rx_coalesce)
1548 netif_info(pf, drv, netdev,
1549 "Rx-secs=0, need to disable adaptive-Rx for a complete disable\n");
1550 } else {
1551 netif_info(pf, drv, netdev,
1552 "Invalid value, Rx-usecs range is 0, 8-8160\n");
Mitch Williams32f5f542014-04-04 04:43:10 +00001553 return -EINVAL;
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001554 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001555
Mitch Williams32f5f542014-04-04 04:43:10 +00001556 if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001557 (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1))) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001558 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001559 } else if (ec->tx_coalesce_usecs == 0) {
1560 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
1561 i40e_irq_dynamic_disable(vsi, vector);
1562 if (ec->use_adaptive_tx_coalesce)
1563 netif_info(pf, drv, netdev,
1564 "Tx-secs=0, need to disable adaptive-Tx for a complete disable\n");
1565 } else {
1566 netif_info(pf, drv, netdev,
1567 "Invalid value, Tx-usecs range is 0, 8-8160\n");
Mitch Williams32f5f542014-04-04 04:43:10 +00001568 return -EINVAL;
Carolyn Wyborny5c2cebd2014-06-04 01:23:18 +00001569 }
Mitch Williams32f5f542014-04-04 04:43:10 +00001570
1571 if (ec->use_adaptive_rx_coalesce)
1572 vsi->rx_itr_setting |= I40E_ITR_DYNAMIC;
1573 else
1574 vsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
1575
1576 if (ec->use_adaptive_tx_coalesce)
1577 vsi->tx_itr_setting |= I40E_ITR_DYNAMIC;
1578 else
1579 vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001580
Alexander Duyck493fb302013-09-28 07:01:44 +00001581 for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
1582 q_vector = vsi->q_vectors[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001583 q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
1584 wr32(hw, I40E_PFINT_ITRN(0, vector - 1), q_vector->rx.itr);
1585 q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
1586 wr32(hw, I40E_PFINT_ITRN(1, vector - 1), q_vector->tx.itr);
1587 i40e_flush(hw);
1588 }
1589
1590 return 0;
1591}
1592
1593/**
1594 * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
1595 * @pf: pointer to the physical function struct
1596 * @cmd: ethtool rxnfc command
1597 *
1598 * Returns Success if the flow is supported, else Invalid Input.
1599 **/
1600static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
1601{
1602 cmd->data = 0;
1603
1604 /* Report default options for RSS on i40e */
1605 switch (cmd->flow_type) {
1606 case TCP_V4_FLOW:
1607 case UDP_V4_FLOW:
1608 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1609 /* fall through to add IP fields */
1610 case SCTP_V4_FLOW:
1611 case AH_ESP_V4_FLOW:
1612 case AH_V4_FLOW:
1613 case ESP_V4_FLOW:
1614 case IPV4_FLOW:
1615 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1616 break;
1617 case TCP_V6_FLOW:
1618 case UDP_V6_FLOW:
1619 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1620 /* fall through to add IP fields */
1621 case SCTP_V6_FLOW:
1622 case AH_ESP_V6_FLOW:
1623 case AH_V6_FLOW:
1624 case ESP_V6_FLOW:
1625 case IPV6_FLOW:
1626 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1627 break;
1628 default:
1629 return -EINVAL;
1630 }
1631
1632 return 0;
1633}
1634
1635/**
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001636 * i40e_get_ethtool_fdir_all - Populates the rule count of a command
1637 * @pf: Pointer to the physical function struct
1638 * @cmd: The command to get or set Rx flow classification rules
1639 * @rule_locs: Array of used rule locations
1640 *
1641 * This function populates both the total and actual rule count of
1642 * the ethtool flow classification command
1643 *
1644 * Returns 0 on success or -EMSGSIZE if entry not found
1645 **/
1646static int i40e_get_ethtool_fdir_all(struct i40e_pf *pf,
1647 struct ethtool_rxnfc *cmd,
1648 u32 *rule_locs)
1649{
1650 struct i40e_fdir_filter *rule;
1651 struct hlist_node *node2;
1652 int cnt = 0;
1653
1654 /* report total rule count */
Anjali Singhai Jain082def12014-04-09 05:59:00 +00001655 cmd->data = i40e_get_fd_cnt_all(pf);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001656
1657 hlist_for_each_entry_safe(rule, node2,
1658 &pf->fdir_filter_list, fdir_node) {
1659 if (cnt == cmd->rule_cnt)
1660 return -EMSGSIZE;
1661
1662 rule_locs[cnt] = rule->fd_id;
1663 cnt++;
1664 }
1665
1666 cmd->rule_cnt = cnt;
1667
1668 return 0;
1669}
1670
1671/**
1672 * i40e_get_ethtool_fdir_entry - Look up a filter based on Rx flow
1673 * @pf: Pointer to the physical function struct
1674 * @cmd: The command to get or set Rx flow classification rules
1675 *
1676 * This function looks up a filter based on the Rx flow classification
1677 * command and fills the flow spec info for it if found
1678 *
1679 * Returns 0 on success or -EINVAL if filter not found
1680 **/
1681static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
1682 struct ethtool_rxnfc *cmd)
1683{
1684 struct ethtool_rx_flow_spec *fsp =
1685 (struct ethtool_rx_flow_spec *)&cmd->fs;
1686 struct i40e_fdir_filter *rule = NULL;
1687 struct hlist_node *node2;
1688
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001689 hlist_for_each_entry_safe(rule, node2,
1690 &pf->fdir_filter_list, fdir_node) {
1691 if (fsp->location <= rule->fd_id)
1692 break;
1693 }
1694
1695 if (!rule || fsp->location != rule->fd_id)
1696 return -EINVAL;
1697
1698 fsp->flow_type = rule->flow_type;
Anjali Singhai Jain7d54eb22014-03-14 07:32:21 +00001699 if (fsp->flow_type == IP_USER_FLOW) {
1700 fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
1701 fsp->h_u.usr_ip4_spec.proto = 0;
1702 fsp->m_u.usr_ip4_spec.proto = 0;
1703 }
1704
Anjali Singhai Jain04b73bd2014-05-22 06:31:41 +00001705 /* Reverse the src and dest notion, since the HW views them from
1706 * Tx perspective where as the user expects it from Rx filter view.
1707 */
1708 fsp->h_u.tcp_ip4_spec.psrc = rule->dst_port;
1709 fsp->h_u.tcp_ip4_spec.pdst = rule->src_port;
1710 fsp->h_u.tcp_ip4_spec.ip4src = rule->dst_ip[0];
1711 fsp->h_u.tcp_ip4_spec.ip4dst = rule->src_ip[0];
Anjali Singhai Jain387ce1a2014-05-22 06:32:23 +00001712
1713 if (rule->dest_ctl == I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET)
1714 fsp->ring_cookie = RX_CLS_FLOW_DISC;
1715 else
1716 fsp->ring_cookie = rule->q_index;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001717
1718 return 0;
1719}
1720
1721/**
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001722 * i40e_get_rxnfc - command to get RX flow classification rules
1723 * @netdev: network interface device structure
1724 * @cmd: ethtool rxnfc command
1725 *
1726 * Returns Success if the command is supported.
1727 **/
1728static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
1729 u32 *rule_locs)
1730{
1731 struct i40e_netdev_priv *np = netdev_priv(netdev);
1732 struct i40e_vsi *vsi = np->vsi;
1733 struct i40e_pf *pf = vsi->back;
1734 int ret = -EOPNOTSUPP;
1735
1736 switch (cmd->cmd) {
1737 case ETHTOOL_GRXRINGS:
1738 cmd->data = vsi->alloc_queue_pairs;
1739 ret = 0;
1740 break;
1741 case ETHTOOL_GRXFH:
1742 ret = i40e_get_rss_hash_opts(pf, cmd);
1743 break;
1744 case ETHTOOL_GRXCLSRLCNT:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001745 cmd->rule_cnt = pf->fdir_pf_active_filters;
Anjali Singhai Jain082def12014-04-09 05:59:00 +00001746 /* report total rule count */
1747 cmd->data = i40e_get_fd_cnt_all(pf);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001748 ret = 0;
1749 break;
1750 case ETHTOOL_GRXCLSRULE:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001751 ret = i40e_get_ethtool_fdir_entry(pf, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001752 break;
1753 case ETHTOOL_GRXCLSRLALL:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001754 ret = i40e_get_ethtool_fdir_all(pf, cmd, rule_locs);
1755 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001756 default:
1757 break;
1758 }
1759
1760 return ret;
1761}
1762
1763/**
1764 * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
1765 * @pf: pointer to the physical function struct
1766 * @cmd: ethtool rxnfc command
1767 *
1768 * Returns Success if the flow input set is supported.
1769 **/
1770static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
1771{
1772 struct i40e_hw *hw = &pf->hw;
1773 u64 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
1774 ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
1775
1776 /* RSS does not support anything other than hashing
1777 * to queues on src and dst IPs and ports
1778 */
1779 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
1780 RXH_L4_B_0_1 | RXH_L4_B_2_3))
1781 return -EINVAL;
1782
1783 /* We need at least the IP SRC and DEST fields for hashing */
1784 if (!(nfc->data & RXH_IP_SRC) ||
1785 !(nfc->data & RXH_IP_DST))
1786 return -EINVAL;
1787
1788 switch (nfc->flow_type) {
1789 case TCP_V4_FLOW:
1790 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1791 case 0:
1792 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1793 break;
1794 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1795 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1796 break;
1797 default:
1798 return -EINVAL;
1799 }
1800 break;
1801 case TCP_V6_FLOW:
1802 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1803 case 0:
1804 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1805 break;
1806 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1807 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1808 break;
1809 default:
1810 return -EINVAL;
1811 }
1812 break;
1813 case UDP_V4_FLOW:
1814 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1815 case 0:
Kevin Scottb2d36c02014-04-09 05:58:59 +00001816 hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
1817 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001818 break;
1819 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Kevin Scottb2d36c02014-04-09 05:58:59 +00001820 hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
1821 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001822 break;
1823 default:
1824 return -EINVAL;
1825 }
1826 break;
1827 case UDP_V6_FLOW:
1828 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1829 case 0:
Kevin Scottb2d36c02014-04-09 05:58:59 +00001830 hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
1831 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001832 break;
1833 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Kevin Scottb2d36c02014-04-09 05:58:59 +00001834 hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
1835 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001836 break;
1837 default:
1838 return -EINVAL;
1839 }
1840 break;
1841 case AH_ESP_V4_FLOW:
1842 case AH_V4_FLOW:
1843 case ESP_V4_FLOW:
1844 case SCTP_V4_FLOW:
1845 if ((nfc->data & RXH_L4_B_0_1) ||
1846 (nfc->data & RXH_L4_B_2_3))
1847 return -EINVAL;
1848 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
1849 break;
1850 case AH_ESP_V6_FLOW:
1851 case AH_V6_FLOW:
1852 case ESP_V6_FLOW:
1853 case SCTP_V6_FLOW:
1854 if ((nfc->data & RXH_L4_B_0_1) ||
1855 (nfc->data & RXH_L4_B_2_3))
1856 return -EINVAL;
1857 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
1858 break;
1859 case IPV4_FLOW:
1860 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
1861 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4);
1862 break;
1863 case IPV6_FLOW:
1864 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
1865 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
1866 break;
1867 default:
1868 return -EINVAL;
1869 }
1870
1871 wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
1872 wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
1873 i40e_flush(hw);
1874
1875 return 0;
1876}
1877
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001878/**
Anjali Singhai Jain43fddb72014-02-11 08:24:09 +00001879 * i40e_match_fdir_input_set - Match a new filter against an existing one
1880 * @rule: The filter already added
1881 * @input: The new filter to comapre against
1882 *
1883 * Returns true if the two input set match
1884 **/
1885static bool i40e_match_fdir_input_set(struct i40e_fdir_filter *rule,
1886 struct i40e_fdir_filter *input)
1887{
1888 if ((rule->dst_ip[0] != input->dst_ip[0]) ||
1889 (rule->src_ip[0] != input->src_ip[0]) ||
1890 (rule->dst_port != input->dst_port) ||
1891 (rule->src_port != input->src_port))
1892 return false;
1893 return true;
1894}
1895
1896/**
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001897 * i40e_update_ethtool_fdir_entry - Updates the fdir filter entry
1898 * @vsi: Pointer to the targeted VSI
1899 * @input: The filter to update or NULL to indicate deletion
1900 * @sw_idx: Software index to the filter
1901 * @cmd: The command to get or set Rx flow classification rules
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001902 *
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001903 * This function updates (or deletes) a Flow Director entry from
1904 * the hlist of the corresponding PF
1905 *
1906 * Returns 0 on success
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001907 **/
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001908static int i40e_update_ethtool_fdir_entry(struct i40e_vsi *vsi,
1909 struct i40e_fdir_filter *input,
1910 u16 sw_idx,
1911 struct ethtool_rxnfc *cmd)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001912{
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001913 struct i40e_fdir_filter *rule, *parent;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001914 struct i40e_pf *pf = vsi->back;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001915 struct hlist_node *node2;
1916 int err = -EINVAL;
Jesse Brandeburgc35a1d72013-12-18 13:46:02 +00001917
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001918 parent = NULL;
1919 rule = NULL;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001920
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001921 hlist_for_each_entry_safe(rule, node2,
1922 &pf->fdir_filter_list, fdir_node) {
1923 /* hash found, or no matching entry */
1924 if (rule->fd_id >= sw_idx)
1925 break;
1926 parent = rule;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001927 }
1928
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001929 /* if there is an old rule occupying our place remove it */
1930 if (rule && (rule->fd_id == sw_idx)) {
Anjali Singhai Jain43fddb72014-02-11 08:24:09 +00001931 if (input && !i40e_match_fdir_input_set(rule, input))
1932 err = i40e_add_del_fdir(vsi, rule, false);
1933 else if (!input)
1934 err = i40e_add_del_fdir(vsi, rule, false);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001935 hlist_del(&rule->fdir_node);
1936 kfree(rule);
1937 pf->fdir_pf_active_filters--;
1938 }
1939
1940 /* If no input this was a delete, err should be 0 if a rule was
1941 * successfully found and removed from the list else -EINVAL
1942 */
1943 if (!input)
1944 return err;
1945
1946 /* initialize node and set software index */
1947 INIT_HLIST_NODE(&input->fdir_node);
1948
1949 /* add filter to the list */
1950 if (parent)
1951 hlist_add_after(&parent->fdir_node, &input->fdir_node);
1952 else
1953 hlist_add_head(&input->fdir_node,
1954 &pf->fdir_filter_list);
1955
1956 /* update counts */
1957 pf->fdir_pf_active_filters++;
1958
1959 return 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001960}
1961
1962/**
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001963 * i40e_del_fdir_entry - Deletes a Flow Director filter entry
1964 * @vsi: Pointer to the targeted VSI
1965 * @cmd: The command to get or set Rx flow classification rules
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001966 *
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001967 * The function removes a Flow Director filter entry from the
1968 * hlist of the corresponding PF
1969 *
1970 * Returns 0 on success
1971 */
1972static int i40e_del_fdir_entry(struct i40e_vsi *vsi,
1973 struct ethtool_rxnfc *cmd)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001974{
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001975 struct ethtool_rx_flow_spec *fsp =
1976 (struct ethtool_rx_flow_spec *)&cmd->fs;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001977 struct i40e_pf *pf = vsi->back;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001978 int ret = 0;
Jesse Brandeburgc35a1d72013-12-18 13:46:02 +00001979
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001980 ret = i40e_update_ethtool_fdir_entry(vsi, NULL, fsp->location, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001981
Anjali Singhai Jain55a5e602014-02-12 06:33:25 +00001982 i40e_fdir_check_and_reenable(pf);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001983 return ret;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001984}
1985
1986/**
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001987 * i40e_add_fdir_ethtool - Add/Remove Flow Director filters
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001988 * @vsi: pointer to the targeted VSI
1989 * @cmd: command to get or set RX flow classification rules
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001990 *
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001991 * Add Flow Director filters for a specific flow spec based on their
1992 * protocol. Returns 0 if the filters were successfully added.
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001993 **/
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001994static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
1995 struct ethtool_rxnfc *cmd)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001996{
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001997 struct ethtool_rx_flow_spec *fsp;
1998 struct i40e_fdir_filter *input;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001999 struct i40e_pf *pf;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002000 int ret = -EINVAL;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002001
2002 if (!vsi)
2003 return -EINVAL;
2004
2005 pf = vsi->back;
2006
Anjali Singhai Jain55a5e602014-02-12 06:33:25 +00002007 if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
2008 return -EOPNOTSUPP;
2009
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00002010 if (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)
Anjali Singhai Jain55a5e602014-02-12 06:33:25 +00002011 return -ENOSPC;
2012
2013 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
2014
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002015 if (fsp->location >= (pf->hw.func_caps.fd_filters_best_effort +
2016 pf->hw.func_caps.fd_filters_guaranteed)) {
2017 return -EINVAL;
2018 }
2019
Anjali Singhai Jain387ce1a2014-05-22 06:32:23 +00002020 if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) &&
2021 (fsp->ring_cookie >= vsi->num_queue_pairs))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002022 return -EINVAL;
2023
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002024 input = kzalloc(sizeof(*input), GFP_KERNEL);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002025
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002026 if (!input)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002027 return -ENOMEM;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002028
2029 input->fd_id = fsp->location;
2030
Anjali Singhai Jain35a91fd2014-03-06 09:00:00 +00002031 if (fsp->ring_cookie == RX_CLS_FLOW_DISC)
2032 input->dest_ctl = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
2033 else
2034 input->dest_ctl =
2035 I40E_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX;
2036
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002037 input->q_index = fsp->ring_cookie;
2038 input->flex_off = 0;
2039 input->pctype = 0;
2040 input->dest_vsi = vsi->id;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002041 input->fd_status = I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID;
Anjali Singhai Jain433c47d2014-05-22 06:32:17 +00002042 input->cnt_index = pf->fd_sb_cnt_idx;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002043 input->flow_type = fsp->flow_type;
2044 input->ip4_proto = fsp->h_u.usr_ip4_spec.proto;
Anjali Singhai Jain04b73bd2014-05-22 06:31:41 +00002045
2046 /* Reverse the src and dest notion, since the HW expects them to be from
2047 * Tx perspective where as the input from user is from Rx filter view.
2048 */
2049 input->dst_port = fsp->h_u.tcp_ip4_spec.psrc;
2050 input->src_port = fsp->h_u.tcp_ip4_spec.pdst;
2051 input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
2052 input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002053
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00002054 ret = i40e_add_del_fdir(vsi, input, true);
2055 if (ret)
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002056 kfree(input);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002057 else
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00002058 i40e_update_ethtool_fdir_entry(vsi, input, fsp->location, NULL);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002059
2060 return ret;
2061}
Jesse Brandeburg8fb905b2014-01-17 15:36:33 -08002062
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002063/**
2064 * i40e_set_rxnfc - command to set RX flow classification rules
2065 * @netdev: network interface device structure
2066 * @cmd: ethtool rxnfc command
2067 *
2068 * Returns Success if the command is supported.
2069 **/
2070static int i40e_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
2071{
2072 struct i40e_netdev_priv *np = netdev_priv(netdev);
2073 struct i40e_vsi *vsi = np->vsi;
2074 struct i40e_pf *pf = vsi->back;
2075 int ret = -EOPNOTSUPP;
2076
2077 switch (cmd->cmd) {
2078 case ETHTOOL_SRXFH:
2079 ret = i40e_set_rss_hash_opt(pf, cmd);
2080 break;
2081 case ETHTOOL_SRXCLSRLINS:
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00002082 ret = i40e_add_fdir_ethtool(vsi, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002083 break;
2084 case ETHTOOL_SRXCLSRLDEL:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00002085 ret = i40e_del_fdir_entry(vsi, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002086 break;
2087 default:
2088 break;
2089 }
2090
2091 return ret;
2092}
2093
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00002094/**
2095 * i40e_max_channels - get Max number of combined channels supported
2096 * @vsi: vsi pointer
2097 **/
2098static unsigned int i40e_max_channels(struct i40e_vsi *vsi)
2099{
2100 /* TODO: This code assumes DCB and FD is disabled for now. */
2101 return vsi->alloc_queue_pairs;
2102}
2103
2104/**
2105 * i40e_get_channels - Get the current channels enabled and max supported etc.
2106 * @netdev: network interface device structure
2107 * @ch: ethtool channels structure
2108 *
2109 * We don't support separate tx and rx queues as channels. The other count
2110 * represents how many queues are being used for control. max_combined counts
2111 * how many queue pairs we can support. They may not be mapped 1 to 1 with
2112 * q_vectors since we support a lot more queue pairs than q_vectors.
2113 **/
2114static void i40e_get_channels(struct net_device *dev,
2115 struct ethtool_channels *ch)
2116{
2117 struct i40e_netdev_priv *np = netdev_priv(dev);
2118 struct i40e_vsi *vsi = np->vsi;
2119 struct i40e_pf *pf = vsi->back;
2120
2121 /* report maximum channels */
2122 ch->max_combined = i40e_max_channels(vsi);
2123
2124 /* report info for other vector */
Jesse Brandeburg60ea5f82014-01-17 15:36:34 -08002125 ch->other_count = (pf->flags & I40E_FLAG_FD_SB_ENABLED) ? 1 : 0;
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00002126 ch->max_other = ch->other_count;
2127
2128 /* Note: This code assumes DCB is disabled for now. */
2129 ch->combined_count = vsi->num_queue_pairs;
2130}
2131
2132/**
2133 * i40e_set_channels - Set the new channels count.
2134 * @netdev: network interface device structure
2135 * @ch: ethtool channels structure
2136 *
2137 * The new channels count may not be the same as requested by the user
2138 * since it gets rounded down to a power of 2 value.
2139 **/
2140static int i40e_set_channels(struct net_device *dev,
2141 struct ethtool_channels *ch)
2142{
2143 struct i40e_netdev_priv *np = netdev_priv(dev);
2144 unsigned int count = ch->combined_count;
2145 struct i40e_vsi *vsi = np->vsi;
2146 struct i40e_pf *pf = vsi->back;
2147 int new_count;
2148
2149 /* We do not support setting channels for any other VSI at present */
2150 if (vsi->type != I40E_VSI_MAIN)
2151 return -EINVAL;
2152
2153 /* verify they are not requesting separate vectors */
2154 if (!count || ch->rx_count || ch->tx_count)
2155 return -EINVAL;
2156
2157 /* verify other_count has not changed */
Jesse Brandeburg60ea5f82014-01-17 15:36:34 -08002158 if (ch->other_count != ((pf->flags & I40E_FLAG_FD_SB_ENABLED) ? 1 : 0))
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00002159 return -EINVAL;
2160
2161 /* verify the number of channels does not exceed hardware limits */
2162 if (count > i40e_max_channels(vsi))
2163 return -EINVAL;
2164
2165 /* update feature limits from largest to smallest supported values */
2166 /* TODO: Flow director limit, DCB etc */
2167
2168 /* cap RSS limit */
2169 if (count > pf->rss_size_max)
2170 count = pf->rss_size_max;
2171
2172 /* use rss_reconfig to rebuild with new queue count and update traffic
2173 * class queue mapping
2174 */
2175 new_count = i40e_reconfig_rss_queues(pf, count);
Anjali Singhai Jain5f90f422013-12-21 05:44:43 +00002176 if (new_count > 0)
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00002177 return 0;
2178 else
2179 return -EINVAL;
2180}
2181
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002182static const struct ethtool_ops i40e_ethtool_ops = {
2183 .get_settings = i40e_get_settings,
Catherine Sullivanbf9c7142014-06-04 08:45:28 +00002184 .set_settings = i40e_set_settings,
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002185 .get_drvinfo = i40e_get_drvinfo,
2186 .get_regs_len = i40e_get_regs_len,
2187 .get_regs = i40e_get_regs,
2188 .nway_reset = i40e_nway_reset,
2189 .get_link = ethtool_op_get_link,
2190 .get_wol = i40e_get_wol,
Shannon Nelson8e2773a2013-11-28 06:39:22 +00002191 .set_wol = i40e_set_wol,
Shannon Nelsoncd552cb2014-07-09 07:46:09 +00002192 .set_eeprom = i40e_set_eeprom,
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002193 .get_eeprom_len = i40e_get_eeprom_len,
2194 .get_eeprom = i40e_get_eeprom,
2195 .get_ringparam = i40e_get_ringparam,
2196 .set_ringparam = i40e_set_ringparam,
2197 .get_pauseparam = i40e_get_pauseparam,
Catherine Sullivan2becc352014-06-04 08:45:27 +00002198 .set_pauseparam = i40e_set_pauseparam,
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002199 .get_msglevel = i40e_get_msglevel,
2200 .set_msglevel = i40e_set_msglevel,
2201 .get_rxnfc = i40e_get_rxnfc,
2202 .set_rxnfc = i40e_set_rxnfc,
2203 .self_test = i40e_diag_test,
2204 .get_strings = i40e_get_strings,
2205 .set_phys_id = i40e_set_phys_id,
2206 .get_sset_count = i40e_get_sset_count,
2207 .get_ethtool_stats = i40e_get_ethtool_stats,
2208 .get_coalesce = i40e_get_coalesce,
2209 .set_coalesce = i40e_set_coalesce,
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00002210 .get_channels = i40e_get_channels,
2211 .set_channels = i40e_set_channels,
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002212 .get_ts_info = i40e_get_ts_info,
2213};
2214
2215void i40e_set_ethtool_ops(struct net_device *netdev)
2216{
Wilfried Klaebe7ad24ea2014-05-11 00:12:32 +00002217 netdev->ethtool_ops = &i40e_ethtool_ops;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00002218}