i40e: Fix firmware API version errors
[deliverable/linux.git] / drivers / net / ethernet / intel / i40e / i40e_ethtool.c
CommitLineData
c7d05ca8
JB
1/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
dc641b73 4 * Copyright(c) 2013 - 2014 Intel Corporation.
c7d05ca8
JB
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 *
dc641b73
GR
15 * 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/>.
c7d05ca8
JB
17 *
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)
8eab9cfd
SN
49#define I40E_VEB_STAT(_name, _stat) \
50 I40E_STAT(struct i40e_veb, _name, _stat)
c7d05ca8
JB
51
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),
c7d05ca8
JB
61 I40E_NETDEV_STAT(collisions),
62 I40E_NETDEV_STAT(rx_length_errors),
63 I40E_NETDEV_STAT(rx_crc_errors),
64};
65
8eab9cfd
SN
66static 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
41a9e55c 81static const struct i40e_stats i40e_gstrings_misc_stats[] = {
418631d4
SN
82 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),
41a9e55c
SN
86 I40E_VSI_STAT("rx_broadcast", eth_stats.rx_broadcast),
87 I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
418631d4 88 I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
41a9e55c
SN
89};
90
1eaa3840
ASJ
91static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
92 struct ethtool_rxnfc *cmd);
17a73f6b 93
c7d05ca8
JB
94/* 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),
532d283d
SN
107 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),
c7d05ca8
JB
113 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),
a47a15f4 121 I40E_PF_STAT("tx_timeout", tx_timeout_count),
8a3c91cc 122 I40E_PF_STAT("rx_csum_bad", hw_csum_rx_error),
c7d05ca8
JB
123 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),
beb0dff1 147 I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
433c47de
ASJ
148 I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match),
149 I40E_PF_STAT("fdir_sb_match", stats.fd_sb_match),
150
bee5af7e
ASJ
151 /* LPI stats */
152 I40E_PF_STAT("tx_lpi_status", stats.tx_lpi_status),
153 I40E_PF_STAT("rx_lpi_status", stats.rx_lpi_status),
154 I40E_PF_STAT("tx_lpi_count", stats.tx_lpi_count),
155 I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
c7d05ca8
JB
156};
157
158#define I40E_QUEUE_STATS_LEN(n) \
31cd840e
SN
159 (((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \
160 * 2 /* Tx and Rx together */ \
161 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
c7d05ca8
JB
162#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
163#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
41a9e55c 164#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
c7d05ca8 165#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
41a9e55c 166 I40E_MISC_STATS_LEN + \
c7d05ca8
JB
167 I40E_QUEUE_STATS_LEN((n)))
168#define I40E_PFC_STATS_LEN ( \
169 (FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \
170 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \
171 FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_tx) + \
172 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
173 FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
174 / sizeof(u64))
8eab9cfd 175#define I40E_VEB_STATS_LEN ARRAY_SIZE(i40e_gstrings_veb_stats)
c7d05ca8
JB
176#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
177 I40E_PFC_STATS_LEN + \
178 I40E_VSI_STATS_LEN((n)))
179
180enum i40e_ethtool_test_id {
181 I40E_ETH_TEST_REG = 0,
182 I40E_ETH_TEST_EEPROM,
183 I40E_ETH_TEST_INTR,
184 I40E_ETH_TEST_LOOPBACK,
185 I40E_ETH_TEST_LINK,
186};
187
188static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
189 "Register test (offline)",
190 "Eeprom test (offline)",
191 "Interrupt test (offline)",
192 "Loopback test (offline)",
193 "Link test (on/offline)"
194};
195
196#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)
197
198/**
199 * i40e_get_settings - Get Link Speed and Duplex settings
200 * @netdev: network interface device structure
201 * @ecmd: ethtool command
202 *
203 * Reports speed/duplex settings based on media_type
204 **/
205static int i40e_get_settings(struct net_device *netdev,
206 struct ethtool_cmd *ecmd)
207{
208 struct i40e_netdev_priv *np = netdev_priv(netdev);
209 struct i40e_pf *pf = np->vsi->back;
210 struct i40e_hw *hw = &pf->hw;
211 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
212 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
213 u32 link_speed = hw_link_info->link_speed;
214
215 /* hardware is either in 40G mode or 10G mode
216 * NOTE: this section initializes supported and advertising
217 */
4e91bcd5
JB
218 if (!link_up) {
219 /* link is down and the driver needs to fall back on
220 * device ID to determine what kinds of info to display,
221 * it's mostly a guess that may change when link is up
222 */
223 switch (hw->device_id) {
224 case I40E_DEV_ID_QSFP_A:
225 case I40E_DEV_ID_QSFP_B:
226 case I40E_DEV_ID_QSFP_C:
227 /* pluggable QSFP */
228 ecmd->supported = SUPPORTED_40000baseSR4_Full |
229 SUPPORTED_40000baseCR4_Full |
230 SUPPORTED_40000baseLR4_Full;
231 ecmd->advertising = ADVERTISED_40000baseSR4_Full |
232 ADVERTISED_40000baseCR4_Full |
233 ADVERTISED_40000baseLR4_Full;
234 break;
235 case I40E_DEV_ID_KX_B:
236 /* backplane 40G */
237 ecmd->supported = SUPPORTED_40000baseKR4_Full;
238 ecmd->advertising = ADVERTISED_40000baseKR4_Full;
239 break;
240 case I40E_DEV_ID_KX_C:
241 /* backplane 10G */
242 ecmd->supported = SUPPORTED_10000baseKR_Full;
243 ecmd->advertising = ADVERTISED_10000baseKR_Full;
244 break;
245 default:
246 /* all the rest are 10G/1G */
247 ecmd->supported = SUPPORTED_10000baseT_Full |
248 SUPPORTED_1000baseT_Full;
249 ecmd->advertising = ADVERTISED_10000baseT_Full |
250 ADVERTISED_1000baseT_Full;
251 break;
252 }
253
254 /* skip phy_type use as it is zero when link is down */
255 goto no_valid_phy_type;
256 }
257
c7d05ca8
JB
258 switch (hw_link_info->phy_type) {
259 case I40E_PHY_TYPE_40GBASE_CR4:
260 case I40E_PHY_TYPE_40GBASE_CR4_CU:
4e91bcd5
JB
261 ecmd->supported = SUPPORTED_Autoneg |
262 SUPPORTED_40000baseCR4_Full;
263 ecmd->advertising = ADVERTISED_Autoneg |
264 ADVERTISED_40000baseCR4_Full;
c7d05ca8
JB
265 break;
266 case I40E_PHY_TYPE_40GBASE_KR4:
4e91bcd5
JB
267 ecmd->supported = SUPPORTED_Autoneg |
268 SUPPORTED_40000baseKR4_Full;
269 ecmd->advertising = ADVERTISED_Autoneg |
270 ADVERTISED_40000baseKR4_Full;
c7d05ca8
JB
271 break;
272 case I40E_PHY_TYPE_40GBASE_SR4:
4e91bcd5
JB
273 case I40E_PHY_TYPE_XLPPI:
274 case I40E_PHY_TYPE_XLAUI:
c7d05ca8 275 ecmd->supported = SUPPORTED_40000baseSR4_Full;
c7d05ca8
JB
276 break;
277 case I40E_PHY_TYPE_40GBASE_LR4:
278 ecmd->supported = SUPPORTED_40000baseLR4_Full;
c7d05ca8
JB
279 break;
280 case I40E_PHY_TYPE_10GBASE_KX4:
4e91bcd5
JB
281 ecmd->supported = SUPPORTED_Autoneg |
282 SUPPORTED_10000baseKX4_Full;
283 ecmd->advertising = ADVERTISED_Autoneg |
284 ADVERTISED_10000baseKX4_Full;
c7d05ca8
JB
285 break;
286 case I40E_PHY_TYPE_10GBASE_KR:
4e91bcd5
JB
287 ecmd->supported = SUPPORTED_Autoneg |
288 SUPPORTED_10000baseKR_Full;
289 ecmd->advertising = ADVERTISED_Autoneg |
290 ADVERTISED_10000baseKR_Full;
c7d05ca8 291 break;
4e91bcd5
JB
292 case I40E_PHY_TYPE_10GBASE_SR:
293 case I40E_PHY_TYPE_10GBASE_LR:
294 ecmd->supported = SUPPORTED_10000baseT_Full;
295 break;
296 case I40E_PHY_TYPE_10GBASE_CR1_CU:
297 case I40E_PHY_TYPE_10GBASE_CR1:
298 case I40E_PHY_TYPE_10GBASE_T:
299 ecmd->supported = SUPPORTED_Autoneg |
300 SUPPORTED_10000baseT_Full;
301 ecmd->advertising = ADVERTISED_Autoneg |
302 ADVERTISED_10000baseT_Full;
303 break;
304 case I40E_PHY_TYPE_XAUI:
305 case I40E_PHY_TYPE_XFI:
306 case I40E_PHY_TYPE_SFI:
307 case I40E_PHY_TYPE_10GBASE_SFPP_CU:
308 ecmd->supported = SUPPORTED_10000baseT_Full;
309 break;
310 case I40E_PHY_TYPE_1000BASE_KX:
311 case I40E_PHY_TYPE_1000BASE_T:
312 ecmd->supported = SUPPORTED_Autoneg |
313 SUPPORTED_1000baseT_Full;
314 ecmd->advertising = ADVERTISED_Autoneg |
315 ADVERTISED_1000baseT_Full;
c7d05ca8 316 break;
4e91bcd5
JB
317 case I40E_PHY_TYPE_100BASE_TX:
318 ecmd->supported = SUPPORTED_Autoneg |
319 SUPPORTED_100baseT_Full;
320 ecmd->advertising = ADVERTISED_Autoneg |
321 ADVERTISED_100baseT_Full;
322 break;
323 case I40E_PHY_TYPE_SGMII:
324 ecmd->supported = SUPPORTED_Autoneg |
325 SUPPORTED_1000baseT_Full |
326 SUPPORTED_100baseT_Full;
327 ecmd->advertising = ADVERTISED_Autoneg |
328 ADVERTISED_1000baseT_Full |
329 ADVERTISED_100baseT_Full;
330 break;
331 default:
332 /* if we got here and link is up something bad is afoot */
333 WARN_ON(link_up);
c7d05ca8
JB
334 }
335
4e91bcd5
JB
336no_valid_phy_type:
337 /* this is if autoneg is enabled or disabled */
c9a3d471
JB
338 ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
339 AUTONEG_ENABLE : AUTONEG_DISABLE);
c7d05ca8 340
c9a3d471
JB
341 switch (hw->phy.media_type) {
342 case I40E_MEDIA_TYPE_BACKPLANE:
4e91bcd5
JB
343 ecmd->supported |= SUPPORTED_Autoneg |
344 SUPPORTED_Backplane;
345 ecmd->advertising |= ADVERTISED_Autoneg |
346 ADVERTISED_Backplane;
c7d05ca8 347 ecmd->port = PORT_NONE;
c9a3d471
JB
348 break;
349 case I40E_MEDIA_TYPE_BASET:
c7d05ca8
JB
350 ecmd->supported |= SUPPORTED_TP;
351 ecmd->advertising |= ADVERTISED_TP;
352 ecmd->port = PORT_TP;
c9a3d471
JB
353 break;
354 case I40E_MEDIA_TYPE_DA:
355 case I40E_MEDIA_TYPE_CX4:
be405eb0
JB
356 ecmd->supported |= SUPPORTED_FIBRE;
357 ecmd->advertising |= ADVERTISED_FIBRE;
358 ecmd->port = PORT_DA;
c9a3d471
JB
359 break;
360 case I40E_MEDIA_TYPE_FIBER:
c7d05ca8 361 ecmd->supported |= SUPPORTED_FIBRE;
c7d05ca8 362 ecmd->port = PORT_FIBRE;
c9a3d471
JB
363 break;
364 case I40E_MEDIA_TYPE_UNKNOWN:
365 default:
366 ecmd->port = PORT_OTHER;
367 break;
c7d05ca8
JB
368 }
369
370 ecmd->transceiver = XCVR_EXTERNAL;
371
4e91bcd5
JB
372 ecmd->supported |= SUPPORTED_Pause;
373
374 switch (hw->fc.current_mode) {
375 case I40E_FC_FULL:
376 ecmd->advertising |= ADVERTISED_Pause;
377 break;
378 case I40E_FC_TX_PAUSE:
379 ecmd->advertising |= ADVERTISED_Asym_Pause;
380 break;
381 case I40E_FC_RX_PAUSE:
382 ecmd->advertising |= (ADVERTISED_Pause |
383 ADVERTISED_Asym_Pause);
384 break;
385 default:
386 ecmd->advertising &= ~(ADVERTISED_Pause |
387 ADVERTISED_Asym_Pause);
388 break;
389 }
390
c7d05ca8
JB
391 if (link_up) {
392 switch (link_speed) {
393 case I40E_LINK_SPEED_40GB:
394 /* need a SPEED_40000 in ethtool.h */
395 ethtool_cmd_speed_set(ecmd, 40000);
396 break;
397 case I40E_LINK_SPEED_10GB:
398 ethtool_cmd_speed_set(ecmd, SPEED_10000);
399 break;
4e91bcd5
JB
400 case I40E_LINK_SPEED_1GB:
401 ethtool_cmd_speed_set(ecmd, SPEED_1000);
402 break;
c7d05ca8
JB
403 default:
404 break;
405 }
406 ecmd->duplex = DUPLEX_FULL;
407 } else {
408 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
409 ecmd->duplex = DUPLEX_UNKNOWN;
410 }
411
412 return 0;
413}
414
bf9c7141
CS
415/**
416 * i40e_set_settings - Set Speed and Duplex
417 * @netdev: network interface device structure
418 * @ecmd: ethtool command
419 *
420 * Set speed/duplex per media_types advertised/forced
421 **/
422static int i40e_set_settings(struct net_device *netdev,
423 struct ethtool_cmd *ecmd)
424{
425 struct i40e_netdev_priv *np = netdev_priv(netdev);
426 struct i40e_aq_get_phy_abilities_resp abilities;
427 struct i40e_aq_set_phy_config config;
428 struct i40e_pf *pf = np->vsi->back;
429 struct i40e_vsi *vsi = np->vsi;
430 struct i40e_hw *hw = &pf->hw;
431 struct ethtool_cmd safe_ecmd;
432 i40e_status status = 0;
433 bool change = false;
434 int err = 0;
435 u8 autoneg;
436 u32 advertise;
437
438 if (vsi != pf->vsi[pf->lan_vsi])
439 return -EOPNOTSUPP;
440
441 if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
442 hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
443 hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE)
444 return -EOPNOTSUPP;
445
446 /* get our own copy of the bits to check against */
447 memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
448 i40e_get_settings(netdev, &safe_ecmd);
449
450 /* save autoneg and speed out of ecmd */
451 autoneg = ecmd->autoneg;
452 advertise = ecmd->advertising;
453
454 /* set autoneg and speed back to what they currently are */
455 ecmd->autoneg = safe_ecmd.autoneg;
456 ecmd->advertising = safe_ecmd.advertising;
457
458 ecmd->cmd = safe_ecmd.cmd;
459 /* If ecmd and safe_ecmd are not the same now, then they are
460 * trying to set something that we do not support
461 */
462 if (memcmp(ecmd, &safe_ecmd, sizeof(struct ethtool_cmd)))
463 return -EOPNOTSUPP;
464
465 while (test_bit(__I40E_CONFIG_BUSY, &vsi->state))
466 usleep_range(1000, 2000);
467
468 /* Get the current phy config */
469 status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
470 NULL);
471 if (status)
472 return -EAGAIN;
473
474 /* Copy link_speed and abilities to config in case they are not
475 * set below
476 */
477 memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
478 config.link_speed = abilities.link_speed;
479 config.abilities = abilities.abilities;
480
481 /* Check autoneg */
482 if (autoneg == AUTONEG_ENABLE) {
483 /* If autoneg is not supported, return error */
484 if (!(safe_ecmd.supported & SUPPORTED_Autoneg)) {
485 netdev_info(netdev, "Autoneg not supported on this phy\n");
486 return -EINVAL;
487 }
488 /* If autoneg was not already enabled */
489 if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
490 config.abilities = abilities.abilities |
491 I40E_AQ_PHY_ENABLE_AN;
492 change = true;
493 }
494 } else {
495 /* If autoneg is supported 10GBASE_T is the only phy that
496 * can disable it, so otherwise return error
497 */
498 if (safe_ecmd.supported & SUPPORTED_Autoneg &&
499 hw->phy.link_info.phy_type != I40E_PHY_TYPE_10GBASE_T) {
500 netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
501 return -EINVAL;
502 }
503 /* If autoneg is currently enabled */
504 if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
505 config.abilities = abilities.abilities |
506 ~I40E_AQ_PHY_ENABLE_AN;
507 change = true;
508 }
509 }
510
511 if (advertise & ~safe_ecmd.supported)
512 return -EINVAL;
513
514 if (advertise & ADVERTISED_100baseT_Full)
515 if (!(abilities.link_speed & I40E_LINK_SPEED_100MB)) {
516 config.link_speed |= I40E_LINK_SPEED_100MB;
517 change = true;
518 }
519 if (advertise & ADVERTISED_1000baseT_Full ||
520 advertise & ADVERTISED_1000baseKX_Full)
521 if (!(abilities.link_speed & I40E_LINK_SPEED_1GB)) {
522 config.link_speed |= I40E_LINK_SPEED_1GB;
523 change = true;
524 }
525 if (advertise & ADVERTISED_10000baseT_Full ||
526 advertise & ADVERTISED_10000baseKX4_Full ||
527 advertise & ADVERTISED_10000baseKR_Full)
528 if (!(abilities.link_speed & I40E_LINK_SPEED_10GB)) {
529 config.link_speed |= I40E_LINK_SPEED_10GB;
530 change = true;
531 }
532 if (advertise & ADVERTISED_40000baseKR4_Full ||
533 advertise & ADVERTISED_40000baseCR4_Full ||
534 advertise & ADVERTISED_40000baseSR4_Full ||
535 advertise & ADVERTISED_40000baseLR4_Full)
536 if (!(abilities.link_speed & I40E_LINK_SPEED_40GB)) {
537 config.link_speed |= I40E_LINK_SPEED_40GB;
538 change = true;
539 }
540
541 if (change) {
542 /* copy over the rest of the abilities */
543 config.phy_type = abilities.phy_type;
544 config.eee_capability = abilities.eee_capability;
545 config.eeer = abilities.eeer_val;
546 config.low_power_ctrl = abilities.d3_lpan;
547
548 /* If link is up set link and an so changes take effect */
549 if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
550 config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
551
552 /* make the aq call */
553 status = i40e_aq_set_phy_config(hw, &config, NULL);
554 if (status) {
555 netdev_info(netdev, "Set phy config failed with error %d.\n",
556 status);
557 return -EAGAIN;
558 }
559
560 status = i40e_update_link_info(hw, true);
561 if (status)
562 netdev_info(netdev, "Updating link info failed with error %d\n",
563 status);
564
565 } else {
566 netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
567 }
568
569 return err;
570}
571
a6599721
JB
572static int i40e_nway_reset(struct net_device *netdev)
573{
574 /* restart autonegotiation */
575 struct i40e_netdev_priv *np = netdev_priv(netdev);
576 struct i40e_pf *pf = np->vsi->back;
577 struct i40e_hw *hw = &pf->hw;
578 bool link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
579 i40e_status ret = 0;
580
581 ret = i40e_aq_set_link_restart_an(hw, link_up, NULL);
582 if (ret) {
583 netdev_info(netdev, "link restart failed, aq_err=%d\n",
584 pf->hw.aq.asq_last_status);
585 return -EIO;
586 }
587
588 return 0;
589}
590
c7d05ca8
JB
591/**
592 * i40e_get_pauseparam - Get Flow Control status
593 * Return tx/rx-pause status
594 **/
595static void i40e_get_pauseparam(struct net_device *netdev,
596 struct ethtool_pauseparam *pause)
597{
598 struct i40e_netdev_priv *np = netdev_priv(netdev);
599 struct i40e_pf *pf = np->vsi->back;
600 struct i40e_hw *hw = &pf->hw;
601 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
602
603 pause->autoneg =
604 ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
605 AUTONEG_ENABLE : AUTONEG_DISABLE);
606
d52c20b7 607 if (hw->fc.current_mode == I40E_FC_RX_PAUSE) {
c7d05ca8 608 pause->rx_pause = 1;
d52c20b7 609 } else if (hw->fc.current_mode == I40E_FC_TX_PAUSE) {
c7d05ca8 610 pause->tx_pause = 1;
d52c20b7
JB
611 } else if (hw->fc.current_mode == I40E_FC_FULL) {
612 pause->rx_pause = 1;
613 pause->tx_pause = 1;
614 }
c7d05ca8
JB
615}
616
2becc35a
CS
617/**
618 * i40e_set_pauseparam - Set Flow Control parameter
619 * @netdev: network interface device structure
620 * @pause: return tx/rx flow control status
621 **/
622static int i40e_set_pauseparam(struct net_device *netdev,
623 struct ethtool_pauseparam *pause)
624{
625 struct i40e_netdev_priv *np = netdev_priv(netdev);
626 struct i40e_pf *pf = np->vsi->back;
627 struct i40e_vsi *vsi = np->vsi;
628 struct i40e_hw *hw = &pf->hw;
629 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
630 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
631 i40e_status status;
632 u8 aq_failures;
633 int err;
634
635 if (vsi != pf->vsi[pf->lan_vsi])
636 return -EOPNOTSUPP;
637
638 if (pause->autoneg != ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
639 AUTONEG_ENABLE : AUTONEG_DISABLE)) {
640 netdev_info(netdev, "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
641 return -EOPNOTSUPP;
642 }
643
644 /* If we have link and don't have autoneg */
645 if (!test_bit(__I40E_DOWN, &pf->state) &&
646 !(hw_link_info->an_info & I40E_AQ_AN_COMPLETED)) {
647 /* Send message that it might not necessarily work*/
648 netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n");
649 }
650
651 if (hw->fc.current_mode == I40E_FC_PFC) {
652 netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n");
653 return -EOPNOTSUPP;
654 }
655
656 if (pause->rx_pause && pause->tx_pause)
657 hw->fc.requested_mode = I40E_FC_FULL;
658 else if (pause->rx_pause && !pause->tx_pause)
659 hw->fc.requested_mode = I40E_FC_RX_PAUSE;
660 else if (!pause->rx_pause && pause->tx_pause)
661 hw->fc.requested_mode = I40E_FC_TX_PAUSE;
662 else if (!pause->rx_pause && !pause->tx_pause)
663 hw->fc.requested_mode = I40E_FC_NONE;
664 else
665 return -EINVAL;
666
667 /* Set the fc mode and only restart an if link is up*/
668 status = i40e_set_fc(hw, &aq_failures, link_up);
669
670 if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) {
671 netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with error %d and status %d\n",
672 status, hw->aq.asq_last_status);
673 err = -EAGAIN;
674 }
675 if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) {
676 netdev_info(netdev, "Set fc failed on the set_phy_config call with error %d and status %d\n",
677 status, hw->aq.asq_last_status);
678 err = -EAGAIN;
679 }
680 if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) {
681 netdev_info(netdev, "Set fc failed on the update_link_info call with error %d and status %d\n",
682 status, hw->aq.asq_last_status);
683 err = -EAGAIN;
684 }
685
686 if (!test_bit(__I40E_DOWN, &pf->state))
687 return i40e_nway_reset(netdev);
688
689 return err;
690}
691
c7d05ca8
JB
692static u32 i40e_get_msglevel(struct net_device *netdev)
693{
694 struct i40e_netdev_priv *np = netdev_priv(netdev);
695 struct i40e_pf *pf = np->vsi->back;
696
697 return pf->msg_enable;
698}
699
700static void i40e_set_msglevel(struct net_device *netdev, u32 data)
701{
702 struct i40e_netdev_priv *np = netdev_priv(netdev);
703 struct i40e_pf *pf = np->vsi->back;
704
705 if (I40E_DEBUG_USER & data)
706 pf->hw.debug_mask = data;
707 pf->msg_enable = data;
708}
709
710static int i40e_get_regs_len(struct net_device *netdev)
711{
712 int reg_count = 0;
713 int i;
714
715 for (i = 0; i40e_reg_list[i].offset != 0; i++)
716 reg_count += i40e_reg_list[i].elements;
717
718 return reg_count * sizeof(u32);
719}
720
721static void i40e_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
722 void *p)
723{
724 struct i40e_netdev_priv *np = netdev_priv(netdev);
725 struct i40e_pf *pf = np->vsi->back;
726 struct i40e_hw *hw = &pf->hw;
727 u32 *reg_buf = p;
728 int i, j, ri;
729 u32 reg;
730
731 /* Tell ethtool which driver-version-specific regs output we have.
732 *
733 * At some point, if we have ethtool doing special formatting of
734 * this data, it will rely on this version number to know how to
735 * interpret things. Hence, this needs to be updated if/when the
736 * diags register table is changed.
737 */
738 regs->version = 1;
739
740 /* loop through the diags reg table for what to print */
741 ri = 0;
742 for (i = 0; i40e_reg_list[i].offset != 0; i++) {
743 for (j = 0; j < i40e_reg_list[i].elements; j++) {
744 reg = i40e_reg_list[i].offset
745 + (j * i40e_reg_list[i].stride);
746 reg_buf[ri++] = rd32(hw, reg);
747 }
748 }
749
750}
751
752static int i40e_get_eeprom(struct net_device *netdev,
753 struct ethtool_eeprom *eeprom, u8 *bytes)
754{
755 struct i40e_netdev_priv *np = netdev_priv(netdev);
756 struct i40e_hw *hw = &np->vsi->back->hw;
e5e0a5db
ASJ
757 struct i40e_pf *pf = np->vsi->back;
758 int ret_val = 0, len;
759 u8 *eeprom_buff;
760 u16 i, sectors;
761 bool last;
cd552cb4
SN
762 u32 magic;
763
e5e0a5db 764#define I40E_NVM_SECTOR_SIZE 4096
c7d05ca8
JB
765 if (eeprom->len == 0)
766 return -EINVAL;
767
cd552cb4
SN
768 /* check for NVMUpdate access method */
769 magic = hw->vendor_id | (hw->device_id << 16);
770 if (eeprom->magic && eeprom->magic != magic) {
771 int errno;
772
773 /* make sure it is the right magic for NVMUpdate */
774 if ((eeprom->magic >> 16) != hw->device_id)
775 return -EINVAL;
776
777 ret_val = i40e_nvmupd_command(hw,
778 (struct i40e_nvm_access *)eeprom,
779 bytes, &errno);
780 if (ret_val)
781 dev_info(&pf->pdev->dev,
782 "NVMUpdate read failed err=%d status=0x%x\n",
783 ret_val, hw->aq.asq_last_status);
784
785 return errno;
786 }
787
788 /* normal ethtool get_eeprom support */
c7d05ca8
JB
789 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
790
e5e0a5db 791 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
c7d05ca8
JB
792 if (!eeprom_buff)
793 return -ENOMEM;
794
e5e0a5db
ASJ
795 ret_val = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
796 if (ret_val) {
797 dev_info(&pf->pdev->dev,
798 "Failed Acquiring NVM resource for read err=%d status=0x%x\n",
799 ret_val, hw->aq.asq_last_status);
800 goto free_buff;
c7d05ca8
JB
801 }
802
e5e0a5db
ASJ
803 sectors = eeprom->len / I40E_NVM_SECTOR_SIZE;
804 sectors += (eeprom->len % I40E_NVM_SECTOR_SIZE) ? 1 : 0;
805 len = I40E_NVM_SECTOR_SIZE;
806 last = false;
807 for (i = 0; i < sectors; i++) {
808 if (i == (sectors - 1)) {
809 len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i);
810 last = true;
811 }
812 ret_val = i40e_aq_read_nvm(hw, 0x0,
813 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
814 len,
cd552cb4 815 (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
e5e0a5db
ASJ
816 last, NULL);
817 if (ret_val) {
818 dev_info(&pf->pdev->dev,
819 "read NVM failed err=%d status=0x%x\n",
820 ret_val, hw->aq.asq_last_status);
821 goto release_nvm;
822 }
823 }
c7d05ca8 824
e5e0a5db
ASJ
825release_nvm:
826 i40e_release_nvm(hw);
cd552cb4 827 memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
e5e0a5db 828free_buff:
c7d05ca8 829 kfree(eeprom_buff);
c7d05ca8
JB
830 return ret_val;
831}
832
833static int i40e_get_eeprom_len(struct net_device *netdev)
834{
835 struct i40e_netdev_priv *np = netdev_priv(netdev);
836 struct i40e_hw *hw = &np->vsi->back->hw;
e5e0a5db
ASJ
837 u32 val;
838
839 val = (rd32(hw, I40E_GLPCI_LBARCTRL)
840 & I40E_GLPCI_LBARCTRL_FL_SIZE_MASK)
841 >> I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT;
842 /* register returns value in power of 2, 64Kbyte chunks. */
843 val = (64 * 1024) * (1 << val);
844 return val;
c7d05ca8
JB
845}
846
cd552cb4
SN
847static int i40e_set_eeprom(struct net_device *netdev,
848 struct ethtool_eeprom *eeprom, u8 *bytes)
849{
850 struct i40e_netdev_priv *np = netdev_priv(netdev);
851 struct i40e_hw *hw = &np->vsi->back->hw;
852 struct i40e_pf *pf = np->vsi->back;
853 int ret_val = 0;
854 int errno;
855 u32 magic;
856
857 /* normal ethtool set_eeprom is not supported */
858 magic = hw->vendor_id | (hw->device_id << 16);
859 if (eeprom->magic == magic)
860 return -EOPNOTSUPP;
861
862 /* check for NVMUpdate access method */
863 if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
864 return -EINVAL;
865
866 if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
867 test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
868 return -EBUSY;
869
870 ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom,
871 bytes, &errno);
872 if (ret_val)
873 dev_info(&pf->pdev->dev,
874 "NVMUpdate write failed err=%d status=0x%x\n",
875 ret_val, hw->aq.asq_last_status);
876
877 return errno;
878}
879
c7d05ca8
JB
880static void i40e_get_drvinfo(struct net_device *netdev,
881 struct ethtool_drvinfo *drvinfo)
882{
883 struct i40e_netdev_priv *np = netdev_priv(netdev);
884 struct i40e_vsi *vsi = np->vsi;
885 struct i40e_pf *pf = vsi->back;
886
887 strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
888 strlcpy(drvinfo->version, i40e_driver_version_str,
889 sizeof(drvinfo->version));
890 strlcpy(drvinfo->fw_version, i40e_fw_version_str(&pf->hw),
891 sizeof(drvinfo->fw_version));
892 strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
893 sizeof(drvinfo->bus_info));
894}
895
896static void i40e_get_ringparam(struct net_device *netdev,
897 struct ethtool_ringparam *ring)
898{
899 struct i40e_netdev_priv *np = netdev_priv(netdev);
900 struct i40e_pf *pf = np->vsi->back;
901 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
902
903 ring->rx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
904 ring->tx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
905 ring->rx_mini_max_pending = 0;
906 ring->rx_jumbo_max_pending = 0;
9f65e15b
AD
907 ring->rx_pending = vsi->rx_rings[0]->count;
908 ring->tx_pending = vsi->tx_rings[0]->count;
c7d05ca8
JB
909 ring->rx_mini_pending = 0;
910 ring->rx_jumbo_pending = 0;
911}
912
913static int i40e_set_ringparam(struct net_device *netdev,
914 struct ethtool_ringparam *ring)
915{
916 struct i40e_ring *tx_rings = NULL, *rx_rings = NULL;
917 struct i40e_netdev_priv *np = netdev_priv(netdev);
918 struct i40e_vsi *vsi = np->vsi;
919 struct i40e_pf *pf = vsi->back;
920 u32 new_rx_count, new_tx_count;
921 int i, err = 0;
922
923 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
924 return -EINVAL;
925
1fa18370
SN
926 if (ring->tx_pending > I40E_MAX_NUM_DESCRIPTORS ||
927 ring->tx_pending < I40E_MIN_NUM_DESCRIPTORS ||
928 ring->rx_pending > I40E_MAX_NUM_DESCRIPTORS ||
929 ring->rx_pending < I40E_MIN_NUM_DESCRIPTORS) {
930 netdev_info(netdev,
931 "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n",
932 ring->tx_pending, ring->rx_pending,
933 I40E_MIN_NUM_DESCRIPTORS, I40E_MAX_NUM_DESCRIPTORS);
934 return -EINVAL;
935 }
936
937 new_tx_count = ALIGN(ring->tx_pending, I40E_REQ_DESCRIPTOR_MULTIPLE);
938 new_rx_count = ALIGN(ring->rx_pending, I40E_REQ_DESCRIPTOR_MULTIPLE);
c7d05ca8
JB
939
940 /* if nothing to do return success */
9f65e15b
AD
941 if ((new_tx_count == vsi->tx_rings[0]->count) &&
942 (new_rx_count == vsi->rx_rings[0]->count))
c7d05ca8
JB
943 return 0;
944
945 while (test_and_set_bit(__I40E_CONFIG_BUSY, &pf->state))
946 usleep_range(1000, 2000);
947
948 if (!netif_running(vsi->netdev)) {
949 /* simple case - set for the next time the netdev is started */
950 for (i = 0; i < vsi->num_queue_pairs; i++) {
9f65e15b
AD
951 vsi->tx_rings[i]->count = new_tx_count;
952 vsi->rx_rings[i]->count = new_rx_count;
c7d05ca8
JB
953 }
954 goto done;
955 }
956
957 /* We can't just free everything and then setup again,
958 * because the ISRs in MSI-X mode get passed pointers
959 * to the Tx and Rx ring structs.
960 */
961
962 /* alloc updated Tx resources */
9f65e15b 963 if (new_tx_count != vsi->tx_rings[0]->count) {
c7d05ca8
JB
964 netdev_info(netdev,
965 "Changing Tx descriptor count from %d to %d.\n",
9f65e15b 966 vsi->tx_rings[0]->count, new_tx_count);
c7d05ca8
JB
967 tx_rings = kcalloc(vsi->alloc_queue_pairs,
968 sizeof(struct i40e_ring), GFP_KERNEL);
969 if (!tx_rings) {
970 err = -ENOMEM;
971 goto done;
972 }
973
974 for (i = 0; i < vsi->num_queue_pairs; i++) {
975 /* clone ring and setup updated count */
9f65e15b 976 tx_rings[i] = *vsi->tx_rings[i];
c7d05ca8
JB
977 tx_rings[i].count = new_tx_count;
978 err = i40e_setup_tx_descriptors(&tx_rings[i]);
979 if (err) {
980 while (i) {
981 i--;
982 i40e_free_tx_resources(&tx_rings[i]);
983 }
984 kfree(tx_rings);
985 tx_rings = NULL;
986
987 goto done;
988 }
989 }
990 }
991
992 /* alloc updated Rx resources */
9f65e15b 993 if (new_rx_count != vsi->rx_rings[0]->count) {
c7d05ca8
JB
994 netdev_info(netdev,
995 "Changing Rx descriptor count from %d to %d\n",
9f65e15b 996 vsi->rx_rings[0]->count, new_rx_count);
c7d05ca8
JB
997 rx_rings = kcalloc(vsi->alloc_queue_pairs,
998 sizeof(struct i40e_ring), GFP_KERNEL);
999 if (!rx_rings) {
1000 err = -ENOMEM;
1001 goto free_tx;
1002 }
1003
1004 for (i = 0; i < vsi->num_queue_pairs; i++) {
1005 /* clone ring and setup updated count */
9f65e15b 1006 rx_rings[i] = *vsi->rx_rings[i];
c7d05ca8
JB
1007 rx_rings[i].count = new_rx_count;
1008 err = i40e_setup_rx_descriptors(&rx_rings[i]);
1009 if (err) {
1010 while (i) {
1011 i--;
1012 i40e_free_rx_resources(&rx_rings[i]);
1013 }
1014 kfree(rx_rings);
1015 rx_rings = NULL;
1016
1017 goto free_tx;
1018 }
1019 }
1020 }
1021
1022 /* Bring interface down, copy in the new ring info,
1023 * then restore the interface
1024 */
1025 i40e_down(vsi);
1026
1027 if (tx_rings) {
1028 for (i = 0; i < vsi->num_queue_pairs; i++) {
9f65e15b
AD
1029 i40e_free_tx_resources(vsi->tx_rings[i]);
1030 *vsi->tx_rings[i] = tx_rings[i];
c7d05ca8
JB
1031 }
1032 kfree(tx_rings);
1033 tx_rings = NULL;
1034 }
1035
1036 if (rx_rings) {
1037 for (i = 0; i < vsi->num_queue_pairs; i++) {
9f65e15b
AD
1038 i40e_free_rx_resources(vsi->rx_rings[i]);
1039 *vsi->rx_rings[i] = rx_rings[i];
c7d05ca8
JB
1040 }
1041 kfree(rx_rings);
1042 rx_rings = NULL;
1043 }
1044
1045 i40e_up(vsi);
1046
1047free_tx:
1048 /* error cleanup if the Rx allocations failed after getting Tx */
1049 if (tx_rings) {
1050 for (i = 0; i < vsi->num_queue_pairs; i++)
1051 i40e_free_tx_resources(&tx_rings[i]);
1052 kfree(tx_rings);
1053 tx_rings = NULL;
1054 }
1055
1056done:
1057 clear_bit(__I40E_CONFIG_BUSY, &pf->state);
1058
1059 return err;
1060}
1061
1062static int i40e_get_sset_count(struct net_device *netdev, int sset)
1063{
1064 struct i40e_netdev_priv *np = netdev_priv(netdev);
1065 struct i40e_vsi *vsi = np->vsi;
1066 struct i40e_pf *pf = vsi->back;
1067
1068 switch (sset) {
1069 case ETH_SS_TEST:
1070 return I40E_TEST_LEN;
1071 case ETH_SS_STATS:
8eab9cfd
SN
1072 if (vsi == pf->vsi[pf->lan_vsi]) {
1073 int len = I40E_PF_STATS_LEN(netdev);
1074
1075 if (pf->lan_veb != I40E_NO_VEB)
1076 len += I40E_VEB_STATS_LEN;
1077 return len;
1078 } else {
c7d05ca8 1079 return I40E_VSI_STATS_LEN(netdev);
8eab9cfd 1080 }
c7d05ca8
JB
1081 default:
1082 return -EOPNOTSUPP;
1083 }
1084}
1085
1086static void i40e_get_ethtool_stats(struct net_device *netdev,
1087 struct ethtool_stats *stats, u64 *data)
1088{
1089 struct i40e_netdev_priv *np = netdev_priv(netdev);
e7046ee1 1090 struct i40e_ring *tx_ring, *rx_ring;
c7d05ca8
JB
1091 struct i40e_vsi *vsi = np->vsi;
1092 struct i40e_pf *pf = vsi->back;
1093 int i = 0;
1094 char *p;
1095 int j;
1096 struct rtnl_link_stats64 *net_stats = i40e_get_vsi_stats_struct(vsi);
980e9b11 1097 unsigned int start;
c7d05ca8
JB
1098
1099 i40e_update_stats(vsi);
1100
1101 for (j = 0; j < I40E_NETDEV_STATS_LEN; j++) {
1102 p = (char *)net_stats + i40e_gstrings_net_stats[j].stat_offset;
1103 data[i++] = (i40e_gstrings_net_stats[j].sizeof_stat ==
1104 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1105 }
41a9e55c
SN
1106 for (j = 0; j < I40E_MISC_STATS_LEN; j++) {
1107 p = (char *)vsi + i40e_gstrings_misc_stats[j].stat_offset;
1108 data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat ==
1109 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1110 }
980e9b11 1111 rcu_read_lock();
99c472a3 1112 for (j = 0; j < vsi->num_queue_pairs; j++) {
e7046ee1 1113 tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
980e9b11
AD
1114
1115 if (!tx_ring)
1116 continue;
1117
1118 /* process Tx ring statistics */
1119 do {
57a7744e 1120 start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
980e9b11
AD
1121 data[i] = tx_ring->stats.packets;
1122 data[i + 1] = tx_ring->stats.bytes;
57a7744e 1123 } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
99c472a3 1124 i += 2;
980e9b11
AD
1125
1126 /* Rx ring is the 2nd half of the queue pair */
1127 rx_ring = &tx_ring[1];
1128 do {
57a7744e 1129 start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
99c472a3
CS
1130 data[i] = rx_ring->stats.packets;
1131 data[i + 1] = rx_ring->stats.bytes;
57a7744e 1132 } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
99c472a3 1133 i += 2;
c7d05ca8 1134 }
980e9b11 1135 rcu_read_unlock();
8eab9cfd
SN
1136 if (vsi != pf->vsi[pf->lan_vsi])
1137 return;
1138
1139 if (pf->lan_veb != I40E_NO_VEB) {
1140 struct i40e_veb *veb = pf->veb[pf->lan_veb];
1141 for (j = 0; j < I40E_VEB_STATS_LEN; j++) {
1142 p = (char *)veb;
1143 p += i40e_gstrings_veb_stats[j].stat_offset;
1144 data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat ==
1145 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
c7d05ca8 1146 }
c7d05ca8 1147 }
8eab9cfd
SN
1148 for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
1149 p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
1150 data[i++] = (i40e_gstrings_stats[j].sizeof_stat ==
1151 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1152 }
1153 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
1154 data[i++] = pf->stats.priority_xon_tx[j];
1155 data[i++] = pf->stats.priority_xoff_tx[j];
1156 }
1157 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) {
1158 data[i++] = pf->stats.priority_xon_rx[j];
1159 data[i++] = pf->stats.priority_xoff_rx[j];
1160 }
1161 for (j = 0; j < I40E_MAX_USER_PRIORITY; j++)
1162 data[i++] = pf->stats.priority_xon_2_xoff[j];
c7d05ca8
JB
1163}
1164
1165static void i40e_get_strings(struct net_device *netdev, u32 stringset,
1166 u8 *data)
1167{
1168 struct i40e_netdev_priv *np = netdev_priv(netdev);
1169 struct i40e_vsi *vsi = np->vsi;
1170 struct i40e_pf *pf = vsi->back;
1171 char *p = (char *)data;
1172 int i;
1173
1174 switch (stringset) {
1175 case ETH_SS_TEST:
1176 for (i = 0; i < I40E_TEST_LEN; i++) {
1177 memcpy(data, i40e_gstrings_test[i], ETH_GSTRING_LEN);
1178 data += ETH_GSTRING_LEN;
1179 }
1180 break;
1181 case ETH_SS_STATS:
1182 for (i = 0; i < I40E_NETDEV_STATS_LEN; i++) {
1183 snprintf(p, ETH_GSTRING_LEN, "%s",
1184 i40e_gstrings_net_stats[i].stat_string);
1185 p += ETH_GSTRING_LEN;
1186 }
41a9e55c
SN
1187 for (i = 0; i < I40E_MISC_STATS_LEN; i++) {
1188 snprintf(p, ETH_GSTRING_LEN, "%s",
1189 i40e_gstrings_misc_stats[i].stat_string);
1190 p += ETH_GSTRING_LEN;
1191 }
c7d05ca8
JB
1192 for (i = 0; i < vsi->num_queue_pairs; i++) {
1193 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
1194 p += ETH_GSTRING_LEN;
1195 snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
1196 p += ETH_GSTRING_LEN;
c7d05ca8
JB
1197 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
1198 p += ETH_GSTRING_LEN;
1199 snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
1200 p += ETH_GSTRING_LEN;
1201 }
8eab9cfd
SN
1202 if (vsi != pf->vsi[pf->lan_vsi])
1203 return;
1204
1205 if (pf->lan_veb != I40E_NO_VEB) {
1206 for (i = 0; i < I40E_VEB_STATS_LEN; i++) {
1207 snprintf(p, ETH_GSTRING_LEN, "veb.%s",
1208 i40e_gstrings_veb_stats[i].stat_string);
c7d05ca8
JB
1209 p += ETH_GSTRING_LEN;
1210 }
1211 }
8eab9cfd
SN
1212 for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
1213 snprintf(p, ETH_GSTRING_LEN, "port.%s",
1214 i40e_gstrings_stats[i].stat_string);
1215 p += ETH_GSTRING_LEN;
1216 }
1217 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
1218 snprintf(p, ETH_GSTRING_LEN,
1219 "port.tx_priority_%u_xon", i);
1220 p += ETH_GSTRING_LEN;
1221 snprintf(p, ETH_GSTRING_LEN,
1222 "port.tx_priority_%u_xoff", i);
1223 p += ETH_GSTRING_LEN;
1224 }
1225 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
1226 snprintf(p, ETH_GSTRING_LEN,
1227 "port.rx_priority_%u_xon", i);
1228 p += ETH_GSTRING_LEN;
1229 snprintf(p, ETH_GSTRING_LEN,
1230 "port.rx_priority_%u_xoff", i);
1231 p += ETH_GSTRING_LEN;
1232 }
1233 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
1234 snprintf(p, ETH_GSTRING_LEN,
1235 "port.rx_priority_%u_xon_2_xoff", i);
1236 p += ETH_GSTRING_LEN;
1237 }
c7d05ca8
JB
1238 /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
1239 break;
1240 }
1241}
1242
1243static int i40e_get_ts_info(struct net_device *dev,
1244 struct ethtool_ts_info *info)
1245{
beb0dff1
JK
1246 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
1247
1248 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
1249 SOF_TIMESTAMPING_RX_SOFTWARE |
1250 SOF_TIMESTAMPING_SOFTWARE |
1251 SOF_TIMESTAMPING_TX_HARDWARE |
1252 SOF_TIMESTAMPING_RX_HARDWARE |
1253 SOF_TIMESTAMPING_RAW_HARDWARE;
1254
1255 if (pf->ptp_clock)
1256 info->phc_index = ptp_clock_index(pf->ptp_clock);
1257 else
1258 info->phc_index = -1;
1259
1260 info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
1261
1262 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
1263 (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
1264 (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
1265 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
1266 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
1267 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
1268 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
1269 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
1270 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
1271 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
1272 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
1273 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
1274
1275 return 0;
c7d05ca8
JB
1276}
1277
7b086397 1278static int i40e_link_test(struct net_device *netdev, u64 *data)
c7d05ca8 1279{
7b086397
SN
1280 struct i40e_netdev_priv *np = netdev_priv(netdev);
1281 struct i40e_pf *pf = np->vsi->back;
1282
b03aaa9c 1283 netif_info(pf, hw, netdev, "link test\n");
c7d05ca8
JB
1284 if (i40e_get_link_status(&pf->hw))
1285 *data = 0;
1286 else
1287 *data = 1;
1288
1289 return *data;
1290}
1291
7b086397 1292static int i40e_reg_test(struct net_device *netdev, u64 *data)
c7d05ca8 1293{
7b086397
SN
1294 struct i40e_netdev_priv *np = netdev_priv(netdev);
1295 struct i40e_pf *pf = np->vsi->back;
c7d05ca8 1296
b03aaa9c 1297 netif_info(pf, hw, netdev, "register test\n");
7b086397 1298 *data = i40e_diag_reg_test(&pf->hw);
c7d05ca8 1299
7b086397 1300 return *data;
c7d05ca8
JB
1301}
1302
7b086397 1303static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
c7d05ca8 1304{
7b086397
SN
1305 struct i40e_netdev_priv *np = netdev_priv(netdev);
1306 struct i40e_pf *pf = np->vsi->back;
c7d05ca8 1307
b03aaa9c 1308 netif_info(pf, hw, netdev, "eeprom test\n");
7b086397 1309 *data = i40e_diag_eeprom_test(&pf->hw);
c7d05ca8 1310
7b086397 1311 return *data;
c7d05ca8
JB
1312}
1313
7b086397 1314static int i40e_intr_test(struct net_device *netdev, u64 *data)
c7d05ca8 1315{
7b086397
SN
1316 struct i40e_netdev_priv *np = netdev_priv(netdev);
1317 struct i40e_pf *pf = np->vsi->back;
cd92e72f
SN
1318 u16 swc_old = pf->sw_int_count;
1319
b03aaa9c 1320 netif_info(pf, hw, netdev, "interrupt test\n");
cd92e72f
SN
1321 wr32(&pf->hw, I40E_PFINT_DYN_CTL0,
1322 (I40E_PFINT_DYN_CTL0_INTENA_MASK |
1323 I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK));
1324 usleep_range(1000, 2000);
1325 *data = (swc_old == pf->sw_int_count);
c7d05ca8
JB
1326
1327 return *data;
1328}
1329
7b086397 1330static int i40e_loopback_test(struct net_device *netdev, u64 *data)
c7d05ca8 1331{
b03aaa9c
SN
1332 struct i40e_netdev_priv *np = netdev_priv(netdev);
1333 struct i40e_pf *pf = np->vsi->back;
1334
1335 netif_info(pf, hw, netdev, "loopback test not implemented\n");
cd92e72f 1336 *data = 0;
c7d05ca8
JB
1337
1338 return *data;
1339}
1340
1341static void i40e_diag_test(struct net_device *netdev,
1342 struct ethtool_test *eth_test, u64 *data)
1343{
1344 struct i40e_netdev_priv *np = netdev_priv(netdev);
1345 struct i40e_pf *pf = np->vsi->back;
1346
c7d05ca8
JB
1347 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
1348 /* Offline tests */
b03aaa9c 1349 netif_info(pf, drv, netdev, "offline testing starting\n");
c7d05ca8 1350
f551b438
SN
1351 set_bit(__I40E_TESTING, &pf->state);
1352
c7d05ca8
JB
1353 /* Link test performed before hardware reset
1354 * so autoneg doesn't interfere with test result
1355 */
7b086397 1356 if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
c7d05ca8
JB
1357 eth_test->flags |= ETH_TEST_FL_FAILED;
1358
7b086397 1359 if (i40e_eeprom_test(netdev, &data[I40E_ETH_TEST_EEPROM]))
c7d05ca8
JB
1360 eth_test->flags |= ETH_TEST_FL_FAILED;
1361
7b086397 1362 if (i40e_intr_test(netdev, &data[I40E_ETH_TEST_INTR]))
c7d05ca8
JB
1363 eth_test->flags |= ETH_TEST_FL_FAILED;
1364
7b086397 1365 if (i40e_loopback_test(netdev, &data[I40E_ETH_TEST_LOOPBACK]))
c7d05ca8
JB
1366 eth_test->flags |= ETH_TEST_FL_FAILED;
1367
f551b438
SN
1368 /* run reg test last, a reset is required after it */
1369 if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
1370 eth_test->flags |= ETH_TEST_FL_FAILED;
1371
1372 clear_bit(__I40E_TESTING, &pf->state);
1373 i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
c7d05ca8 1374 } else {
c7d05ca8 1375 /* Online tests */
b03aaa9c
SN
1376 netif_info(pf, drv, netdev, "online testing starting\n");
1377
7b086397 1378 if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
c7d05ca8
JB
1379 eth_test->flags |= ETH_TEST_FL_FAILED;
1380
1381 /* Offline only tests, not run in online; pass by default */
1382 data[I40E_ETH_TEST_REG] = 0;
1383 data[I40E_ETH_TEST_EEPROM] = 0;
1384 data[I40E_ETH_TEST_INTR] = 0;
1385 data[I40E_ETH_TEST_LOOPBACK] = 0;
c7d05ca8 1386 }
c140c17b 1387
b03aaa9c 1388 netif_info(pf, drv, netdev, "testing finished\n");
c7d05ca8
JB
1389}
1390
1391static void i40e_get_wol(struct net_device *netdev,
1392 struct ethtool_wolinfo *wol)
1393{
8e2773ae
SN
1394 struct i40e_netdev_priv *np = netdev_priv(netdev);
1395 struct i40e_pf *pf = np->vsi->back;
1396 struct i40e_hw *hw = &pf->hw;
1397 u16 wol_nvm_bits;
1398
1399 /* NVM bit on means WoL disabled for the port */
1400 i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
1401 if ((1 << hw->port) & wol_nvm_bits) {
1402 wol->supported = 0;
1403 wol->wolopts = 0;
1404 } else {
1405 wol->supported = WAKE_MAGIC;
1406 wol->wolopts = (pf->wol_en ? WAKE_MAGIC : 0);
1407 }
1408}
1409
1410static int i40e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1411{
1412 struct i40e_netdev_priv *np = netdev_priv(netdev);
1413 struct i40e_pf *pf = np->vsi->back;
1414 struct i40e_hw *hw = &pf->hw;
1415 u16 wol_nvm_bits;
1416
1417 /* NVM bit on means WoL disabled for the port */
1418 i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
1419 if (((1 << hw->port) & wol_nvm_bits))
1420 return -EOPNOTSUPP;
1421
1422 /* only magic packet is supported */
1423 if (wol->wolopts && (wol->wolopts != WAKE_MAGIC))
1424 return -EOPNOTSUPP;
1425
1426 /* is this a new value? */
1427 if (pf->wol_en != !!wol->wolopts) {
1428 pf->wol_en = !!wol->wolopts;
1429 device_set_wakeup_enable(&pf->pdev->dev, pf->wol_en);
1430 }
1431
c7d05ca8
JB
1432 return 0;
1433}
1434
1435static int i40e_set_phys_id(struct net_device *netdev,
1436 enum ethtool_phys_id_state state)
1437{
1438 struct i40e_netdev_priv *np = netdev_priv(netdev);
1439 struct i40e_pf *pf = np->vsi->back;
1440 struct i40e_hw *hw = &pf->hw;
1441 int blink_freq = 2;
1442
1443 switch (state) {
1444 case ETHTOOL_ID_ACTIVE:
1445 pf->led_status = i40e_led_get(hw);
1446 return blink_freq;
1447 case ETHTOOL_ID_ON:
0556a9e3 1448 i40e_led_set(hw, 0xF, false);
c7d05ca8
JB
1449 break;
1450 case ETHTOOL_ID_OFF:
0556a9e3 1451 i40e_led_set(hw, 0x0, false);
c7d05ca8
JB
1452 break;
1453 case ETHTOOL_ID_INACTIVE:
0556a9e3 1454 i40e_led_set(hw, pf->led_status, false);
c7d05ca8
JB
1455 break;
1456 }
1457
1458 return 0;
1459}
1460
1461/* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
1462 * Throttle Rate (ITR) ie. ITR(1) = 2us ITR(10) = 20 us, and also
1463 * 125us (8000 interrupts per second) == ITR(62)
1464 */
1465
1466static int i40e_get_coalesce(struct net_device *netdev,
1467 struct ethtool_coalesce *ec)
1468{
1469 struct i40e_netdev_priv *np = netdev_priv(netdev);
1470 struct i40e_vsi *vsi = np->vsi;
1471
1472 ec->tx_max_coalesced_frames_irq = vsi->work_limit;
1473 ec->rx_max_coalesced_frames_irq = vsi->work_limit;
1474
1475 if (ITR_IS_DYNAMIC(vsi->rx_itr_setting))
32f5f54a 1476 ec->use_adaptive_rx_coalesce = 1;
c7d05ca8
JB
1477
1478 if (ITR_IS_DYNAMIC(vsi->tx_itr_setting))
32f5f54a
MW
1479 ec->use_adaptive_tx_coalesce = 1;
1480
1481 ec->rx_coalesce_usecs = vsi->rx_itr_setting & ~I40E_ITR_DYNAMIC;
1482 ec->tx_coalesce_usecs = vsi->tx_itr_setting & ~I40E_ITR_DYNAMIC;
c7d05ca8
JB
1483
1484 return 0;
1485}
1486
1487static int i40e_set_coalesce(struct net_device *netdev,
1488 struct ethtool_coalesce *ec)
1489{
1490 struct i40e_netdev_priv *np = netdev_priv(netdev);
1491 struct i40e_q_vector *q_vector;
1492 struct i40e_vsi *vsi = np->vsi;
1493 struct i40e_pf *pf = vsi->back;
1494 struct i40e_hw *hw = &pf->hw;
1495 u16 vector;
1496 int i;
1497
1498 if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
1499 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
1500
5c2cebda 1501 vector = vsi->base_vector;
32f5f54a 1502 if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
5c2cebda 1503 (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1))) {
c7d05ca8 1504 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
5c2cebda
CW
1505 } else if (ec->rx_coalesce_usecs == 0) {
1506 vsi->rx_itr_setting = ec->rx_coalesce_usecs;
1507 i40e_irq_dynamic_disable(vsi, vector);
1508 if (ec->use_adaptive_rx_coalesce)
1509 netif_info(pf, drv, netdev,
1510 "Rx-secs=0, need to disable adaptive-Rx for a complete disable\n");
1511 } else {
1512 netif_info(pf, drv, netdev,
1513 "Invalid value, Rx-usecs range is 0, 8-8160\n");
32f5f54a 1514 return -EINVAL;
5c2cebda 1515 }
c7d05ca8 1516
32f5f54a 1517 if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
5c2cebda 1518 (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1))) {
c7d05ca8 1519 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
5c2cebda
CW
1520 } else if (ec->tx_coalesce_usecs == 0) {
1521 vsi->tx_itr_setting = ec->tx_coalesce_usecs;
1522 i40e_irq_dynamic_disable(vsi, vector);
1523 if (ec->use_adaptive_tx_coalesce)
1524 netif_info(pf, drv, netdev,
1525 "Tx-secs=0, need to disable adaptive-Tx for a complete disable\n");
1526 } else {
1527 netif_info(pf, drv, netdev,
1528 "Invalid value, Tx-usecs range is 0, 8-8160\n");
32f5f54a 1529 return -EINVAL;
5c2cebda 1530 }
32f5f54a
MW
1531
1532 if (ec->use_adaptive_rx_coalesce)
1533 vsi->rx_itr_setting |= I40E_ITR_DYNAMIC;
1534 else
1535 vsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
1536
1537 if (ec->use_adaptive_tx_coalesce)
1538 vsi->tx_itr_setting |= I40E_ITR_DYNAMIC;
1539 else
1540 vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
c7d05ca8 1541
493fb300
AD
1542 for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
1543 q_vector = vsi->q_vectors[i];
c7d05ca8
JB
1544 q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
1545 wr32(hw, I40E_PFINT_ITRN(0, vector - 1), q_vector->rx.itr);
1546 q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
1547 wr32(hw, I40E_PFINT_ITRN(1, vector - 1), q_vector->tx.itr);
1548 i40e_flush(hw);
1549 }
1550
1551 return 0;
1552}
1553
1554/**
1555 * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
1556 * @pf: pointer to the physical function struct
1557 * @cmd: ethtool rxnfc command
1558 *
1559 * Returns Success if the flow is supported, else Invalid Input.
1560 **/
1561static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
1562{
1563 cmd->data = 0;
1564
1565 /* Report default options for RSS on i40e */
1566 switch (cmd->flow_type) {
1567 case TCP_V4_FLOW:
1568 case UDP_V4_FLOW:
1569 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1570 /* fall through to add IP fields */
1571 case SCTP_V4_FLOW:
1572 case AH_ESP_V4_FLOW:
1573 case AH_V4_FLOW:
1574 case ESP_V4_FLOW:
1575 case IPV4_FLOW:
1576 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1577 break;
1578 case TCP_V6_FLOW:
1579 case UDP_V6_FLOW:
1580 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1581 /* fall through to add IP fields */
1582 case SCTP_V6_FLOW:
1583 case AH_ESP_V6_FLOW:
1584 case AH_V6_FLOW:
1585 case ESP_V6_FLOW:
1586 case IPV6_FLOW:
1587 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1588 break;
1589 default:
1590 return -EINVAL;
1591 }
1592
1593 return 0;
1594}
1595
17a73f6b
JG
1596/**
1597 * i40e_get_ethtool_fdir_all - Populates the rule count of a command
1598 * @pf: Pointer to the physical function struct
1599 * @cmd: The command to get or set Rx flow classification rules
1600 * @rule_locs: Array of used rule locations
1601 *
1602 * This function populates both the total and actual rule count of
1603 * the ethtool flow classification command
1604 *
1605 * Returns 0 on success or -EMSGSIZE if entry not found
1606 **/
1607static int i40e_get_ethtool_fdir_all(struct i40e_pf *pf,
1608 struct ethtool_rxnfc *cmd,
1609 u32 *rule_locs)
1610{
1611 struct i40e_fdir_filter *rule;
1612 struct hlist_node *node2;
1613 int cnt = 0;
1614
1615 /* report total rule count */
082def10 1616 cmd->data = i40e_get_fd_cnt_all(pf);
17a73f6b
JG
1617
1618 hlist_for_each_entry_safe(rule, node2,
1619 &pf->fdir_filter_list, fdir_node) {
1620 if (cnt == cmd->rule_cnt)
1621 return -EMSGSIZE;
1622
1623 rule_locs[cnt] = rule->fd_id;
1624 cnt++;
1625 }
1626
1627 cmd->rule_cnt = cnt;
1628
1629 return 0;
1630}
1631
1632/**
1633 * i40e_get_ethtool_fdir_entry - Look up a filter based on Rx flow
1634 * @pf: Pointer to the physical function struct
1635 * @cmd: The command to get or set Rx flow classification rules
1636 *
1637 * This function looks up a filter based on the Rx flow classification
1638 * command and fills the flow spec info for it if found
1639 *
1640 * Returns 0 on success or -EINVAL if filter not found
1641 **/
1642static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
1643 struct ethtool_rxnfc *cmd)
1644{
1645 struct ethtool_rx_flow_spec *fsp =
1646 (struct ethtool_rx_flow_spec *)&cmd->fs;
1647 struct i40e_fdir_filter *rule = NULL;
1648 struct hlist_node *node2;
1649
17a73f6b
JG
1650 hlist_for_each_entry_safe(rule, node2,
1651 &pf->fdir_filter_list, fdir_node) {
1652 if (fsp->location <= rule->fd_id)
1653 break;
1654 }
1655
1656 if (!rule || fsp->location != rule->fd_id)
1657 return -EINVAL;
1658
1659 fsp->flow_type = rule->flow_type;
7d54eb2c
ASJ
1660 if (fsp->flow_type == IP_USER_FLOW) {
1661 fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
1662 fsp->h_u.usr_ip4_spec.proto = 0;
1663 fsp->m_u.usr_ip4_spec.proto = 0;
1664 }
1665
04b73bd7
ASJ
1666 /* Reverse the src and dest notion, since the HW views them from
1667 * Tx perspective where as the user expects it from Rx filter view.
1668 */
1669 fsp->h_u.tcp_ip4_spec.psrc = rule->dst_port;
1670 fsp->h_u.tcp_ip4_spec.pdst = rule->src_port;
1671 fsp->h_u.tcp_ip4_spec.ip4src = rule->dst_ip[0];
1672 fsp->h_u.tcp_ip4_spec.ip4dst = rule->src_ip[0];
387ce1a9
ASJ
1673
1674 if (rule->dest_ctl == I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET)
1675 fsp->ring_cookie = RX_CLS_FLOW_DISC;
1676 else
1677 fsp->ring_cookie = rule->q_index;
17a73f6b
JG
1678
1679 return 0;
1680}
1681
c7d05ca8
JB
1682/**
1683 * i40e_get_rxnfc - command to get RX flow classification rules
1684 * @netdev: network interface device structure
1685 * @cmd: ethtool rxnfc command
1686 *
1687 * Returns Success if the command is supported.
1688 **/
1689static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
1690 u32 *rule_locs)
1691{
1692 struct i40e_netdev_priv *np = netdev_priv(netdev);
1693 struct i40e_vsi *vsi = np->vsi;
1694 struct i40e_pf *pf = vsi->back;
1695 int ret = -EOPNOTSUPP;
1696
1697 switch (cmd->cmd) {
1698 case ETHTOOL_GRXRINGS:
1699 cmd->data = vsi->alloc_queue_pairs;
1700 ret = 0;
1701 break;
1702 case ETHTOOL_GRXFH:
1703 ret = i40e_get_rss_hash_opts(pf, cmd);
1704 break;
1705 case ETHTOOL_GRXCLSRLCNT:
17a73f6b 1706 cmd->rule_cnt = pf->fdir_pf_active_filters;
082def10
ASJ
1707 /* report total rule count */
1708 cmd->data = i40e_get_fd_cnt_all(pf);
c7d05ca8
JB
1709 ret = 0;
1710 break;
1711 case ETHTOOL_GRXCLSRULE:
17a73f6b 1712 ret = i40e_get_ethtool_fdir_entry(pf, cmd);
c7d05ca8
JB
1713 break;
1714 case ETHTOOL_GRXCLSRLALL:
17a73f6b
JG
1715 ret = i40e_get_ethtool_fdir_all(pf, cmd, rule_locs);
1716 break;
c7d05ca8
JB
1717 default:
1718 break;
1719 }
1720
1721 return ret;
1722}
1723
1724/**
1725 * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
1726 * @pf: pointer to the physical function struct
1727 * @cmd: ethtool rxnfc command
1728 *
1729 * Returns Success if the flow input set is supported.
1730 **/
1731static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
1732{
1733 struct i40e_hw *hw = &pf->hw;
1734 u64 hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
1735 ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
1736
1737 /* RSS does not support anything other than hashing
1738 * to queues on src and dst IPs and ports
1739 */
1740 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
1741 RXH_L4_B_0_1 | RXH_L4_B_2_3))
1742 return -EINVAL;
1743
1744 /* We need at least the IP SRC and DEST fields for hashing */
1745 if (!(nfc->data & RXH_IP_SRC) ||
1746 !(nfc->data & RXH_IP_DST))
1747 return -EINVAL;
1748
1749 switch (nfc->flow_type) {
1750 case TCP_V4_FLOW:
1751 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1752 case 0:
1753 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1754 break;
1755 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1756 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
1757 break;
1758 default:
1759 return -EINVAL;
1760 }
1761 break;
1762 case TCP_V6_FLOW:
1763 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1764 case 0:
1765 hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1766 break;
1767 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1768 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
1769 break;
1770 default:
1771 return -EINVAL;
1772 }
1773 break;
1774 case UDP_V4_FLOW:
1775 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1776 case 0:
b2d36c03
KS
1777 hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
1778 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
c7d05ca8
JB
1779 break;
1780 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
b2d36c03
KS
1781 hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
1782 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
c7d05ca8
JB
1783 break;
1784 default:
1785 return -EINVAL;
1786 }
1787 break;
1788 case UDP_V6_FLOW:
1789 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1790 case 0:
b2d36c03
KS
1791 hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
1792 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
c7d05ca8
JB
1793 break;
1794 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
b2d36c03
KS
1795 hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
1796 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
c7d05ca8
JB
1797 break;
1798 default:
1799 return -EINVAL;
1800 }
1801 break;
1802 case AH_ESP_V4_FLOW:
1803 case AH_V4_FLOW:
1804 case ESP_V4_FLOW:
1805 case SCTP_V4_FLOW:
1806 if ((nfc->data & RXH_L4_B_0_1) ||
1807 (nfc->data & RXH_L4_B_2_3))
1808 return -EINVAL;
1809 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
1810 break;
1811 case AH_ESP_V6_FLOW:
1812 case AH_V6_FLOW:
1813 case ESP_V6_FLOW:
1814 case SCTP_V6_FLOW:
1815 if ((nfc->data & RXH_L4_B_0_1) ||
1816 (nfc->data & RXH_L4_B_2_3))
1817 return -EINVAL;
1818 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
1819 break;
1820 case IPV4_FLOW:
1821 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
1822 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4);
1823 break;
1824 case IPV6_FLOW:
1825 hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
1826 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
1827 break;
1828 default:
1829 return -EINVAL;
1830 }
1831
1832 wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
1833 wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
1834 i40e_flush(hw);
1835
1836 return 0;
1837}
1838
43fddb75
ASJ
1839/**
1840 * i40e_match_fdir_input_set - Match a new filter against an existing one
1841 * @rule: The filter already added
1842 * @input: The new filter to comapre against
1843 *
1844 * Returns true if the two input set match
1845 **/
1846static bool i40e_match_fdir_input_set(struct i40e_fdir_filter *rule,
1847 struct i40e_fdir_filter *input)
1848{
1849 if ((rule->dst_ip[0] != input->dst_ip[0]) ||
1850 (rule->src_ip[0] != input->src_ip[0]) ||
1851 (rule->dst_port != input->dst_port) ||
1852 (rule->src_port != input->src_port))
1853 return false;
1854 return true;
1855}
1856
c7d05ca8 1857/**
17a73f6b
JG
1858 * i40e_update_ethtool_fdir_entry - Updates the fdir filter entry
1859 * @vsi: Pointer to the targeted VSI
1860 * @input: The filter to update or NULL to indicate deletion
1861 * @sw_idx: Software index to the filter
1862 * @cmd: The command to get or set Rx flow classification rules
c7d05ca8 1863 *
17a73f6b
JG
1864 * This function updates (or deletes) a Flow Director entry from
1865 * the hlist of the corresponding PF
1866 *
1867 * Returns 0 on success
c7d05ca8 1868 **/
17a73f6b
JG
1869static int i40e_update_ethtool_fdir_entry(struct i40e_vsi *vsi,
1870 struct i40e_fdir_filter *input,
1871 u16 sw_idx,
1872 struct ethtool_rxnfc *cmd)
c7d05ca8 1873{
17a73f6b 1874 struct i40e_fdir_filter *rule, *parent;
c7d05ca8 1875 struct i40e_pf *pf = vsi->back;
17a73f6b
JG
1876 struct hlist_node *node2;
1877 int err = -EINVAL;
c7d05ca8 1878
17a73f6b
JG
1879 parent = NULL;
1880 rule = NULL;
c7d05ca8 1881
17a73f6b
JG
1882 hlist_for_each_entry_safe(rule, node2,
1883 &pf->fdir_filter_list, fdir_node) {
1884 /* hash found, or no matching entry */
1885 if (rule->fd_id >= sw_idx)
1886 break;
1887 parent = rule;
c7d05ca8
JB
1888 }
1889
17a73f6b
JG
1890 /* if there is an old rule occupying our place remove it */
1891 if (rule && (rule->fd_id == sw_idx)) {
43fddb75
ASJ
1892 if (input && !i40e_match_fdir_input_set(rule, input))
1893 err = i40e_add_del_fdir(vsi, rule, false);
1894 else if (!input)
1895 err = i40e_add_del_fdir(vsi, rule, false);
17a73f6b
JG
1896 hlist_del(&rule->fdir_node);
1897 kfree(rule);
1898 pf->fdir_pf_active_filters--;
cbf61325
ASJ
1899 }
1900
17a73f6b
JG
1901 /* If no input this was a delete, err should be 0 if a rule was
1902 * successfully found and removed from the list else -EINVAL
1903 */
1904 if (!input)
1905 return err;
c7d05ca8 1906
17a73f6b
JG
1907 /* initialize node and set software index */
1908 INIT_HLIST_NODE(&input->fdir_node);
c7d05ca8 1909
17a73f6b
JG
1910 /* add filter to the list */
1911 if (parent)
1912 hlist_add_after(&parent->fdir_node, &input->fdir_node);
1913 else
1914 hlist_add_head(&input->fdir_node,
1915 &pf->fdir_filter_list);
c7d05ca8 1916
17a73f6b
JG
1917 /* update counts */
1918 pf->fdir_pf_active_filters++;
c7d05ca8 1919
17a73f6b 1920 return 0;
c7d05ca8
JB
1921}
1922
1923/**
17a73f6b
JG
1924 * i40e_del_fdir_entry - Deletes a Flow Director filter entry
1925 * @vsi: Pointer to the targeted VSI
1926 * @cmd: The command to get or set Rx flow classification rules
c7d05ca8 1927 *
17a73f6b
JG
1928 * The function removes a Flow Director filter entry from the
1929 * hlist of the corresponding PF
c7d05ca8 1930 *
17a73f6b
JG
1931 * Returns 0 on success
1932 */
1933static int i40e_del_fdir_entry(struct i40e_vsi *vsi,
1934 struct ethtool_rxnfc *cmd)
c7d05ca8 1935{
17a73f6b
JG
1936 struct ethtool_rx_flow_spec *fsp =
1937 (struct ethtool_rx_flow_spec *)&cmd->fs;
c7d05ca8 1938 struct i40e_pf *pf = vsi->back;
17a73f6b 1939 int ret = 0;
c7d05ca8 1940
17a73f6b 1941 ret = i40e_update_ethtool_fdir_entry(vsi, NULL, fsp->location, cmd);
c7d05ca8 1942
55a5e60b 1943 i40e_fdir_check_and_reenable(pf);
17a73f6b 1944 return ret;
c7d05ca8
JB
1945}
1946
1947/**
1eaa3840 1948 * i40e_add_fdir_ethtool - Add/Remove Flow Director filters
c7d05ca8
JB
1949 * @vsi: pointer to the targeted VSI
1950 * @cmd: command to get or set RX flow classification rules
c7d05ca8 1951 *
1eaa3840
ASJ
1952 * Add Flow Director filters for a specific flow spec based on their
1953 * protocol. Returns 0 if the filters were successfully added.
c7d05ca8 1954 **/
1eaa3840
ASJ
1955static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
1956 struct ethtool_rxnfc *cmd)
c7d05ca8 1957{
17a73f6b
JG
1958 struct ethtool_rx_flow_spec *fsp;
1959 struct i40e_fdir_filter *input;
c7d05ca8 1960 struct i40e_pf *pf;
17a73f6b 1961 int ret = -EINVAL;
c7d05ca8
JB
1962
1963 if (!vsi)
1964 return -EINVAL;
1965
1966 pf = vsi->back;
1967
55a5e60b
ASJ
1968 if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
1969 return -EOPNOTSUPP;
1970
1eaa3840 1971 if (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)
55a5e60b
ASJ
1972 return -ENOSPC;
1973
1974 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
1975
17a73f6b
JG
1976 if (fsp->location >= (pf->hw.func_caps.fd_filters_best_effort +
1977 pf->hw.func_caps.fd_filters_guaranteed)) {
c7d05ca8 1978 return -EINVAL;
17a73f6b 1979 }
c7d05ca8 1980
387ce1a9
ASJ
1981 if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) &&
1982 (fsp->ring_cookie >= vsi->num_queue_pairs))
17a73f6b 1983 return -EINVAL;
c7d05ca8 1984
17a73f6b 1985 input = kzalloc(sizeof(*input), GFP_KERNEL);
c7d05ca8 1986
17a73f6b
JG
1987 if (!input)
1988 return -ENOMEM;
c7d05ca8 1989
17a73f6b
JG
1990 input->fd_id = fsp->location;
1991
35a91fdd
ASJ
1992 if (fsp->ring_cookie == RX_CLS_FLOW_DISC)
1993 input->dest_ctl = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
1994 else
1995 input->dest_ctl =
1996 I40E_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX;
1997
17a73f6b
JG
1998 input->q_index = fsp->ring_cookie;
1999 input->flex_off = 0;
2000 input->pctype = 0;
2001 input->dest_vsi = vsi->id;
17a73f6b 2002 input->fd_status = I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID;
433c47de 2003 input->cnt_index = pf->fd_sb_cnt_idx;
17a73f6b
JG
2004 input->flow_type = fsp->flow_type;
2005 input->ip4_proto = fsp->h_u.usr_ip4_spec.proto;
04b73bd7
ASJ
2006
2007 /* Reverse the src and dest notion, since the HW expects them to be from
2008 * Tx perspective where as the input from user is from Rx filter view.
2009 */
2010 input->dst_port = fsp->h_u.tcp_ip4_spec.psrc;
2011 input->src_port = fsp->h_u.tcp_ip4_spec.pdst;
2012 input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
2013 input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;
17a73f6b 2014
1eaa3840
ASJ
2015 ret = i40e_add_del_fdir(vsi, input, true);
2016 if (ret)
17a73f6b 2017 kfree(input);
17a73f6b 2018 else
1eaa3840 2019 i40e_update_ethtool_fdir_entry(vsi, input, fsp->location, NULL);
c7d05ca8
JB
2020
2021 return ret;
2022}
8fb905b3 2023
c7d05ca8
JB
2024/**
2025 * i40e_set_rxnfc - command to set RX flow classification rules
2026 * @netdev: network interface device structure
2027 * @cmd: ethtool rxnfc command
2028 *
2029 * Returns Success if the command is supported.
2030 **/
2031static int i40e_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
2032{
2033 struct i40e_netdev_priv *np = netdev_priv(netdev);
2034 struct i40e_vsi *vsi = np->vsi;
2035 struct i40e_pf *pf = vsi->back;
2036 int ret = -EOPNOTSUPP;
2037
2038 switch (cmd->cmd) {
2039 case ETHTOOL_SRXFH:
2040 ret = i40e_set_rss_hash_opt(pf, cmd);
2041 break;
2042 case ETHTOOL_SRXCLSRLINS:
1eaa3840 2043 ret = i40e_add_fdir_ethtool(vsi, cmd);
c7d05ca8
JB
2044 break;
2045 case ETHTOOL_SRXCLSRLDEL:
17a73f6b 2046 ret = i40e_del_fdir_entry(vsi, cmd);
c7d05ca8
JB
2047 break;
2048 default:
2049 break;
2050 }
2051
2052 return ret;
2053}
2054
4b7820ca
ASJ
2055/**
2056 * i40e_max_channels - get Max number of combined channels supported
2057 * @vsi: vsi pointer
2058 **/
2059static unsigned int i40e_max_channels(struct i40e_vsi *vsi)
2060{
2061 /* TODO: This code assumes DCB and FD is disabled for now. */
2062 return vsi->alloc_queue_pairs;
2063}
2064
2065/**
2066 * i40e_get_channels - Get the current channels enabled and max supported etc.
2067 * @netdev: network interface device structure
2068 * @ch: ethtool channels structure
2069 *
2070 * We don't support separate tx and rx queues as channels. The other count
2071 * represents how many queues are being used for control. max_combined counts
2072 * how many queue pairs we can support. They may not be mapped 1 to 1 with
2073 * q_vectors since we support a lot more queue pairs than q_vectors.
2074 **/
2075static void i40e_get_channels(struct net_device *dev,
2076 struct ethtool_channels *ch)
2077{
2078 struct i40e_netdev_priv *np = netdev_priv(dev);
2079 struct i40e_vsi *vsi = np->vsi;
2080 struct i40e_pf *pf = vsi->back;
2081
2082 /* report maximum channels */
2083 ch->max_combined = i40e_max_channels(vsi);
2084
2085 /* report info for other vector */
60ea5f83 2086 ch->other_count = (pf->flags & I40E_FLAG_FD_SB_ENABLED) ? 1 : 0;
4b7820ca
ASJ
2087 ch->max_other = ch->other_count;
2088
2089 /* Note: This code assumes DCB is disabled for now. */
2090 ch->combined_count = vsi->num_queue_pairs;
2091}
2092
2093/**
2094 * i40e_set_channels - Set the new channels count.
2095 * @netdev: network interface device structure
2096 * @ch: ethtool channels structure
2097 *
2098 * The new channels count may not be the same as requested by the user
2099 * since it gets rounded down to a power of 2 value.
2100 **/
2101static int i40e_set_channels(struct net_device *dev,
2102 struct ethtool_channels *ch)
2103{
2104 struct i40e_netdev_priv *np = netdev_priv(dev);
2105 unsigned int count = ch->combined_count;
2106 struct i40e_vsi *vsi = np->vsi;
2107 struct i40e_pf *pf = vsi->back;
2108 int new_count;
2109
2110 /* We do not support setting channels for any other VSI at present */
2111 if (vsi->type != I40E_VSI_MAIN)
2112 return -EINVAL;
2113
2114 /* verify they are not requesting separate vectors */
2115 if (!count || ch->rx_count || ch->tx_count)
2116 return -EINVAL;
2117
2118 /* verify other_count has not changed */
60ea5f83 2119 if (ch->other_count != ((pf->flags & I40E_FLAG_FD_SB_ENABLED) ? 1 : 0))
4b7820ca
ASJ
2120 return -EINVAL;
2121
2122 /* verify the number of channels does not exceed hardware limits */
2123 if (count > i40e_max_channels(vsi))
2124 return -EINVAL;
2125
2126 /* update feature limits from largest to smallest supported values */
2127 /* TODO: Flow director limit, DCB etc */
2128
2129 /* cap RSS limit */
2130 if (count > pf->rss_size_max)
2131 count = pf->rss_size_max;
2132
2133 /* use rss_reconfig to rebuild with new queue count and update traffic
2134 * class queue mapping
2135 */
2136 new_count = i40e_reconfig_rss_queues(pf, count);
5f90f422 2137 if (new_count > 0)
4b7820ca
ASJ
2138 return 0;
2139 else
2140 return -EINVAL;
2141}
2142
c7d05ca8
JB
2143static const struct ethtool_ops i40e_ethtool_ops = {
2144 .get_settings = i40e_get_settings,
bf9c7141 2145 .set_settings = i40e_set_settings,
c7d05ca8
JB
2146 .get_drvinfo = i40e_get_drvinfo,
2147 .get_regs_len = i40e_get_regs_len,
2148 .get_regs = i40e_get_regs,
2149 .nway_reset = i40e_nway_reset,
2150 .get_link = ethtool_op_get_link,
2151 .get_wol = i40e_get_wol,
8e2773ae 2152 .set_wol = i40e_set_wol,
cd552cb4 2153 .set_eeprom = i40e_set_eeprom,
c7d05ca8
JB
2154 .get_eeprom_len = i40e_get_eeprom_len,
2155 .get_eeprom = i40e_get_eeprom,
2156 .get_ringparam = i40e_get_ringparam,
2157 .set_ringparam = i40e_set_ringparam,
2158 .get_pauseparam = i40e_get_pauseparam,
2becc35a 2159 .set_pauseparam = i40e_set_pauseparam,
c7d05ca8
JB
2160 .get_msglevel = i40e_get_msglevel,
2161 .set_msglevel = i40e_set_msglevel,
2162 .get_rxnfc = i40e_get_rxnfc,
2163 .set_rxnfc = i40e_set_rxnfc,
2164 .self_test = i40e_diag_test,
2165 .get_strings = i40e_get_strings,
2166 .set_phys_id = i40e_set_phys_id,
2167 .get_sset_count = i40e_get_sset_count,
2168 .get_ethtool_stats = i40e_get_ethtool_stats,
2169 .get_coalesce = i40e_get_coalesce,
2170 .set_coalesce = i40e_set_coalesce,
4b7820ca
ASJ
2171 .get_channels = i40e_get_channels,
2172 .set_channels = i40e_set_channels,
c7d05ca8
JB
2173 .get_ts_info = i40e_get_ts_info,
2174};
2175
2176void i40e_set_ethtool_ops(struct net_device *netdev)
2177{
7ad24ea4 2178 netdev->ethtool_ops = &i40e_ethtool_ops;
c7d05ca8 2179}
This page took 0.419135 seconds and 5 git commands to generate.