blob: c67121cc7b235a215f2b068d81aea08014ce558e [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
Jeff Kirshere05546e2015-04-03 13:27:03 -070079 FM10K_STAT("tx_hang_count", tx_timeout_count),
80
Alexander Duycka211e012014-09-20 19:54:07 -040081 FM10K_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
Alexander Duyck82dd0f72014-09-20 19:50:15 -040082};
83
Jacob Keller80043f32015-07-01 17:38:36 -070084static const struct fm10k_stats fm10k_gstrings_debug_stats[] = {
85 FM10K_STAT("hw_sm_mbx_full", hw_sm_mbx_full),
86 FM10K_STAT("hw_csum_tx_good", hw_csum_tx_good),
87 FM10K_STAT("hw_csum_rx_good", hw_csum_rx_good),
88 FM10K_STAT("rx_switch_errors", rx_switch_errors),
89 FM10K_STAT("rx_drops", rx_drops),
90 FM10K_STAT("rx_pp_errors", rx_pp_errors),
91 FM10K_STAT("rx_link_errors", rx_link_errors),
92 FM10K_STAT("rx_length_errors", rx_length_errors),
93};
94
Jeff Kirsherfbdb1592015-04-03 13:27:00 -070095static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
96 FM10K_STAT("timeout", stats.timeout.count),
97 FM10K_STAT("ur", stats.ur.count),
98 FM10K_STAT("ca", stats.ca.count),
99 FM10K_STAT("um", stats.um.count),
100 FM10K_STAT("xec", stats.xec.count),
101 FM10K_STAT("vlan_drop", stats.vlan_drop.count),
102 FM10K_STAT("loopback_drop", stats.loopback_drop.count),
103 FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
104};
105
Jacob Keller80043f32015-07-01 17:38:36 -0700106#define FM10K_MBX_STAT(_name, _stat) { \
107 .stat_string = _name, \
108 .sizeof_stat = FIELD_SIZEOF(struct fm10k_mbx_info, _stat), \
109 .stat_offset = offsetof(struct fm10k_mbx_info, _stat) \
110}
111
112static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
113 FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
Jacob Keller5680ea62015-10-16 10:57:03 -0700114 FM10K_MBX_STAT("mbx_tx_dropped", tx_dropped),
Jacob Keller80043f32015-07-01 17:38:36 -0700115 FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
116 FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
Jacob Keller17d39fa2015-10-16 10:57:02 -0700117 FM10K_MBX_STAT("mbx_tx_mbmem_pulled", tx_mbmem_pulled),
Jacob Keller80043f32015-07-01 17:38:36 -0700118 FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
119 FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
120 FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
Jacob Keller17d39fa2015-10-16 10:57:02 -0700121 FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed),
Jacob Keller80043f32015-07-01 17:38:36 -0700122};
123
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700124#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
Jacob Keller80043f32015-07-01 17:38:36 -0700125#define FM10K_DEBUG_STATS_LEN ARRAY_SIZE(fm10k_gstrings_debug_stats)
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700126#define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats)
Jacob Keller80043f32015-07-01 17:38:36 -0700127#define FM10K_MBX_STATS_LEN ARRAY_SIZE(fm10k_gstrings_mbx_stats)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400128
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700129#define FM10K_QUEUE_STATS_LEN(_n) \
Bruce Allana4fcad62015-10-28 17:19:40 -0700130 ((_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64)))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400131
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700132#define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
Jacob Keller80043f32015-07-01 17:38:36 -0700133 FM10K_NETDEV_STATS_LEN + \
134 FM10K_MBX_STATS_LEN)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400135
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400136static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
137 "Mailbox test (on/offline)"
138};
139
140#define FM10K_TEST_LEN (sizeof(fm10k_gstrings_test) / ETH_GSTRING_LEN)
141
142enum fm10k_self_test_types {
143 FM10K_TEST_MBX,
144 FM10K_TEST_MAX = FM10K_TEST_LEN
145};
146
Jacob Keller80043f32015-07-01 17:38:36 -0700147enum {
148 FM10K_PRV_FLAG_DEBUG_STATS,
149 FM10K_PRV_FLAG_LEN,
150};
151
152static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
153 "debug-statistics",
154};
155
Jacob Kellerd2e07212016-02-05 10:43:08 -0800156static void fm10k_add_stat_strings(char **p, const char *prefix,
157 const struct fm10k_stats stats[],
158 const unsigned int size)
159{
160 unsigned int i;
161
162 for (i = 0; i < size; i++) {
163 snprintf(*p, ETH_GSTRING_LEN, "%s%s",
164 prefix, stats[i].stat_string);
165 *p += ETH_GSTRING_LEN;
166 }
167}
168
Jacob Keller80043f32015-07-01 17:38:36 -0700169static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400170{
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700171 struct fm10k_intfc *interface = netdev_priv(dev);
Jacob Keller80043f32015-07-01 17:38:36 -0700172 struct fm10k_iov_data *iov_data = interface->iov_data;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400173 char *p = (char *)data;
Jacob Kellerc0e58e92015-06-16 13:39:11 -0700174 unsigned int i;
Jacob Keller80043f32015-07-01 17:38:36 -0700175
Jacob Kellerd2e07212016-02-05 10:43:08 -0800176 fm10k_add_stat_strings(&p, "", fm10k_gstrings_net_stats,
177 FM10K_NETDEV_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700178
Jacob Kellerd2e07212016-02-05 10:43:08 -0800179 fm10k_add_stat_strings(&p, "", fm10k_gstrings_global_stats,
180 FM10K_GLOBAL_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700181
Jacob Kellerd2e07212016-02-05 10:43:08 -0800182 if (interface->flags & FM10K_FLAG_DEBUG_STATS)
183 fm10k_add_stat_strings(&p, "", fm10k_gstrings_debug_stats,
184 FM10K_DEBUG_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700185
Jacob Kellerd2e07212016-02-05 10:43:08 -0800186 fm10k_add_stat_strings(&p, "", fm10k_gstrings_mbx_stats,
187 FM10K_MBX_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700188
Jacob Kellerd2e07212016-02-05 10:43:08 -0800189 if (interface->hw.mac.type != fm10k_mac_vf)
190 fm10k_add_stat_strings(&p, "", fm10k_gstrings_pf_stats,
191 FM10K_PF_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700192
193 if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
194 for (i = 0; i < iov_data->num_vfs; i++) {
Jacob Kellerd2e07212016-02-05 10:43:08 -0800195 char prefix[ETH_GSTRING_LEN];
196
197 snprintf(prefix, ETH_GSTRING_LEN, "vf_%u_", i);
198 fm10k_add_stat_strings(&p, prefix,
199 fm10k_gstrings_mbx_stats,
200 FM10K_MBX_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700201 }
202 }
203
204 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Jacob Kellerf6f19f82015-08-24 17:01:58 -0700205 snprintf(p, ETH_GSTRING_LEN, "tx_queue_%u_packets", i);
Jacob Keller80043f32015-07-01 17:38:36 -0700206 p += ETH_GSTRING_LEN;
Jacob Kellerf6f19f82015-08-24 17:01:58 -0700207 snprintf(p, ETH_GSTRING_LEN, "tx_queue_%u_bytes", i);
Jacob Keller80043f32015-07-01 17:38:36 -0700208 p += ETH_GSTRING_LEN;
Jacob Kellerf6f19f82015-08-24 17:01:58 -0700209 snprintf(p, ETH_GSTRING_LEN, "rx_queue_%u_packets", i);
Jacob Keller80043f32015-07-01 17:38:36 -0700210 p += ETH_GSTRING_LEN;
Jacob Kellerf6f19f82015-08-24 17:01:58 -0700211 snprintf(p, ETH_GSTRING_LEN, "rx_queue_%u_bytes", i);
Jacob Keller80043f32015-07-01 17:38:36 -0700212 p += ETH_GSTRING_LEN;
213 }
214}
215
216static void fm10k_get_strings(struct net_device *dev,
217 u32 stringset, u8 *data)
218{
219 char *p = (char *)data;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400220
221 switch (stringset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400222 case ETH_SS_TEST:
223 memcpy(data, *fm10k_gstrings_test,
224 FM10K_TEST_LEN * ETH_GSTRING_LEN);
225 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400226 case ETH_SS_STATS:
Jacob Keller80043f32015-07-01 17:38:36 -0700227 fm10k_get_stat_strings(dev, data);
228 break;
229 case ETH_SS_PRIV_FLAGS:
230 memcpy(p, fm10k_prv_flags,
231 FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400232 break;
233 }
234}
235
236static int fm10k_get_sset_count(struct net_device *dev, int sset)
237{
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700238 struct fm10k_intfc *interface = netdev_priv(dev);
Jacob Keller80043f32015-07-01 17:38:36 -0700239 struct fm10k_iov_data *iov_data = interface->iov_data;
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700240 struct fm10k_hw *hw = &interface->hw;
241 int stats_len = FM10K_STATIC_STATS_LEN;
242
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400243 switch (sset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400244 case ETH_SS_TEST:
245 return FM10K_TEST_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400246 case ETH_SS_STATS:
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700247 stats_len += FM10K_QUEUE_STATS_LEN(hw->mac.max_queues);
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700248
249 if (hw->mac.type != fm10k_mac_vf)
250 stats_len += FM10K_PF_STATS_LEN;
251
Jacob Keller80043f32015-07-01 17:38:36 -0700252 if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
253 stats_len += FM10K_DEBUG_STATS_LEN;
254
255 if (iov_data)
Bruce Allan3d02b3d2015-10-28 17:19:56 -0700256 stats_len += FM10K_MBX_STATS_LEN *
257 iov_data->num_vfs;
Jacob Keller80043f32015-07-01 17:38:36 -0700258 }
259
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700260 return stats_len;
Jacob Keller80043f32015-07-01 17:38:36 -0700261 case ETH_SS_PRIV_FLAGS:
262 return FM10K_PRV_FLAG_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400263 default:
264 return -EOPNOTSUPP;
265 }
266}
267
Jacob Kellerd2e07212016-02-05 10:43:08 -0800268static void fm10k_add_ethtool_stats(u64 **data, void *pointer,
269 const struct fm10k_stats stats[],
270 const unsigned int size)
271{
272 unsigned int i;
273 char *p;
274
275 /* simply skip forward if we were not given a valid pointer */
276 if (!pointer) {
277 *data += size;
278 return;
279 }
280
281 for (i = 0; i < size; i++) {
282 p = (char *)pointer + stats[i].stat_offset;
283
284 switch (stats[i].sizeof_stat) {
285 case sizeof(u64):
286 *((*data)++) = *(u64 *)p;
287 break;
288 case sizeof(u32):
289 *((*data)++) = *(u32 *)p;
290 break;
291 case sizeof(u16):
292 *((*data)++) = *(u16 *)p;
293 break;
294 case sizeof(u8):
295 *((*data)++) = *(u8 *)p;
296 break;
297 default:
298 *((*data)++) = 0;
299 }
300 }
301}
302
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400303static void fm10k_get_ethtool_stats(struct net_device *netdev,
Jeff Kirsherde445192015-04-03 13:26:56 -0700304 struct ethtool_stats __always_unused *stats,
305 u64 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400306{
307 const int stat_count = sizeof(struct fm10k_queue_stats) / sizeof(u64);
308 struct fm10k_intfc *interface = netdev_priv(netdev);
Jacob Keller80043f32015-07-01 17:38:36 -0700309 struct fm10k_iov_data *iov_data = interface->iov_data;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400310 struct net_device_stats *net_stats = &netdev->stats;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400311 int i, j;
312
313 fm10k_update_stats(interface);
314
Jacob Kellerd2e07212016-02-05 10:43:08 -0800315 fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats,
316 FM10K_NETDEV_STATS_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400317
Jacob Kellerd2e07212016-02-05 10:43:08 -0800318 fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats,
319 FM10K_GLOBAL_STATS_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400320
Jacob Kellerd2e07212016-02-05 10:43:08 -0800321 if (interface->flags & FM10K_FLAG_DEBUG_STATS)
322 fm10k_add_ethtool_stats(&data, interface,
323 fm10k_gstrings_debug_stats,
324 FM10K_DEBUG_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700325
Jacob Kellerd2e07212016-02-05 10:43:08 -0800326 fm10k_add_ethtool_stats(&data, &interface->hw.mbx,
327 fm10k_gstrings_mbx_stats,
328 FM10K_MBX_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700329
330 if (interface->hw.mac.type != fm10k_mac_vf) {
Jacob Kellerd2e07212016-02-05 10:43:08 -0800331 fm10k_add_ethtool_stats(&data, interface,
332 fm10k_gstrings_pf_stats,
333 FM10K_PF_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700334 }
335
336 if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
337 for (i = 0; i < iov_data->num_vfs; i++) {
338 struct fm10k_vf_info *vf_info;
Bruce Allana4fcad62015-10-28 17:19:40 -0700339
Jacob Keller80043f32015-07-01 17:38:36 -0700340 vf_info = &iov_data->vf_info[i];
341
Jacob Kellerd2e07212016-02-05 10:43:08 -0800342 fm10k_add_ethtool_stats(&data, &vf_info->mbx,
343 fm10k_gstrings_mbx_stats,
344 FM10K_MBX_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700345 }
346 }
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700347
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700348 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400349 struct fm10k_ring *ring;
350 u64 *queue_stat;
351
352 ring = interface->tx_ring[i];
353 if (ring)
354 queue_stat = (u64 *)&ring->stats;
355 for (j = 0; j < stat_count; j++)
356 *(data++) = ring ? queue_stat[j] : 0;
357
358 ring = interface->rx_ring[i];
359 if (ring)
360 queue_stat = (u64 *)&ring->stats;
361 for (j = 0; j < stat_count; j++)
362 *(data++) = ring ? queue_stat[j] : 0;
363 }
364}
365
366/* If function below adds more registers this define needs to be updated */
367#define FM10K_REGS_LEN_Q 29
368
369static void fm10k_get_reg_q(struct fm10k_hw *hw, u32 *buff, int i)
370{
371 int idx = 0;
372
373 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAL(i));
374 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAH(i));
375 buff[idx++] = fm10k_read_reg(hw, FM10K_RDLEN(i));
376 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_RXCTRL(i));
377 buff[idx++] = fm10k_read_reg(hw, FM10K_RDH(i));
378 buff[idx++] = fm10k_read_reg(hw, FM10K_RDT(i));
379 buff[idx++] = fm10k_read_reg(hw, FM10K_RXQCTL(i));
380 buff[idx++] = fm10k_read_reg(hw, FM10K_RXDCTL(i));
381 buff[idx++] = fm10k_read_reg(hw, FM10K_RXINT(i));
382 buff[idx++] = fm10k_read_reg(hw, FM10K_SRRCTL(i));
383 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRC(i));
384 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRDC(i));
385 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_L(i));
386 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_H(i));
387 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAL(i));
388 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAH(i));
389 buff[idx++] = fm10k_read_reg(hw, FM10K_TDLEN(i));
390 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_TXCTRL(i));
391 buff[idx++] = fm10k_read_reg(hw, FM10K_TDH(i));
392 buff[idx++] = fm10k_read_reg(hw, FM10K_TDT(i));
393 buff[idx++] = fm10k_read_reg(hw, FM10K_TXDCTL(i));
394 buff[idx++] = fm10k_read_reg(hw, FM10K_TXQCTL(i));
395 buff[idx++] = fm10k_read_reg(hw, FM10K_TXINT(i));
396 buff[idx++] = fm10k_read_reg(hw, FM10K_QPTC(i));
397 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_L(i));
398 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_H(i));
399 buff[idx++] = fm10k_read_reg(hw, FM10K_TQDLOC(i));
400 buff[idx++] = fm10k_read_reg(hw, FM10K_TX_SGLORT(i));
401 buff[idx++] = fm10k_read_reg(hw, FM10K_PFVTCTL(i));
402
403 BUG_ON(idx != FM10K_REGS_LEN_Q);
404}
405
406/* If function above adds more registers this define needs to be updated */
407#define FM10K_REGS_LEN_VSI 43
408
409static void fm10k_get_reg_vsi(struct fm10k_hw *hw, u32 *buff, int i)
410{
411 int idx = 0, j;
412
413 buff[idx++] = fm10k_read_reg(hw, FM10K_MRQC(i));
414 for (j = 0; j < 10; j++)
415 buff[idx++] = fm10k_read_reg(hw, FM10K_RSSRK(i, j));
416 for (j = 0; j < 32; j++)
417 buff[idx++] = fm10k_read_reg(hw, FM10K_RETA(i, j));
418
419 BUG_ON(idx != FM10K_REGS_LEN_VSI);
420}
421
422static void fm10k_get_regs(struct net_device *netdev,
423 struct ethtool_regs *regs, void *p)
424{
425 struct fm10k_intfc *interface = netdev_priv(netdev);
426 struct fm10k_hw *hw = &interface->hw;
427 u32 *buff = p;
428 u16 i;
429
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800430 regs->version = BIT(24) | (hw->revision_id << 16) | hw->device_id;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400431
432 switch (hw->mac.type) {
433 case fm10k_mac_pf:
434 /* General PF Registers */
435 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL);
436 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL_EXT);
437 *(buff++) = fm10k_read_reg(hw, FM10K_GCR);
438 *(buff++) = fm10k_read_reg(hw, FM10K_GCR_EXT);
439
440 for (i = 0; i < 8; i++) {
441 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTMAP(i));
442 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTDEC(i));
443 }
444
445 for (i = 0; i < 65; i++) {
446 fm10k_get_reg_vsi(hw, buff, i);
447 buff += FM10K_REGS_LEN_VSI;
448 }
449
450 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL);
451 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
452
453 for (i = 0; i < FM10K_MAX_QUEUES_PF; i++) {
454 fm10k_get_reg_q(hw, buff, i);
455 buff += FM10K_REGS_LEN_Q;
456 }
457
458 *(buff++) = fm10k_read_reg(hw, FM10K_TPH_CTRL);
459
460 for (i = 0; i < 8; i++)
461 *(buff++) = fm10k_read_reg(hw, FM10K_INT_MAP(i));
462
463 /* Interrupt Throttling Registers */
464 for (i = 0; i < 130; i++)
465 *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
466
467 break;
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400468 case fm10k_mac_vf:
469 /* General VF registers */
470 *(buff++) = fm10k_read_reg(hw, FM10K_VFCTRL);
471 *(buff++) = fm10k_read_reg(hw, FM10K_VFINT_MAP);
472 *(buff++) = fm10k_read_reg(hw, FM10K_VFSYSTIME);
473
474 /* Interrupt Throttling Registers */
475 for (i = 0; i < 8; i++)
476 *(buff++) = fm10k_read_reg(hw, FM10K_VFITR(i));
477
478 fm10k_get_reg_vsi(hw, buff, 0);
479 buff += FM10K_REGS_LEN_VSI;
480
481 for (i = 0; i < FM10K_MAX_QUEUES_POOL; i++) {
482 if (i < hw->mac.max_queues)
483 fm10k_get_reg_q(hw, buff, i);
484 else
485 memset(buff, 0, sizeof(u32) * FM10K_REGS_LEN_Q);
486 buff += FM10K_REGS_LEN_Q;
487 }
488
489 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400490 default:
491 return;
492 }
493}
494
495/* If function above adds more registers these define need to be updated */
496#define FM10K_REGS_LEN_PF \
497(162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q))
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400498#define FM10K_REGS_LEN_VF \
499(11 + FM10K_REGS_LEN_VSI + (FM10K_MAX_QUEUES_POOL * FM10K_REGS_LEN_Q))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400500
501static int fm10k_get_regs_len(struct net_device *netdev)
502{
503 struct fm10k_intfc *interface = netdev_priv(netdev);
504 struct fm10k_hw *hw = &interface->hw;
505
506 switch (hw->mac.type) {
507 case fm10k_mac_pf:
508 return FM10K_REGS_LEN_PF * sizeof(u32);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400509 case fm10k_mac_vf:
510 return FM10K_REGS_LEN_VF * sizeof(u32);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400511 default:
512 return 0;
513 }
514}
515
516static void fm10k_get_drvinfo(struct net_device *dev,
517 struct ethtool_drvinfo *info)
518{
519 struct fm10k_intfc *interface = netdev_priv(dev);
520
521 strncpy(info->driver, fm10k_driver_name,
522 sizeof(info->driver) - 1);
523 strncpy(info->version, fm10k_driver_version,
524 sizeof(info->version) - 1);
525 strncpy(info->bus_info, pci_name(interface->pdev),
526 sizeof(info->bus_info) - 1);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400527}
528
529static void fm10k_get_pauseparam(struct net_device *dev,
530 struct ethtool_pauseparam *pause)
531{
532 struct fm10k_intfc *interface = netdev_priv(dev);
533
534 /* record fixed values for autoneg and tx pause */
535 pause->autoneg = 0;
536 pause->tx_pause = 1;
537
538 pause->rx_pause = interface->rx_pause ? 1 : 0;
539}
540
541static int fm10k_set_pauseparam(struct net_device *dev,
542 struct ethtool_pauseparam *pause)
543{
544 struct fm10k_intfc *interface = netdev_priv(dev);
545 struct fm10k_hw *hw = &interface->hw;
546
547 if (pause->autoneg || !pause->tx_pause)
548 return -EINVAL;
549
550 /* we can only support pause on the PF to avoid head-of-line blocking */
551 if (hw->mac.type == fm10k_mac_pf)
552 interface->rx_pause = pause->rx_pause ? ~0 : 0;
553 else if (pause->rx_pause)
554 return -EINVAL;
555
556 if (netif_running(dev))
557 fm10k_update_rx_drop_en(interface);
558
559 return 0;
560}
561
562static u32 fm10k_get_msglevel(struct net_device *netdev)
563{
564 struct fm10k_intfc *interface = netdev_priv(netdev);
565
566 return interface->msg_enable;
567}
568
569static void fm10k_set_msglevel(struct net_device *netdev, u32 data)
570{
571 struct fm10k_intfc *interface = netdev_priv(netdev);
572
573 interface->msg_enable = data;
574}
575
576static void fm10k_get_ringparam(struct net_device *netdev,
577 struct ethtool_ringparam *ring)
578{
579 struct fm10k_intfc *interface = netdev_priv(netdev);
580
581 ring->rx_max_pending = FM10K_MAX_RXD;
582 ring->tx_max_pending = FM10K_MAX_TXD;
583 ring->rx_mini_max_pending = 0;
584 ring->rx_jumbo_max_pending = 0;
585 ring->rx_pending = interface->rx_ring_count;
586 ring->tx_pending = interface->tx_ring_count;
587 ring->rx_mini_pending = 0;
588 ring->rx_jumbo_pending = 0;
589}
590
591static int fm10k_set_ringparam(struct net_device *netdev,
592 struct ethtool_ringparam *ring)
593{
594 struct fm10k_intfc *interface = netdev_priv(netdev);
595 struct fm10k_ring *temp_ring;
596 int i, err = 0;
597 u32 new_rx_count, new_tx_count;
598
599 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
600 return -EINVAL;
601
602 new_tx_count = clamp_t(u32, ring->tx_pending,
603 FM10K_MIN_TXD, FM10K_MAX_TXD);
604 new_tx_count = ALIGN(new_tx_count, FM10K_REQ_TX_DESCRIPTOR_MULTIPLE);
605
606 new_rx_count = clamp_t(u32, ring->rx_pending,
607 FM10K_MIN_RXD, FM10K_MAX_RXD);
608 new_rx_count = ALIGN(new_rx_count, FM10K_REQ_RX_DESCRIPTOR_MULTIPLE);
609
610 if ((new_tx_count == interface->tx_ring_count) &&
611 (new_rx_count == interface->rx_ring_count)) {
612 /* nothing to do */
613 return 0;
614 }
615
616 while (test_and_set_bit(__FM10K_RESETTING, &interface->state))
617 usleep_range(1000, 2000);
618
619 if (!netif_running(interface->netdev)) {
620 for (i = 0; i < interface->num_tx_queues; i++)
621 interface->tx_ring[i]->count = new_tx_count;
622 for (i = 0; i < interface->num_rx_queues; i++)
623 interface->rx_ring[i]->count = new_rx_count;
624 interface->tx_ring_count = new_tx_count;
625 interface->rx_ring_count = new_rx_count;
626 goto clear_reset;
627 }
628
629 /* allocate temporary buffer to store rings in */
630 i = max_t(int, interface->num_tx_queues, interface->num_rx_queues);
631 temp_ring = vmalloc(i * sizeof(struct fm10k_ring));
632
633 if (!temp_ring) {
634 err = -ENOMEM;
635 goto clear_reset;
636 }
637
638 fm10k_down(interface);
639
640 /* Setup new Tx resources and free the old Tx resources in that order.
641 * We can then assign the new resources to the rings via a memcpy.
642 * The advantage to this approach is that we are guaranteed to still
643 * have resources even in the case of an allocation failure.
644 */
645 if (new_tx_count != interface->tx_ring_count) {
646 for (i = 0; i < interface->num_tx_queues; i++) {
647 memcpy(&temp_ring[i], interface->tx_ring[i],
648 sizeof(struct fm10k_ring));
649
650 temp_ring[i].count = new_tx_count;
651 err = fm10k_setup_tx_resources(&temp_ring[i]);
652 if (err) {
653 while (i) {
654 i--;
655 fm10k_free_tx_resources(&temp_ring[i]);
656 }
657 goto err_setup;
658 }
659 }
660
661 for (i = 0; i < interface->num_tx_queues; i++) {
662 fm10k_free_tx_resources(interface->tx_ring[i]);
663
664 memcpy(interface->tx_ring[i], &temp_ring[i],
665 sizeof(struct fm10k_ring));
666 }
667
668 interface->tx_ring_count = new_tx_count;
669 }
670
671 /* Repeat the process for the Rx rings if needed */
672 if (new_rx_count != interface->rx_ring_count) {
673 for (i = 0; i < interface->num_rx_queues; i++) {
674 memcpy(&temp_ring[i], interface->rx_ring[i],
675 sizeof(struct fm10k_ring));
676
677 temp_ring[i].count = new_rx_count;
678 err = fm10k_setup_rx_resources(&temp_ring[i]);
679 if (err) {
680 while (i) {
681 i--;
682 fm10k_free_rx_resources(&temp_ring[i]);
683 }
684 goto err_setup;
685 }
686 }
687
688 for (i = 0; i < interface->num_rx_queues; i++) {
689 fm10k_free_rx_resources(interface->rx_ring[i]);
690
691 memcpy(interface->rx_ring[i], &temp_ring[i],
692 sizeof(struct fm10k_ring));
693 }
694
695 interface->rx_ring_count = new_rx_count;
696 }
697
698err_setup:
699 fm10k_up(interface);
700 vfree(temp_ring);
701clear_reset:
702 clear_bit(__FM10K_RESETTING, &interface->state);
703 return err;
704}
705
706static int fm10k_get_coalesce(struct net_device *dev,
707 struct ethtool_coalesce *ec)
708{
709 struct fm10k_intfc *interface = netdev_priv(dev);
710
Jacob Keller584373f2015-10-16 10:57:06 -0700711 ec->use_adaptive_tx_coalesce = ITR_IS_ADAPTIVE(interface->tx_itr);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400712 ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;
713
Jacob Keller584373f2015-10-16 10:57:06 -0700714 ec->use_adaptive_rx_coalesce = ITR_IS_ADAPTIVE(interface->rx_itr);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400715 ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;
716
717 return 0;
718}
719
720static int fm10k_set_coalesce(struct net_device *dev,
721 struct ethtool_coalesce *ec)
722{
723 struct fm10k_intfc *interface = netdev_priv(dev);
724 struct fm10k_q_vector *qv;
725 u16 tx_itr, rx_itr;
726 int i;
727
728 /* verify limits */
729 if ((ec->rx_coalesce_usecs > FM10K_ITR_MAX) ||
730 (ec->tx_coalesce_usecs > FM10K_ITR_MAX))
731 return -EINVAL;
732
733 /* record settings */
734 tx_itr = ec->tx_coalesce_usecs;
735 rx_itr = ec->rx_coalesce_usecs;
736
737 /* set initial values for adaptive ITR */
738 if (ec->use_adaptive_tx_coalesce)
Jacob Keller436ea952015-10-16 10:57:08 -0700739 tx_itr = FM10K_ITR_ADAPTIVE | FM10K_TX_ITR_DEFAULT;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400740
741 if (ec->use_adaptive_rx_coalesce)
Jacob Keller436ea952015-10-16 10:57:08 -0700742 rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400743
744 /* update interface */
745 interface->tx_itr = tx_itr;
746 interface->rx_itr = rx_itr;
747
748 /* update q_vectors */
749 for (i = 0; i < interface->num_q_vectors; i++) {
750 qv = interface->q_vector[i];
751 qv->tx.itr = tx_itr;
752 qv->rx.itr = rx_itr;
753 }
754
755 return 0;
756}
757
758static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
759 struct ethtool_rxnfc *cmd)
760{
761 cmd->data = 0;
762
763 /* Report default options for RSS on fm10k */
764 switch (cmd->flow_type) {
765 case TCP_V4_FLOW:
766 case TCP_V6_FLOW:
767 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
768 /* fall through */
769 case UDP_V4_FLOW:
770 if (interface->flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP)
771 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
772 /* fall through */
773 case SCTP_V4_FLOW:
774 case SCTP_V6_FLOW:
775 case AH_ESP_V4_FLOW:
776 case AH_ESP_V6_FLOW:
777 case AH_V4_FLOW:
778 case AH_V6_FLOW:
779 case ESP_V4_FLOW:
780 case ESP_V6_FLOW:
781 case IPV4_FLOW:
782 case IPV6_FLOW:
783 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
784 break;
785 case UDP_V6_FLOW:
786 if (interface->flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP)
787 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
788 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
789 break;
790 default:
791 return -EINVAL;
792 }
793
794 return 0;
795}
796
797static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
Jeff Kirsherde445192015-04-03 13:26:56 -0700798 u32 __always_unused *rule_locs)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400799{
800 struct fm10k_intfc *interface = netdev_priv(dev);
801 int ret = -EOPNOTSUPP;
802
803 switch (cmd->cmd) {
804 case ETHTOOL_GRXRINGS:
805 cmd->data = interface->num_rx_queues;
806 ret = 0;
807 break;
808 case ETHTOOL_GRXFH:
809 ret = fm10k_get_rss_hash_opts(interface, cmd);
810 break;
811 default:
812 break;
813 }
814
815 return ret;
816}
817
818#define UDP_RSS_FLAGS (FM10K_FLAG_RSS_FIELD_IPV4_UDP | \
819 FM10K_FLAG_RSS_FIELD_IPV6_UDP)
820static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
821 struct ethtool_rxnfc *nfc)
822{
823 u32 flags = interface->flags;
824
825 /* RSS does not support anything other than hashing
826 * to queues on src and dst IPs and ports
827 */
828 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
829 RXH_L4_B_0_1 | RXH_L4_B_2_3))
830 return -EINVAL;
831
832 switch (nfc->flow_type) {
833 case TCP_V4_FLOW:
834 case TCP_V6_FLOW:
835 if (!(nfc->data & RXH_IP_SRC) ||
836 !(nfc->data & RXH_IP_DST) ||
837 !(nfc->data & RXH_L4_B_0_1) ||
838 !(nfc->data & RXH_L4_B_2_3))
839 return -EINVAL;
840 break;
841 case UDP_V4_FLOW:
842 if (!(nfc->data & RXH_IP_SRC) ||
843 !(nfc->data & RXH_IP_DST))
844 return -EINVAL;
845 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
846 case 0:
847 flags &= ~FM10K_FLAG_RSS_FIELD_IPV4_UDP;
848 break;
849 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
850 flags |= FM10K_FLAG_RSS_FIELD_IPV4_UDP;
851 break;
852 default:
853 return -EINVAL;
854 }
855 break;
856 case UDP_V6_FLOW:
857 if (!(nfc->data & RXH_IP_SRC) ||
858 !(nfc->data & RXH_IP_DST))
859 return -EINVAL;
860 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
861 case 0:
862 flags &= ~FM10K_FLAG_RSS_FIELD_IPV6_UDP;
863 break;
864 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
865 flags |= FM10K_FLAG_RSS_FIELD_IPV6_UDP;
866 break;
867 default:
868 return -EINVAL;
869 }
870 break;
871 case AH_ESP_V4_FLOW:
872 case AH_V4_FLOW:
873 case ESP_V4_FLOW:
874 case SCTP_V4_FLOW:
875 case AH_ESP_V6_FLOW:
876 case AH_V6_FLOW:
877 case ESP_V6_FLOW:
878 case SCTP_V6_FLOW:
879 if (!(nfc->data & RXH_IP_SRC) ||
880 !(nfc->data & RXH_IP_DST) ||
881 (nfc->data & RXH_L4_B_0_1) ||
882 (nfc->data & RXH_L4_B_2_3))
883 return -EINVAL;
884 break;
885 default:
886 return -EINVAL;
887 }
888
889 /* if we changed something we need to update flags */
890 if (flags != interface->flags) {
891 struct fm10k_hw *hw = &interface->hw;
892 u32 mrqc;
893
894 if ((flags & UDP_RSS_FLAGS) &&
895 !(interface->flags & UDP_RSS_FLAGS))
896 netif_warn(interface, drv, interface->netdev,
897 "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
898
899 interface->flags = flags;
900
901 /* Perform hash on these packet types */
902 mrqc = FM10K_MRQC_IPV4 |
903 FM10K_MRQC_TCP_IPV4 |
904 FM10K_MRQC_IPV6 |
905 FM10K_MRQC_TCP_IPV6;
906
907 if (flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP)
908 mrqc |= FM10K_MRQC_UDP_IPV4;
909 if (flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP)
910 mrqc |= FM10K_MRQC_UDP_IPV6;
911
912 fm10k_write_reg(hw, FM10K_MRQC(0), mrqc);
913 }
914
915 return 0;
916}
917
918static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
919{
920 struct fm10k_intfc *interface = netdev_priv(dev);
921 int ret = -EOPNOTSUPP;
922
923 switch (cmd->cmd) {
924 case ETHTOOL_SRXFH:
925 ret = fm10k_set_rss_hash_opt(interface, cmd);
926 break;
927 default:
928 break;
929 }
930
931 return ret;
932}
933
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400934static int fm10k_mbx_test(struct fm10k_intfc *interface, u64 *data)
935{
936 struct fm10k_hw *hw = &interface->hw;
937 struct fm10k_mbx_info *mbx = &hw->mbx;
938 u32 attr_flag, test_msg[6];
939 unsigned long timeout;
940 int err;
941
942 /* For now this is a VF only feature */
943 if (hw->mac.type != fm10k_mac_vf)
944 return 0;
945
946 /* loop through both nested and unnested attribute types */
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800947 for (attr_flag = BIT(FM10K_TEST_MSG_UNSET);
948 attr_flag < BIT(2 * FM10K_TEST_MSG_NESTED);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400949 attr_flag += attr_flag) {
950 /* generate message to be tested */
951 fm10k_tlv_msg_test_create(test_msg, attr_flag);
952
953 fm10k_mbx_lock(interface);
954 mbx->test_result = FM10K_NOT_IMPLEMENTED;
955 err = mbx->ops.enqueue_tx(hw, mbx, test_msg);
956 fm10k_mbx_unlock(interface);
957
958 /* wait up to 1 second for response */
959 timeout = jiffies + HZ;
960 do {
961 if (err < 0)
962 goto err_out;
963
964 usleep_range(500, 1000);
965
966 fm10k_mbx_lock(interface);
967 mbx->ops.process(hw, mbx);
968 fm10k_mbx_unlock(interface);
969
970 err = mbx->test_result;
971 if (!err)
972 break;
973 } while (time_is_after_jiffies(timeout));
974
975 /* reporting errors */
976 if (err)
977 goto err_out;
978 }
979
980err_out:
981 *data = err < 0 ? (attr_flag) : (err > 0);
982 return err;
983}
984
985static void fm10k_self_test(struct net_device *dev,
986 struct ethtool_test *eth_test, u64 *data)
987{
988 struct fm10k_intfc *interface = netdev_priv(dev);
989 struct fm10k_hw *hw = &interface->hw;
990
991 memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
992
993 if (FM10K_REMOVED(hw)) {
994 netif_err(interface, drv, dev,
995 "Interface removed - test blocked\n");
996 eth_test->flags |= ETH_TEST_FL_FAILED;
997 return;
998 }
999
1000 if (fm10k_mbx_test(interface, &data[FM10K_TEST_MBX]))
1001 eth_test->flags |= ETH_TEST_FL_FAILED;
1002}
1003
Jacob Keller80043f32015-07-01 17:38:36 -07001004static u32 fm10k_get_priv_flags(struct net_device *netdev)
1005{
1006 struct fm10k_intfc *interface = netdev_priv(netdev);
1007 u32 priv_flags = 0;
1008
1009 if (interface->flags & FM10K_FLAG_DEBUG_STATS)
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001010 priv_flags |= BIT(FM10K_PRV_FLAG_DEBUG_STATS);
Jacob Keller80043f32015-07-01 17:38:36 -07001011
1012 return priv_flags;
1013}
1014
1015static int fm10k_set_priv_flags(struct net_device *netdev, u32 priv_flags)
1016{
1017 struct fm10k_intfc *interface = netdev_priv(netdev);
1018
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001019 if (priv_flags >= BIT(FM10K_PRV_FLAG_LEN))
Jacob Keller80043f32015-07-01 17:38:36 -07001020 return -EINVAL;
1021
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001022 if (priv_flags & BIT(FM10K_PRV_FLAG_DEBUG_STATS))
Jacob Keller80043f32015-07-01 17:38:36 -07001023 interface->flags |= FM10K_FLAG_DEBUG_STATS;
1024 else
1025 interface->flags &= ~FM10K_FLAG_DEBUG_STATS;
1026
1027 return 0;
1028}
1029
Jeff Kirsherde445192015-04-03 13:26:56 -07001030static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001031{
1032 return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
1033}
1034
1035static int fm10k_get_reta(struct net_device *netdev, u32 *indir)
1036{
1037 struct fm10k_intfc *interface = netdev_priv(netdev);
1038 int i;
1039
1040 if (!indir)
1041 return 0;
1042
1043 for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
1044 u32 reta = interface->reta[i];
1045
1046 indir[0] = (reta << 24) >> 24;
1047 indir[1] = (reta << 16) >> 24;
1048 indir[2] = (reta << 8) >> 24;
1049 indir[3] = (reta) >> 24;
1050 }
1051
1052 return 0;
1053}
1054
1055static int fm10k_set_reta(struct net_device *netdev, const u32 *indir)
1056{
1057 struct fm10k_intfc *interface = netdev_priv(netdev);
1058 struct fm10k_hw *hw = &interface->hw;
1059 int i;
1060 u16 rss_i;
1061
1062 if (!indir)
1063 return 0;
1064
1065 /* Verify user input. */
1066 rss_i = interface->ring_feature[RING_F_RSS].indices;
1067 for (i = fm10k_get_reta_size(netdev); i--;) {
1068 if (indir[i] < rss_i)
1069 continue;
1070 return -EINVAL;
1071 }
1072
1073 /* record entries to reta table */
1074 for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
1075 u32 reta = indir[0] |
1076 (indir[1] << 8) |
1077 (indir[2] << 16) |
1078 (indir[3] << 24);
1079
1080 if (interface->reta[i] == reta)
1081 continue;
1082
1083 interface->reta[i] = reta;
1084 fm10k_write_reg(hw, FM10K_RETA(0, i), reta);
1085 }
1086
1087 return 0;
1088}
1089
Jeff Kirsherde445192015-04-03 13:26:56 -07001090static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001091{
1092 return FM10K_RSSRK_SIZE * FM10K_RSSRK_ENTRIES_PER_REG;
1093}
1094
Eyal Perry892311f2014-12-02 18:12:10 +02001095static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
1096 u8 *hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001097{
1098 struct fm10k_intfc *interface = netdev_priv(netdev);
1099 int i, err;
1100
Eyal Perry892311f2014-12-02 18:12:10 +02001101 if (hfunc)
1102 *hfunc = ETH_RSS_HASH_TOP;
1103
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001104 err = fm10k_get_reta(netdev, indir);
1105 if (err || !key)
1106 return err;
1107
1108 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4)
1109 *(__le32 *)key = cpu_to_le32(interface->rssrk[i]);
1110
1111 return 0;
1112}
1113
1114static int fm10k_set_rssh(struct net_device *netdev, const u32 *indir,
Eyal Perry892311f2014-12-02 18:12:10 +02001115 const u8 *key, const u8 hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001116{
1117 struct fm10k_intfc *interface = netdev_priv(netdev);
1118 struct fm10k_hw *hw = &interface->hw;
1119 int i, err;
1120
Eyal Perry892311f2014-12-02 18:12:10 +02001121 /* We do not allow change in unsupported parameters */
1122 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1123 return -EOPNOTSUPP;
1124
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001125 err = fm10k_set_reta(netdev, indir);
1126 if (err || !key)
1127 return err;
1128
1129 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4) {
1130 u32 rssrk = le32_to_cpu(*(__le32 *)key);
1131
1132 if (interface->rssrk[i] == rssrk)
1133 continue;
1134
1135 interface->rssrk[i] = rssrk;
1136 fm10k_write_reg(hw, FM10K_RSSRK(0, i), rssrk);
1137 }
1138
1139 return 0;
1140}
1141
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001142static unsigned int fm10k_max_channels(struct net_device *dev)
1143{
1144 struct fm10k_intfc *interface = netdev_priv(dev);
1145 unsigned int max_combined = interface->hw.mac.max_queues;
1146 u8 tcs = netdev_get_num_tc(dev);
1147
1148 /* For QoS report channels per traffic class */
1149 if (tcs > 1)
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001150 max_combined = BIT((fls(max_combined / tcs) - 1));
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001151
1152 return max_combined;
1153}
1154
1155static void fm10k_get_channels(struct net_device *dev,
1156 struct ethtool_channels *ch)
1157{
1158 struct fm10k_intfc *interface = netdev_priv(dev);
1159 struct fm10k_hw *hw = &interface->hw;
1160
1161 /* report maximum channels */
1162 ch->max_combined = fm10k_max_channels(dev);
1163
1164 /* report info for other vector */
1165 ch->max_other = NON_Q_VECTORS(hw);
1166 ch->other_count = ch->max_other;
1167
1168 /* record RSS queues */
1169 ch->combined_count = interface->ring_feature[RING_F_RSS].indices;
1170}
1171
1172static int fm10k_set_channels(struct net_device *dev,
1173 struct ethtool_channels *ch)
1174{
1175 struct fm10k_intfc *interface = netdev_priv(dev);
1176 unsigned int count = ch->combined_count;
1177 struct fm10k_hw *hw = &interface->hw;
1178
1179 /* verify they are not requesting separate vectors */
1180 if (!count || ch->rx_count || ch->tx_count)
1181 return -EINVAL;
1182
1183 /* verify other_count has not changed */
1184 if (ch->other_count != NON_Q_VECTORS(hw))
1185 return -EINVAL;
1186
1187 /* verify the number of channels does not exceed hardware limits */
1188 if (count > fm10k_max_channels(dev))
1189 return -EINVAL;
1190
1191 interface->ring_feature[RING_F_RSS].limit = count;
1192
1193 /* use setup TC to update any traffic class queue mapping */
1194 return fm10k_setup_tc(dev, netdev_get_num_tc(dev));
1195}
1196
Alexander Duycka211e012014-09-20 19:54:07 -04001197static int fm10k_get_ts_info(struct net_device *dev,
Matthew Vickeca32042015-01-31 02:23:05 +00001198 struct ethtool_ts_info *info)
Alexander Duycka211e012014-09-20 19:54:07 -04001199{
1200 struct fm10k_intfc *interface = netdev_priv(dev);
1201
1202 info->so_timestamping =
1203 SOF_TIMESTAMPING_TX_SOFTWARE |
1204 SOF_TIMESTAMPING_RX_SOFTWARE |
1205 SOF_TIMESTAMPING_SOFTWARE |
1206 SOF_TIMESTAMPING_TX_HARDWARE |
1207 SOF_TIMESTAMPING_RX_HARDWARE |
1208 SOF_TIMESTAMPING_RAW_HARDWARE;
1209
1210 if (interface->ptp_clock)
1211 info->phc_index = ptp_clock_index(interface->ptp_clock);
1212 else
1213 info->phc_index = -1;
1214
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001215 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
Alexander Duycka211e012014-09-20 19:54:07 -04001216
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001217 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
Alexander Duycka211e012014-09-20 19:54:07 -04001218
1219 return 0;
1220}
1221
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001222static const struct ethtool_ops fm10k_ethtool_ops = {
1223 .get_strings = fm10k_get_strings,
1224 .get_sset_count = fm10k_get_sset_count,
1225 .get_ethtool_stats = fm10k_get_ethtool_stats,
1226 .get_drvinfo = fm10k_get_drvinfo,
1227 .get_link = ethtool_op_get_link,
1228 .get_pauseparam = fm10k_get_pauseparam,
1229 .set_pauseparam = fm10k_set_pauseparam,
1230 .get_msglevel = fm10k_get_msglevel,
1231 .set_msglevel = fm10k_set_msglevel,
1232 .get_ringparam = fm10k_get_ringparam,
1233 .set_ringparam = fm10k_set_ringparam,
1234 .get_coalesce = fm10k_get_coalesce,
1235 .set_coalesce = fm10k_set_coalesce,
1236 .get_rxnfc = fm10k_get_rxnfc,
1237 .set_rxnfc = fm10k_set_rxnfc,
1238 .get_regs = fm10k_get_regs,
1239 .get_regs_len = fm10k_get_regs_len,
Alexander Duyck5cb8db42014-09-20 19:51:40 -04001240 .self_test = fm10k_self_test,
Jacob Keller80043f32015-07-01 17:38:36 -07001241 .get_priv_flags = fm10k_get_priv_flags,
1242 .set_priv_flags = fm10k_set_priv_flags,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001243 .get_rxfh_indir_size = fm10k_get_reta_size,
1244 .get_rxfh_key_size = fm10k_get_rssrk_size,
1245 .get_rxfh = fm10k_get_rssh,
1246 .set_rxfh = fm10k_set_rssh,
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001247 .get_channels = fm10k_get_channels,
1248 .set_channels = fm10k_set_channels,
Alexander Duycka211e012014-09-20 19:54:07 -04001249 .get_ts_info = fm10k_get_ts_info,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001250};
1251
1252void fm10k_set_ethtool_ops(struct net_device *dev)
1253{
1254 dev->ethtool_ops = &fm10k_ethtool_ops;
1255}