blob: c6dc9683429e4aa4810722b7e861d4ed0cb4ad83 [file] [log] [blame]
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001/* Intel Ethernet Switch Host Interface Driver
Jeff Kirsher97c71e32015-04-03 13:26:52 -07002 * Copyright(c) 2013 - 2015 Intel Corporation.
Alexander Duyck82dd0f72014-09-20 19:50:15 -04003 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 *
16 * Contact Information:
17 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
19 */
20
Stephen Rothwelleb51bba2014-10-01 17:00:49 +100021#include <linux/vmalloc.h>
22
Alexander Duyck82dd0f72014-09-20 19:50:15 -040023#include "fm10k.h"
24
25struct fm10k_stats {
26 char stat_string[ETH_GSTRING_LEN];
27 int sizeof_stat;
28 int stat_offset;
29};
30
31#define FM10K_NETDEV_STAT(_net_stat) { \
32 .stat_string = #_net_stat, \
33 .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
34 .stat_offset = offsetof(struct net_device_stats, _net_stat) \
35}
36
37static const struct fm10k_stats fm10k_gstrings_net_stats[] = {
38 FM10K_NETDEV_STAT(tx_packets),
39 FM10K_NETDEV_STAT(tx_bytes),
40 FM10K_NETDEV_STAT(tx_errors),
41 FM10K_NETDEV_STAT(rx_packets),
42 FM10K_NETDEV_STAT(rx_bytes),
43 FM10K_NETDEV_STAT(rx_errors),
44 FM10K_NETDEV_STAT(rx_dropped),
45
46 /* detailed Rx errors */
47 FM10K_NETDEV_STAT(rx_length_errors),
48 FM10K_NETDEV_STAT(rx_crc_errors),
49 FM10K_NETDEV_STAT(rx_fifo_errors),
50};
51
52#define FM10K_NETDEV_STATS_LEN ARRAY_SIZE(fm10k_gstrings_net_stats)
53
54#define FM10K_STAT(_name, _stat) { \
55 .stat_string = _name, \
56 .sizeof_stat = FIELD_SIZEOF(struct fm10k_intfc, _stat), \
57 .stat_offset = offsetof(struct fm10k_intfc, _stat) \
58}
59
Jeff Kirsherfbdb1592015-04-03 13:27:00 -070060static const struct fm10k_stats fm10k_gstrings_global_stats[] = {
Alexander Duyck82dd0f72014-09-20 19:50:15 -040061 FM10K_STAT("tx_restart_queue", restart_queue),
62 FM10K_STAT("tx_busy", tx_busy),
63 FM10K_STAT("tx_csum_errors", tx_csum_errors),
64 FM10K_STAT("rx_alloc_failed", alloc_failed),
65 FM10K_STAT("rx_csum_errors", rx_csum_errors),
Alexander Duyck82dd0f72014-09-20 19:50:15 -040066
67 FM10K_STAT("tx_packets_nic", tx_packets_nic),
68 FM10K_STAT("tx_bytes_nic", tx_bytes_nic),
69 FM10K_STAT("rx_packets_nic", rx_packets_nic),
70 FM10K_STAT("rx_bytes_nic", rx_bytes_nic),
71 FM10K_STAT("rx_drops_nic", rx_drops_nic),
72 FM10K_STAT("rx_overrun_pf", rx_overrun_pf),
73 FM10K_STAT("rx_overrun_vf", rx_overrun_vf),
74
Alexander Duyck82dd0f72014-09-20 19:50:15 -040075 FM10K_STAT("swapi_status", hw.swapi.status),
76 FM10K_STAT("mac_rules_used", hw.swapi.mac.used),
77 FM10K_STAT("mac_rules_avail", hw.swapi.mac.avail),
78
79 FM10K_STAT("mbx_tx_busy", hw.mbx.tx_busy),
Jeff Kirsher750c6072015-04-03 13:27:12 -070080 FM10K_STAT("mbx_tx_oversized", hw.mbx.tx_dropped),
Alexander Duyck82dd0f72014-09-20 19:50:15 -040081 FM10K_STAT("mbx_tx_messages", hw.mbx.tx_messages),
82 FM10K_STAT("mbx_tx_dwords", hw.mbx.tx_dwords),
83 FM10K_STAT("mbx_rx_messages", hw.mbx.rx_messages),
84 FM10K_STAT("mbx_rx_dwords", hw.mbx.rx_dwords),
85 FM10K_STAT("mbx_rx_parse_err", hw.mbx.rx_parse_err),
Alexander Duycka211e012014-09-20 19:54:07 -040086
Jeff Kirshere05546e2015-04-03 13:27:03 -070087 FM10K_STAT("tx_hang_count", tx_timeout_count),
88
Alexander Duycka211e012014-09-20 19:54:07 -040089 FM10K_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
Alexander Duyck82dd0f72014-09-20 19:50:15 -040090};
91
Jeff Kirsherfbdb1592015-04-03 13:27:00 -070092static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
93 FM10K_STAT("timeout", stats.timeout.count),
94 FM10K_STAT("ur", stats.ur.count),
95 FM10K_STAT("ca", stats.ca.count),
96 FM10K_STAT("um", stats.um.count),
97 FM10K_STAT("xec", stats.xec.count),
98 FM10K_STAT("vlan_drop", stats.vlan_drop.count),
99 FM10K_STAT("loopback_drop", stats.loopback_drop.count),
100 FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
101};
102
103#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
104#define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400105
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700106#define FM10K_QUEUE_STATS_LEN(_n) \
107 ( (_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64)))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400108
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700109#define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
110 FM10K_NETDEV_STATS_LEN)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400111
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400112static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
113 "Mailbox test (on/offline)"
114};
115
116#define FM10K_TEST_LEN (sizeof(fm10k_gstrings_test) / ETH_GSTRING_LEN)
117
118enum fm10k_self_test_types {
119 FM10K_TEST_MBX,
120 FM10K_TEST_MAX = FM10K_TEST_LEN
121};
122
Jeff Kirsherde445192015-04-03 13:26:56 -0700123static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400124{
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700125 struct fm10k_intfc *interface = netdev_priv(dev);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400126 char *p = (char *)data;
Jacob Kellerc0e58e92015-06-16 13:39:11 -0700127 unsigned int i;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400128
129 switch (stringset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400130 case ETH_SS_TEST:
131 memcpy(data, *fm10k_gstrings_test,
132 FM10K_TEST_LEN * ETH_GSTRING_LEN);
133 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400134 case ETH_SS_STATS:
135 for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
136 memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
137 ETH_GSTRING_LEN);
138 p += ETH_GSTRING_LEN;
139 }
140 for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) {
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700141 memcpy(p, fm10k_gstrings_global_stats[i].stat_string,
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400142 ETH_GSTRING_LEN);
143 p += ETH_GSTRING_LEN;
144 }
145
Alexander Duyck986eec42015-06-03 18:53:17 -0700146 if (interface->hw.mac.type != fm10k_mac_vf) {
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700147 for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
148 memcpy(p, fm10k_gstrings_pf_stats[i].stat_string,
149 ETH_GSTRING_LEN);
150 p += ETH_GSTRING_LEN;
151 }
Alexander Duyck986eec42015-06-03 18:53:17 -0700152 }
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700153
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700154 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400155 sprintf(p, "tx_queue_%u_packets", i);
156 p += ETH_GSTRING_LEN;
157 sprintf(p, "tx_queue_%u_bytes", i);
158 p += ETH_GSTRING_LEN;
159 sprintf(p, "rx_queue_%u_packets", i);
160 p += ETH_GSTRING_LEN;
161 sprintf(p, "rx_queue_%u_bytes", i);
162 p += ETH_GSTRING_LEN;
163 }
164 break;
165 }
166}
167
168static int fm10k_get_sset_count(struct net_device *dev, int sset)
169{
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700170 struct fm10k_intfc *interface = netdev_priv(dev);
171 struct fm10k_hw *hw = &interface->hw;
172 int stats_len = FM10K_STATIC_STATS_LEN;
173
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400174 switch (sset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400175 case ETH_SS_TEST:
176 return FM10K_TEST_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400177 case ETH_SS_STATS:
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700178 stats_len += FM10K_QUEUE_STATS_LEN(hw->mac.max_queues);
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700179
180 if (hw->mac.type != fm10k_mac_vf)
181 stats_len += FM10K_PF_STATS_LEN;
182
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700183 return stats_len;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400184 default:
185 return -EOPNOTSUPP;
186 }
187}
188
189static void fm10k_get_ethtool_stats(struct net_device *netdev,
Jeff Kirsherde445192015-04-03 13:26:56 -0700190 struct ethtool_stats __always_unused *stats,
191 u64 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400192{
193 const int stat_count = sizeof(struct fm10k_queue_stats) / sizeof(u64);
194 struct fm10k_intfc *interface = netdev_priv(netdev);
195 struct net_device_stats *net_stats = &netdev->stats;
196 char *p;
197 int i, j;
198
199 fm10k_update_stats(interface);
200
201 for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
202 p = (char *)net_stats + fm10k_gstrings_net_stats[i].stat_offset;
203 *(data++) = (fm10k_gstrings_net_stats[i].sizeof_stat ==
204 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
205 }
206
207 for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) {
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700208 p = (char *)interface +
209 fm10k_gstrings_global_stats[i].stat_offset;
210 *(data++) = (fm10k_gstrings_global_stats[i].sizeof_stat ==
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400211 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
212 }
213
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700214 if (interface->hw.mac.type != fm10k_mac_vf)
215 for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
216 p = (char *)interface +
217 fm10k_gstrings_pf_stats[i].stat_offset;
218 *(data++) = (fm10k_gstrings_pf_stats[i].sizeof_stat ==
219 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
220 }
221
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700222 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400223 struct fm10k_ring *ring;
224 u64 *queue_stat;
225
226 ring = interface->tx_ring[i];
227 if (ring)
228 queue_stat = (u64 *)&ring->stats;
229 for (j = 0; j < stat_count; j++)
230 *(data++) = ring ? queue_stat[j] : 0;
231
232 ring = interface->rx_ring[i];
233 if (ring)
234 queue_stat = (u64 *)&ring->stats;
235 for (j = 0; j < stat_count; j++)
236 *(data++) = ring ? queue_stat[j] : 0;
237 }
238}
239
240/* If function below adds more registers this define needs to be updated */
241#define FM10K_REGS_LEN_Q 29
242
243static void fm10k_get_reg_q(struct fm10k_hw *hw, u32 *buff, int i)
244{
245 int idx = 0;
246
247 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAL(i));
248 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAH(i));
249 buff[idx++] = fm10k_read_reg(hw, FM10K_RDLEN(i));
250 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_RXCTRL(i));
251 buff[idx++] = fm10k_read_reg(hw, FM10K_RDH(i));
252 buff[idx++] = fm10k_read_reg(hw, FM10K_RDT(i));
253 buff[idx++] = fm10k_read_reg(hw, FM10K_RXQCTL(i));
254 buff[idx++] = fm10k_read_reg(hw, FM10K_RXDCTL(i));
255 buff[idx++] = fm10k_read_reg(hw, FM10K_RXINT(i));
256 buff[idx++] = fm10k_read_reg(hw, FM10K_SRRCTL(i));
257 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRC(i));
258 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRDC(i));
259 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_L(i));
260 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_H(i));
261 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAL(i));
262 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAH(i));
263 buff[idx++] = fm10k_read_reg(hw, FM10K_TDLEN(i));
264 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_TXCTRL(i));
265 buff[idx++] = fm10k_read_reg(hw, FM10K_TDH(i));
266 buff[idx++] = fm10k_read_reg(hw, FM10K_TDT(i));
267 buff[idx++] = fm10k_read_reg(hw, FM10K_TXDCTL(i));
268 buff[idx++] = fm10k_read_reg(hw, FM10K_TXQCTL(i));
269 buff[idx++] = fm10k_read_reg(hw, FM10K_TXINT(i));
270 buff[idx++] = fm10k_read_reg(hw, FM10K_QPTC(i));
271 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_L(i));
272 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_H(i));
273 buff[idx++] = fm10k_read_reg(hw, FM10K_TQDLOC(i));
274 buff[idx++] = fm10k_read_reg(hw, FM10K_TX_SGLORT(i));
275 buff[idx++] = fm10k_read_reg(hw, FM10K_PFVTCTL(i));
276
277 BUG_ON(idx != FM10K_REGS_LEN_Q);
278}
279
280/* If function above adds more registers this define needs to be updated */
281#define FM10K_REGS_LEN_VSI 43
282
283static void fm10k_get_reg_vsi(struct fm10k_hw *hw, u32 *buff, int i)
284{
285 int idx = 0, j;
286
287 buff[idx++] = fm10k_read_reg(hw, FM10K_MRQC(i));
288 for (j = 0; j < 10; j++)
289 buff[idx++] = fm10k_read_reg(hw, FM10K_RSSRK(i, j));
290 for (j = 0; j < 32; j++)
291 buff[idx++] = fm10k_read_reg(hw, FM10K_RETA(i, j));
292
293 BUG_ON(idx != FM10K_REGS_LEN_VSI);
294}
295
296static void fm10k_get_regs(struct net_device *netdev,
297 struct ethtool_regs *regs, void *p)
298{
299 struct fm10k_intfc *interface = netdev_priv(netdev);
300 struct fm10k_hw *hw = &interface->hw;
301 u32 *buff = p;
302 u16 i;
303
304 regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
305
306 switch (hw->mac.type) {
307 case fm10k_mac_pf:
308 /* General PF Registers */
309 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL);
310 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL_EXT);
311 *(buff++) = fm10k_read_reg(hw, FM10K_GCR);
312 *(buff++) = fm10k_read_reg(hw, FM10K_GCR_EXT);
313
314 for (i = 0; i < 8; i++) {
315 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTMAP(i));
316 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTDEC(i));
317 }
318
319 for (i = 0; i < 65; i++) {
320 fm10k_get_reg_vsi(hw, buff, i);
321 buff += FM10K_REGS_LEN_VSI;
322 }
323
324 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL);
325 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
326
327 for (i = 0; i < FM10K_MAX_QUEUES_PF; i++) {
328 fm10k_get_reg_q(hw, buff, i);
329 buff += FM10K_REGS_LEN_Q;
330 }
331
332 *(buff++) = fm10k_read_reg(hw, FM10K_TPH_CTRL);
333
334 for (i = 0; i < 8; i++)
335 *(buff++) = fm10k_read_reg(hw, FM10K_INT_MAP(i));
336
337 /* Interrupt Throttling Registers */
338 for (i = 0; i < 130; i++)
339 *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
340
341 break;
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400342 case fm10k_mac_vf:
343 /* General VF registers */
344 *(buff++) = fm10k_read_reg(hw, FM10K_VFCTRL);
345 *(buff++) = fm10k_read_reg(hw, FM10K_VFINT_MAP);
346 *(buff++) = fm10k_read_reg(hw, FM10K_VFSYSTIME);
347
348 /* Interrupt Throttling Registers */
349 for (i = 0; i < 8; i++)
350 *(buff++) = fm10k_read_reg(hw, FM10K_VFITR(i));
351
352 fm10k_get_reg_vsi(hw, buff, 0);
353 buff += FM10K_REGS_LEN_VSI;
354
355 for (i = 0; i < FM10K_MAX_QUEUES_POOL; i++) {
356 if (i < hw->mac.max_queues)
357 fm10k_get_reg_q(hw, buff, i);
358 else
359 memset(buff, 0, sizeof(u32) * FM10K_REGS_LEN_Q);
360 buff += FM10K_REGS_LEN_Q;
361 }
362
363 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400364 default:
365 return;
366 }
367}
368
369/* If function above adds more registers these define need to be updated */
370#define FM10K_REGS_LEN_PF \
371(162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q))
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400372#define FM10K_REGS_LEN_VF \
373(11 + FM10K_REGS_LEN_VSI + (FM10K_MAX_QUEUES_POOL * FM10K_REGS_LEN_Q))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400374
375static int fm10k_get_regs_len(struct net_device *netdev)
376{
377 struct fm10k_intfc *interface = netdev_priv(netdev);
378 struct fm10k_hw *hw = &interface->hw;
379
380 switch (hw->mac.type) {
381 case fm10k_mac_pf:
382 return FM10K_REGS_LEN_PF * sizeof(u32);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400383 case fm10k_mac_vf:
384 return FM10K_REGS_LEN_VF * sizeof(u32);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400385 default:
386 return 0;
387 }
388}
389
390static void fm10k_get_drvinfo(struct net_device *dev,
391 struct ethtool_drvinfo *info)
392{
393 struct fm10k_intfc *interface = netdev_priv(dev);
394
395 strncpy(info->driver, fm10k_driver_name,
396 sizeof(info->driver) - 1);
397 strncpy(info->version, fm10k_driver_version,
398 sizeof(info->version) - 1);
399 strncpy(info->bus_info, pci_name(interface->pdev),
400 sizeof(info->bus_info) - 1);
401
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700402 info->n_stats = fm10k_get_sset_count(dev, ETH_SS_STATS);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400403
404 info->regdump_len = fm10k_get_regs_len(dev);
405}
406
407static void fm10k_get_pauseparam(struct net_device *dev,
408 struct ethtool_pauseparam *pause)
409{
410 struct fm10k_intfc *interface = netdev_priv(dev);
411
412 /* record fixed values for autoneg and tx pause */
413 pause->autoneg = 0;
414 pause->tx_pause = 1;
415
416 pause->rx_pause = interface->rx_pause ? 1 : 0;
417}
418
419static int fm10k_set_pauseparam(struct net_device *dev,
420 struct ethtool_pauseparam *pause)
421{
422 struct fm10k_intfc *interface = netdev_priv(dev);
423 struct fm10k_hw *hw = &interface->hw;
424
425 if (pause->autoneg || !pause->tx_pause)
426 return -EINVAL;
427
428 /* we can only support pause on the PF to avoid head-of-line blocking */
429 if (hw->mac.type == fm10k_mac_pf)
430 interface->rx_pause = pause->rx_pause ? ~0 : 0;
431 else if (pause->rx_pause)
432 return -EINVAL;
433
434 if (netif_running(dev))
435 fm10k_update_rx_drop_en(interface);
436
437 return 0;
438}
439
440static u32 fm10k_get_msglevel(struct net_device *netdev)
441{
442 struct fm10k_intfc *interface = netdev_priv(netdev);
443
444 return interface->msg_enable;
445}
446
447static void fm10k_set_msglevel(struct net_device *netdev, u32 data)
448{
449 struct fm10k_intfc *interface = netdev_priv(netdev);
450
451 interface->msg_enable = data;
452}
453
454static void fm10k_get_ringparam(struct net_device *netdev,
455 struct ethtool_ringparam *ring)
456{
457 struct fm10k_intfc *interface = netdev_priv(netdev);
458
459 ring->rx_max_pending = FM10K_MAX_RXD;
460 ring->tx_max_pending = FM10K_MAX_TXD;
461 ring->rx_mini_max_pending = 0;
462 ring->rx_jumbo_max_pending = 0;
463 ring->rx_pending = interface->rx_ring_count;
464 ring->tx_pending = interface->tx_ring_count;
465 ring->rx_mini_pending = 0;
466 ring->rx_jumbo_pending = 0;
467}
468
469static int fm10k_set_ringparam(struct net_device *netdev,
470 struct ethtool_ringparam *ring)
471{
472 struct fm10k_intfc *interface = netdev_priv(netdev);
473 struct fm10k_ring *temp_ring;
474 int i, err = 0;
475 u32 new_rx_count, new_tx_count;
476
477 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
478 return -EINVAL;
479
480 new_tx_count = clamp_t(u32, ring->tx_pending,
481 FM10K_MIN_TXD, FM10K_MAX_TXD);
482 new_tx_count = ALIGN(new_tx_count, FM10K_REQ_TX_DESCRIPTOR_MULTIPLE);
483
484 new_rx_count = clamp_t(u32, ring->rx_pending,
485 FM10K_MIN_RXD, FM10K_MAX_RXD);
486 new_rx_count = ALIGN(new_rx_count, FM10K_REQ_RX_DESCRIPTOR_MULTIPLE);
487
488 if ((new_tx_count == interface->tx_ring_count) &&
489 (new_rx_count == interface->rx_ring_count)) {
490 /* nothing to do */
491 return 0;
492 }
493
494 while (test_and_set_bit(__FM10K_RESETTING, &interface->state))
495 usleep_range(1000, 2000);
496
497 if (!netif_running(interface->netdev)) {
498 for (i = 0; i < interface->num_tx_queues; i++)
499 interface->tx_ring[i]->count = new_tx_count;
500 for (i = 0; i < interface->num_rx_queues; i++)
501 interface->rx_ring[i]->count = new_rx_count;
502 interface->tx_ring_count = new_tx_count;
503 interface->rx_ring_count = new_rx_count;
504 goto clear_reset;
505 }
506
507 /* allocate temporary buffer to store rings in */
508 i = max_t(int, interface->num_tx_queues, interface->num_rx_queues);
509 temp_ring = vmalloc(i * sizeof(struct fm10k_ring));
510
511 if (!temp_ring) {
512 err = -ENOMEM;
513 goto clear_reset;
514 }
515
516 fm10k_down(interface);
517
518 /* Setup new Tx resources and free the old Tx resources in that order.
519 * We can then assign the new resources to the rings via a memcpy.
520 * The advantage to this approach is that we are guaranteed to still
521 * have resources even in the case of an allocation failure.
522 */
523 if (new_tx_count != interface->tx_ring_count) {
524 for (i = 0; i < interface->num_tx_queues; i++) {
525 memcpy(&temp_ring[i], interface->tx_ring[i],
526 sizeof(struct fm10k_ring));
527
528 temp_ring[i].count = new_tx_count;
529 err = fm10k_setup_tx_resources(&temp_ring[i]);
530 if (err) {
531 while (i) {
532 i--;
533 fm10k_free_tx_resources(&temp_ring[i]);
534 }
535 goto err_setup;
536 }
537 }
538
539 for (i = 0; i < interface->num_tx_queues; i++) {
540 fm10k_free_tx_resources(interface->tx_ring[i]);
541
542 memcpy(interface->tx_ring[i], &temp_ring[i],
543 sizeof(struct fm10k_ring));
544 }
545
546 interface->tx_ring_count = new_tx_count;
547 }
548
549 /* Repeat the process for the Rx rings if needed */
550 if (new_rx_count != interface->rx_ring_count) {
551 for (i = 0; i < interface->num_rx_queues; i++) {
552 memcpy(&temp_ring[i], interface->rx_ring[i],
553 sizeof(struct fm10k_ring));
554
555 temp_ring[i].count = new_rx_count;
556 err = fm10k_setup_rx_resources(&temp_ring[i]);
557 if (err) {
558 while (i) {
559 i--;
560 fm10k_free_rx_resources(&temp_ring[i]);
561 }
562 goto err_setup;
563 }
564 }
565
566 for (i = 0; i < interface->num_rx_queues; i++) {
567 fm10k_free_rx_resources(interface->rx_ring[i]);
568
569 memcpy(interface->rx_ring[i], &temp_ring[i],
570 sizeof(struct fm10k_ring));
571 }
572
573 interface->rx_ring_count = new_rx_count;
574 }
575
576err_setup:
577 fm10k_up(interface);
578 vfree(temp_ring);
579clear_reset:
580 clear_bit(__FM10K_RESETTING, &interface->state);
581 return err;
582}
583
584static int fm10k_get_coalesce(struct net_device *dev,
585 struct ethtool_coalesce *ec)
586{
587 struct fm10k_intfc *interface = netdev_priv(dev);
588
589 ec->use_adaptive_tx_coalesce =
590 !!(interface->tx_itr & FM10K_ITR_ADAPTIVE);
591 ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;
592
593 ec->use_adaptive_rx_coalesce =
594 !!(interface->rx_itr & FM10K_ITR_ADAPTIVE);
595 ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;
596
597 return 0;
598}
599
600static int fm10k_set_coalesce(struct net_device *dev,
601 struct ethtool_coalesce *ec)
602{
603 struct fm10k_intfc *interface = netdev_priv(dev);
604 struct fm10k_q_vector *qv;
605 u16 tx_itr, rx_itr;
606 int i;
607
608 /* verify limits */
609 if ((ec->rx_coalesce_usecs > FM10K_ITR_MAX) ||
610 (ec->tx_coalesce_usecs > FM10K_ITR_MAX))
611 return -EINVAL;
612
613 /* record settings */
614 tx_itr = ec->tx_coalesce_usecs;
615 rx_itr = ec->rx_coalesce_usecs;
616
617 /* set initial values for adaptive ITR */
618 if (ec->use_adaptive_tx_coalesce)
619 tx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_10K;
620
621 if (ec->use_adaptive_rx_coalesce)
622 rx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_20K;
623
624 /* update interface */
625 interface->tx_itr = tx_itr;
626 interface->rx_itr = rx_itr;
627
628 /* update q_vectors */
629 for (i = 0; i < interface->num_q_vectors; i++) {
630 qv = interface->q_vector[i];
631 qv->tx.itr = tx_itr;
632 qv->rx.itr = rx_itr;
633 }
634
635 return 0;
636}
637
638static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
639 struct ethtool_rxnfc *cmd)
640{
641 cmd->data = 0;
642
643 /* Report default options for RSS on fm10k */
644 switch (cmd->flow_type) {
645 case TCP_V4_FLOW:
646 case TCP_V6_FLOW:
647 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
648 /* fall through */
649 case UDP_V4_FLOW:
650 if (interface->flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP)
651 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
652 /* fall through */
653 case SCTP_V4_FLOW:
654 case SCTP_V6_FLOW:
655 case AH_ESP_V4_FLOW:
656 case AH_ESP_V6_FLOW:
657 case AH_V4_FLOW:
658 case AH_V6_FLOW:
659 case ESP_V4_FLOW:
660 case ESP_V6_FLOW:
661 case IPV4_FLOW:
662 case IPV6_FLOW:
663 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
664 break;
665 case UDP_V6_FLOW:
666 if (interface->flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP)
667 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
668 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
669 break;
670 default:
671 return -EINVAL;
672 }
673
674 return 0;
675}
676
677static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
Jeff Kirsherde445192015-04-03 13:26:56 -0700678 u32 __always_unused *rule_locs)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400679{
680 struct fm10k_intfc *interface = netdev_priv(dev);
681 int ret = -EOPNOTSUPP;
682
683 switch (cmd->cmd) {
684 case ETHTOOL_GRXRINGS:
685 cmd->data = interface->num_rx_queues;
686 ret = 0;
687 break;
688 case ETHTOOL_GRXFH:
689 ret = fm10k_get_rss_hash_opts(interface, cmd);
690 break;
691 default:
692 break;
693 }
694
695 return ret;
696}
697
698#define UDP_RSS_FLAGS (FM10K_FLAG_RSS_FIELD_IPV4_UDP | \
699 FM10K_FLAG_RSS_FIELD_IPV6_UDP)
700static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
701 struct ethtool_rxnfc *nfc)
702{
703 u32 flags = interface->flags;
704
705 /* RSS does not support anything other than hashing
706 * to queues on src and dst IPs and ports
707 */
708 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
709 RXH_L4_B_0_1 | RXH_L4_B_2_3))
710 return -EINVAL;
711
712 switch (nfc->flow_type) {
713 case TCP_V4_FLOW:
714 case TCP_V6_FLOW:
715 if (!(nfc->data & RXH_IP_SRC) ||
716 !(nfc->data & RXH_IP_DST) ||
717 !(nfc->data & RXH_L4_B_0_1) ||
718 !(nfc->data & RXH_L4_B_2_3))
719 return -EINVAL;
720 break;
721 case UDP_V4_FLOW:
722 if (!(nfc->data & RXH_IP_SRC) ||
723 !(nfc->data & RXH_IP_DST))
724 return -EINVAL;
725 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
726 case 0:
727 flags &= ~FM10K_FLAG_RSS_FIELD_IPV4_UDP;
728 break;
729 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
730 flags |= FM10K_FLAG_RSS_FIELD_IPV4_UDP;
731 break;
732 default:
733 return -EINVAL;
734 }
735 break;
736 case UDP_V6_FLOW:
737 if (!(nfc->data & RXH_IP_SRC) ||
738 !(nfc->data & RXH_IP_DST))
739 return -EINVAL;
740 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
741 case 0:
742 flags &= ~FM10K_FLAG_RSS_FIELD_IPV6_UDP;
743 break;
744 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
745 flags |= FM10K_FLAG_RSS_FIELD_IPV6_UDP;
746 break;
747 default:
748 return -EINVAL;
749 }
750 break;
751 case AH_ESP_V4_FLOW:
752 case AH_V4_FLOW:
753 case ESP_V4_FLOW:
754 case SCTP_V4_FLOW:
755 case AH_ESP_V6_FLOW:
756 case AH_V6_FLOW:
757 case ESP_V6_FLOW:
758 case SCTP_V6_FLOW:
759 if (!(nfc->data & RXH_IP_SRC) ||
760 !(nfc->data & RXH_IP_DST) ||
761 (nfc->data & RXH_L4_B_0_1) ||
762 (nfc->data & RXH_L4_B_2_3))
763 return -EINVAL;
764 break;
765 default:
766 return -EINVAL;
767 }
768
769 /* if we changed something we need to update flags */
770 if (flags != interface->flags) {
771 struct fm10k_hw *hw = &interface->hw;
772 u32 mrqc;
773
774 if ((flags & UDP_RSS_FLAGS) &&
775 !(interface->flags & UDP_RSS_FLAGS))
776 netif_warn(interface, drv, interface->netdev,
777 "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
778
779 interface->flags = flags;
780
781 /* Perform hash on these packet types */
782 mrqc = FM10K_MRQC_IPV4 |
783 FM10K_MRQC_TCP_IPV4 |
784 FM10K_MRQC_IPV6 |
785 FM10K_MRQC_TCP_IPV6;
786
787 if (flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP)
788 mrqc |= FM10K_MRQC_UDP_IPV4;
789 if (flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP)
790 mrqc |= FM10K_MRQC_UDP_IPV6;
791
792 fm10k_write_reg(hw, FM10K_MRQC(0), mrqc);
793 }
794
795 return 0;
796}
797
798static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
799{
800 struct fm10k_intfc *interface = netdev_priv(dev);
801 int ret = -EOPNOTSUPP;
802
803 switch (cmd->cmd) {
804 case ETHTOOL_SRXFH:
805 ret = fm10k_set_rss_hash_opt(interface, cmd);
806 break;
807 default:
808 break;
809 }
810
811 return ret;
812}
813
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400814static int fm10k_mbx_test(struct fm10k_intfc *interface, u64 *data)
815{
816 struct fm10k_hw *hw = &interface->hw;
817 struct fm10k_mbx_info *mbx = &hw->mbx;
818 u32 attr_flag, test_msg[6];
819 unsigned long timeout;
820 int err;
821
822 /* For now this is a VF only feature */
823 if (hw->mac.type != fm10k_mac_vf)
824 return 0;
825
826 /* loop through both nested and unnested attribute types */
827 for (attr_flag = (1 << FM10K_TEST_MSG_UNSET);
828 attr_flag < (1 << (2 * FM10K_TEST_MSG_NESTED));
829 attr_flag += attr_flag) {
830 /* generate message to be tested */
831 fm10k_tlv_msg_test_create(test_msg, attr_flag);
832
833 fm10k_mbx_lock(interface);
834 mbx->test_result = FM10K_NOT_IMPLEMENTED;
835 err = mbx->ops.enqueue_tx(hw, mbx, test_msg);
836 fm10k_mbx_unlock(interface);
837
838 /* wait up to 1 second for response */
839 timeout = jiffies + HZ;
840 do {
841 if (err < 0)
842 goto err_out;
843
844 usleep_range(500, 1000);
845
846 fm10k_mbx_lock(interface);
847 mbx->ops.process(hw, mbx);
848 fm10k_mbx_unlock(interface);
849
850 err = mbx->test_result;
851 if (!err)
852 break;
853 } while (time_is_after_jiffies(timeout));
854
855 /* reporting errors */
856 if (err)
857 goto err_out;
858 }
859
860err_out:
861 *data = err < 0 ? (attr_flag) : (err > 0);
862 return err;
863}
864
865static void fm10k_self_test(struct net_device *dev,
866 struct ethtool_test *eth_test, u64 *data)
867{
868 struct fm10k_intfc *interface = netdev_priv(dev);
869 struct fm10k_hw *hw = &interface->hw;
870
871 memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
872
873 if (FM10K_REMOVED(hw)) {
874 netif_err(interface, drv, dev,
875 "Interface removed - test blocked\n");
876 eth_test->flags |= ETH_TEST_FL_FAILED;
877 return;
878 }
879
880 if (fm10k_mbx_test(interface, &data[FM10K_TEST_MBX]))
881 eth_test->flags |= ETH_TEST_FL_FAILED;
882}
883
Jeff Kirsherde445192015-04-03 13:26:56 -0700884static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400885{
886 return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
887}
888
889static int fm10k_get_reta(struct net_device *netdev, u32 *indir)
890{
891 struct fm10k_intfc *interface = netdev_priv(netdev);
892 int i;
893
894 if (!indir)
895 return 0;
896
897 for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
898 u32 reta = interface->reta[i];
899
900 indir[0] = (reta << 24) >> 24;
901 indir[1] = (reta << 16) >> 24;
902 indir[2] = (reta << 8) >> 24;
903 indir[3] = (reta) >> 24;
904 }
905
906 return 0;
907}
908
909static int fm10k_set_reta(struct net_device *netdev, const u32 *indir)
910{
911 struct fm10k_intfc *interface = netdev_priv(netdev);
912 struct fm10k_hw *hw = &interface->hw;
913 int i;
914 u16 rss_i;
915
916 if (!indir)
917 return 0;
918
919 /* Verify user input. */
920 rss_i = interface->ring_feature[RING_F_RSS].indices;
921 for (i = fm10k_get_reta_size(netdev); i--;) {
922 if (indir[i] < rss_i)
923 continue;
924 return -EINVAL;
925 }
926
927 /* record entries to reta table */
928 for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
929 u32 reta = indir[0] |
930 (indir[1] << 8) |
931 (indir[2] << 16) |
932 (indir[3] << 24);
933
934 if (interface->reta[i] == reta)
935 continue;
936
937 interface->reta[i] = reta;
938 fm10k_write_reg(hw, FM10K_RETA(0, i), reta);
939 }
940
941 return 0;
942}
943
Jeff Kirsherde445192015-04-03 13:26:56 -0700944static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400945{
946 return FM10K_RSSRK_SIZE * FM10K_RSSRK_ENTRIES_PER_REG;
947}
948
Eyal Perry892311f2014-12-02 18:12:10 +0200949static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
950 u8 *hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400951{
952 struct fm10k_intfc *interface = netdev_priv(netdev);
953 int i, err;
954
Eyal Perry892311f2014-12-02 18:12:10 +0200955 if (hfunc)
956 *hfunc = ETH_RSS_HASH_TOP;
957
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400958 err = fm10k_get_reta(netdev, indir);
959 if (err || !key)
960 return err;
961
962 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4)
963 *(__le32 *)key = cpu_to_le32(interface->rssrk[i]);
964
965 return 0;
966}
967
968static int fm10k_set_rssh(struct net_device *netdev, const u32 *indir,
Eyal Perry892311f2014-12-02 18:12:10 +0200969 const u8 *key, const u8 hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400970{
971 struct fm10k_intfc *interface = netdev_priv(netdev);
972 struct fm10k_hw *hw = &interface->hw;
973 int i, err;
974
Eyal Perry892311f2014-12-02 18:12:10 +0200975 /* We do not allow change in unsupported parameters */
976 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
977 return -EOPNOTSUPP;
978
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400979 err = fm10k_set_reta(netdev, indir);
980 if (err || !key)
981 return err;
982
983 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4) {
984 u32 rssrk = le32_to_cpu(*(__le32 *)key);
985
986 if (interface->rssrk[i] == rssrk)
987 continue;
988
989 interface->rssrk[i] = rssrk;
990 fm10k_write_reg(hw, FM10K_RSSRK(0, i), rssrk);
991 }
992
993 return 0;
994}
995
Alexander Duyckaa3ac822014-09-20 19:50:42 -0400996static unsigned int fm10k_max_channels(struct net_device *dev)
997{
998 struct fm10k_intfc *interface = netdev_priv(dev);
999 unsigned int max_combined = interface->hw.mac.max_queues;
1000 u8 tcs = netdev_get_num_tc(dev);
1001
1002 /* For QoS report channels per traffic class */
1003 if (tcs > 1)
1004 max_combined = 1 << (fls(max_combined / tcs) - 1);
1005
1006 return max_combined;
1007}
1008
1009static void fm10k_get_channels(struct net_device *dev,
1010 struct ethtool_channels *ch)
1011{
1012 struct fm10k_intfc *interface = netdev_priv(dev);
1013 struct fm10k_hw *hw = &interface->hw;
1014
1015 /* report maximum channels */
1016 ch->max_combined = fm10k_max_channels(dev);
1017
1018 /* report info for other vector */
1019 ch->max_other = NON_Q_VECTORS(hw);
1020 ch->other_count = ch->max_other;
1021
1022 /* record RSS queues */
1023 ch->combined_count = interface->ring_feature[RING_F_RSS].indices;
1024}
1025
1026static int fm10k_set_channels(struct net_device *dev,
1027 struct ethtool_channels *ch)
1028{
1029 struct fm10k_intfc *interface = netdev_priv(dev);
1030 unsigned int count = ch->combined_count;
1031 struct fm10k_hw *hw = &interface->hw;
1032
1033 /* verify they are not requesting separate vectors */
1034 if (!count || ch->rx_count || ch->tx_count)
1035 return -EINVAL;
1036
1037 /* verify other_count has not changed */
1038 if (ch->other_count != NON_Q_VECTORS(hw))
1039 return -EINVAL;
1040
1041 /* verify the number of channels does not exceed hardware limits */
1042 if (count > fm10k_max_channels(dev))
1043 return -EINVAL;
1044
1045 interface->ring_feature[RING_F_RSS].limit = count;
1046
1047 /* use setup TC to update any traffic class queue mapping */
1048 return fm10k_setup_tc(dev, netdev_get_num_tc(dev));
1049}
1050
Alexander Duycka211e012014-09-20 19:54:07 -04001051static int fm10k_get_ts_info(struct net_device *dev,
Matthew Vickeca32042015-01-31 02:23:05 +00001052 struct ethtool_ts_info *info)
Alexander Duycka211e012014-09-20 19:54:07 -04001053{
1054 struct fm10k_intfc *interface = netdev_priv(dev);
1055
1056 info->so_timestamping =
1057 SOF_TIMESTAMPING_TX_SOFTWARE |
1058 SOF_TIMESTAMPING_RX_SOFTWARE |
1059 SOF_TIMESTAMPING_SOFTWARE |
1060 SOF_TIMESTAMPING_TX_HARDWARE |
1061 SOF_TIMESTAMPING_RX_HARDWARE |
1062 SOF_TIMESTAMPING_RAW_HARDWARE;
1063
1064 if (interface->ptp_clock)
1065 info->phc_index = ptp_clock_index(interface->ptp_clock);
1066 else
1067 info->phc_index = -1;
1068
1069 info->tx_types = (1 << HWTSTAMP_TX_OFF) |
1070 (1 << HWTSTAMP_TX_ON);
1071
1072 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
1073 (1 << HWTSTAMP_FILTER_ALL);
1074
1075 return 0;
1076}
1077
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001078static const struct ethtool_ops fm10k_ethtool_ops = {
1079 .get_strings = fm10k_get_strings,
1080 .get_sset_count = fm10k_get_sset_count,
1081 .get_ethtool_stats = fm10k_get_ethtool_stats,
1082 .get_drvinfo = fm10k_get_drvinfo,
1083 .get_link = ethtool_op_get_link,
1084 .get_pauseparam = fm10k_get_pauseparam,
1085 .set_pauseparam = fm10k_set_pauseparam,
1086 .get_msglevel = fm10k_get_msglevel,
1087 .set_msglevel = fm10k_set_msglevel,
1088 .get_ringparam = fm10k_get_ringparam,
1089 .set_ringparam = fm10k_set_ringparam,
1090 .get_coalesce = fm10k_get_coalesce,
1091 .set_coalesce = fm10k_set_coalesce,
1092 .get_rxnfc = fm10k_get_rxnfc,
1093 .set_rxnfc = fm10k_set_rxnfc,
1094 .get_regs = fm10k_get_regs,
1095 .get_regs_len = fm10k_get_regs_len,
Alexander Duyck5cb8db42014-09-20 19:51:40 -04001096 .self_test = fm10k_self_test,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001097 .get_rxfh_indir_size = fm10k_get_reta_size,
1098 .get_rxfh_key_size = fm10k_get_rssrk_size,
1099 .get_rxfh = fm10k_get_rssh,
1100 .set_rxfh = fm10k_set_rssh,
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001101 .get_channels = fm10k_get_channels,
1102 .set_channels = fm10k_set_channels,
Alexander Duycka211e012014-09-20 19:54:07 -04001103 .get_ts_info = fm10k_get_ts_info,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001104};
1105
1106void fm10k_set_ethtool_ops(struct net_device *dev)
1107{
1108 dev->ethtool_ops = &fm10k_ethtool_ops;
1109}