blob: 09fa1a30ee3e8666886871190424bea9ee383a95 [file] [log] [blame]
Jeff Kirsherae06c702018-03-22 10:08:48 -07001// SPDX-License-Identifier: GPL-2.0
Jeff Kirsher51dce242018-04-26 08:08:09 -07002/* Copyright(c) 2013 - 2018 Intel Corporation. */
Alexander Duyck82dd0f72014-09-20 19:50:15 -04003
Stephen Rothwelleb51bba2014-10-01 17:00:49 +10004#include <linux/vmalloc.h>
5
Alexander Duyck82dd0f72014-09-20 19:50:15 -04006#include "fm10k.h"
7
8struct fm10k_stats {
Jacob Kellerd63bb212018-04-12 11:15:56 -07009 /* The stat_string is expected to be a format string formatted using
10 * vsnprintf by fm10k_add_stat_strings. Every member of a stats array
11 * should use the same format specifiers as they will be formatted
12 * using the same variadic arguments.
13 */
Alexander Duyck82dd0f72014-09-20 19:50:15 -040014 char stat_string[ETH_GSTRING_LEN];
15 int sizeof_stat;
16 int stat_offset;
17};
18
Jacob Keller2ead8ae2018-04-12 11:15:55 -070019#define FM10K_STAT_FIELDS(_type, _name, _stat) { \
20 .stat_string = _name, \
21 .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
22 .stat_offset = offsetof(_type, _stat) \
Alexander Duyck82dd0f72014-09-20 19:50:15 -040023}
24
Jacob Keller2ead8ae2018-04-12 11:15:55 -070025/* netdevice statistics */
26#define FM10K_NETDEV_STAT(_net_stat) \
27 FM10K_STAT_FIELDS(struct net_device_stats, __stringify(_net_stat), \
28 _net_stat)
29
Alexander Duyck82dd0f72014-09-20 19:50:15 -040030static const struct fm10k_stats fm10k_gstrings_net_stats[] = {
31 FM10K_NETDEV_STAT(tx_packets),
32 FM10K_NETDEV_STAT(tx_bytes),
33 FM10K_NETDEV_STAT(tx_errors),
34 FM10K_NETDEV_STAT(rx_packets),
35 FM10K_NETDEV_STAT(rx_bytes),
36 FM10K_NETDEV_STAT(rx_errors),
37 FM10K_NETDEV_STAT(rx_dropped),
38
39 /* detailed Rx errors */
40 FM10K_NETDEV_STAT(rx_length_errors),
41 FM10K_NETDEV_STAT(rx_crc_errors),
42 FM10K_NETDEV_STAT(rx_fifo_errors),
43};
44
45#define FM10K_NETDEV_STATS_LEN ARRAY_SIZE(fm10k_gstrings_net_stats)
46
Jacob Keller2ead8ae2018-04-12 11:15:55 -070047/* General interface statistics */
48#define FM10K_STAT(_name, _stat) \
49 FM10K_STAT_FIELDS(struct fm10k_intfc, _name, _stat)
Alexander Duyck82dd0f72014-09-20 19:50:15 -040050
Jeff Kirsherfbdb1592015-04-03 13:27:00 -070051static const struct fm10k_stats fm10k_gstrings_global_stats[] = {
Alexander Duyck82dd0f72014-09-20 19:50:15 -040052 FM10K_STAT("tx_restart_queue", restart_queue),
53 FM10K_STAT("tx_busy", tx_busy),
54 FM10K_STAT("tx_csum_errors", tx_csum_errors),
55 FM10K_STAT("rx_alloc_failed", alloc_failed),
56 FM10K_STAT("rx_csum_errors", rx_csum_errors),
Alexander Duyck82dd0f72014-09-20 19:50:15 -040057
58 FM10K_STAT("tx_packets_nic", tx_packets_nic),
59 FM10K_STAT("tx_bytes_nic", tx_bytes_nic),
60 FM10K_STAT("rx_packets_nic", rx_packets_nic),
61 FM10K_STAT("rx_bytes_nic", rx_bytes_nic),
62 FM10K_STAT("rx_drops_nic", rx_drops_nic),
63 FM10K_STAT("rx_overrun_pf", rx_overrun_pf),
64 FM10K_STAT("rx_overrun_vf", rx_overrun_vf),
65
Alexander Duyck82dd0f72014-09-20 19:50:15 -040066 FM10K_STAT("swapi_status", hw.swapi.status),
67 FM10K_STAT("mac_rules_used", hw.swapi.mac.used),
68 FM10K_STAT("mac_rules_avail", hw.swapi.mac.avail),
69
Jacob Kellerce336242016-06-07 16:08:47 -070070 FM10K_STAT("reset_while_pending", hw.mac.reset_while_pending),
71
Jeff Kirshere05546e2015-04-03 13:27:03 -070072 FM10K_STAT("tx_hang_count", tx_timeout_count),
Alexander Duyck82dd0f72014-09-20 19:50:15 -040073};
74
Jeff Kirsherfbdb1592015-04-03 13:27:00 -070075static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
76 FM10K_STAT("timeout", stats.timeout.count),
77 FM10K_STAT("ur", stats.ur.count),
78 FM10K_STAT("ca", stats.ca.count),
79 FM10K_STAT("um", stats.um.count),
80 FM10K_STAT("xec", stats.xec.count),
81 FM10K_STAT("vlan_drop", stats.vlan_drop.count),
82 FM10K_STAT("loopback_drop", stats.loopback_drop.count),
83 FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
84};
85
Jacob Keller2ead8ae2018-04-12 11:15:55 -070086/* mailbox statistics */
87#define FM10K_MBX_STAT(_name, _stat) \
88 FM10K_STAT_FIELDS(struct fm10k_mbx_info, _name, _stat)
Jacob Keller80043f32015-07-01 17:38:36 -070089
90static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
91 FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
Jacob Keller5680ea62015-10-16 10:57:03 -070092 FM10K_MBX_STAT("mbx_tx_dropped", tx_dropped),
Jacob Keller80043f32015-07-01 17:38:36 -070093 FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
94 FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
Jacob Keller17d39fa2015-10-16 10:57:02 -070095 FM10K_MBX_STAT("mbx_tx_mbmem_pulled", tx_mbmem_pulled),
Jacob Keller80043f32015-07-01 17:38:36 -070096 FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
97 FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
98 FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
Jacob Keller17d39fa2015-10-16 10:57:02 -070099 FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed),
Jacob Keller80043f32015-07-01 17:38:36 -0700100};
101
Jacob Kellerd63bb212018-04-12 11:15:56 -0700102/* per-queue ring statistics */
103#define FM10K_QUEUE_STAT(_name, _stat) \
104 FM10K_STAT_FIELDS(struct fm10k_ring, _name, _stat)
Jacob Keller09401ae2016-04-01 11:15:09 -0700105
106static const struct fm10k_stats fm10k_gstrings_queue_stats[] = {
Jacob Kellerd63bb212018-04-12 11:15:56 -0700107 FM10K_QUEUE_STAT("%s_queue_%u_packets", stats.packets),
108 FM10K_QUEUE_STAT("%s_queue_%u_bytes", stats.bytes),
Jacob Keller09401ae2016-04-01 11:15:09 -0700109};
110
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700111#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
112#define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats)
Jacob Keller80043f32015-07-01 17:38:36 -0700113#define FM10K_MBX_STATS_LEN ARRAY_SIZE(fm10k_gstrings_mbx_stats)
Jacob Keller09401ae2016-04-01 11:15:09 -0700114#define FM10K_QUEUE_STATS_LEN ARRAY_SIZE(fm10k_gstrings_queue_stats)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400115
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700116#define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
Jacob Keller80043f32015-07-01 17:38:36 -0700117 FM10K_NETDEV_STATS_LEN + \
118 FM10K_MBX_STATS_LEN)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400119
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400120static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
121 "Mailbox test (on/offline)"
122};
123
124#define FM10K_TEST_LEN (sizeof(fm10k_gstrings_test) / ETH_GSTRING_LEN)
125
126enum fm10k_self_test_types {
127 FM10K_TEST_MBX,
128 FM10K_TEST_MAX = FM10K_TEST_LEN
129};
130
Jacob Keller80043f32015-07-01 17:38:36 -0700131enum {
Jacob Keller80043f32015-07-01 17:38:36 -0700132 FM10K_PRV_FLAG_LEN,
133};
134
135static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
Jacob Keller80043f32015-07-01 17:38:36 -0700136};
137
Jacob Keller36592d62018-04-12 11:15:57 -0700138static void __fm10k_add_stat_strings(u8 **p, const struct fm10k_stats stats[],
139 const unsigned int size, ...)
Jacob Kellerd2e07212016-02-05 10:43:08 -0800140{
141 unsigned int i;
142
143 for (i = 0; i < size; i++) {
Jacob Kellerd63bb212018-04-12 11:15:56 -0700144 va_list args;
145
146 va_start(args, size);
147 vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
Jacob Kellerd2e07212016-02-05 10:43:08 -0800148 *p += ETH_GSTRING_LEN;
Jacob Kellerd63bb212018-04-12 11:15:56 -0700149 va_end(args);
Jacob Kellerd2e07212016-02-05 10:43:08 -0800150 }
151}
152
Jacob Keller36592d62018-04-12 11:15:57 -0700153#define fm10k_add_stat_strings(p, stats, ...) \
154 __fm10k_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
155
Jacob Keller80043f32015-07-01 17:38:36 -0700156static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400157{
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700158 struct fm10k_intfc *interface = netdev_priv(dev);
Jacob Kellerc0e58e92015-06-16 13:39:11 -0700159 unsigned int i;
Jacob Keller80043f32015-07-01 17:38:36 -0700160
Jacob Keller36592d62018-04-12 11:15:57 -0700161 fm10k_add_stat_strings(&data, fm10k_gstrings_net_stats);
Jacob Keller80043f32015-07-01 17:38:36 -0700162
Jacob Keller36592d62018-04-12 11:15:57 -0700163 fm10k_add_stat_strings(&data, fm10k_gstrings_global_stats);
Jacob Keller80043f32015-07-01 17:38:36 -0700164
Jacob Keller36592d62018-04-12 11:15:57 -0700165 fm10k_add_stat_strings(&data, fm10k_gstrings_mbx_stats);
Jacob Keller80043f32015-07-01 17:38:36 -0700166
Jacob Kellerd2e07212016-02-05 10:43:08 -0800167 if (interface->hw.mac.type != fm10k_mac_vf)
Jacob Keller36592d62018-04-12 11:15:57 -0700168 fm10k_add_stat_strings(&data, fm10k_gstrings_pf_stats);
Jacob Keller80043f32015-07-01 17:38:36 -0700169
Jacob Keller80043f32015-07-01 17:38:36 -0700170 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Jacob Kellerd63bb212018-04-12 11:15:56 -0700171 fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats,
Jacob Kellerd63bb212018-04-12 11:15:56 -0700172 "tx", i);
Jacob Keller09401ae2016-04-01 11:15:09 -0700173
Jacob Kellerd63bb212018-04-12 11:15:56 -0700174 fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats,
Jacob Kellerd63bb212018-04-12 11:15:56 -0700175 "rx", i);
Jacob Keller80043f32015-07-01 17:38:36 -0700176 }
177}
178
179static void fm10k_get_strings(struct net_device *dev,
180 u32 stringset, u8 *data)
181{
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400182 switch (stringset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400183 case ETH_SS_TEST:
Jacob Kelleraee24332016-11-02 16:44:45 -0700184 memcpy(data, fm10k_gstrings_test,
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400185 FM10K_TEST_LEN * ETH_GSTRING_LEN);
186 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400187 case ETH_SS_STATS:
Jacob Keller80043f32015-07-01 17:38:36 -0700188 fm10k_get_stat_strings(dev, data);
189 break;
190 case ETH_SS_PRIV_FLAGS:
Jacob Kelleraee24332016-11-02 16:44:45 -0700191 memcpy(data, fm10k_prv_flags,
Jacob Keller80043f32015-07-01 17:38:36 -0700192 FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400193 break;
194 }
195}
196
197static int fm10k_get_sset_count(struct net_device *dev, int sset)
198{
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700199 struct fm10k_intfc *interface = netdev_priv(dev);
200 struct fm10k_hw *hw = &interface->hw;
201 int stats_len = FM10K_STATIC_STATS_LEN;
202
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400203 switch (sset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400204 case ETH_SS_TEST:
205 return FM10K_TEST_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400206 case ETH_SS_STATS:
Jacob Keller09401ae2016-04-01 11:15:09 -0700207 stats_len += hw->mac.max_queues * 2 * FM10K_QUEUE_STATS_LEN;
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700208
209 if (hw->mac.type != fm10k_mac_vf)
210 stats_len += FM10K_PF_STATS_LEN;
211
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700212 return stats_len;
Jacob Keller80043f32015-07-01 17:38:36 -0700213 case ETH_SS_PRIV_FLAGS:
214 return FM10K_PRV_FLAG_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400215 default:
216 return -EOPNOTSUPP;
217 }
218}
219
Jacob Keller36592d62018-04-12 11:15:57 -0700220static void __fm10k_add_ethtool_stats(u64 **data, void *pointer,
221 const struct fm10k_stats stats[],
222 const unsigned int size)
Jacob Kellerd2e07212016-02-05 10:43:08 -0800223{
224 unsigned int i;
225 char *p;
226
Jacob Kellerd2e07212016-02-05 10:43:08 -0800227 if (!pointer) {
Jacob Keller09401ae2016-04-01 11:15:09 -0700228 /* memory is not zero allocated so we have to clear it */
229 for (i = 0; i < size; i++)
230 *((*data)++) = 0;
Jacob Kellerd2e07212016-02-05 10:43:08 -0800231 return;
232 }
233
234 for (i = 0; i < size; i++) {
235 p = (char *)pointer + stats[i].stat_offset;
236
237 switch (stats[i].sizeof_stat) {
238 case sizeof(u64):
239 *((*data)++) = *(u64 *)p;
240 break;
241 case sizeof(u32):
242 *((*data)++) = *(u32 *)p;
243 break;
244 case sizeof(u16):
245 *((*data)++) = *(u16 *)p;
246 break;
247 case sizeof(u8):
248 *((*data)++) = *(u8 *)p;
249 break;
250 default:
251 *((*data)++) = 0;
252 }
253 }
254}
255
Jacob Keller36592d62018-04-12 11:15:57 -0700256#define fm10k_add_ethtool_stats(data, pointer, stats) \
257 __fm10k_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
258
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400259static void fm10k_get_ethtool_stats(struct net_device *netdev,
Jeff Kirsherde445192015-04-03 13:26:56 -0700260 struct ethtool_stats __always_unused *stats,
261 u64 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400262{
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400263 struct fm10k_intfc *interface = netdev_priv(netdev);
264 struct net_device_stats *net_stats = &netdev->stats;
Jacob Keller09401ae2016-04-01 11:15:09 -0700265 int i;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400266
267 fm10k_update_stats(interface);
268
Jacob Keller36592d62018-04-12 11:15:57 -0700269 fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400270
Jacob Keller36592d62018-04-12 11:15:57 -0700271 fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400272
Jacob Kellerd2e07212016-02-05 10:43:08 -0800273 fm10k_add_ethtool_stats(&data, &interface->hw.mbx,
Jacob Keller36592d62018-04-12 11:15:57 -0700274 fm10k_gstrings_mbx_stats);
Jacob Keller80043f32015-07-01 17:38:36 -0700275
276 if (interface->hw.mac.type != fm10k_mac_vf) {
Jacob Kellerd2e07212016-02-05 10:43:08 -0800277 fm10k_add_ethtool_stats(&data, interface,
Jacob Keller36592d62018-04-12 11:15:57 -0700278 fm10k_gstrings_pf_stats);
Jacob Keller80043f32015-07-01 17:38:36 -0700279 }
280
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700281 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400282 struct fm10k_ring *ring;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400283
284 ring = interface->tx_ring[i];
Jacob Keller09401ae2016-04-01 11:15:09 -0700285 fm10k_add_ethtool_stats(&data, ring,
Jacob Keller36592d62018-04-12 11:15:57 -0700286 fm10k_gstrings_queue_stats);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400287
288 ring = interface->rx_ring[i];
Jacob Keller09401ae2016-04-01 11:15:09 -0700289 fm10k_add_ethtool_stats(&data, ring,
Jacob Keller36592d62018-04-12 11:15:57 -0700290 fm10k_gstrings_queue_stats);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400291 }
292}
293
294/* If function below adds more registers this define needs to be updated */
295#define FM10K_REGS_LEN_Q 29
296
297static void fm10k_get_reg_q(struct fm10k_hw *hw, u32 *buff, int i)
298{
299 int idx = 0;
300
301 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAL(i));
302 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAH(i));
303 buff[idx++] = fm10k_read_reg(hw, FM10K_RDLEN(i));
304 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_RXCTRL(i));
305 buff[idx++] = fm10k_read_reg(hw, FM10K_RDH(i));
306 buff[idx++] = fm10k_read_reg(hw, FM10K_RDT(i));
307 buff[idx++] = fm10k_read_reg(hw, FM10K_RXQCTL(i));
308 buff[idx++] = fm10k_read_reg(hw, FM10K_RXDCTL(i));
309 buff[idx++] = fm10k_read_reg(hw, FM10K_RXINT(i));
310 buff[idx++] = fm10k_read_reg(hw, FM10K_SRRCTL(i));
311 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRC(i));
312 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRDC(i));
313 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_L(i));
314 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_H(i));
315 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAL(i));
316 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAH(i));
317 buff[idx++] = fm10k_read_reg(hw, FM10K_TDLEN(i));
318 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_TXCTRL(i));
319 buff[idx++] = fm10k_read_reg(hw, FM10K_TDH(i));
320 buff[idx++] = fm10k_read_reg(hw, FM10K_TDT(i));
321 buff[idx++] = fm10k_read_reg(hw, FM10K_TXDCTL(i));
322 buff[idx++] = fm10k_read_reg(hw, FM10K_TXQCTL(i));
323 buff[idx++] = fm10k_read_reg(hw, FM10K_TXINT(i));
324 buff[idx++] = fm10k_read_reg(hw, FM10K_QPTC(i));
325 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_L(i));
326 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_H(i));
327 buff[idx++] = fm10k_read_reg(hw, FM10K_TQDLOC(i));
328 buff[idx++] = fm10k_read_reg(hw, FM10K_TX_SGLORT(i));
329 buff[idx++] = fm10k_read_reg(hw, FM10K_PFVTCTL(i));
330
331 BUG_ON(idx != FM10K_REGS_LEN_Q);
332}
333
334/* If function above adds more registers this define needs to be updated */
335#define FM10K_REGS_LEN_VSI 43
336
337static void fm10k_get_reg_vsi(struct fm10k_hw *hw, u32 *buff, int i)
338{
339 int idx = 0, j;
340
341 buff[idx++] = fm10k_read_reg(hw, FM10K_MRQC(i));
342 for (j = 0; j < 10; j++)
343 buff[idx++] = fm10k_read_reg(hw, FM10K_RSSRK(i, j));
344 for (j = 0; j < 32; j++)
345 buff[idx++] = fm10k_read_reg(hw, FM10K_RETA(i, j));
346
347 BUG_ON(idx != FM10K_REGS_LEN_VSI);
348}
349
350static void fm10k_get_regs(struct net_device *netdev,
351 struct ethtool_regs *regs, void *p)
352{
353 struct fm10k_intfc *interface = netdev_priv(netdev);
354 struct fm10k_hw *hw = &interface->hw;
355 u32 *buff = p;
356 u16 i;
357
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800358 regs->version = BIT(24) | (hw->revision_id << 16) | hw->device_id;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400359
360 switch (hw->mac.type) {
361 case fm10k_mac_pf:
362 /* General PF Registers */
363 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL);
364 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL_EXT);
365 *(buff++) = fm10k_read_reg(hw, FM10K_GCR);
366 *(buff++) = fm10k_read_reg(hw, FM10K_GCR_EXT);
367
368 for (i = 0; i < 8; i++) {
369 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTMAP(i));
370 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTDEC(i));
371 }
372
373 for (i = 0; i < 65; i++) {
374 fm10k_get_reg_vsi(hw, buff, i);
375 buff += FM10K_REGS_LEN_VSI;
376 }
377
378 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL);
379 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
380
381 for (i = 0; i < FM10K_MAX_QUEUES_PF; i++) {
382 fm10k_get_reg_q(hw, buff, i);
383 buff += FM10K_REGS_LEN_Q;
384 }
385
386 *(buff++) = fm10k_read_reg(hw, FM10K_TPH_CTRL);
387
388 for (i = 0; i < 8; i++)
389 *(buff++) = fm10k_read_reg(hw, FM10K_INT_MAP(i));
390
391 /* Interrupt Throttling Registers */
392 for (i = 0; i < 130; i++)
393 *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
394
395 break;
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400396 case fm10k_mac_vf:
397 /* General VF registers */
398 *(buff++) = fm10k_read_reg(hw, FM10K_VFCTRL);
399 *(buff++) = fm10k_read_reg(hw, FM10K_VFINT_MAP);
400 *(buff++) = fm10k_read_reg(hw, FM10K_VFSYSTIME);
401
402 /* Interrupt Throttling Registers */
403 for (i = 0; i < 8; i++)
404 *(buff++) = fm10k_read_reg(hw, FM10K_VFITR(i));
405
406 fm10k_get_reg_vsi(hw, buff, 0);
407 buff += FM10K_REGS_LEN_VSI;
408
409 for (i = 0; i < FM10K_MAX_QUEUES_POOL; i++) {
410 if (i < hw->mac.max_queues)
411 fm10k_get_reg_q(hw, buff, i);
412 else
413 memset(buff, 0, sizeof(u32) * FM10K_REGS_LEN_Q);
414 buff += FM10K_REGS_LEN_Q;
415 }
416
417 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400418 default:
419 return;
420 }
421}
422
423/* If function above adds more registers these define need to be updated */
424#define FM10K_REGS_LEN_PF \
425(162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q))
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400426#define FM10K_REGS_LEN_VF \
427(11 + FM10K_REGS_LEN_VSI + (FM10K_MAX_QUEUES_POOL * FM10K_REGS_LEN_Q))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400428
429static int fm10k_get_regs_len(struct net_device *netdev)
430{
431 struct fm10k_intfc *interface = netdev_priv(netdev);
432 struct fm10k_hw *hw = &interface->hw;
433
434 switch (hw->mac.type) {
435 case fm10k_mac_pf:
436 return FM10K_REGS_LEN_PF * sizeof(u32);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400437 case fm10k_mac_vf:
438 return FM10K_REGS_LEN_VF * sizeof(u32);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400439 default:
440 return 0;
441 }
442}
443
444static void fm10k_get_drvinfo(struct net_device *dev,
445 struct ethtool_drvinfo *info)
446{
447 struct fm10k_intfc *interface = netdev_priv(dev);
448
449 strncpy(info->driver, fm10k_driver_name,
450 sizeof(info->driver) - 1);
451 strncpy(info->version, fm10k_driver_version,
452 sizeof(info->version) - 1);
453 strncpy(info->bus_info, pci_name(interface->pdev),
454 sizeof(info->bus_info) - 1);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400455}
456
457static void fm10k_get_pauseparam(struct net_device *dev,
458 struct ethtool_pauseparam *pause)
459{
460 struct fm10k_intfc *interface = netdev_priv(dev);
461
462 /* record fixed values for autoneg and tx pause */
463 pause->autoneg = 0;
464 pause->tx_pause = 1;
465
466 pause->rx_pause = interface->rx_pause ? 1 : 0;
467}
468
469static int fm10k_set_pauseparam(struct net_device *dev,
470 struct ethtool_pauseparam *pause)
471{
472 struct fm10k_intfc *interface = netdev_priv(dev);
473 struct fm10k_hw *hw = &interface->hw;
474
475 if (pause->autoneg || !pause->tx_pause)
476 return -EINVAL;
477
478 /* we can only support pause on the PF to avoid head-of-line blocking */
479 if (hw->mac.type == fm10k_mac_pf)
480 interface->rx_pause = pause->rx_pause ? ~0 : 0;
481 else if (pause->rx_pause)
482 return -EINVAL;
483
484 if (netif_running(dev))
485 fm10k_update_rx_drop_en(interface);
486
487 return 0;
488}
489
490static u32 fm10k_get_msglevel(struct net_device *netdev)
491{
492 struct fm10k_intfc *interface = netdev_priv(netdev);
493
494 return interface->msg_enable;
495}
496
497static void fm10k_set_msglevel(struct net_device *netdev, u32 data)
498{
499 struct fm10k_intfc *interface = netdev_priv(netdev);
500
501 interface->msg_enable = data;
502}
503
504static void fm10k_get_ringparam(struct net_device *netdev,
505 struct ethtool_ringparam *ring)
506{
507 struct fm10k_intfc *interface = netdev_priv(netdev);
508
509 ring->rx_max_pending = FM10K_MAX_RXD;
510 ring->tx_max_pending = FM10K_MAX_TXD;
511 ring->rx_mini_max_pending = 0;
512 ring->rx_jumbo_max_pending = 0;
513 ring->rx_pending = interface->rx_ring_count;
514 ring->tx_pending = interface->tx_ring_count;
515 ring->rx_mini_pending = 0;
516 ring->rx_jumbo_pending = 0;
517}
518
519static int fm10k_set_ringparam(struct net_device *netdev,
520 struct ethtool_ringparam *ring)
521{
522 struct fm10k_intfc *interface = netdev_priv(netdev);
523 struct fm10k_ring *temp_ring;
524 int i, err = 0;
525 u32 new_rx_count, new_tx_count;
526
527 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
528 return -EINVAL;
529
530 new_tx_count = clamp_t(u32, ring->tx_pending,
531 FM10K_MIN_TXD, FM10K_MAX_TXD);
532 new_tx_count = ALIGN(new_tx_count, FM10K_REQ_TX_DESCRIPTOR_MULTIPLE);
533
534 new_rx_count = clamp_t(u32, ring->rx_pending,
535 FM10K_MIN_RXD, FM10K_MAX_RXD);
536 new_rx_count = ALIGN(new_rx_count, FM10K_REQ_RX_DESCRIPTOR_MULTIPLE);
537
538 if ((new_tx_count == interface->tx_ring_count) &&
539 (new_rx_count == interface->rx_ring_count)) {
540 /* nothing to do */
541 return 0;
542 }
543
Jacob Keller46929552017-01-12 15:59:39 -0800544 while (test_and_set_bit(__FM10K_RESETTING, interface->state))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400545 usleep_range(1000, 2000);
546
547 if (!netif_running(interface->netdev)) {
548 for (i = 0; i < interface->num_tx_queues; i++)
549 interface->tx_ring[i]->count = new_tx_count;
550 for (i = 0; i < interface->num_rx_queues; i++)
551 interface->rx_ring[i]->count = new_rx_count;
552 interface->tx_ring_count = new_tx_count;
553 interface->rx_ring_count = new_rx_count;
554 goto clear_reset;
555 }
556
557 /* allocate temporary buffer to store rings in */
558 i = max_t(int, interface->num_tx_queues, interface->num_rx_queues);
559 temp_ring = vmalloc(i * sizeof(struct fm10k_ring));
560
561 if (!temp_ring) {
562 err = -ENOMEM;
563 goto clear_reset;
564 }
565
566 fm10k_down(interface);
567
568 /* Setup new Tx resources and free the old Tx resources in that order.
569 * We can then assign the new resources to the rings via a memcpy.
570 * The advantage to this approach is that we are guaranteed to still
571 * have resources even in the case of an allocation failure.
572 */
573 if (new_tx_count != interface->tx_ring_count) {
574 for (i = 0; i < interface->num_tx_queues; i++) {
575 memcpy(&temp_ring[i], interface->tx_ring[i],
576 sizeof(struct fm10k_ring));
577
578 temp_ring[i].count = new_tx_count;
579 err = fm10k_setup_tx_resources(&temp_ring[i]);
580 if (err) {
581 while (i) {
582 i--;
583 fm10k_free_tx_resources(&temp_ring[i]);
584 }
585 goto err_setup;
586 }
587 }
588
589 for (i = 0; i < interface->num_tx_queues; i++) {
590 fm10k_free_tx_resources(interface->tx_ring[i]);
591
592 memcpy(interface->tx_ring[i], &temp_ring[i],
593 sizeof(struct fm10k_ring));
594 }
595
596 interface->tx_ring_count = new_tx_count;
597 }
598
599 /* Repeat the process for the Rx rings if needed */
600 if (new_rx_count != interface->rx_ring_count) {
601 for (i = 0; i < interface->num_rx_queues; i++) {
602 memcpy(&temp_ring[i], interface->rx_ring[i],
603 sizeof(struct fm10k_ring));
604
605 temp_ring[i].count = new_rx_count;
606 err = fm10k_setup_rx_resources(&temp_ring[i]);
607 if (err) {
608 while (i) {
609 i--;
610 fm10k_free_rx_resources(&temp_ring[i]);
611 }
612 goto err_setup;
613 }
614 }
615
616 for (i = 0; i < interface->num_rx_queues; i++) {
617 fm10k_free_rx_resources(interface->rx_ring[i]);
618
619 memcpy(interface->rx_ring[i], &temp_ring[i],
620 sizeof(struct fm10k_ring));
621 }
622
623 interface->rx_ring_count = new_rx_count;
624 }
625
626err_setup:
627 fm10k_up(interface);
628 vfree(temp_ring);
629clear_reset:
Jacob Keller46929552017-01-12 15:59:39 -0800630 clear_bit(__FM10K_RESETTING, interface->state);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400631 return err;
632}
633
634static int fm10k_get_coalesce(struct net_device *dev,
635 struct ethtool_coalesce *ec)
636{
637 struct fm10k_intfc *interface = netdev_priv(dev);
638
Jacob Keller584373f2015-10-16 10:57:06 -0700639 ec->use_adaptive_tx_coalesce = ITR_IS_ADAPTIVE(interface->tx_itr);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400640 ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;
641
Jacob Keller584373f2015-10-16 10:57:06 -0700642 ec->use_adaptive_rx_coalesce = ITR_IS_ADAPTIVE(interface->rx_itr);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400643 ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;
644
645 return 0;
646}
647
648static int fm10k_set_coalesce(struct net_device *dev,
649 struct ethtool_coalesce *ec)
650{
651 struct fm10k_intfc *interface = netdev_priv(dev);
652 struct fm10k_q_vector *qv;
653 u16 tx_itr, rx_itr;
654 int i;
655
656 /* verify limits */
657 if ((ec->rx_coalesce_usecs > FM10K_ITR_MAX) ||
658 (ec->tx_coalesce_usecs > FM10K_ITR_MAX))
659 return -EINVAL;
660
661 /* record settings */
662 tx_itr = ec->tx_coalesce_usecs;
663 rx_itr = ec->rx_coalesce_usecs;
664
665 /* set initial values for adaptive ITR */
666 if (ec->use_adaptive_tx_coalesce)
Jacob Keller436ea952015-10-16 10:57:08 -0700667 tx_itr = FM10K_ITR_ADAPTIVE | FM10K_TX_ITR_DEFAULT;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400668
669 if (ec->use_adaptive_rx_coalesce)
Jacob Keller436ea952015-10-16 10:57:08 -0700670 rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400671
672 /* update interface */
673 interface->tx_itr = tx_itr;
674 interface->rx_itr = rx_itr;
675
676 /* update q_vectors */
677 for (i = 0; i < interface->num_q_vectors; i++) {
678 qv = interface->q_vector[i];
679 qv->tx.itr = tx_itr;
680 qv->rx.itr = rx_itr;
681 }
682
683 return 0;
684}
685
686static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
687 struct ethtool_rxnfc *cmd)
688{
689 cmd->data = 0;
690
691 /* Report default options for RSS on fm10k */
692 switch (cmd->flow_type) {
693 case TCP_V4_FLOW:
694 case TCP_V6_FLOW:
695 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
696 /* fall through */
697 case UDP_V4_FLOW:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800698 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
699 interface->flags))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400700 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
701 /* fall through */
702 case SCTP_V4_FLOW:
703 case SCTP_V6_FLOW:
704 case AH_ESP_V4_FLOW:
705 case AH_ESP_V6_FLOW:
706 case AH_V4_FLOW:
707 case AH_V6_FLOW:
708 case ESP_V4_FLOW:
709 case ESP_V6_FLOW:
710 case IPV4_FLOW:
711 case IPV6_FLOW:
712 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
713 break;
714 case UDP_V6_FLOW:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800715 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
716 interface->flags))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400717 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
718 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
719 break;
720 default:
721 return -EINVAL;
722 }
723
724 return 0;
725}
726
727static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
Jeff Kirsherde445192015-04-03 13:26:56 -0700728 u32 __always_unused *rule_locs)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400729{
730 struct fm10k_intfc *interface = netdev_priv(dev);
731 int ret = -EOPNOTSUPP;
732
733 switch (cmd->cmd) {
734 case ETHTOOL_GRXRINGS:
735 cmd->data = interface->num_rx_queues;
736 ret = 0;
737 break;
738 case ETHTOOL_GRXFH:
739 ret = fm10k_get_rss_hash_opts(interface, cmd);
740 break;
741 default:
742 break;
743 }
744
745 return ret;
746}
747
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400748static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
749 struct ethtool_rxnfc *nfc)
750{
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800751 int rss_ipv4_udp = test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
752 interface->flags);
753 int rss_ipv6_udp = test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
754 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400755
756 /* RSS does not support anything other than hashing
757 * to queues on src and dst IPs and ports
758 */
759 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
760 RXH_L4_B_0_1 | RXH_L4_B_2_3))
761 return -EINVAL;
762
763 switch (nfc->flow_type) {
764 case TCP_V4_FLOW:
765 case TCP_V6_FLOW:
766 if (!(nfc->data & RXH_IP_SRC) ||
767 !(nfc->data & RXH_IP_DST) ||
768 !(nfc->data & RXH_L4_B_0_1) ||
769 !(nfc->data & RXH_L4_B_2_3))
770 return -EINVAL;
771 break;
772 case UDP_V4_FLOW:
773 if (!(nfc->data & RXH_IP_SRC) ||
774 !(nfc->data & RXH_IP_DST))
775 return -EINVAL;
776 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
777 case 0:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800778 clear_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
779 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400780 break;
781 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800782 set_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
783 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400784 break;
785 default:
786 return -EINVAL;
787 }
788 break;
789 case UDP_V6_FLOW:
790 if (!(nfc->data & RXH_IP_SRC) ||
791 !(nfc->data & RXH_IP_DST))
792 return -EINVAL;
793 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
794 case 0:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800795 clear_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
796 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400797 break;
798 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800799 set_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
800 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400801 break;
802 default:
803 return -EINVAL;
804 }
805 break;
806 case AH_ESP_V4_FLOW:
807 case AH_V4_FLOW:
808 case ESP_V4_FLOW:
809 case SCTP_V4_FLOW:
810 case AH_ESP_V6_FLOW:
811 case AH_V6_FLOW:
812 case ESP_V6_FLOW:
813 case SCTP_V6_FLOW:
814 if (!(nfc->data & RXH_IP_SRC) ||
815 !(nfc->data & RXH_IP_DST) ||
816 (nfc->data & RXH_L4_B_0_1) ||
817 (nfc->data & RXH_L4_B_2_3))
818 return -EINVAL;
819 break;
820 default:
821 return -EINVAL;
822 }
823
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800824 /* If something changed we need to update the MRQC register. Note that
825 * test_bit() is guaranteed to return strictly 0 or 1, so testing for
826 * equality is safe.
827 */
828 if ((rss_ipv4_udp != test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
829 interface->flags)) ||
830 (rss_ipv6_udp != test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
831 interface->flags))) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400832 struct fm10k_hw *hw = &interface->hw;
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800833 bool warn = false;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400834 u32 mrqc;
835
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400836 /* Perform hash on these packet types */
837 mrqc = FM10K_MRQC_IPV4 |
838 FM10K_MRQC_TCP_IPV4 |
839 FM10K_MRQC_IPV6 |
840 FM10K_MRQC_TCP_IPV6;
841
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800842 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
843 interface->flags)) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400844 mrqc |= FM10K_MRQC_UDP_IPV4;
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800845 warn = true;
846 }
847 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
848 interface->flags)) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400849 mrqc |= FM10K_MRQC_UDP_IPV6;
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800850 warn = true;
851 }
852
853 /* If we enable UDP RSS display a warning that this may cause
854 * fragmented UDP packets to arrive out of order.
855 */
856 if (warn)
857 netif_warn(interface, drv, interface->netdev,
858 "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400859
860 fm10k_write_reg(hw, FM10K_MRQC(0), mrqc);
861 }
862
863 return 0;
864}
865
866static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
867{
868 struct fm10k_intfc *interface = netdev_priv(dev);
869 int ret = -EOPNOTSUPP;
870
871 switch (cmd->cmd) {
872 case ETHTOOL_SRXFH:
873 ret = fm10k_set_rss_hash_opt(interface, cmd);
874 break;
875 default:
876 break;
877 }
878
879 return ret;
880}
881
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400882static int fm10k_mbx_test(struct fm10k_intfc *interface, u64 *data)
883{
884 struct fm10k_hw *hw = &interface->hw;
885 struct fm10k_mbx_info *mbx = &hw->mbx;
886 u32 attr_flag, test_msg[6];
887 unsigned long timeout;
Bruce Allanc4114e32016-02-10 14:45:47 -0800888 int err = -EINVAL;
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400889
890 /* For now this is a VF only feature */
891 if (hw->mac.type != fm10k_mac_vf)
892 return 0;
893
894 /* loop through both nested and unnested attribute types */
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800895 for (attr_flag = BIT(FM10K_TEST_MSG_UNSET);
896 attr_flag < BIT(2 * FM10K_TEST_MSG_NESTED);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400897 attr_flag += attr_flag) {
898 /* generate message to be tested */
899 fm10k_tlv_msg_test_create(test_msg, attr_flag);
900
901 fm10k_mbx_lock(interface);
902 mbx->test_result = FM10K_NOT_IMPLEMENTED;
903 err = mbx->ops.enqueue_tx(hw, mbx, test_msg);
904 fm10k_mbx_unlock(interface);
905
906 /* wait up to 1 second for response */
907 timeout = jiffies + HZ;
908 do {
909 if (err < 0)
910 goto err_out;
911
912 usleep_range(500, 1000);
913
914 fm10k_mbx_lock(interface);
915 mbx->ops.process(hw, mbx);
916 fm10k_mbx_unlock(interface);
917
918 err = mbx->test_result;
919 if (!err)
920 break;
921 } while (time_is_after_jiffies(timeout));
922
923 /* reporting errors */
924 if (err)
925 goto err_out;
926 }
927
928err_out:
929 *data = err < 0 ? (attr_flag) : (err > 0);
930 return err;
931}
932
933static void fm10k_self_test(struct net_device *dev,
934 struct ethtool_test *eth_test, u64 *data)
935{
936 struct fm10k_intfc *interface = netdev_priv(dev);
937 struct fm10k_hw *hw = &interface->hw;
938
939 memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
940
Phil Turnbull540fca32016-11-23 13:33:58 -0500941 if (FM10K_REMOVED(hw->hw_addr)) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400942 netif_err(interface, drv, dev,
943 "Interface removed - test blocked\n");
944 eth_test->flags |= ETH_TEST_FL_FAILED;
945 return;
946 }
947
948 if (fm10k_mbx_test(interface, &data[FM10K_TEST_MBX]))
949 eth_test->flags |= ETH_TEST_FL_FAILED;
950}
951
Jacob Keller80043f32015-07-01 17:38:36 -0700952static u32 fm10k_get_priv_flags(struct net_device *netdev)
953{
Jacob Keller3ef2f562016-03-04 15:37:48 -0800954 return 0;
Jacob Keller80043f32015-07-01 17:38:36 -0700955}
956
957static int fm10k_set_priv_flags(struct net_device *netdev, u32 priv_flags)
958{
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800959 if (priv_flags >= BIT(FM10K_PRV_FLAG_LEN))
Jacob Keller80043f32015-07-01 17:38:36 -0700960 return -EINVAL;
961
Jacob Keller80043f32015-07-01 17:38:36 -0700962 return 0;
963}
964
Jacob Keller88cdcfe2016-06-17 14:36:45 -0700965static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400966{
967 return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
968}
969
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800970void fm10k_write_reta(struct fm10k_intfc *interface, const u32 *indir)
971{
Jacob Keller540a5d82016-04-07 08:21:20 -0700972 u16 rss_i = interface->ring_feature[RING_F_RSS].indices;
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800973 struct fm10k_hw *hw = &interface->hw;
Jacob Keller540a5d82016-04-07 08:21:20 -0700974 u32 table[4];
975 int i, j;
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800976
977 /* record entries to reta table */
Jacob Keller540a5d82016-04-07 08:21:20 -0700978 for (i = 0; i < FM10K_RETA_SIZE; i++) {
979 u32 reta, n;
980
981 /* generate a new table if we weren't given one */
982 for (j = 0; j < 4; j++) {
983 if (indir)
Jacob Keller34875882016-04-18 15:45:00 -0700984 n = indir[4 * i + j];
Jacob Keller540a5d82016-04-07 08:21:20 -0700985 else
Jacob Keller34875882016-04-18 15:45:00 -0700986 n = ethtool_rxfh_indir_default(4 * i + j,
987 rss_i);
Jacob Keller540a5d82016-04-07 08:21:20 -0700988
989 table[j] = n;
990 }
991
992 reta = table[0] |
993 (table[1] << 8) |
994 (table[2] << 16) |
995 (table[3] << 24);
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800996
997 if (interface->reta[i] == reta)
998 continue;
999
1000 interface->reta[i] = reta;
1001 fm10k_write_reg(hw, FM10K_RETA(0, i), reta);
1002 }
1003}
1004
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001005static int fm10k_get_reta(struct net_device *netdev, u32 *indir)
1006{
1007 struct fm10k_intfc *interface = netdev_priv(netdev);
1008 int i;
1009
1010 if (!indir)
1011 return 0;
1012
1013 for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
1014 u32 reta = interface->reta[i];
1015
1016 indir[0] = (reta << 24) >> 24;
1017 indir[1] = (reta << 16) >> 24;
1018 indir[2] = (reta << 8) >> 24;
1019 indir[3] = (reta) >> 24;
1020 }
1021
1022 return 0;
1023}
1024
1025static int fm10k_set_reta(struct net_device *netdev, const u32 *indir)
1026{
1027 struct fm10k_intfc *interface = netdev_priv(netdev);
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001028 int i;
1029 u16 rss_i;
1030
1031 if (!indir)
1032 return 0;
1033
1034 /* Verify user input. */
1035 rss_i = interface->ring_feature[RING_F_RSS].indices;
1036 for (i = fm10k_get_reta_size(netdev); i--;) {
1037 if (indir[i] < rss_i)
1038 continue;
1039 return -EINVAL;
1040 }
1041
Jacob Keller0ea7fae2016-02-16 16:19:24 -08001042 fm10k_write_reta(interface, indir);
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001043
1044 return 0;
1045}
1046
Jeff Kirsherde445192015-04-03 13:26:56 -07001047static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001048{
1049 return FM10K_RSSRK_SIZE * FM10K_RSSRK_ENTRIES_PER_REG;
1050}
1051
Eyal Perry892311f2014-12-02 18:12:10 +02001052static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
1053 u8 *hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001054{
1055 struct fm10k_intfc *interface = netdev_priv(netdev);
1056 int i, err;
1057
Eyal Perry892311f2014-12-02 18:12:10 +02001058 if (hfunc)
1059 *hfunc = ETH_RSS_HASH_TOP;
1060
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001061 err = fm10k_get_reta(netdev, indir);
1062 if (err || !key)
1063 return err;
1064
1065 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4)
1066 *(__le32 *)key = cpu_to_le32(interface->rssrk[i]);
1067
1068 return 0;
1069}
1070
1071static int fm10k_set_rssh(struct net_device *netdev, const u32 *indir,
Eyal Perry892311f2014-12-02 18:12:10 +02001072 const u8 *key, const u8 hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001073{
1074 struct fm10k_intfc *interface = netdev_priv(netdev);
1075 struct fm10k_hw *hw = &interface->hw;
1076 int i, err;
1077
Eyal Perry892311f2014-12-02 18:12:10 +02001078 /* We do not allow change in unsupported parameters */
1079 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1080 return -EOPNOTSUPP;
1081
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001082 err = fm10k_set_reta(netdev, indir);
1083 if (err || !key)
1084 return err;
1085
1086 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4) {
1087 u32 rssrk = le32_to_cpu(*(__le32 *)key);
1088
1089 if (interface->rssrk[i] == rssrk)
1090 continue;
1091
1092 interface->rssrk[i] = rssrk;
1093 fm10k_write_reg(hw, FM10K_RSSRK(0, i), rssrk);
1094 }
1095
1096 return 0;
1097}
1098
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001099static unsigned int fm10k_max_channels(struct net_device *dev)
1100{
1101 struct fm10k_intfc *interface = netdev_priv(dev);
1102 unsigned int max_combined = interface->hw.mac.max_queues;
1103 u8 tcs = netdev_get_num_tc(dev);
1104
1105 /* For QoS report channels per traffic class */
1106 if (tcs > 1)
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001107 max_combined = BIT((fls(max_combined / tcs) - 1));
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001108
1109 return max_combined;
1110}
1111
1112static void fm10k_get_channels(struct net_device *dev,
1113 struct ethtool_channels *ch)
1114{
1115 struct fm10k_intfc *interface = netdev_priv(dev);
1116 struct fm10k_hw *hw = &interface->hw;
1117
1118 /* report maximum channels */
1119 ch->max_combined = fm10k_max_channels(dev);
1120
1121 /* report info for other vector */
1122 ch->max_other = NON_Q_VECTORS(hw);
1123 ch->other_count = ch->max_other;
1124
1125 /* record RSS queues */
1126 ch->combined_count = interface->ring_feature[RING_F_RSS].indices;
1127}
1128
1129static int fm10k_set_channels(struct net_device *dev,
1130 struct ethtool_channels *ch)
1131{
1132 struct fm10k_intfc *interface = netdev_priv(dev);
1133 unsigned int count = ch->combined_count;
1134 struct fm10k_hw *hw = &interface->hw;
1135
1136 /* verify they are not requesting separate vectors */
1137 if (!count || ch->rx_count || ch->tx_count)
1138 return -EINVAL;
1139
1140 /* verify other_count has not changed */
1141 if (ch->other_count != NON_Q_VECTORS(hw))
1142 return -EINVAL;
1143
1144 /* verify the number of channels does not exceed hardware limits */
1145 if (count > fm10k_max_channels(dev))
1146 return -EINVAL;
1147
1148 interface->ring_feature[RING_F_RSS].limit = count;
1149
1150 /* use setup TC to update any traffic class queue mapping */
1151 return fm10k_setup_tc(dev, netdev_get_num_tc(dev));
1152}
1153
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001154static const struct ethtool_ops fm10k_ethtool_ops = {
1155 .get_strings = fm10k_get_strings,
1156 .get_sset_count = fm10k_get_sset_count,
1157 .get_ethtool_stats = fm10k_get_ethtool_stats,
1158 .get_drvinfo = fm10k_get_drvinfo,
1159 .get_link = ethtool_op_get_link,
1160 .get_pauseparam = fm10k_get_pauseparam,
1161 .set_pauseparam = fm10k_set_pauseparam,
1162 .get_msglevel = fm10k_get_msglevel,
1163 .set_msglevel = fm10k_set_msglevel,
1164 .get_ringparam = fm10k_get_ringparam,
1165 .set_ringparam = fm10k_set_ringparam,
1166 .get_coalesce = fm10k_get_coalesce,
1167 .set_coalesce = fm10k_set_coalesce,
1168 .get_rxnfc = fm10k_get_rxnfc,
1169 .set_rxnfc = fm10k_set_rxnfc,
1170 .get_regs = fm10k_get_regs,
1171 .get_regs_len = fm10k_get_regs_len,
Alexander Duyck5cb8db42014-09-20 19:51:40 -04001172 .self_test = fm10k_self_test,
Jacob Keller80043f32015-07-01 17:38:36 -07001173 .get_priv_flags = fm10k_get_priv_flags,
1174 .set_priv_flags = fm10k_set_priv_flags,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001175 .get_rxfh_indir_size = fm10k_get_reta_size,
1176 .get_rxfh_key_size = fm10k_get_rssrk_size,
1177 .get_rxfh = fm10k_get_rssh,
1178 .set_rxfh = fm10k_set_rssh,
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001179 .get_channels = fm10k_get_channels,
1180 .set_channels = fm10k_set_channels,
Jacob Kellerbab02a62016-08-25 14:06:54 -07001181 .get_ts_info = ethtool_op_get_ts_info,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001182};
1183
1184void fm10k_set_ethtool_ops(struct net_device *dev)
1185{
1186 dev->ethtool_ops = &fm10k_ethtool_ops;
1187}