blob: c7718631ed02af87527d23331b0b0a3ee995ff4c [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 Jainbee5af72014-03-06 08:59:50 +0000148 /* LPI stats */
149 I40E_PF_STAT("tx_lpi_status", stats.tx_lpi_status),
150 I40E_PF_STAT("rx_lpi_status", stats.rx_lpi_status),
151 I40E_PF_STAT("tx_lpi_count", stats.tx_lpi_count),
152 I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000153};
154
155#define I40E_QUEUE_STATS_LEN(n) \
Shannon Nelson31cd8402014-04-04 04:43:12 +0000156 (((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \
157 * 2 /* Tx and Rx together */ \
158 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000159#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
160#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
Shannon Nelson41a9e552014-04-23 04:50:20 +0000161#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000162#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
Shannon Nelson41a9e552014-04-23 04:50:20 +0000163 I40E_MISC_STATS_LEN + \
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000164 I40E_QUEUE_STATS_LEN((n)))
165#define I40E_PFC_STATS_LEN ( \
166 (FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \
167 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \
168 FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_tx) + \
169 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
170 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
171 / sizeof(u64))
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000172#define I40E_VEB_STATS_LEN ARRAY_SIZE(i40e_gstrings_veb_stats)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000173#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
174 I40E_PFC_STATS_LEN + \
175 I40E_VSI_STATS_LEN((n)))
176
177enum i40e_ethtool_test_id {
178 I40E_ETH_TEST_REG = 0,
179 I40E_ETH_TEST_EEPROM,
180 I40E_ETH_TEST_INTR,
181 I40E_ETH_TEST_LOOPBACK,
182 I40E_ETH_TEST_LINK,
183};
184
185static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
186 "Register test (offline)",
187 "Eeprom test (offline)",
188 "Interrupt test (offline)",
189 "Loopback test (offline)",
190 "Link test (on/offline)"
191};
192
193#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)
194
195/**
196 * i40e_get_settings - Get Link Speed and Duplex settings
197 * @netdev: network interface device structure
198 * @ecmd: ethtool command
199 *
200 * Reports speed/duplex settings based on media_type
201 **/
202static int i40e_get_settings(struct net_device *netdev,
203 struct ethtool_cmd *ecmd)
204{
205 struct i40e_netdev_priv *np = netdev_priv(netdev);
206 struct i40e_pf *pf = np->vsi->back;
207 struct i40e_hw *hw = &pf->hw;
208 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
209 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
210 u32 link_speed = hw_link_info->link_speed;
211
212 /* hardware is either in 40G mode or 10G mode
213 * NOTE: this section initializes supported and advertising
214 */
215 switch (hw_link_info->phy_type) {
216 case I40E_PHY_TYPE_40GBASE_CR4:
217 case I40E_PHY_TYPE_40GBASE_CR4_CU:
218 ecmd->supported = SUPPORTED_40000baseCR4_Full;
219 ecmd->advertising = ADVERTISED_40000baseCR4_Full;
220 break;
221 case I40E_PHY_TYPE_40GBASE_KR4:
222 ecmd->supported = SUPPORTED_40000baseKR4_Full;
223 ecmd->advertising = ADVERTISED_40000baseKR4_Full;
224 break;
225 case I40E_PHY_TYPE_40GBASE_SR4:
226 ecmd->supported = SUPPORTED_40000baseSR4_Full;
227 ecmd->advertising = ADVERTISED_40000baseSR4_Full;
228 break;
229 case I40E_PHY_TYPE_40GBASE_LR4:
230 ecmd->supported = SUPPORTED_40000baseLR4_Full;
231 ecmd->advertising = ADVERTISED_40000baseLR4_Full;
232 break;
233 case I40E_PHY_TYPE_10GBASE_KX4:
234 ecmd->supported = SUPPORTED_10000baseKX4_Full;
235 ecmd->advertising = ADVERTISED_10000baseKX4_Full;
236 break;
237 case I40E_PHY_TYPE_10GBASE_KR:
238 ecmd->supported = SUPPORTED_10000baseKR_Full;
239 ecmd->advertising = ADVERTISED_10000baseKR_Full;
240 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000241 default:
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000242 if (i40e_is_40G_device(hw->device_id)) {
243 ecmd->supported = SUPPORTED_40000baseSR4_Full;
244 ecmd->advertising = ADVERTISED_40000baseSR4_Full;
245 } else {
246 ecmd->supported = SUPPORTED_10000baseT_Full;
247 ecmd->advertising = ADVERTISED_10000baseT_Full;
248 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000249 break;
250 }
251
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000252 ecmd->supported |= SUPPORTED_Autoneg;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000253 ecmd->advertising |= ADVERTISED_Autoneg;
254 ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
255 AUTONEG_ENABLE : AUTONEG_DISABLE);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000256
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000257 switch (hw->phy.media_type) {
258 case I40E_MEDIA_TYPE_BACKPLANE:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000259 ecmd->supported |= SUPPORTED_Backplane;
260 ecmd->advertising |= ADVERTISED_Backplane;
261 ecmd->port = PORT_NONE;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000262 break;
263 case I40E_MEDIA_TYPE_BASET:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000264 ecmd->supported |= SUPPORTED_TP;
265 ecmd->advertising |= ADVERTISED_TP;
266 ecmd->port = PORT_TP;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000267 break;
268 case I40E_MEDIA_TYPE_DA:
269 case I40E_MEDIA_TYPE_CX4:
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +0000270 ecmd->supported |= SUPPORTED_FIBRE;
271 ecmd->advertising |= ADVERTISED_FIBRE;
272 ecmd->port = PORT_DA;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000273 break;
274 case I40E_MEDIA_TYPE_FIBER:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000275 ecmd->supported |= SUPPORTED_FIBRE;
276 ecmd->advertising |= ADVERTISED_FIBRE;
277 ecmd->port = PORT_FIBRE;
Jesse Brandeburgc9a3d472013-11-26 10:49:10 +0000278 break;
279 case I40E_MEDIA_TYPE_UNKNOWN:
280 default:
281 ecmd->port = PORT_OTHER;
282 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000283 }
284
285 ecmd->transceiver = XCVR_EXTERNAL;
286
287 if (link_up) {
288 switch (link_speed) {
289 case I40E_LINK_SPEED_40GB:
290 /* need a SPEED_40000 in ethtool.h */
291 ethtool_cmd_speed_set(ecmd, 40000);
292 break;
293 case I40E_LINK_SPEED_10GB:
294 ethtool_cmd_speed_set(ecmd, SPEED_10000);
295 break;
296 default:
297 break;
298 }
299 ecmd->duplex = DUPLEX_FULL;
300 } else {
301 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
302 ecmd->duplex = DUPLEX_UNKNOWN;
303 }
304
305 return 0;
306}
307
308/**
309 * i40e_get_pauseparam - Get Flow Control status
310 * Return tx/rx-pause status
311 **/
312static void i40e_get_pauseparam(struct net_device *netdev,
313 struct ethtool_pauseparam *pause)
314{
315 struct i40e_netdev_priv *np = netdev_priv(netdev);
316 struct i40e_pf *pf = np->vsi->back;
317 struct i40e_hw *hw = &pf->hw;
318 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
319
320 pause->autoneg =
321 ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
322 AUTONEG_ENABLE : AUTONEG_DISABLE);
323
Jesse Brandeburgd52c20b2013-11-26 10:49:15 +0000324 if (hw->fc.current_mode == I40E_FC_RX_PAUSE) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000325 pause->rx_pause = 1;
Jesse Brandeburgd52c20b2013-11-26 10:49:15 +0000326 } else if (hw->fc.current_mode == I40E_FC_TX_PAUSE) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000327 pause->tx_pause = 1;
Jesse Brandeburgd52c20b2013-11-26 10:49:15 +0000328 } else if (hw->fc.current_mode == I40E_FC_FULL) {
329 pause->rx_pause = 1;
330 pause->tx_pause = 1;
331 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000332}
333
334static u32 i40e_get_msglevel(struct net_device *netdev)
335{
336 struct i40e_netdev_priv *np = netdev_priv(netdev);
337 struct i40e_pf *pf = np->vsi->back;
338
339 return pf->msg_enable;
340}
341
342static void i40e_set_msglevel(struct net_device *netdev, u32 data)
343{
344 struct i40e_netdev_priv *np = netdev_priv(netdev);
345 struct i40e_pf *pf = np->vsi->back;
346
347 if (I40E_DEBUG_USER & data)
348 pf->hw.debug_mask = data;
349 pf->msg_enable = data;
350}
351
352static int i40e_get_regs_len(struct net_device *netdev)
353{
354 int reg_count = 0;
355 int i;
356
357 for (i = 0; i40e_reg_list[i].offset != 0; i++)
358 reg_count += i40e_reg_list[i].elements;
359
360 return reg_count * sizeof(u32);
361}
362
363static void i40e_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
364 void *p)
365{
366 struct i40e_netdev_priv *np = netdev_priv(netdev);
367 struct i40e_pf *pf = np->vsi->back;
368 struct i40e_hw *hw = &pf->hw;
369 u32 *reg_buf = p;
370 int i, j, ri;
371 u32 reg;
372
373 /* Tell ethtool which driver-version-specific regs output we have.
374 *
375 * At some point, if we have ethtool doing special formatting of
376 * this data, it will rely on this version number to know how to
377 * interpret things. Hence, this needs to be updated if/when the
378 * diags register table is changed.
379 */
380 regs->version = 1;
381
382 /* loop through the diags reg table for what to print */
383 ri = 0;
384 for (i = 0; i40e_reg_list[i].offset != 0; i++) {
385 for (j = 0; j < i40e_reg_list[i].elements; j++) {
386 reg = i40e_reg_list[i].offset
387 + (j * i40e_reg_list[i].stride);
388 reg_buf[ri++] = rd32(hw, reg);
389 }
390 }
391
392}
393
394static int i40e_get_eeprom(struct net_device *netdev,
395 struct ethtool_eeprom *eeprom, u8 *bytes)
396{
397 struct i40e_netdev_priv *np = netdev_priv(netdev);
398 struct i40e_hw *hw = &np->vsi->back->hw;
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000399 struct i40e_pf *pf = np->vsi->back;
400 int ret_val = 0, len;
401 u8 *eeprom_buff;
402 u16 i, sectors;
403 bool last;
404#define I40E_NVM_SECTOR_SIZE 4096
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000405 if (eeprom->len == 0)
406 return -EINVAL;
407
408 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
409
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000410 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000411 if (!eeprom_buff)
412 return -ENOMEM;
413
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000414 ret_val = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
415 if (ret_val) {
416 dev_info(&pf->pdev->dev,
417 "Failed Acquiring NVM resource for read err=%d status=0x%x\n",
418 ret_val, hw->aq.asq_last_status);
419 goto free_buff;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000420 }
421
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000422 sectors = eeprom->len / I40E_NVM_SECTOR_SIZE;
423 sectors += (eeprom->len % I40E_NVM_SECTOR_SIZE) ? 1 : 0;
424 len = I40E_NVM_SECTOR_SIZE;
425 last = false;
426 for (i = 0; i < sectors; i++) {
427 if (i == (sectors - 1)) {
428 len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i);
429 last = true;
430 }
431 ret_val = i40e_aq_read_nvm(hw, 0x0,
432 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
433 len,
Joe Perches3dbb7fd2014-03-25 04:30:38 +0000434 eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000435 last, NULL);
436 if (ret_val) {
437 dev_info(&pf->pdev->dev,
438 "read NVM failed err=%d status=0x%x\n",
439 ret_val, hw->aq.asq_last_status);
440 goto release_nvm;
441 }
442 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000443
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000444release_nvm:
445 i40e_release_nvm(hw);
Joe Perches3dbb7fd2014-03-25 04:30:38 +0000446 memcpy(bytes, eeprom_buff, eeprom->len);
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000447free_buff:
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000448 kfree(eeprom_buff);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000449 return ret_val;
450}
451
452static int i40e_get_eeprom_len(struct net_device *netdev)
453{
454 struct i40e_netdev_priv *np = netdev_priv(netdev);
455 struct i40e_hw *hw = &np->vsi->back->hw;
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000456 u32 val;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000457
Anjali Singhai Jaine5e0a5d2013-11-28 06:39:28 +0000458 val = (rd32(hw, I40E_GLPCI_LBARCTRL)
459 & I40E_GLPCI_LBARCTRL_FL_SIZE_MASK)
460 >> I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT;
461 /* register returns value in power of 2, 64Kbyte chunks. */
462 val = (64 * 1024) * (1 << val);
463 return val;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000464}
465
466static void i40e_get_drvinfo(struct net_device *netdev,
467 struct ethtool_drvinfo *drvinfo)
468{
469 struct i40e_netdev_priv *np = netdev_priv(netdev);
470 struct i40e_vsi *vsi = np->vsi;
471 struct i40e_pf *pf = vsi->back;
472
473 strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
474 strlcpy(drvinfo->version, i40e_driver_version_str,
475 sizeof(drvinfo->version));
476 strlcpy(drvinfo->fw_version, i40e_fw_version_str(&pf->hw),
477 sizeof(drvinfo->fw_version));
478 strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
479 sizeof(drvinfo->bus_info));
480}
481
482static void i40e_get_ringparam(struct net_device *netdev,
483 struct ethtool_ringparam *ring)
484{
485 struct i40e_netdev_priv *np = netdev_priv(netdev);
486 struct i40e_pf *pf = np->vsi->back;
487 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
488
489 ring->rx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
490 ring->tx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
491 ring->rx_mini_max_pending = 0;
492 ring->rx_jumbo_max_pending = 0;
Alexander Duyck9f65e152013-09-28 06:00:58 +0000493 ring->rx_pending = vsi->rx_rings[0]->count;
494 ring->tx_pending = vsi->tx_rings[0]->count;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000495 ring->rx_mini_pending = 0;
496 ring->rx_jumbo_pending = 0;
497}
498
499static int i40e_set_ringparam(struct net_device *netdev,
500 struct ethtool_ringparam *ring)
501{
502 struct i40e_ring *tx_rings = NULL, *rx_rings = NULL;
503 struct i40e_netdev_priv *np = netdev_priv(netdev);
504 struct i40e_vsi *vsi = np->vsi;
505 struct i40e_pf *pf = vsi->back;
506 u32 new_rx_count, new_tx_count;
507 int i, err = 0;
508
509 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
510 return -EINVAL;
511
Shannon Nelson1fa18372013-11-20 10:03:08 +0000512 if (ring->tx_pending > I40E_MAX_NUM_DESCRIPTORS ||
513 ring->tx_pending < I40E_MIN_NUM_DESCRIPTORS ||
514 ring->rx_pending > I40E_MAX_NUM_DESCRIPTORS ||
515 ring->rx_pending < I40E_MIN_NUM_DESCRIPTORS) {
516 netdev_info(netdev,
517 "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n",
518 ring->tx_pending, ring->rx_pending,
519 I40E_MIN_NUM_DESCRIPTORS, I40E_MAX_NUM_DESCRIPTORS);
520 return -EINVAL;
521 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000522
Shannon Nelson1fa18372013-11-20 10:03:08 +0000523 new_tx_count = ALIGN(ring->tx_pending, I40E_REQ_DESCRIPTOR_MULTIPLE);
524 new_rx_count = ALIGN(ring->rx_pending, I40E_REQ_DESCRIPTOR_MULTIPLE);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000525
526 /* if nothing to do return success */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000527 if ((new_tx_count == vsi->tx_rings[0]->count) &&
528 (new_rx_count == vsi->rx_rings[0]->count))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000529 return 0;
530
531 while (test_and_set_bit(__I40E_CONFIG_BUSY, &pf->state))
532 usleep_range(1000, 2000);
533
534 if (!netif_running(vsi->netdev)) {
535 /* simple case - set for the next time the netdev is started */
536 for (i = 0; i < vsi->num_queue_pairs; i++) {
Alexander Duyck9f65e152013-09-28 06:00:58 +0000537 vsi->tx_rings[i]->count = new_tx_count;
538 vsi->rx_rings[i]->count = new_rx_count;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000539 }
540 goto done;
541 }
542
543 /* We can't just free everything and then setup again,
544 * because the ISRs in MSI-X mode get passed pointers
545 * to the Tx and Rx ring structs.
546 */
547
548 /* alloc updated Tx resources */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000549 if (new_tx_count != vsi->tx_rings[0]->count) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000550 netdev_info(netdev,
551 "Changing Tx descriptor count from %d to %d.\n",
Alexander Duyck9f65e152013-09-28 06:00:58 +0000552 vsi->tx_rings[0]->count, new_tx_count);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000553 tx_rings = kcalloc(vsi->alloc_queue_pairs,
554 sizeof(struct i40e_ring), GFP_KERNEL);
555 if (!tx_rings) {
556 err = -ENOMEM;
557 goto done;
558 }
559
560 for (i = 0; i < vsi->num_queue_pairs; i++) {
561 /* clone ring and setup updated count */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000562 tx_rings[i] = *vsi->tx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000563 tx_rings[i].count = new_tx_count;
564 err = i40e_setup_tx_descriptors(&tx_rings[i]);
565 if (err) {
566 while (i) {
567 i--;
568 i40e_free_tx_resources(&tx_rings[i]);
569 }
570 kfree(tx_rings);
571 tx_rings = NULL;
572
573 goto done;
574 }
575 }
576 }
577
578 /* alloc updated Rx resources */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000579 if (new_rx_count != vsi->rx_rings[0]->count) {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000580 netdev_info(netdev,
581 "Changing Rx descriptor count from %d to %d\n",
Alexander Duyck9f65e152013-09-28 06:00:58 +0000582 vsi->rx_rings[0]->count, new_rx_count);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000583 rx_rings = kcalloc(vsi->alloc_queue_pairs,
584 sizeof(struct i40e_ring), GFP_KERNEL);
585 if (!rx_rings) {
586 err = -ENOMEM;
587 goto free_tx;
588 }
589
590 for (i = 0; i < vsi->num_queue_pairs; i++) {
591 /* clone ring and setup updated count */
Alexander Duyck9f65e152013-09-28 06:00:58 +0000592 rx_rings[i] = *vsi->rx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000593 rx_rings[i].count = new_rx_count;
594 err = i40e_setup_rx_descriptors(&rx_rings[i]);
595 if (err) {
596 while (i) {
597 i--;
598 i40e_free_rx_resources(&rx_rings[i]);
599 }
600 kfree(rx_rings);
601 rx_rings = NULL;
602
603 goto free_tx;
604 }
605 }
606 }
607
608 /* Bring interface down, copy in the new ring info,
609 * then restore the interface
610 */
611 i40e_down(vsi);
612
613 if (tx_rings) {
614 for (i = 0; i < vsi->num_queue_pairs; i++) {
Alexander Duyck9f65e152013-09-28 06:00:58 +0000615 i40e_free_tx_resources(vsi->tx_rings[i]);
616 *vsi->tx_rings[i] = tx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000617 }
618 kfree(tx_rings);
619 tx_rings = NULL;
620 }
621
622 if (rx_rings) {
623 for (i = 0; i < vsi->num_queue_pairs; i++) {
Alexander Duyck9f65e152013-09-28 06:00:58 +0000624 i40e_free_rx_resources(vsi->rx_rings[i]);
625 *vsi->rx_rings[i] = rx_rings[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000626 }
627 kfree(rx_rings);
628 rx_rings = NULL;
629 }
630
631 i40e_up(vsi);
632
633free_tx:
634 /* error cleanup if the Rx allocations failed after getting Tx */
635 if (tx_rings) {
636 for (i = 0; i < vsi->num_queue_pairs; i++)
637 i40e_free_tx_resources(&tx_rings[i]);
638 kfree(tx_rings);
639 tx_rings = NULL;
640 }
641
642done:
643 clear_bit(__I40E_CONFIG_BUSY, &pf->state);
644
645 return err;
646}
647
648static int i40e_get_sset_count(struct net_device *netdev, int sset)
649{
650 struct i40e_netdev_priv *np = netdev_priv(netdev);
651 struct i40e_vsi *vsi = np->vsi;
652 struct i40e_pf *pf = vsi->back;
653
654 switch (sset) {
655 case ETH_SS_TEST:
656 return I40E_TEST_LEN;
657 case ETH_SS_STATS:
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000658 if (vsi == pf->vsi[pf->lan_vsi]) {
659 int len = I40E_PF_STATS_LEN(netdev);
660
661 if (pf->lan_veb != I40E_NO_VEB)
662 len += I40E_VEB_STATS_LEN;
663 return len;
664 } else {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000665 return I40E_VSI_STATS_LEN(netdev);
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000666 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000667 default:
668 return -EOPNOTSUPP;
669 }
670}
671
672static void i40e_get_ethtool_stats(struct net_device *netdev,
673 struct ethtool_stats *stats, u64 *data)
674{
675 struct i40e_netdev_priv *np = netdev_priv(netdev);
Akeem G Abodunrine7046ee2014-04-09 05:58:58 +0000676 struct i40e_ring *tx_ring, *rx_ring;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000677 struct i40e_vsi *vsi = np->vsi;
678 struct i40e_pf *pf = vsi->back;
679 int i = 0;
680 char *p;
681 int j;
682 struct rtnl_link_stats64 *net_stats = i40e_get_vsi_stats_struct(vsi);
Alexander Duyck980e9b12013-09-28 06:01:03 +0000683 unsigned int start;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000684
685 i40e_update_stats(vsi);
686
687 for (j = 0; j < I40E_NETDEV_STATS_LEN; j++) {
688 p = (char *)net_stats + i40e_gstrings_net_stats[j].stat_offset;
689 data[i++] = (i40e_gstrings_net_stats[j].sizeof_stat ==
690 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
691 }
Shannon Nelson41a9e552014-04-23 04:50:20 +0000692 for (j = 0; j < I40E_MISC_STATS_LEN; j++) {
693 p = (char *)vsi + i40e_gstrings_misc_stats[j].stat_offset;
694 data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat ==
695 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
696 }
Alexander Duyck980e9b12013-09-28 06:01:03 +0000697 rcu_read_lock();
Catherine Sullivan99c472a2014-03-14 07:32:30 +0000698 for (j = 0; j < vsi->num_queue_pairs; j++) {
Akeem G Abodunrine7046ee2014-04-09 05:58:58 +0000699 tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
Alexander Duyck980e9b12013-09-28 06:01:03 +0000700
701 if (!tx_ring)
702 continue;
703
704 /* process Tx ring statistics */
705 do {
Eric W. Biederman57a77442014-03-13 21:26:42 -0700706 start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
Alexander Duyck980e9b12013-09-28 06:01:03 +0000707 data[i] = tx_ring->stats.packets;
708 data[i + 1] = tx_ring->stats.bytes;
Eric W. Biederman57a77442014-03-13 21:26:42 -0700709 } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
Catherine Sullivan99c472a2014-03-14 07:32:30 +0000710 i += 2;
Alexander Duyck980e9b12013-09-28 06:01:03 +0000711
712 /* Rx ring is the 2nd half of the queue pair */
713 rx_ring = &tx_ring[1];
714 do {
Eric W. Biederman57a77442014-03-13 21:26:42 -0700715 start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
Catherine Sullivan99c472a2014-03-14 07:32:30 +0000716 data[i] = rx_ring->stats.packets;
717 data[i + 1] = rx_ring->stats.bytes;
Eric W. Biederman57a77442014-03-13 21:26:42 -0700718 } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
Catherine Sullivan99c472a2014-03-14 07:32:30 +0000719 i += 2;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000720 }
Alexander Duyck980e9b12013-09-28 06:01:03 +0000721 rcu_read_unlock();
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000722 if (vsi != pf->vsi[pf->lan_vsi])
723 return;
724
725 if (pf->lan_veb != I40E_NO_VEB) {
726 struct i40e_veb *veb = pf->veb[pf->lan_veb];
727 for (j = 0; j < I40E_VEB_STATS_LEN; j++) {
728 p = (char *)veb;
729 p += i40e_gstrings_veb_stats[j].stat_offset;
730 data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat ==
731 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000732 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000733 }
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000734 for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
735 p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
736 data[i++] = (i40e_gstrings_stats[j].sizeof_stat ==
737 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
738 }
739 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
740 data[i++] = pf->stats.priority_xon_tx[j];
741 data[i++] = pf->stats.priority_xoff_tx[j];
742 }
743 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
744 data[i++] = pf->stats.priority_xon_rx[j];
745 data[i++] = pf->stats.priority_xoff_rx[j];
746 }
747 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++)
748 data[i++] = pf->stats.priority_xon_2_xoff[j];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000749}
750
751static void i40e_get_strings(struct net_device *netdev, u32 stringset,
752 u8 *data)
753{
754 struct i40e_netdev_priv *np = netdev_priv(netdev);
755 struct i40e_vsi *vsi = np->vsi;
756 struct i40e_pf *pf = vsi->back;
757 char *p = (char *)data;
758 int i;
759
760 switch (stringset) {
761 case ETH_SS_TEST:
762 for (i = 0; i < I40E_TEST_LEN; i++) {
763 memcpy(data, i40e_gstrings_test[i], ETH_GSTRING_LEN);
764 data += ETH_GSTRING_LEN;
765 }
766 break;
767 case ETH_SS_STATS:
768 for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
769 snprintf(p, ETH_GSTRING_LEN, "%s",
770 i40e_gstrings_net_stats[i].stat_string);
771 p += ETH_GSTRING_LEN;
772 }
Shannon Nelson41a9e552014-04-23 04:50:20 +0000773 for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
774 snprintf(p, ETH_GSTRING_LEN, "%s",
775 i40e_gstrings_misc_stats[i].stat_string);
776 p += ETH_GSTRING_LEN;
777 }
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000778 for (i = 0; i < vsi->num_queue_pairs; i++) {
779 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
780 p += ETH_GSTRING_LEN;
781 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
782 p += ETH_GSTRING_LEN;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000783 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
784 p += ETH_GSTRING_LEN;
785 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
786 p += ETH_GSTRING_LEN;
787 }
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000788 if (vsi != pf->vsi[pf->lan_vsi])
789 return;
790
791 if (pf->lan_veb != I40E_NO_VEB) {
792 for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
793 snprintf(p, ETH_GSTRING_LEN, "veb.%s",
794 i40e_gstrings_veb_stats[i].stat_string);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000795 p += ETH_GSTRING_LEN;
796 }
Shannon Nelson8eab9cf2014-04-23 04:49:55 +0000797 }
798 for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
799 snprintf(p, ETH_GSTRING_LEN, "port.%s",
800 i40e_gstrings_stats[i].stat_string);
801 p += ETH_GSTRING_LEN;
802 }
803 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
804 snprintf(p, ETH_GSTRING_LEN,
805 "port.tx_priority_%u_xon", i);
806 p += ETH_GSTRING_LEN;
807 snprintf(p, ETH_GSTRING_LEN,
808 "port.tx_priority_%u_xoff", i);
809 p += ETH_GSTRING_LEN;
810 }
811 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
812 snprintf(p, ETH_GSTRING_LEN,
813 "port.rx_priority_%u_xon", i);
814 p += ETH_GSTRING_LEN;
815 snprintf(p, ETH_GSTRING_LEN,
816 "port.rx_priority_%u_xoff", i);
817 p += ETH_GSTRING_LEN;
818 }
819 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
820 snprintf(p, ETH_GSTRING_LEN,
821 "port.rx_priority_%u_xon_2_xoff", i);
822 p += ETH_GSTRING_LEN;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000823 }
824 /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
825 break;
826 }
827}
828
829static int i40e_get_ts_info(struct net_device *dev,
830 struct ethtool_ts_info *info)
831{
Jacob Kellerbeb0dff2014-01-11 05:43:19 +0000832 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
833
834 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
835 SOF_TIMESTAMPING_RX_SOFTWARE |
836 SOF_TIMESTAMPING_SOFTWARE |
837 SOF_TIMESTAMPING_TX_HARDWARE |
838 SOF_TIMESTAMPING_RX_HARDWARE |
839 SOF_TIMESTAMPING_RAW_HARDWARE;
840
841 if (pf->ptp_clock)
842 info->phc_index = ptp_clock_index(pf->ptp_clock);
843 else
844 info->phc_index = -1;
845
846 info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
847
848 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
849 (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
850 (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
851 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
852 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
853 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
854 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
855 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
856 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
857 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
858 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
859 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
860
861 return 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000862}
863
Shannon Nelson7b086392013-11-20 10:02:59 +0000864static int i40e_link_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000865{
Shannon Nelson7b086392013-11-20 10:02:59 +0000866 struct i40e_netdev_priv *np = netdev_priv(netdev);
867 struct i40e_pf *pf = np->vsi->back;
868
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000869 netif_info(pf, hw, netdev, "link test\n");
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000870 if (i40e_get_link_status(&pf->hw))
871 *data = 0;
872 else
873 *data = 1;
874
875 return *data;
876}
877
Shannon Nelson7b086392013-11-20 10:02:59 +0000878static int i40e_reg_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000879{
Shannon Nelson7b086392013-11-20 10:02:59 +0000880 struct i40e_netdev_priv *np = netdev_priv(netdev);
881 struct i40e_pf *pf = np->vsi->back;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000882
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000883 netif_info(pf, hw, netdev, "register test\n");
Shannon Nelson7b086392013-11-20 10:02:59 +0000884 *data = i40e_diag_reg_test(&pf->hw);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000885
Shannon Nelson7b086392013-11-20 10:02:59 +0000886 return *data;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000887}
888
Shannon Nelson7b086392013-11-20 10:02:59 +0000889static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000890{
Shannon Nelson7b086392013-11-20 10:02:59 +0000891 struct i40e_netdev_priv *np = netdev_priv(netdev);
892 struct i40e_pf *pf = np->vsi->back;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000893
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000894 netif_info(pf, hw, netdev, "eeprom test\n");
Shannon Nelson7b086392013-11-20 10:02:59 +0000895 *data = i40e_diag_eeprom_test(&pf->hw);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000896
Shannon Nelson7b086392013-11-20 10:02:59 +0000897 return *data;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000898}
899
Shannon Nelson7b086392013-11-20 10:02:59 +0000900static int i40e_intr_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000901{
Shannon Nelson7b086392013-11-20 10:02:59 +0000902 struct i40e_netdev_priv *np = netdev_priv(netdev);
903 struct i40e_pf *pf = np->vsi->back;
Shannon Nelsoncd92e722013-11-16 10:00:44 +0000904 u16 swc_old = pf->sw_int_count;
905
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000906 netif_info(pf, hw, netdev, "interrupt test\n");
Shannon Nelsoncd92e722013-11-16 10:00:44 +0000907 wr32(&pf->hw, I40E_PFINT_DYN_CTL0,
908 (I40E_PFINT_DYN_CTL0_INTENA_MASK |
909 I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK));
910 usleep_range(1000, 2000);
911 *data = (swc_old == pf->sw_int_count);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000912
913 return *data;
914}
915
Shannon Nelson7b086392013-11-20 10:02:59 +0000916static int i40e_loopback_test(struct net_device *netdev, u64 *data)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000917{
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000918 struct i40e_netdev_priv *np = netdev_priv(netdev);
919 struct i40e_pf *pf = np->vsi->back;
920
921 netif_info(pf, hw, netdev, "loopback test not implemented\n");
Shannon Nelsoncd92e722013-11-16 10:00:44 +0000922 *data = 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000923
924 return *data;
925}
926
927static void i40e_diag_test(struct net_device *netdev,
928 struct ethtool_test *eth_test, u64 *data)
929{
930 struct i40e_netdev_priv *np = netdev_priv(netdev);
931 struct i40e_pf *pf = np->vsi->back;
932
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000933 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
934 /* Offline tests */
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000935 netif_info(pf, drv, netdev, "offline testing starting\n");
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000936
Shannon Nelsonf551b432013-11-26 10:49:12 +0000937 set_bit(__I40E_TESTING, &pf->state);
938
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000939 /* Link test performed before hardware reset
940 * so autoneg doesn't interfere with test result
941 */
Shannon Nelson7b086392013-11-20 10:02:59 +0000942 if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000943 eth_test->flags |= ETH_TEST_FL_FAILED;
944
Shannon Nelson7b086392013-11-20 10:02:59 +0000945 if (i40e_eeprom_test(netdev, &data[I40E_ETH_TEST_EEPROM]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000946 eth_test->flags |= ETH_TEST_FL_FAILED;
947
Shannon Nelson7b086392013-11-20 10:02:59 +0000948 if (i40e_intr_test(netdev, &data[I40E_ETH_TEST_INTR]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000949 eth_test->flags |= ETH_TEST_FL_FAILED;
950
Shannon Nelson7b086392013-11-20 10:02:59 +0000951 if (i40e_loopback_test(netdev, &data[I40E_ETH_TEST_LOOPBACK]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000952 eth_test->flags |= ETH_TEST_FL_FAILED;
953
Shannon Nelsonf551b432013-11-26 10:49:12 +0000954 /* run reg test last, a reset is required after it */
955 if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
956 eth_test->flags |= ETH_TEST_FL_FAILED;
957
958 clear_bit(__I40E_TESTING, &pf->state);
959 i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000960 } else {
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000961 /* Online tests */
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000962 netif_info(pf, drv, netdev, "online testing starting\n");
963
Shannon Nelson7b086392013-11-20 10:02:59 +0000964 if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000965 eth_test->flags |= ETH_TEST_FL_FAILED;
966
967 /* Offline only tests, not run in online; pass by default */
968 data[I40E_ETH_TEST_REG] = 0;
969 data[I40E_ETH_TEST_EEPROM] = 0;
970 data[I40E_ETH_TEST_INTR] = 0;
971 data[I40E_ETH_TEST_LOOPBACK] = 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000972 }
Shannon Nelsonc140c172013-11-20 10:02:58 +0000973
Shannon Nelsonb03aaa92013-11-20 10:03:06 +0000974 netif_info(pf, drv, netdev, "testing finished\n");
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +0000975}
976
977static void i40e_get_wol(struct net_device *netdev,
978 struct ethtool_wolinfo *wol)
979{
Shannon Nelson8e2773a2013-11-28 06:39:22 +0000980 struct i40e_netdev_priv *np = netdev_priv(netdev);
981 struct i40e_pf *pf = np->vsi->back;
982 struct i40e_hw *hw = &pf->hw;
983 u16 wol_nvm_bits;
984
985 /* NVM bit on means WoL disabled for the port */
986 i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
987 if ((1 << hw->port) & wol_nvm_bits) {
988 wol->supported = 0;
989 wol->wolopts = 0;
990 } else {
991 wol->supported = WAKE_MAGIC;
992 wol->wolopts = (pf->wol_en ? WAKE_MAGIC : 0);
993 }
994}
995
996static int i40e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
997{
998 struct i40e_netdev_priv *np = netdev_priv(netdev);
999 struct i40e_pf *pf = np->vsi->back;
1000 struct i40e_hw *hw = &pf->hw;
1001 u16 wol_nvm_bits;
1002
1003 /* NVM bit on means WoL disabled for the port */
1004 i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
1005 if (((1 << hw->port) & wol_nvm_bits))
1006 return -EOPNOTSUPP;
1007
1008 /* only magic packet is supported */
1009 if (wol->wolopts && (wol->wolopts != WAKE_MAGIC))
1010 return -EOPNOTSUPP;
1011
1012 /* is this a new value? */
1013 if (pf->wol_en != !!wol->wolopts) {
1014 pf->wol_en = !!wol->wolopts;
1015 device_set_wakeup_enable(&pf->pdev->dev, pf->wol_en);
1016 }
1017
1018 return 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001019}
1020
1021static int i40e_nway_reset(struct net_device *netdev)
1022{
1023 /* restart autonegotiation */
1024 struct i40e_netdev_priv *np = netdev_priv(netdev);
1025 struct i40e_pf *pf = np->vsi->back;
1026 struct i40e_hw *hw = &pf->hw;
1027 i40e_status ret = 0;
1028
1029 ret = i40e_aq_set_link_restart_an(hw, NULL);
1030 if (ret) {
1031 netdev_info(netdev, "link restart failed, aq_err=%d\n",
1032 pf->hw.aq.asq_last_status);
1033 return -EIO;
1034 }
1035
1036 return 0;
1037}
1038
1039static int i40e_set_phys_id(struct net_device *netdev,
1040 enum ethtool_phys_id_state state)
1041{
1042 struct i40e_netdev_priv *np = netdev_priv(netdev);
1043 struct i40e_pf *pf = np->vsi->back;
1044 struct i40e_hw *hw = &pf->hw;
1045 int blink_freq = 2;
1046
1047 switch (state) {
1048 case ETHTOOL_ID_ACTIVE:
1049 pf->led_status = i40e_led_get(hw);
1050 return blink_freq;
1051 case ETHTOOL_ID_ON:
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001052 i40e_led_set(hw, 0xF, false);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001053 break;
1054 case ETHTOOL_ID_OFF:
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001055 i40e_led_set(hw, 0x0, false);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001056 break;
1057 case ETHTOOL_ID_INACTIVE:
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001058 i40e_led_set(hw, pf->led_status, false);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001059 break;
1060 }
1061
1062 return 0;
1063}
1064
1065/* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
1066 * Throttle Rate (ITR) ie. ITR(1) = 2us ITR(10) = 20 us, and also
1067 * 125us (8000 interrupts per second) == ITR(62)
1068 */
1069
1070static int i40e_get_coalesce(struct net_device *netdev,
1071 struct ethtool_coalesce *ec)
1072{
1073 struct i40e_netdev_priv *np = netdev_priv(netdev);
1074 struct i40e_vsi *vsi = np->vsi;
1075
1076 ec->tx_max_coalesced_frames_irq = vsi->work_limit;
1077 ec->rx_max_coalesced_frames_irq = vsi->work_limit;
1078
1079 if (ITR_IS_DYNAMIC(vsi->rx_itr_setting))
Mitch Williams32f5f542014-04-04 04:43:10 +00001080 ec->use_adaptive_rx_coalesce = 1;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001081
1082 if (ITR_IS_DYNAMIC(vsi->tx_itr_setting))
Mitch Williams32f5f542014-04-04 04:43:10 +00001083 ec->use_adaptive_tx_coalesce = 1;
1084
1085 ec->rx_coalesce_usecs = vsi->rx_itr_setting & ~I40E_ITR_DYNAMIC;
1086 ec->tx_coalesce_usecs = vsi->tx_itr_setting & ~I40E_ITR_DYNAMIC;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001087
1088 return 0;
1089}
1090
1091static int i40e_set_coalesce(struct net_device *netdev,
1092 struct ethtool_coalesce *ec)
1093{
1094 struct i40e_netdev_priv *np = netdev_priv(netdev);
1095 struct i40e_q_vector *q_vector;
1096 struct i40e_vsi *vsi = np->vsi;
1097 struct i40e_pf *pf = vsi->back;
1098 struct i40e_hw *hw = &pf->hw;
1099 u16 vector;
1100 int i;
1101
1102 if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
1103 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
1104
Mitch Williams32f5f542014-04-04 04:43:10 +00001105 if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
1106 (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001107 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
Mitch Williams32f5f542014-04-04 04:43:10 +00001108 else
1109 return -EINVAL;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001110
Mitch Williams32f5f542014-04-04 04:43:10 +00001111 if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
1112 (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001113 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
Mitch Williams32f5f542014-04-04 04:43:10 +00001114 else
1115 return -EINVAL;
1116
1117 if (ec->use_adaptive_rx_coalesce)
1118 vsi->rx_itr_setting |= I40E_ITR_DYNAMIC;
1119 else
1120 vsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
1121
1122 if (ec->use_adaptive_tx_coalesce)
1123 vsi->tx_itr_setting |= I40E_ITR_DYNAMIC;
1124 else
1125 vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001126
1127 vector = vsi->base_vector;
Alexander Duyck493fb302013-09-28 07:01:44 +00001128 for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
1129 q_vector = vsi->q_vectors[i];
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001130 q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
1131 wr32(hw, I40E_PFINT_ITRN(0, vector - 1), q_vector->rx.itr);
1132 q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
1133 wr32(hw, I40E_PFINT_ITRN(1, vector - 1), q_vector->tx.itr);
1134 i40e_flush(hw);
1135 }
1136
1137 return 0;
1138}
1139
1140/**
1141 * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
1142 * @pf: pointer to the physical function struct
1143 * @cmd: ethtool rxnfc command
1144 *
1145 * Returns Success if the flow is supported, else Invalid Input.
1146 **/
1147static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
1148{
1149 cmd->data = 0;
1150
1151 /* Report default options for RSS on i40e */
1152 switch (cmd->flow_type) {
1153 case TCP_V4_FLOW:
1154 case UDP_V4_FLOW:
1155 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1156 /* fall through to add IP fields */
1157 case SCTP_V4_FLOW:
1158 case AH_ESP_V4_FLOW:
1159 case AH_V4_FLOW:
1160 case ESP_V4_FLOW:
1161 case IPV4_FLOW:
1162 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1163 break;
1164 case TCP_V6_FLOW:
1165 case UDP_V6_FLOW:
1166 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1167 /* fall through to add IP fields */
1168 case SCTP_V6_FLOW:
1169 case AH_ESP_V6_FLOW:
1170 case AH_V6_FLOW:
1171 case ESP_V6_FLOW:
1172 case IPV6_FLOW:
1173 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1174 break;
1175 default:
1176 return -EINVAL;
1177 }
1178
1179 return 0;
1180}
1181
1182/**
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001183 * i40e_get_ethtool_fdir_all - Populates the rule count of a command
1184 * @pf: Pointer to the physical function struct
1185 * @cmd: The command to get or set Rx flow classification rules
1186 * @rule_locs: Array of used rule locations
1187 *
1188 * This function populates both the total and actual rule count of
1189 * the ethtool flow classification command
1190 *
1191 * Returns 0 on success or -EMSGSIZE if entry not found
1192 **/
1193static int i40e_get_ethtool_fdir_all(struct i40e_pf *pf,
1194 struct ethtool_rxnfc *cmd,
1195 u32 *rule_locs)
1196{
1197 struct i40e_fdir_filter *rule;
1198 struct hlist_node *node2;
1199 int cnt = 0;
1200
1201 /* report total rule count */
Anjali Singhai Jain082def12014-04-09 05:59:00 +00001202 cmd->data = i40e_get_fd_cnt_all(pf);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001203
1204 hlist_for_each_entry_safe(rule, node2,
1205 &pf->fdir_filter_list, fdir_node) {
1206 if (cnt == cmd->rule_cnt)
1207 return -EMSGSIZE;
1208
1209 rule_locs[cnt] = rule->fd_id;
1210 cnt++;
1211 }
1212
1213 cmd->rule_cnt = cnt;
1214
1215 return 0;
1216}
1217
1218/**
1219 * i40e_get_ethtool_fdir_entry - Look up a filter based on Rx flow
1220 * @pf: Pointer to the physical function struct
1221 * @cmd: The command to get or set Rx flow classification rules
1222 *
1223 * This function looks up a filter based on the Rx flow classification
1224 * command and fills the flow spec info for it if found
1225 *
1226 * Returns 0 on success or -EINVAL if filter not found
1227 **/
1228static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
1229 struct ethtool_rxnfc *cmd)
1230{
1231 struct ethtool_rx_flow_spec *fsp =
1232 (struct ethtool_rx_flow_spec *)&cmd->fs;
1233 struct i40e_fdir_filter *rule = NULL;
1234 struct hlist_node *node2;
1235
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001236 hlist_for_each_entry_safe(rule, node2,
1237 &pf->fdir_filter_list, fdir_node) {
1238 if (fsp->location <= rule->fd_id)
1239 break;
1240 }
1241
1242 if (!rule || fsp->location != rule->fd_id)
1243 return -EINVAL;
1244
1245 fsp->flow_type = rule->flow_type;
Anjali Singhai Jain7d54eb22014-03-14 07:32:21 +00001246 if (fsp->flow_type == IP_USER_FLOW) {
1247 fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
1248 fsp->h_u.usr_ip4_spec.proto = 0;
1249 fsp->m_u.usr_ip4_spec.proto = 0;
1250 }
1251
Anjali Singhai Jain04b73bd2014-05-22 06:31:41 +00001252 /* Reverse the src and dest notion, since the HW views them from
1253 * Tx perspective where as the user expects it from Rx filter view.
1254 */
1255 fsp->h_u.tcp_ip4_spec.psrc = rule->dst_port;
1256 fsp->h_u.tcp_ip4_spec.pdst = rule->src_port;
1257 fsp->h_u.tcp_ip4_spec.ip4src = rule->dst_ip[0];
1258 fsp->h_u.tcp_ip4_spec.ip4dst = rule->src_ip[0];
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001259 fsp->ring_cookie = rule->q_index;
1260
1261 return 0;
1262}
1263
1264/**
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001265 * i40e_get_rxnfc - command to get RX flow classification rules
1266 * @netdev: network interface device structure
1267 * @cmd: ethtool rxnfc command
1268 *
1269 * Returns Success if the command is supported.
1270 **/
1271static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
1272 u32 *rule_locs)
1273{
1274 struct i40e_netdev_priv *np = netdev_priv(netdev);
1275 struct i40e_vsi *vsi = np->vsi;
1276 struct i40e_pf *pf = vsi->back;
1277 int ret = -EOPNOTSUPP;
1278
1279 switch (cmd->cmd) {
1280 case ETHTOOL_GRXRINGS:
1281 cmd->data = vsi->alloc_queue_pairs;
1282 ret = 0;
1283 break;
1284 case ETHTOOL_GRXFH:
1285 ret = i40e_get_rss_hash_opts(pf, cmd);
1286 break;
1287 case ETHTOOL_GRXCLSRLCNT:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001288 cmd->rule_cnt = pf->fdir_pf_active_filters;
Anjali Singhai Jain082def12014-04-09 05:59:00 +00001289 /* report total rule count */
1290 cmd->data = i40e_get_fd_cnt_all(pf);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001291 ret = 0;
1292 break;
1293 case ETHTOOL_GRXCLSRULE:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001294 ret = i40e_get_ethtool_fdir_entry(pf, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001295 break;
1296 case ETHTOOL_GRXCLSRLALL:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001297 ret = i40e_get_ethtool_fdir_all(pf, cmd, rule_locs);
1298 break;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001299 default:
1300 break;
1301 }
1302
1303 return ret;
1304}
1305
1306/**
1307 * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
1308 * @pf: pointer to the physical function struct
1309 * @cmd: ethtool rxnfc command
1310 *
1311 * Returns Success if the flow input set is supported.
1312 **/
1313static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
1314{
1315 struct i40e_hw *hw = &pf->hw;
1316 u64 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
1317 ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
1318
1319 /* RSS does not support anything other than hashing
1320 * to queues on src and dst IPs and ports
1321 */
1322 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
1323 RXH_L4_B_0_1 | RXH_L4_B_2_3))
1324 return -EINVAL;
1325
1326 /* We need at least the IP SRC and DEST fields for hashing */
1327 if (!(nfc->data & RXH_IP_SRC) ||
1328 !(nfc->data & RXH_IP_DST))
1329 return -EINVAL;
1330
1331 switch (nfc->flow_type) {
1332 case TCP_V4_FLOW:
1333 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1334 case 0:
1335 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1336 break;
1337 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1338 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1339 break;
1340 default:
1341 return -EINVAL;
1342 }
1343 break;
1344 case TCP_V6_FLOW:
1345 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1346 case 0:
1347 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1348 break;
1349 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1350 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1351 break;
1352 default:
1353 return -EINVAL;
1354 }
1355 break;
1356 case UDP_V4_FLOW:
1357 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1358 case 0:
Kevin Scottb2d36c02014-04-09 05:58:59 +00001359 hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
1360 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001361 break;
1362 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Kevin Scottb2d36c02014-04-09 05:58:59 +00001363 hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
1364 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001365 break;
1366 default:
1367 return -EINVAL;
1368 }
1369 break;
1370 case UDP_V6_FLOW:
1371 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1372 case 0:
Kevin Scottb2d36c02014-04-09 05:58:59 +00001373 hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
1374 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001375 break;
1376 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Kevin Scottb2d36c02014-04-09 05:58:59 +00001377 hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
1378 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001379 break;
1380 default:
1381 return -EINVAL;
1382 }
1383 break;
1384 case AH_ESP_V4_FLOW:
1385 case AH_V4_FLOW:
1386 case ESP_V4_FLOW:
1387 case SCTP_V4_FLOW:
1388 if ((nfc->data & RXH_L4_B_0_1) ||
1389 (nfc->data & RXH_L4_B_2_3))
1390 return -EINVAL;
1391 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
1392 break;
1393 case AH_ESP_V6_FLOW:
1394 case AH_V6_FLOW:
1395 case ESP_V6_FLOW:
1396 case SCTP_V6_FLOW:
1397 if ((nfc->data & RXH_L4_B_0_1) ||
1398 (nfc->data & RXH_L4_B_2_3))
1399 return -EINVAL;
1400 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
1401 break;
1402 case IPV4_FLOW:
1403 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
1404 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4);
1405 break;
1406 case IPV6_FLOW:
1407 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
1408 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
1409 break;
1410 default:
1411 return -EINVAL;
1412 }
1413
1414 wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
1415 wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
1416 i40e_flush(hw);
1417
1418 return 0;
1419}
1420
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001421/**
Anjali Singhai Jain43fddb72014-02-11 08:24:09 +00001422 * i40e_match_fdir_input_set - Match a new filter against an existing one
1423 * @rule: The filter already added
1424 * @input: The new filter to comapre against
1425 *
1426 * Returns true if the two input set match
1427 **/
1428static bool i40e_match_fdir_input_set(struct i40e_fdir_filter *rule,
1429 struct i40e_fdir_filter *input)
1430{
1431 if ((rule->dst_ip[0] != input->dst_ip[0]) ||
1432 (rule->src_ip[0] != input->src_ip[0]) ||
1433 (rule->dst_port != input->dst_port) ||
1434 (rule->src_port != input->src_port))
1435 return false;
1436 return true;
1437}
1438
1439/**
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001440 * i40e_update_ethtool_fdir_entry - Updates the fdir filter entry
1441 * @vsi: Pointer to the targeted VSI
1442 * @input: The filter to update or NULL to indicate deletion
1443 * @sw_idx: Software index to the filter
1444 * @cmd: The command to get or set Rx flow classification rules
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001445 *
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001446 * This function updates (or deletes) a Flow Director entry from
1447 * the hlist of the corresponding PF
1448 *
1449 * Returns 0 on success
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001450 **/
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001451static int i40e_update_ethtool_fdir_entry(struct i40e_vsi *vsi,
1452 struct i40e_fdir_filter *input,
1453 u16 sw_idx,
1454 struct ethtool_rxnfc *cmd)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001455{
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001456 struct i40e_fdir_filter *rule, *parent;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001457 struct i40e_pf *pf = vsi->back;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001458 struct hlist_node *node2;
1459 int err = -EINVAL;
Jesse Brandeburgc35a1d72013-12-18 13:46:02 +00001460
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001461 parent = NULL;
1462 rule = NULL;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001463
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001464 hlist_for_each_entry_safe(rule, node2,
1465 &pf->fdir_filter_list, fdir_node) {
1466 /* hash found, or no matching entry */
1467 if (rule->fd_id >= sw_idx)
1468 break;
1469 parent = rule;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001470 }
1471
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001472 /* if there is an old rule occupying our place remove it */
1473 if (rule && (rule->fd_id == sw_idx)) {
Anjali Singhai Jain43fddb72014-02-11 08:24:09 +00001474 if (input && !i40e_match_fdir_input_set(rule, input))
1475 err = i40e_add_del_fdir(vsi, rule, false);
1476 else if (!input)
1477 err = i40e_add_del_fdir(vsi, rule, false);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001478 hlist_del(&rule->fdir_node);
1479 kfree(rule);
1480 pf->fdir_pf_active_filters--;
1481 }
1482
1483 /* If no input this was a delete, err should be 0 if a rule was
1484 * successfully found and removed from the list else -EINVAL
1485 */
1486 if (!input)
1487 return err;
1488
1489 /* initialize node and set software index */
1490 INIT_HLIST_NODE(&input->fdir_node);
1491
1492 /* add filter to the list */
1493 if (parent)
1494 hlist_add_after(&parent->fdir_node, &input->fdir_node);
1495 else
1496 hlist_add_head(&input->fdir_node,
1497 &pf->fdir_filter_list);
1498
1499 /* update counts */
1500 pf->fdir_pf_active_filters++;
1501
1502 return 0;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001503}
1504
1505/**
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001506 * i40e_del_fdir_entry - Deletes a Flow Director filter entry
1507 * @vsi: Pointer to the targeted VSI
1508 * @cmd: The command to get or set Rx flow classification rules
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001509 *
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001510 * The function removes a Flow Director filter entry from the
1511 * hlist of the corresponding PF
1512 *
1513 * Returns 0 on success
1514 */
1515static int i40e_del_fdir_entry(struct i40e_vsi *vsi,
1516 struct ethtool_rxnfc *cmd)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001517{
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001518 struct ethtool_rx_flow_spec *fsp =
1519 (struct ethtool_rx_flow_spec *)&cmd->fs;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001520 struct i40e_pf *pf = vsi->back;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001521 int ret = 0;
Jesse Brandeburgc35a1d72013-12-18 13:46:02 +00001522
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001523 ret = i40e_update_ethtool_fdir_entry(vsi, NULL, fsp->location, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001524
Anjali Singhai Jain55a5e602014-02-12 06:33:25 +00001525 i40e_fdir_check_and_reenable(pf);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001526 return ret;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001527}
1528
1529/**
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001530 * i40e_add_fdir_ethtool - Add/Remove Flow Director filters
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001531 * @vsi: pointer to the targeted VSI
1532 * @cmd: command to get or set RX flow classification rules
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001533 *
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001534 * Add Flow Director filters for a specific flow spec based on their
1535 * protocol. Returns 0 if the filters were successfully added.
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001536 **/
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001537static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
1538 struct ethtool_rxnfc *cmd)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001539{
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001540 struct ethtool_rx_flow_spec *fsp;
1541 struct i40e_fdir_filter *input;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001542 struct i40e_pf *pf;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001543 int ret = -EINVAL;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001544
1545 if (!vsi)
1546 return -EINVAL;
1547
1548 pf = vsi->back;
1549
Anjali Singhai Jain55a5e602014-02-12 06:33:25 +00001550 if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
1551 return -EOPNOTSUPP;
1552
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001553 if (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)
Anjali Singhai Jain55a5e602014-02-12 06:33:25 +00001554 return -ENOSPC;
1555
1556 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
1557
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001558 if (fsp->location >= (pf->hw.func_caps.fd_filters_best_effort +
1559 pf->hw.func_caps.fd_filters_guaranteed)) {
1560 return -EINVAL;
1561 }
1562
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001563 if (fsp->ring_cookie >= vsi->num_queue_pairs)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001564 return -EINVAL;
1565
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001566 input = kzalloc(sizeof(*input), GFP_KERNEL);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001567
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001568 if (!input)
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001569 return -ENOMEM;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001570
1571 input->fd_id = fsp->location;
1572
Anjali Singhai Jain35a91fd2014-03-06 09:00:00 +00001573 if (fsp->ring_cookie == RX_CLS_FLOW_DISC)
1574 input->dest_ctl = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
1575 else
1576 input->dest_ctl =
1577 I40E_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX;
1578
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001579 input->q_index = fsp->ring_cookie;
1580 input->flex_off = 0;
1581 input->pctype = 0;
1582 input->dest_vsi = vsi->id;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001583 input->fd_status = I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID;
1584 input->cnt_index = 0;
1585 input->flow_type = fsp->flow_type;
1586 input->ip4_proto = fsp->h_u.usr_ip4_spec.proto;
Anjali Singhai Jain04b73bd2014-05-22 06:31:41 +00001587
1588 /* Reverse the src and dest notion, since the HW expects them to be from
1589 * Tx perspective where as the input from user is from Rx filter view.
1590 */
1591 input->dst_port = fsp->h_u.tcp_ip4_spec.psrc;
1592 input->src_port = fsp->h_u.tcp_ip4_spec.pdst;
1593 input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
1594 input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001595
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001596 ret = i40e_add_del_fdir(vsi, input, true);
1597 if (ret)
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001598 kfree(input);
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001599 else
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001600 i40e_update_ethtool_fdir_entry(vsi, input, fsp->location, NULL);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001601
1602 return ret;
1603}
Jesse Brandeburg8fb905b2014-01-17 15:36:33 -08001604
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001605/**
1606 * i40e_set_rxnfc - command to set RX flow classification rules
1607 * @netdev: network interface device structure
1608 * @cmd: ethtool rxnfc command
1609 *
1610 * Returns Success if the command is supported.
1611 **/
1612static int i40e_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
1613{
1614 struct i40e_netdev_priv *np = netdev_priv(netdev);
1615 struct i40e_vsi *vsi = np->vsi;
1616 struct i40e_pf *pf = vsi->back;
1617 int ret = -EOPNOTSUPP;
1618
1619 switch (cmd->cmd) {
1620 case ETHTOOL_SRXFH:
1621 ret = i40e_set_rss_hash_opt(pf, cmd);
1622 break;
1623 case ETHTOOL_SRXCLSRLINS:
Anjali Singhai Jain1eaa3842014-03-06 08:59:59 +00001624 ret = i40e_add_fdir_ethtool(vsi, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001625 break;
1626 case ETHTOOL_SRXCLSRLDEL:
Joseph Gasparakis17a73f62014-02-12 01:45:30 +00001627 ret = i40e_del_fdir_entry(vsi, cmd);
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001628 break;
1629 default:
1630 break;
1631 }
1632
1633 return ret;
1634}
1635
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00001636/**
1637 * i40e_max_channels - get Max number of combined channels supported
1638 * @vsi: vsi pointer
1639 **/
1640static unsigned int i40e_max_channels(struct i40e_vsi *vsi)
1641{
1642 /* TODO: This code assumes DCB and FD is disabled for now. */
1643 return vsi->alloc_queue_pairs;
1644}
1645
1646/**
1647 * i40e_get_channels - Get the current channels enabled and max supported etc.
1648 * @netdev: network interface device structure
1649 * @ch: ethtool channels structure
1650 *
1651 * We don't support separate tx and rx queues as channels. The other count
1652 * represents how many queues are being used for control. max_combined counts
1653 * how many queue pairs we can support. They may not be mapped 1 to 1 with
1654 * q_vectors since we support a lot more queue pairs than q_vectors.
1655 **/
1656static void i40e_get_channels(struct net_device *dev,
1657 struct ethtool_channels *ch)
1658{
1659 struct i40e_netdev_priv *np = netdev_priv(dev);
1660 struct i40e_vsi *vsi = np->vsi;
1661 struct i40e_pf *pf = vsi->back;
1662
1663 /* report maximum channels */
1664 ch->max_combined = i40e_max_channels(vsi);
1665
1666 /* report info for other vector */
Jesse Brandeburg60ea5f82014-01-17 15:36:34 -08001667 ch->other_count = (pf->flags & I40E_FLAG_FD_SB_ENABLED) ? 1 : 0;
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00001668 ch->max_other = ch->other_count;
1669
1670 /* Note: This code assumes DCB is disabled for now. */
1671 ch->combined_count = vsi->num_queue_pairs;
1672}
1673
1674/**
1675 * i40e_set_channels - Set the new channels count.
1676 * @netdev: network interface device structure
1677 * @ch: ethtool channels structure
1678 *
1679 * The new channels count may not be the same as requested by the user
1680 * since it gets rounded down to a power of 2 value.
1681 **/
1682static int i40e_set_channels(struct net_device *dev,
1683 struct ethtool_channels *ch)
1684{
1685 struct i40e_netdev_priv *np = netdev_priv(dev);
1686 unsigned int count = ch->combined_count;
1687 struct i40e_vsi *vsi = np->vsi;
1688 struct i40e_pf *pf = vsi->back;
1689 int new_count;
1690
1691 /* We do not support setting channels for any other VSI at present */
1692 if (vsi->type != I40E_VSI_MAIN)
1693 return -EINVAL;
1694
1695 /* verify they are not requesting separate vectors */
1696 if (!count || ch->rx_count || ch->tx_count)
1697 return -EINVAL;
1698
1699 /* verify other_count has not changed */
Jesse Brandeburg60ea5f82014-01-17 15:36:34 -08001700 if (ch->other_count != ((pf->flags & I40E_FLAG_FD_SB_ENABLED) ? 1 : 0))
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00001701 return -EINVAL;
1702
1703 /* verify the number of channels does not exceed hardware limits */
1704 if (count > i40e_max_channels(vsi))
1705 return -EINVAL;
1706
1707 /* update feature limits from largest to smallest supported values */
1708 /* TODO: Flow director limit, DCB etc */
1709
1710 /* cap RSS limit */
1711 if (count > pf->rss_size_max)
1712 count = pf->rss_size_max;
1713
1714 /* use rss_reconfig to rebuild with new queue count and update traffic
1715 * class queue mapping
1716 */
1717 new_count = i40e_reconfig_rss_queues(pf, count);
Anjali Singhai Jain5f90f422013-12-21 05:44:43 +00001718 if (new_count > 0)
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00001719 return 0;
1720 else
1721 return -EINVAL;
1722}
1723
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001724static const struct ethtool_ops i40e_ethtool_ops = {
1725 .get_settings = i40e_get_settings,
1726 .get_drvinfo = i40e_get_drvinfo,
1727 .get_regs_len = i40e_get_regs_len,
1728 .get_regs = i40e_get_regs,
1729 .nway_reset = i40e_nway_reset,
1730 .get_link = ethtool_op_get_link,
1731 .get_wol = i40e_get_wol,
Shannon Nelson8e2773a2013-11-28 06:39:22 +00001732 .set_wol = i40e_set_wol,
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001733 .get_eeprom_len = i40e_get_eeprom_len,
1734 .get_eeprom = i40e_get_eeprom,
1735 .get_ringparam = i40e_get_ringparam,
1736 .set_ringparam = i40e_set_ringparam,
1737 .get_pauseparam = i40e_get_pauseparam,
1738 .get_msglevel = i40e_get_msglevel,
1739 .set_msglevel = i40e_set_msglevel,
1740 .get_rxnfc = i40e_get_rxnfc,
1741 .set_rxnfc = i40e_set_rxnfc,
1742 .self_test = i40e_diag_test,
1743 .get_strings = i40e_get_strings,
1744 .set_phys_id = i40e_set_phys_id,
1745 .get_sset_count = i40e_get_sset_count,
1746 .get_ethtool_stats = i40e_get_ethtool_stats,
1747 .get_coalesce = i40e_get_coalesce,
1748 .set_coalesce = i40e_set_coalesce,
Anjali Singhai Jain4b7820c2013-11-26 11:59:30 +00001749 .get_channels = i40e_get_channels,
1750 .set_channels = i40e_set_channels,
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001751 .get_ts_info = i40e_get_ts_info,
1752};
1753
1754void i40e_set_ethtool_ops(struct net_device *netdev)
1755{
Wilfried Klaebe7ad24ea2014-05-11 00:12:32 +00001756 netdev->ethtool_ops = &i40e_ethtool_ops;
Jesse Brandeburgc7d05ca2013-09-11 08:39:56 +00001757}