aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2013-09-11 04:39:56 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-09-11 04:50:49 -0400
commitc7d05ca89f8e40d4c80834ef0c097226947d120a (patch)
treed62d90c1eabd7efc2096c1d123df63937cfe6e1c /drivers/net
parentfd0a05ce74efc9aadd3b2e259ae1d16ee7c935c1 (diff)
i40e: driver ethtool core
This patch contains the ethtool interface and implementation. The goal in this patch series is minimal functionality while not including much in the way of "set support." Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Shannon Nelson <shannon.nelson@intel.com> CC: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> CC: e1000-devel@lists.sourceforge.net Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c1449
1 files changed, 1449 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
new file mode 100644
index 000000000000..9a76b8cec76c
--- /dev/null
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -0,0 +1,1449 @@
1/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
4 * Copyright(c) 2013 Intel Corporation.
5 *
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 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * The full GNU General Public License is included in this distribution in
20 * the file called "COPYING".
21 *
22 * Contact Information:
23 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25 *
26 ******************************************************************************/
27
28/* ethtool support for i40e */
29
30#include "i40e.h"
31#include "i40e_diag.h"
32
33struct i40e_stats {
34 char stat_string[ETH_GSTRING_LEN];
35 int sizeof_stat;
36 int stat_offset;
37};
38
39#define I40E_STAT(_type, _name, _stat) { \
40 .stat_string = _name, \
41 .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
42 .stat_offset = offsetof(_type, _stat) \
43}
44#define I40E_NETDEV_STAT(_net_stat) \
45 I40E_STAT(struct net_device_stats, #_net_stat, _net_stat)
46#define I40E_PF_STAT(_name, _stat) \
47 I40E_STAT(struct i40e_pf, _name, _stat)
48#define I40E_VSI_STAT(_name, _stat) \
49 I40E_STAT(struct i40e_vsi, _name, _stat)
50
51static const struct i40e_stats i40e_gstrings_net_stats[] = {
52 I40E_NETDEV_STAT(rx_packets),
53 I40E_NETDEV_STAT(tx_packets),
54 I40E_NETDEV_STAT(rx_bytes),
55 I40E_NETDEV_STAT(tx_bytes),
56 I40E_NETDEV_STAT(rx_errors),
57 I40E_NETDEV_STAT(tx_errors),
58 I40E_NETDEV_STAT(rx_dropped),
59 I40E_NETDEV_STAT(tx_dropped),
60 I40E_NETDEV_STAT(multicast),
61 I40E_NETDEV_STAT(collisions),
62 I40E_NETDEV_STAT(rx_length_errors),
63 I40E_NETDEV_STAT(rx_crc_errors),
64};
65
66/* These PF_STATs might look like duplicates of some NETDEV_STATs,
67 * but they are separate. This device supports Virtualization, and
68 * as such might have several netdevs supporting VMDq and FCoE going
69 * through a single port. The NETDEV_STATs are for individual netdevs
70 * seen at the top of the stack, and the PF_STATs are for the physical
71 * function at the bottom of the stack hosting those netdevs.
72 *
73 * The PF_STATs are appended to the netdev stats only when ethtool -S
74 * is queried on the base PF netdev, not on the VMDq or FCoE netdev.
75 */
76static struct i40e_stats i40e_gstrings_stats[] = {
77 I40E_PF_STAT("rx_bytes", stats.eth.rx_bytes),
78 I40E_PF_STAT("tx_bytes", stats.eth.tx_bytes),
79 I40E_PF_STAT("rx_errors", stats.eth.rx_errors),
80 I40E_PF_STAT("tx_errors", stats.eth.tx_errors),
81 I40E_PF_STAT("rx_dropped", stats.eth.rx_discards),
82 I40E_PF_STAT("tx_dropped", stats.eth.tx_discards),
83 I40E_PF_STAT("tx_dropped_link_down", stats.tx_dropped_link_down),
84 I40E_PF_STAT("crc_errors", stats.crc_errors),
85 I40E_PF_STAT("illegal_bytes", stats.illegal_bytes),
86 I40E_PF_STAT("mac_local_faults", stats.mac_local_faults),
87 I40E_PF_STAT("mac_remote_faults", stats.mac_remote_faults),
88 I40E_PF_STAT("rx_length_errors", stats.rx_length_errors),
89 I40E_PF_STAT("link_xon_rx", stats.link_xon_rx),
90 I40E_PF_STAT("link_xoff_rx", stats.link_xoff_rx),
91 I40E_PF_STAT("link_xon_tx", stats.link_xon_tx),
92 I40E_PF_STAT("link_xoff_tx", stats.link_xoff_tx),
93 I40E_PF_STAT("rx_size_64", stats.rx_size_64),
94 I40E_PF_STAT("rx_size_127", stats.rx_size_127),
95 I40E_PF_STAT("rx_size_255", stats.rx_size_255),
96 I40E_PF_STAT("rx_size_511", stats.rx_size_511),
97 I40E_PF_STAT("rx_size_1023", stats.rx_size_1023),
98 I40E_PF_STAT("rx_size_1522", stats.rx_size_1522),
99 I40E_PF_STAT("rx_size_big", stats.rx_size_big),
100 I40E_PF_STAT("tx_size_64", stats.tx_size_64),
101 I40E_PF_STAT("tx_size_127", stats.tx_size_127),
102 I40E_PF_STAT("tx_size_255", stats.tx_size_255),
103 I40E_PF_STAT("tx_size_511", stats.tx_size_511),
104 I40E_PF_STAT("tx_size_1023", stats.tx_size_1023),
105 I40E_PF_STAT("tx_size_1522", stats.tx_size_1522),
106 I40E_PF_STAT("tx_size_big", stats.tx_size_big),
107 I40E_PF_STAT("rx_undersize", stats.rx_undersize),
108 I40E_PF_STAT("rx_fragments", stats.rx_fragments),
109 I40E_PF_STAT("rx_oversize", stats.rx_oversize),
110 I40E_PF_STAT("rx_jabber", stats.rx_jabber),
111 I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests),
112};
113
114#define I40E_QUEUE_STATS_LEN(n) \
115 ((((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs + \
116 ((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs) * 2)
117#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
118#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
119#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
120 I40E_QUEUE_STATS_LEN((n)))
121#define I40E_PFC_STATS_LEN ( \
122 (FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \
123 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \
124 FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_tx) + \
125 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
126 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
127 / sizeof(u64))
128#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
129 I40E_PFC_STATS_LEN + \
130 I40E_VSI_STATS_LEN((n)))
131
132enum i40e_ethtool_test_id {
133 I40E_ETH_TEST_REG = 0,
134 I40E_ETH_TEST_EEPROM,
135 I40E_ETH_TEST_INTR,
136 I40E_ETH_TEST_LOOPBACK,
137 I40E_ETH_TEST_LINK,
138};
139
140static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
141 "Register test (offline)",
142 "Eeprom test (offline)",
143 "Interrupt test (offline)",
144 "Loopback test (offline)",
145 "Link test (on/offline)"
146};
147
148#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)
149
150/**
151 * i40e_get_settings - Get Link Speed and Duplex settings
152 * @netdev: network interface device structure
153 * @ecmd: ethtool command
154 *
155 * Reports speed/duplex settings based on media_type
156 **/
157static int i40e_get_settings(struct net_device *netdev,
158 struct ethtool_cmd *ecmd)
159{
160 struct i40e_netdev_priv *np = netdev_priv(netdev);
161 struct i40e_pf *pf = np->vsi->back;
162 struct i40e_hw *hw = &pf->hw;
163 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
164 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
165 u32 link_speed = hw_link_info->link_speed;
166
167 /* hardware is either in 40G mode or 10G mode
168 * NOTE: this section initializes supported and advertising
169 */
170 switch (hw_link_info->phy_type) {
171 case I40E_PHY_TYPE_40GBASE_CR4:
172 case I40E_PHY_TYPE_40GBASE_CR4_CU:
173 ecmd->supported = SUPPORTED_40000baseCR4_Full;
174 ecmd->advertising = ADVERTISED_40000baseCR4_Full;
175 break;
176 case I40E_PHY_TYPE_40GBASE_KR4:
177 ecmd->supported = SUPPORTED_40000baseKR4_Full;
178 ecmd->advertising = ADVERTISED_40000baseKR4_Full;
179 break;
180 case I40E_PHY_TYPE_40GBASE_SR4:
181 ecmd->supported = SUPPORTED_40000baseSR4_Full;
182 ecmd->advertising = ADVERTISED_40000baseSR4_Full;
183 break;
184 case I40E_PHY_TYPE_40GBASE_LR4:
185 ecmd->supported = SUPPORTED_40000baseLR4_Full;
186 ecmd->advertising = ADVERTISED_40000baseLR4_Full;
187 break;
188 case I40E_PHY_TYPE_10GBASE_KX4:
189 ecmd->supported = SUPPORTED_10000baseKX4_Full;
190 ecmd->advertising = ADVERTISED_10000baseKX4_Full;
191 break;
192 case I40E_PHY_TYPE_10GBASE_KR:
193 ecmd->supported = SUPPORTED_10000baseKR_Full;
194 ecmd->advertising = ADVERTISED_10000baseKR_Full;
195 break;
196 case I40E_PHY_TYPE_10GBASE_T:
197 default:
198 ecmd->supported = SUPPORTED_10000baseT_Full;
199 ecmd->advertising = ADVERTISED_10000baseT_Full;
200 break;
201 }
202
203 /* for now just say autoneg all the time */
204 ecmd->supported |= SUPPORTED_Autoneg;
205
206 if (hw->phy.media_type == I40E_MEDIA_TYPE_BACKPLANE) {
207 ecmd->supported |= SUPPORTED_Backplane;
208 ecmd->advertising |= ADVERTISED_Backplane;
209 ecmd->port = PORT_NONE;
210 } else if (hw->phy.media_type == I40E_MEDIA_TYPE_BASET) {
211 ecmd->supported |= SUPPORTED_TP;
212 ecmd->advertising |= ADVERTISED_TP;
213 ecmd->port = PORT_TP;
214 } else {
215 ecmd->supported |= SUPPORTED_FIBRE;
216 ecmd->advertising |= ADVERTISED_FIBRE;
217 ecmd->port = PORT_FIBRE;
218 }
219
220 ecmd->transceiver = XCVR_EXTERNAL;
221
222 if (link_up) {
223 switch (link_speed) {
224 case I40E_LINK_SPEED_40GB:
225 /* need a SPEED_40000 in ethtool.h */
226 ethtool_cmd_speed_set(ecmd, 40000);
227 break;
228 case I40E_LINK_SPEED_10GB:
229 ethtool_cmd_speed_set(ecmd, SPEED_10000);
230 break;
231 default:
232 break;
233 }
234 ecmd->duplex = DUPLEX_FULL;
235 } else {
236 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
237 ecmd->duplex = DUPLEX_UNKNOWN;
238 }
239
240 return 0;
241}
242
243/**
244 * i40e_get_pauseparam - Get Flow Control status
245 * Return tx/rx-pause status
246 **/
247static void i40e_get_pauseparam(struct net_device *netdev,
248 struct ethtool_pauseparam *pause)
249{
250 struct i40e_netdev_priv *np = netdev_priv(netdev);
251 struct i40e_pf *pf = np->vsi->back;
252 struct i40e_hw *hw = &pf->hw;
253 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
254
255 pause->autoneg =
256 ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
257 AUTONEG_ENABLE : AUTONEG_DISABLE);
258
259 pause->rx_pause = 0;
260 pause->tx_pause = 0;
261 if (hw_link_info->an_info & I40E_AQ_LINK_PAUSE_RX)
262 pause->rx_pause = 1;
263 if (hw_link_info->an_info & I40E_AQ_LINK_PAUSE_TX)
264 pause->tx_pause = 1;
265}
266
267static u32 i40e_get_msglevel(struct net_device *netdev)
268{
269 struct i40e_netdev_priv *np = netdev_priv(netdev);
270 struct i40e_pf *pf = np->vsi->back;
271
272 return pf->msg_enable;
273}
274
275static void i40e_set_msglevel(struct net_device *netdev, u32 data)
276{
277 struct i40e_netdev_priv *np = netdev_priv(netdev);
278 struct i40e_pf *pf = np->vsi->back;
279
280 if (I40E_DEBUG_USER & data)
281 pf->hw.debug_mask = data;
282 pf->msg_enable = data;
283}
284
285static int i40e_get_regs_len(struct net_device *netdev)
286{
287 int reg_count = 0;
288 int i;
289
290 for (i = 0; i40e_reg_list[i].offset != 0; i++)
291 reg_count += i40e_reg_list[i].elements;
292
293 return reg_count * sizeof(u32);
294}
295
296static void i40e_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
297 void *p)
298{
299 struct i40e_netdev_priv *np = netdev_priv(netdev);
300 struct i40e_pf *pf = np->vsi->back;
301 struct i40e_hw *hw = &pf->hw;
302 u32 *reg_buf = p;
303 int i, j, ri;
304 u32 reg;
305
306 /* Tell ethtool which driver-version-specific regs output we have.
307 *
308 * At some point, if we have ethtool doing special formatting of
309 * this data, it will rely on this version number to know how to
310 * interpret things. Hence, this needs to be updated if/when the
311 * diags register table is changed.
312 */
313 regs->version = 1;
314
315 /* loop through the diags reg table for what to print */
316 ri = 0;
317 for (i = 0; i40e_reg_list[i].offset != 0; i++) {
318 for (j = 0; j < i40e_reg_list[i].elements; j++) {
319 reg = i40e_reg_list[i].offset
320 + (j * i40e_reg_list[i].stride);
321 reg_buf[ri++] = rd32(hw, reg);
322 }
323 }
324
325}
326
327static int i40e_get_eeprom(struct net_device *netdev,
328 struct ethtool_eeprom *eeprom, u8 *bytes)
329{
330 struct i40e_netdev_priv *np = netdev_priv(netdev);
331 struct i40e_hw *hw = &np->vsi->back->hw;
332 int first_word, last_word;
333 u16 i, eeprom_len;
334 u16 *eeprom_buff;
335 int ret_val = 0;
336
337 if (eeprom->len == 0)
338 return -EINVAL;
339
340 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
341
342 first_word = eeprom->offset >> 1;
343 last_word = (eeprom->offset + eeprom->len - 1) >> 1;
344 eeprom_len = last_word - first_word + 1;
345
346 eeprom_buff = kmalloc(sizeof(u16) * eeprom_len, GFP_KERNEL);
347 if (!eeprom_buff)
348 return -ENOMEM;
349
350 ret_val = i40e_read_nvm_buffer(hw, first_word, &eeprom_len,
351 eeprom_buff);
352 if (eeprom_len == 0) {
353 kfree(eeprom_buff);
354 return -EACCES;
355 }
356
357 /* Device's eeprom is always little-endian, word addressable */
358 for (i = 0; i < eeprom_len; i++)
359 le16_to_cpus(&eeprom_buff[i]);
360
361 memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
362 kfree(eeprom_buff);
363
364 return ret_val;
365}
366
367static int i40e_get_eeprom_len(struct net_device *netdev)
368{
369 struct i40e_netdev_priv *np = netdev_priv(netdev);
370 struct i40e_hw *hw = &np->vsi->back->hw;
371
372 return hw->nvm.sr_size * 2;
373}
374
375static void i40e_get_drvinfo(struct net_device *netdev,
376 struct ethtool_drvinfo *drvinfo)
377{
378 struct i40e_netdev_priv *np = netdev_priv(netdev);
379 struct i40e_vsi *vsi = np->vsi;
380 struct i40e_pf *pf = vsi->back;
381
382 strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
383 strlcpy(drvinfo->version, i40e_driver_version_str,
384 sizeof(drvinfo->version));
385 strlcpy(drvinfo->fw_version, i40e_fw_version_str(&pf->hw),
386 sizeof(drvinfo->fw_version));
387 strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
388 sizeof(drvinfo->bus_info));
389}
390
391static void i40e_get_ringparam(struct net_device *netdev,
392 struct ethtool_ringparam *ring)
393{
394 struct i40e_netdev_priv *np = netdev_priv(netdev);
395 struct i40e_pf *pf = np->vsi->back;
396 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
397
398 ring->rx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
399 ring->tx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
400 ring->rx_mini_max_pending = 0;
401 ring->rx_jumbo_max_pending = 0;
402 ring->rx_pending = vsi->rx_rings[0].count;
403 ring->tx_pending = vsi->tx_rings[0].count;
404 ring->rx_mini_pending = 0;
405 ring->rx_jumbo_pending = 0;
406}
407
408static int i40e_set_ringparam(struct net_device *netdev,
409 struct ethtool_ringparam *ring)
410{
411 struct i40e_ring *tx_rings = NULL, *rx_rings = NULL;
412 struct i40e_netdev_priv *np = netdev_priv(netdev);
413 struct i40e_vsi *vsi = np->vsi;
414 struct i40e_pf *pf = vsi->back;
415 u32 new_rx_count, new_tx_count;
416 int i, err = 0;
417
418 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
419 return -EINVAL;
420
421 new_tx_count = clamp_t(u32, ring->tx_pending,
422 I40E_MIN_NUM_DESCRIPTORS,
423 I40E_MAX_NUM_DESCRIPTORS);
424 new_tx_count = ALIGN(new_tx_count, I40E_REQ_DESCRIPTOR_MULTIPLE);
425
426 new_rx_count = clamp_t(u32, ring->rx_pending,
427 I40E_MIN_NUM_DESCRIPTORS,
428 I40E_MAX_NUM_DESCRIPTORS);
429 new_rx_count = ALIGN(new_rx_count, I40E_REQ_DESCRIPTOR_MULTIPLE);
430
431 /* if nothing to do return success */
432 if ((new_tx_count == vsi->tx_rings[0].count) &&
433 (new_rx_count == vsi->rx_rings[0].count))
434 return 0;
435
436 while (test_and_set_bit(__I40E_CONFIG_BUSY, &pf->state))
437 usleep_range(1000, 2000);
438
439 if (!netif_running(vsi->netdev)) {
440 /* simple case - set for the next time the netdev is started */
441 for (i = 0; i < vsi->num_queue_pairs; i++) {
442 vsi->tx_rings[i].count = new_tx_count;
443 vsi->rx_rings[i].count = new_rx_count;
444 }
445 goto done;
446 }
447
448 /* We can't just free everything and then setup again,
449 * because the ISRs in MSI-X mode get passed pointers
450 * to the Tx and Rx ring structs.
451 */
452
453 /* alloc updated Tx resources */
454 if (new_tx_count != vsi->tx_rings[0].count) {
455 netdev_info(netdev,
456 "Changing Tx descriptor count from %d to %d.\n",
457 vsi->tx_rings[0].count, new_tx_count);
458 tx_rings = kcalloc(vsi->alloc_queue_pairs,
459 sizeof(struct i40e_ring), GFP_KERNEL);
460 if (!tx_rings) {
461 err = -ENOMEM;
462 goto done;
463 }
464
465 for (i = 0; i < vsi->num_queue_pairs; i++) {
466 /* clone ring and setup updated count */
467 tx_rings[i] = vsi->tx_rings[i];
468 tx_rings[i].count = new_tx_count;
469 err = i40e_setup_tx_descriptors(&tx_rings[i]);
470 if (err) {
471 while (i) {
472 i--;
473 i40e_free_tx_resources(&tx_rings[i]);
474 }
475 kfree(tx_rings);
476 tx_rings = NULL;
477
478 goto done;
479 }
480 }
481 }
482
483 /* alloc updated Rx resources */
484 if (new_rx_count != vsi->rx_rings[0].count) {
485 netdev_info(netdev,
486 "Changing Rx descriptor count from %d to %d\n",
487 vsi->rx_rings[0].count, new_rx_count);
488 rx_rings = kcalloc(vsi->alloc_queue_pairs,
489 sizeof(struct i40e_ring), GFP_KERNEL);
490 if (!rx_rings) {
491 err = -ENOMEM;
492 goto free_tx;
493 }
494
495 for (i = 0; i < vsi->num_queue_pairs; i++) {
496 /* clone ring and setup updated count */
497 rx_rings[i] = vsi->rx_rings[i];
498 rx_rings[i].count = new_rx_count;
499 err = i40e_setup_rx_descriptors(&rx_rings[i]);
500 if (err) {
501 while (i) {
502 i--;
503 i40e_free_rx_resources(&rx_rings[i]);
504 }
505 kfree(rx_rings);
506 rx_rings = NULL;
507
508 goto free_tx;
509 }
510 }
511 }
512
513 /* Bring interface down, copy in the new ring info,
514 * then restore the interface
515 */
516 i40e_down(vsi);
517
518 if (tx_rings) {
519 for (i = 0; i < vsi->num_queue_pairs; i++) {
520 i40e_free_tx_resources(&vsi->tx_rings[i]);
521 vsi->tx_rings[i] = tx_rings[i];
522 }
523 kfree(tx_rings);
524 tx_rings = NULL;
525 }
526
527 if (rx_rings) {
528 for (i = 0; i < vsi->num_queue_pairs; i++) {
529 i40e_free_rx_resources(&vsi->rx_rings[i]);
530 vsi->rx_rings[i] = rx_rings[i];
531 }
532 kfree(rx_rings);
533 rx_rings = NULL;
534 }
535
536 i40e_up(vsi);
537
538free_tx:
539 /* error cleanup if the Rx allocations failed after getting Tx */
540 if (tx_rings) {
541 for (i = 0; i < vsi->num_queue_pairs; i++)
542 i40e_free_tx_resources(&tx_rings[i]);
543 kfree(tx_rings);
544 tx_rings = NULL;
545 }
546
547done:
548 clear_bit(__I40E_CONFIG_BUSY, &pf->state);
549
550 return err;
551}
552
553static int i40e_get_sset_count(struct net_device *netdev, int sset)
554{
555 struct i40e_netdev_priv *np = netdev_priv(netdev);
556 struct i40e_vsi *vsi = np->vsi;
557 struct i40e_pf *pf = vsi->back;
558
559 switch (sset) {
560 case ETH_SS_TEST:
561 return I40E_TEST_LEN;
562 case ETH_SS_STATS:
563 if (vsi == pf->vsi[pf->lan_vsi])
564 return I40E_PF_STATS_LEN(netdev);
565 else
566 return I40E_VSI_STATS_LEN(netdev);
567 default:
568 return -EOPNOTSUPP;
569 }
570}
571
572static void i40e_get_ethtool_stats(struct net_device *netdev,
573 struct ethtool_stats *stats, u64 *data)
574{
575 struct i40e_netdev_priv *np = netdev_priv(netdev);
576 struct i40e_vsi *vsi = np->vsi;
577 struct i40e_pf *pf = vsi->back;
578 int i = 0;
579 char *p;
580 int j;
581 struct rtnl_link_stats64 *net_stats = i40e_get_vsi_stats_struct(vsi);
582
583 i40e_update_stats(vsi);
584
585 for (j = 0; j < I40E_NETDEV_STATS_LEN; j++) {
586 p = (char *)net_stats + i40e_gstrings_net_stats[j].stat_offset;
587 data[i++] = (i40e_gstrings_net_stats[j].sizeof_stat ==
588 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
589 }
590 for (j = 0; j < vsi->num_queue_pairs; j++) {
591 data[i++] = vsi->tx_rings[j].tx_stats.packets;
592 data[i++] = vsi->tx_rings[j].tx_stats.bytes;
593 }
594 for (j = 0; j < vsi->num_queue_pairs; j++) {
595 data[i++] = vsi->rx_rings[j].rx_stats.packets;
596 data[i++] = vsi->rx_rings[j].rx_stats.bytes;
597 }
598 if (vsi == pf->vsi[pf->lan_vsi]) {
599 for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
600 p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
601 data[i++] = (i40e_gstrings_stats[j].sizeof_stat ==
602 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
603 }
604 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
605 data[i++] = pf->stats.priority_xon_tx[j];
606 data[i++] = pf->stats.priority_xoff_tx[j];
607 }
608 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
609 data[i++] = pf->stats.priority_xon_rx[j];
610 data[i++] = pf->stats.priority_xoff_rx[j];
611 }
612 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++)
613 data[i++] = pf->stats.priority_xon_2_xoff[j];
614 }
615}
616
617static void i40e_get_strings(struct net_device *netdev, u32 stringset,
618 u8 *data)
619{
620 struct i40e_netdev_priv *np = netdev_priv(netdev);
621 struct i40e_vsi *vsi = np->vsi;
622 struct i40e_pf *pf = vsi->back;
623 char *p = (char *)data;
624 int i;
625
626 switch (stringset) {
627 case ETH_SS_TEST:
628 for (i = 0; i < I40E_TEST_LEN; i++) {
629 memcpy(data, i40e_gstrings_test[i], ETH_GSTRING_LEN);
630 data += ETH_GSTRING_LEN;
631 }
632 break;
633 case ETH_SS_STATS:
634 for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
635 snprintf(p, ETH_GSTRING_LEN, "%s",
636 i40e_gstrings_net_stats[i].stat_string);
637 p += ETH_GSTRING_LEN;
638 }
639 for (i = 0; i < vsi->num_queue_pairs; i++) {
640 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
641 p += ETH_GSTRING_LEN;
642 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
643 p += ETH_GSTRING_LEN;
644 }
645 for (i = 0; i < vsi->num_queue_pairs; i++) {
646 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
647 p += ETH_GSTRING_LEN;
648 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
649 p += ETH_GSTRING_LEN;
650 }
651 if (vsi == pf->vsi[pf->lan_vsi]) {
652 for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
653 snprintf(p, ETH_GSTRING_LEN, "port.%s",
654 i40e_gstrings_stats[i].stat_string);
655 p += ETH_GSTRING_LEN;
656 }
657 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
658 snprintf(p, ETH_GSTRING_LEN,
659 "port.tx_priority_%u_xon", i);
660 p += ETH_GSTRING_LEN;
661 snprintf(p, ETH_GSTRING_LEN,
662 "port.tx_priority_%u_xoff", i);
663 p += ETH_GSTRING_LEN;
664 }
665 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
666 snprintf(p, ETH_GSTRING_LEN,
667 "port.rx_priority_%u_xon", i);
668 p += ETH_GSTRING_LEN;
669 snprintf(p, ETH_GSTRING_LEN,
670 "port.rx_priority_%u_xoff", i);
671 p += ETH_GSTRING_LEN;
672 }
673 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
674 snprintf(p, ETH_GSTRING_LEN,
675 "port.rx_priority_%u_xon_2_xoff", i);
676 p += ETH_GSTRING_LEN;
677 }
678 }
679 /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
680 break;
681 }
682}
683
684static int i40e_get_ts_info(struct net_device *dev,
685 struct ethtool_ts_info *info)
686{
687 return ethtool_op_get_ts_info(dev, info);
688}
689
690static int i40e_link_test(struct i40e_pf *pf, u64 *data)
691{
692 if (i40e_get_link_status(&pf->hw))
693 *data = 0;
694 else
695 *data = 1;
696
697 return *data;
698}
699
700static int i40e_reg_test(struct i40e_pf *pf, u64 *data)
701{
702 i40e_status ret;
703
704 ret = i40e_diag_reg_test(&pf->hw);
705 *data = ret;
706
707 return ret;
708}
709
710static int i40e_eeprom_test(struct i40e_pf *pf, u64 *data)
711{
712 i40e_status ret;
713
714 ret = i40e_diag_eeprom_test(&pf->hw);
715 *data = ret;
716
717 return ret;
718}
719
720static int i40e_intr_test(struct i40e_pf *pf, u64 *data)
721{
722 *data = -ENOSYS;
723
724 return *data;
725}
726
727static int i40e_loopback_test(struct i40e_pf *pf, u64 *data)
728{
729 *data = -ENOSYS;
730
731 return *data;
732}
733
734static void i40e_diag_test(struct net_device *netdev,
735 struct ethtool_test *eth_test, u64 *data)
736{
737 struct i40e_netdev_priv *np = netdev_priv(netdev);
738 struct i40e_pf *pf = np->vsi->back;
739
740 set_bit(__I40E_TESTING, &pf->state);
741 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
742 /* Offline tests */
743
744 netdev_info(netdev, "offline testing starting\n");
745
746 /* Link test performed before hardware reset
747 * so autoneg doesn't interfere with test result
748 */
749 netdev_info(netdev, "link test starting\n");
750 if (i40e_link_test(pf, &data[I40E_ETH_TEST_LINK]))
751 eth_test->flags |= ETH_TEST_FL_FAILED;
752
753 netdev_info(netdev, "register test starting\n");
754 if (i40e_reg_test(pf, &data[I40E_ETH_TEST_REG]))
755 eth_test->flags |= ETH_TEST_FL_FAILED;
756
757 i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
758 netdev_info(netdev, "eeprom test starting\n");
759 if (i40e_eeprom_test(pf, &data[I40E_ETH_TEST_EEPROM]))
760 eth_test->flags |= ETH_TEST_FL_FAILED;
761
762 i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
763 netdev_info(netdev, "interrupt test starting\n");
764 if (i40e_intr_test(pf, &data[I40E_ETH_TEST_INTR]))
765 eth_test->flags |= ETH_TEST_FL_FAILED;
766
767 i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
768 netdev_info(netdev, "loopback test starting\n");
769 if (i40e_loopback_test(pf, &data[I40E_ETH_TEST_LOOPBACK]))
770 eth_test->flags |= ETH_TEST_FL_FAILED;
771
772 } else {
773 netdev_info(netdev, "online test starting\n");
774 /* Online tests */
775 if (i40e_link_test(pf, &data[I40E_ETH_TEST_LINK]))
776 eth_test->flags |= ETH_TEST_FL_FAILED;
777
778 /* Offline only tests, not run in online; pass by default */
779 data[I40E_ETH_TEST_REG] = 0;
780 data[I40E_ETH_TEST_EEPROM] = 0;
781 data[I40E_ETH_TEST_INTR] = 0;
782 data[I40E_ETH_TEST_LOOPBACK] = 0;
783
784 clear_bit(__I40E_TESTING, &pf->state);
785 }
786}
787
788static void i40e_get_wol(struct net_device *netdev,
789 struct ethtool_wolinfo *wol)
790{
791 wol->supported = 0;
792 wol->wolopts = 0;
793}
794
795static int i40e_nway_reset(struct net_device *netdev)
796{
797 /* restart autonegotiation */
798 struct i40e_netdev_priv *np = netdev_priv(netdev);
799 struct i40e_pf *pf = np->vsi->back;
800 struct i40e_hw *hw = &pf->hw;
801 i40e_status ret = 0;
802
803 ret = i40e_aq_set_link_restart_an(hw, NULL);
804 if (ret) {
805 netdev_info(netdev, "link restart failed, aq_err=%d\n",
806 pf->hw.aq.asq_last_status);
807 return -EIO;
808 }
809
810 return 0;
811}
812
813static int i40e_set_phys_id(struct net_device *netdev,
814 enum ethtool_phys_id_state state)
815{
816 struct i40e_netdev_priv *np = netdev_priv(netdev);
817 struct i40e_pf *pf = np->vsi->back;
818 struct i40e_hw *hw = &pf->hw;
819 int blink_freq = 2;
820
821 switch (state) {
822 case ETHTOOL_ID_ACTIVE:
823 pf->led_status = i40e_led_get(hw);
824 return blink_freq;
825 case ETHTOOL_ID_ON:
826 i40e_led_set(hw, 0xF);
827 break;
828 case ETHTOOL_ID_OFF:
829 i40e_led_set(hw, 0x0);
830 break;
831 case ETHTOOL_ID_INACTIVE:
832 i40e_led_set(hw, pf->led_status);
833 break;
834 }
835
836 return 0;
837}
838
839/* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
840 * Throttle Rate (ITR) ie. ITR(1) = 2us ITR(10) = 20 us, and also
841 * 125us (8000 interrupts per second) == ITR(62)
842 */
843
844static int i40e_get_coalesce(struct net_device *netdev,
845 struct ethtool_coalesce *ec)
846{
847 struct i40e_netdev_priv *np = netdev_priv(netdev);
848 struct i40e_vsi *vsi = np->vsi;
849
850 ec->tx_max_coalesced_frames_irq = vsi->work_limit;
851 ec->rx_max_coalesced_frames_irq = vsi->work_limit;
852
853 if (ITR_IS_DYNAMIC(vsi->rx_itr_setting))
854 ec->rx_coalesce_usecs = 1;
855 else
856 ec->rx_coalesce_usecs = vsi->rx_itr_setting;
857
858 if (ITR_IS_DYNAMIC(vsi->tx_itr_setting))
859 ec->tx_coalesce_usecs = 1;
860 else
861 ec->tx_coalesce_usecs = vsi->tx_itr_setting;
862
863 return 0;
864}
865
866static int i40e_set_coalesce(struct net_device *netdev,
867 struct ethtool_coalesce *ec)
868{
869 struct i40e_netdev_priv *np = netdev_priv(netdev);
870 struct i40e_q_vector *q_vector;
871 struct i40e_vsi *vsi = np->vsi;
872 struct i40e_pf *pf = vsi->back;
873 struct i40e_hw *hw = &pf->hw;
874 u16 vector;
875 int i;
876
877 if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
878 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
879
880 switch (ec->rx_coalesce_usecs) {
881 case 0:
882 vsi->rx_itr_setting = 0;
883 break;
884 case 1:
885 vsi->rx_itr_setting = (I40E_ITR_DYNAMIC |
886 ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
887 break;
888 default:
889 if ((ec->rx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||
890 (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1)))
891 return -EINVAL;
892 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
893 break;
894 }
895
896 switch (ec->tx_coalesce_usecs) {
897 case 0:
898 vsi->tx_itr_setting = 0;
899 break;
900 case 1:
901 vsi->tx_itr_setting = (I40E_ITR_DYNAMIC |
902 ITR_REG_TO_USEC(I40E_ITR_TX_DEF));
903 break;
904 default:
905 if ((ec->tx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||
906 (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1)))
907 return -EINVAL;
908 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
909 break;
910 }
911
912 vector = vsi->base_vector;
913 q_vector = vsi->q_vectors;
914 for (i = 0; i < vsi->num_q_vectors; i++, vector++, q_vector++) {
915 q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
916 wr32(hw, I40E_PFINT_ITRN(0, vector - 1), q_vector->rx.itr);
917 q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
918 wr32(hw, I40E_PFINT_ITRN(1, vector - 1), q_vector->tx.itr);
919 i40e_flush(hw);
920 }
921
922 return 0;
923}
924
925/**
926 * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
927 * @pf: pointer to the physical function struct
928 * @cmd: ethtool rxnfc command
929 *
930 * Returns Success if the flow is supported, else Invalid Input.
931 **/
932static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
933{
934 cmd->data = 0;
935
936 /* Report default options for RSS on i40e */
937 switch (cmd->flow_type) {
938 case TCP_V4_FLOW:
939 case UDP_V4_FLOW:
940 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
941 /* fall through to add IP fields */
942 case SCTP_V4_FLOW:
943 case AH_ESP_V4_FLOW:
944 case AH_V4_FLOW:
945 case ESP_V4_FLOW:
946 case IPV4_FLOW:
947 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
948 break;
949 case TCP_V6_FLOW:
950 case UDP_V6_FLOW:
951 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
952 /* fall through to add IP fields */
953 case SCTP_V6_FLOW:
954 case AH_ESP_V6_FLOW:
955 case AH_V6_FLOW:
956 case ESP_V6_FLOW:
957 case IPV6_FLOW:
958 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
959 break;
960 default:
961 return -EINVAL;
962 }
963
964 return 0;
965}
966
967/**
968 * i40e_get_rxnfc - command to get RX flow classification rules
969 * @netdev: network interface device structure
970 * @cmd: ethtool rxnfc command
971 *
972 * Returns Success if the command is supported.
973 **/
974static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
975 u32 *rule_locs)
976{
977 struct i40e_netdev_priv *np = netdev_priv(netdev);
978 struct i40e_vsi *vsi = np->vsi;
979 struct i40e_pf *pf = vsi->back;
980 int ret = -EOPNOTSUPP;
981
982 switch (cmd->cmd) {
983 case ETHTOOL_GRXRINGS:
984 cmd->data = vsi->alloc_queue_pairs;
985 ret = 0;
986 break;
987 case ETHTOOL_GRXFH:
988 ret = i40e_get_rss_hash_opts(pf, cmd);
989 break;
990 case ETHTOOL_GRXCLSRLCNT:
991 ret = 0;
992 break;
993 case ETHTOOL_GRXCLSRULE:
994 ret = 0;
995 break;
996 case ETHTOOL_GRXCLSRLALL:
997 cmd->data = 500;
998 ret = 0;
999 default:
1000 break;
1001 }
1002
1003 return ret;
1004}
1005
1006/**
1007 * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
1008 * @pf: pointer to the physical function struct
1009 * @cmd: ethtool rxnfc command
1010 *
1011 * Returns Success if the flow input set is supported.
1012 **/
1013static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
1014{
1015 struct i40e_hw *hw = &pf->hw;
1016 u64 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
1017 ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
1018
1019 /* RSS does not support anything other than hashing
1020 * to queues on src and dst IPs and ports
1021 */
1022 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
1023 RXH_L4_B_0_1 | RXH_L4_B_2_3))
1024 return -EINVAL;
1025
1026 /* We need at least the IP SRC and DEST fields for hashing */
1027 if (!(nfc->data & RXH_IP_SRC) ||
1028 !(nfc->data & RXH_IP_DST))
1029 return -EINVAL;
1030
1031 switch (nfc->flow_type) {
1032 case TCP_V4_FLOW:
1033 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1034 case 0:
1035 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1036 break;
1037 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1038 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1039 break;
1040 default:
1041 return -EINVAL;
1042 }
1043 break;
1044 case TCP_V6_FLOW:
1045 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1046 case 0:
1047 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1048 break;
1049 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1050 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1051 break;
1052 default:
1053 return -EINVAL;
1054 }
1055 break;
1056 case UDP_V4_FLOW:
1057 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1058 case 0:
1059 hena &=
1060 ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
1061 ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) |
1062 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
1063 break;
1064 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1065 hena |=
1066 (((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
1067 ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) |
1068 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
1069 break;
1070 default:
1071 return -EINVAL;
1072 }
1073 break;
1074 case UDP_V6_FLOW:
1075 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1076 case 0:
1077 hena &=
1078 ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
1079 ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) |
1080 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
1081 break;
1082 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1083 hena |=
1084 (((u64)1 << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
1085 ((u64)1 << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP) |
1086 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
1087 break;
1088 default:
1089 return -EINVAL;
1090 }
1091 break;
1092 case AH_ESP_V4_FLOW:
1093 case AH_V4_FLOW:
1094 case ESP_V4_FLOW:
1095 case SCTP_V4_FLOW:
1096 if ((nfc->data & RXH_L4_B_0_1) ||
1097 (nfc->data & RXH_L4_B_2_3))
1098 return -EINVAL;
1099 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
1100 break;
1101 case AH_ESP_V6_FLOW:
1102 case AH_V6_FLOW:
1103 case ESP_V6_FLOW:
1104 case SCTP_V6_FLOW:
1105 if ((nfc->data & RXH_L4_B_0_1) ||
1106 (nfc->data & RXH_L4_B_2_3))
1107 return -EINVAL;
1108 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
1109 break;
1110 case IPV4_FLOW:
1111 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
1112 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4);
1113 break;
1114 case IPV6_FLOW:
1115 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
1116 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
1117 break;
1118 default:
1119 return -EINVAL;
1120 }
1121
1122 wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
1123 wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
1124 i40e_flush(hw);
1125
1126 return 0;
1127}
1128
1129#define IP_HEADER_OFFSET 14
1130/**
1131 * i40e_add_del_fdir_udpv4 - Add/Remove UDPv4 Flow Director filters for
1132 * a specific flow spec
1133 * @vsi: pointer to the targeted VSI
1134 * @fd_data: the flow director data required from the FDir descriptor
1135 * @ethtool_rx_flow_spec: the flow spec
1136 * @add: true adds a filter, false removes it
1137 *
1138 * Returns 0 if the filters were successfully added or removed
1139 **/
1140static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
1141 struct i40e_fdir_data *fd_data,
1142 struct ethtool_rx_flow_spec *fsp, bool add)
1143{
1144 struct i40e_pf *pf = vsi->back;
1145 struct udphdr *udp;
1146 struct iphdr *ip;
1147 bool err = false;
1148 int ret;
1149 int i;
1150
1151 ip = (struct iphdr *)(fd_data->raw_packet + IP_HEADER_OFFSET);
1152 udp = (struct udphdr *)(fd_data->raw_packet + IP_HEADER_OFFSET
1153 + sizeof(struct iphdr));
1154
1155 ip->saddr = fsp->h_u.tcp_ip4_spec.ip4src;
1156 ip->daddr = fsp->h_u.tcp_ip4_spec.ip4dst;
1157 udp->source = fsp->h_u.tcp_ip4_spec.psrc;
1158 udp->dest = fsp->h_u.tcp_ip4_spec.pdst;
1159
1160 for (i = I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP;
1161 i <= I40E_FILTER_PCTYPE_NONF_IPV4_UDP; i++) {
1162 fd_data->pctype = i;
1163 ret = i40e_program_fdir_filter(fd_data, pf, add);
1164
1165 if (ret) {
1166 dev_info(&pf->pdev->dev,
1167 "Filter command send failed for PCTYPE %d (ret = %d)\n",
1168 fd_data->pctype, ret);
1169 err = true;
1170 } else {
1171 dev_info(&pf->pdev->dev,
1172 "Filter OK for PCTYPE %d (ret = %d)\n",
1173 fd_data->pctype, ret);
1174 }
1175 }
1176
1177 return err ? -EOPNOTSUPP : 0;
1178}
1179
1180/**
1181 * i40e_add_del_fdir_tcpv4 - Add/Remove TCPv4 Flow Director filters for
1182 * a specific flow spec
1183 * @vsi: pointer to the targeted VSI
1184 * @fd_data: the flow director data required from the FDir descriptor
1185 * @ethtool_rx_flow_spec: the flow spec
1186 * @add: true adds a filter, false removes it
1187 *
1188 * Returns 0 if the filters were successfully added or removed
1189 **/
1190static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
1191 struct i40e_fdir_data *fd_data,
1192 struct ethtool_rx_flow_spec *fsp, bool add)
1193{
1194 struct i40e_pf *pf = vsi->back;
1195 struct tcphdr *tcp;
1196 struct iphdr *ip;
1197 bool err = false;
1198 int ret;
1199
1200 ip = (struct iphdr *)(fd_data->raw_packet + IP_HEADER_OFFSET);
1201 tcp = (struct tcphdr *)(fd_data->raw_packet + IP_HEADER_OFFSET
1202 + sizeof(struct iphdr));
1203
1204 ip->daddr = fsp->h_u.tcp_ip4_spec.ip4dst;
1205 tcp->dest = fsp->h_u.tcp_ip4_spec.pdst;
1206
1207 fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN;
1208 ret = i40e_program_fdir_filter(fd_data, pf, add);
1209
1210 if (ret) {
1211 dev_info(&pf->pdev->dev,
1212 "Filter command send failed for PCTYPE %d (ret = %d)\n",
1213 fd_data->pctype, ret);
1214 err = true;
1215 } else {
1216 dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d (ret = %d)\n",
1217 fd_data->pctype, ret);
1218 }
1219
1220 ip->saddr = fsp->h_u.tcp_ip4_spec.ip4src;
1221 tcp->source = fsp->h_u.tcp_ip4_spec.psrc;
1222
1223 fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
1224
1225 ret = i40e_program_fdir_filter(fd_data, pf, add);
1226 if (ret) {
1227 dev_info(&pf->pdev->dev,
1228 "Filter command send failed for PCTYPE %d (ret = %d)\n",
1229 fd_data->pctype, ret);
1230 err = true;
1231 } else {
1232 dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d (ret = %d)\n",
1233 fd_data->pctype, ret);
1234 }
1235
1236 return err ? -EOPNOTSUPP : 0;
1237}
1238
1239/**
1240 * i40e_add_del_fdir_sctpv4 - Add/Remove SCTPv4 Flow Director filters for
1241 * a specific flow spec
1242 * @vsi: pointer to the targeted VSI
1243 * @fd_data: the flow director data required from the FDir descriptor
1244 * @ethtool_rx_flow_spec: the flow spec
1245 * @add: true adds a filter, false removes it
1246 *
1247 * Returns 0 if the filters were successfully added or removed
1248 **/
1249static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi,
1250 struct i40e_fdir_data *fd_data,
1251 struct ethtool_rx_flow_spec *fsp, bool add)
1252{
1253 return -EOPNOTSUPP;
1254}
1255
1256/**
1257 * i40e_add_del_fdir_ipv4 - Add/Remove IPv4 Flow Director filters for
1258 * a specific flow spec
1259 * @vsi: pointer to the targeted VSI
1260 * @fd_data: the flow director data required for the FDir descriptor
1261 * @fsp: the ethtool flow spec
1262 * @add: true adds a filter, false removes it
1263 *
1264 * Returns 0 if the filters were successfully added or removed
1265 **/
1266static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi,
1267 struct i40e_fdir_data *fd_data,
1268 struct ethtool_rx_flow_spec *fsp, bool add)
1269{
1270 struct i40e_pf *pf = vsi->back;
1271 struct iphdr *ip;
1272 bool err = false;
1273 int ret;
1274 int i;
1275
1276 ip = (struct iphdr *)(fd_data->raw_packet + IP_HEADER_OFFSET);
1277
1278 ip->saddr = fsp->h_u.usr_ip4_spec.ip4src;
1279 ip->daddr = fsp->h_u.usr_ip4_spec.ip4dst;
1280 ip->protocol = fsp->h_u.usr_ip4_spec.proto;
1281
1282 for (i = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
1283 i <= I40E_FILTER_PCTYPE_FRAG_IPV4; i++) {
1284 fd_data->pctype = i;
1285 ret = i40e_program_fdir_filter(fd_data, pf, add);
1286
1287 if (ret) {
1288 dev_info(&pf->pdev->dev,
1289 "Filter command send failed for PCTYPE %d (ret = %d)\n",
1290 fd_data->pctype, ret);
1291 err = true;
1292 } else {
1293 dev_info(&pf->pdev->dev,
1294 "Filter OK for PCTYPE %d (ret = %d)\n",
1295 fd_data->pctype, ret);
1296 }
1297 }
1298
1299 return err ? -EOPNOTSUPP : 0;
1300}
1301
1302/**
1303 * i40e_add_del_fdir_ethtool - Add/Remove Flow Director filters for
1304 * a specific flow spec based on their protocol
1305 * @vsi: pointer to the targeted VSI
1306 * @cmd: command to get or set RX flow classification rules
1307 * @add: true adds a filter, false removes it
1308 *
1309 * Returns 0 if the filters were successfully added or removed
1310 **/
1311static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
1312 struct ethtool_rxnfc *cmd, bool add)
1313{
1314 struct i40e_fdir_data fd_data;
1315 int ret = -EINVAL;
1316 struct i40e_pf *pf;
1317 struct ethtool_rx_flow_spec *fsp =
1318 (struct ethtool_rx_flow_spec *)&cmd->fs;
1319
1320 if (!vsi)
1321 return -EINVAL;
1322
1323 pf = vsi->back;
1324
1325 if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) &&
1326 (fsp->ring_cookie >= vsi->num_queue_pairs))
1327 return -EINVAL;
1328
1329 /* Populate the Flow Director that we have at the moment
1330 * and allocate the raw packet buffer for the calling functions
1331 */
1332 fd_data.raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_LOOKUP,
1333 GFP_KERNEL);
1334
1335 if (!fd_data.raw_packet) {
1336 dev_info(&pf->pdev->dev, "Could not allocate memory\n");
1337 return -ENOMEM;
1338 }
1339
1340 fd_data.q_index = fsp->ring_cookie;
1341 fd_data.flex_off = 0;
1342 fd_data.pctype = 0;
1343 fd_data.dest_vsi = vsi->id;
1344 fd_data.dest_ctl = 0;
1345 fd_data.fd_status = 0;
1346 fd_data.cnt_index = 0;
1347 fd_data.fd_id = 0;
1348
1349 switch (fsp->flow_type & ~FLOW_EXT) {
1350 case TCP_V4_FLOW:
1351 ret = i40e_add_del_fdir_tcpv4(vsi, &fd_data, fsp, add);
1352 break;
1353 case UDP_V4_FLOW:
1354 ret = i40e_add_del_fdir_udpv4(vsi, &fd_data, fsp, add);
1355 break;
1356 case SCTP_V4_FLOW:
1357 ret = i40e_add_del_fdir_sctpv4(vsi, &fd_data, fsp, add);
1358 break;
1359 case IPV4_FLOW:
1360 ret = i40e_add_del_fdir_ipv4(vsi, &fd_data, fsp, add);
1361 break;
1362 case IP_USER_FLOW:
1363 switch (fsp->h_u.usr_ip4_spec.proto) {
1364 case IPPROTO_TCP:
1365 ret = i40e_add_del_fdir_tcpv4(vsi, &fd_data, fsp, add);
1366 break;
1367 case IPPROTO_UDP:
1368 ret = i40e_add_del_fdir_udpv4(vsi, &fd_data, fsp, add);
1369 break;
1370 case IPPROTO_SCTP:
1371 ret = i40e_add_del_fdir_sctpv4(vsi, &fd_data, fsp, add);
1372 break;
1373 default:
1374 ret = i40e_add_del_fdir_ipv4(vsi, &fd_data, fsp, add);
1375 break;
1376 }
1377 break;
1378 default:
1379 dev_info(&pf->pdev->dev, "Could not specify spec type\n");
1380 ret = -EINVAL;
1381 }
1382
1383 kfree(fd_data.raw_packet);
1384 fd_data.raw_packet = NULL;
1385
1386 return ret;
1387}
1388/**
1389 * i40e_set_rxnfc - command to set RX flow classification rules
1390 * @netdev: network interface device structure
1391 * @cmd: ethtool rxnfc command
1392 *
1393 * Returns Success if the command is supported.
1394 **/
1395static int i40e_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
1396{
1397 struct i40e_netdev_priv *np = netdev_priv(netdev);
1398 struct i40e_vsi *vsi = np->vsi;
1399 struct i40e_pf *pf = vsi->back;
1400 int ret = -EOPNOTSUPP;
1401
1402 switch (cmd->cmd) {
1403 case ETHTOOL_SRXFH:
1404 ret = i40e_set_rss_hash_opt(pf, cmd);
1405 break;
1406 case ETHTOOL_SRXCLSRLINS:
1407 ret = i40e_add_del_fdir_ethtool(vsi, cmd, true);
1408 break;
1409 case ETHTOOL_SRXCLSRLDEL:
1410 ret = i40e_add_del_fdir_ethtool(vsi, cmd, false);
1411 break;
1412 default:
1413 break;
1414 }
1415
1416 return ret;
1417}
1418
1419static const struct ethtool_ops i40e_ethtool_ops = {
1420 .get_settings = i40e_get_settings,
1421 .get_drvinfo = i40e_get_drvinfo,
1422 .get_regs_len = i40e_get_regs_len,
1423 .get_regs = i40e_get_regs,
1424 .nway_reset = i40e_nway_reset,
1425 .get_link = ethtool_op_get_link,
1426 .get_wol = i40e_get_wol,
1427 .get_eeprom_len = i40e_get_eeprom_len,
1428 .get_eeprom = i40e_get_eeprom,
1429 .get_ringparam = i40e_get_ringparam,
1430 .set_ringparam = i40e_set_ringparam,
1431 .get_pauseparam = i40e_get_pauseparam,
1432 .get_msglevel = i40e_get_msglevel,
1433 .set_msglevel = i40e_set_msglevel,
1434 .get_rxnfc = i40e_get_rxnfc,
1435 .set_rxnfc = i40e_set_rxnfc,
1436 .self_test = i40e_diag_test,
1437 .get_strings = i40e_get_strings,
1438 .set_phys_id = i40e_set_phys_id,
1439 .get_sset_count = i40e_get_sset_count,
1440 .get_ethtool_stats = i40e_get_ethtool_stats,
1441 .get_coalesce = i40e_get_coalesce,
1442 .set_coalesce = i40e_set_coalesce,
1443 .get_ts_info = i40e_get_ts_info,
1444};
1445
1446void i40e_set_ethtool_ops(struct net_device *netdev)
1447{
1448 SET_ETHTOOL_OPS(netdev, &i40e_ethtool_ops);
1449}