blob: 17d2388e71a2c185d6304d46bead4a41b88c7500 [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 Kellerd63bb212018-04-12 11:15:56 -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 Keller80043f32015-07-01 17:38:36 -0700153static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400154{
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700155 struct fm10k_intfc *interface = netdev_priv(dev);
Jacob Kellerc0e58e92015-06-16 13:39:11 -0700156 unsigned int i;
Jacob Keller80043f32015-07-01 17:38:36 -0700157
Jacob Kellerd63bb212018-04-12 11:15:56 -0700158 fm10k_add_stat_strings(&data, fm10k_gstrings_net_stats,
Jacob Kellerd2e07212016-02-05 10:43:08 -0800159 FM10K_NETDEV_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700160
Jacob Kellerd63bb212018-04-12 11:15:56 -0700161 fm10k_add_stat_strings(&data, fm10k_gstrings_global_stats,
Jacob Kellerd2e07212016-02-05 10:43:08 -0800162 FM10K_GLOBAL_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700163
Jacob Kellerd63bb212018-04-12 11:15:56 -0700164 fm10k_add_stat_strings(&data, fm10k_gstrings_mbx_stats,
Jacob Kellerd2e07212016-02-05 10:43:08 -0800165 FM10K_MBX_STATS_LEN);
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 Kellerd63bb212018-04-12 11:15:56 -0700168 fm10k_add_stat_strings(&data, fm10k_gstrings_pf_stats,
Jacob Kellerd2e07212016-02-05 10:43:08 -0800169 FM10K_PF_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700170
Jacob Keller80043f32015-07-01 17:38:36 -0700171 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Jacob Kellerd63bb212018-04-12 11:15:56 -0700172 fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats,
173 FM10K_QUEUE_STATS_LEN,
174 "tx", i);
Jacob Keller09401ae2016-04-01 11:15:09 -0700175
Jacob Kellerd63bb212018-04-12 11:15:56 -0700176 fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats,
177 FM10K_QUEUE_STATS_LEN,
178 "rx", i);
Jacob Keller80043f32015-07-01 17:38:36 -0700179 }
180}
181
182static void fm10k_get_strings(struct net_device *dev,
183 u32 stringset, u8 *data)
184{
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400185 switch (stringset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400186 case ETH_SS_TEST:
Jacob Kelleraee24332016-11-02 16:44:45 -0700187 memcpy(data, fm10k_gstrings_test,
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400188 FM10K_TEST_LEN * ETH_GSTRING_LEN);
189 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400190 case ETH_SS_STATS:
Jacob Keller80043f32015-07-01 17:38:36 -0700191 fm10k_get_stat_strings(dev, data);
192 break;
193 case ETH_SS_PRIV_FLAGS:
Jacob Kelleraee24332016-11-02 16:44:45 -0700194 memcpy(data, fm10k_prv_flags,
Jacob Keller80043f32015-07-01 17:38:36 -0700195 FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400196 break;
197 }
198}
199
200static int fm10k_get_sset_count(struct net_device *dev, int sset)
201{
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700202 struct fm10k_intfc *interface = netdev_priv(dev);
203 struct fm10k_hw *hw = &interface->hw;
204 int stats_len = FM10K_STATIC_STATS_LEN;
205
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400206 switch (sset) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400207 case ETH_SS_TEST:
208 return FM10K_TEST_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400209 case ETH_SS_STATS:
Jacob Keller09401ae2016-04-01 11:15:09 -0700210 stats_len += hw->mac.max_queues * 2 * FM10K_QUEUE_STATS_LEN;
Jeff Kirsherfbdb1592015-04-03 13:27:00 -0700211
212 if (hw->mac.type != fm10k_mac_vf)
213 stats_len += FM10K_PF_STATS_LEN;
214
Jeff Kirsherc0e61782015-04-03 13:26:59 -0700215 return stats_len;
Jacob Keller80043f32015-07-01 17:38:36 -0700216 case ETH_SS_PRIV_FLAGS:
217 return FM10K_PRV_FLAG_LEN;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400218 default:
219 return -EOPNOTSUPP;
220 }
221}
222
Jacob Kellerd2e07212016-02-05 10:43:08 -0800223static void fm10k_add_ethtool_stats(u64 **data, void *pointer,
224 const struct fm10k_stats stats[],
225 const unsigned int size)
226{
227 unsigned int i;
228 char *p;
229
Jacob Kellerd2e07212016-02-05 10:43:08 -0800230 if (!pointer) {
Jacob Keller09401ae2016-04-01 11:15:09 -0700231 /* memory is not zero allocated so we have to clear it */
232 for (i = 0; i < size; i++)
233 *((*data)++) = 0;
Jacob Kellerd2e07212016-02-05 10:43:08 -0800234 return;
235 }
236
237 for (i = 0; i < size; i++) {
238 p = (char *)pointer + stats[i].stat_offset;
239
240 switch (stats[i].sizeof_stat) {
241 case sizeof(u64):
242 *((*data)++) = *(u64 *)p;
243 break;
244 case sizeof(u32):
245 *((*data)++) = *(u32 *)p;
246 break;
247 case sizeof(u16):
248 *((*data)++) = *(u16 *)p;
249 break;
250 case sizeof(u8):
251 *((*data)++) = *(u8 *)p;
252 break;
253 default:
254 *((*data)++) = 0;
255 }
256 }
257}
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 Kellerd2e07212016-02-05 10:43:08 -0800269 fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats,
270 FM10K_NETDEV_STATS_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400271
Jacob Kellerd2e07212016-02-05 10:43:08 -0800272 fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats,
273 FM10K_GLOBAL_STATS_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400274
Jacob Kellerd2e07212016-02-05 10:43:08 -0800275 fm10k_add_ethtool_stats(&data, &interface->hw.mbx,
276 fm10k_gstrings_mbx_stats,
277 FM10K_MBX_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700278
279 if (interface->hw.mac.type != fm10k_mac_vf) {
Jacob Kellerd2e07212016-02-05 10:43:08 -0800280 fm10k_add_ethtool_stats(&data, interface,
281 fm10k_gstrings_pf_stats,
282 FM10K_PF_STATS_LEN);
Jacob Keller80043f32015-07-01 17:38:36 -0700283 }
284
Jeff Kirsher29a928e2015-04-03 13:26:58 -0700285 for (i = 0; i < interface->hw.mac.max_queues; i++) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400286 struct fm10k_ring *ring;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400287
288 ring = interface->tx_ring[i];
Jacob Keller09401ae2016-04-01 11:15:09 -0700289 fm10k_add_ethtool_stats(&data, ring,
290 fm10k_gstrings_queue_stats,
291 FM10K_QUEUE_STATS_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400292
293 ring = interface->rx_ring[i];
Jacob Keller09401ae2016-04-01 11:15:09 -0700294 fm10k_add_ethtool_stats(&data, ring,
295 fm10k_gstrings_queue_stats,
296 FM10K_QUEUE_STATS_LEN);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400297 }
298}
299
300/* If function below adds more registers this define needs to be updated */
301#define FM10K_REGS_LEN_Q 29
302
303static void fm10k_get_reg_q(struct fm10k_hw *hw, u32 *buff, int i)
304{
305 int idx = 0;
306
307 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAL(i));
308 buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAH(i));
309 buff[idx++] = fm10k_read_reg(hw, FM10K_RDLEN(i));
310 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_RXCTRL(i));
311 buff[idx++] = fm10k_read_reg(hw, FM10K_RDH(i));
312 buff[idx++] = fm10k_read_reg(hw, FM10K_RDT(i));
313 buff[idx++] = fm10k_read_reg(hw, FM10K_RXQCTL(i));
314 buff[idx++] = fm10k_read_reg(hw, FM10K_RXDCTL(i));
315 buff[idx++] = fm10k_read_reg(hw, FM10K_RXINT(i));
316 buff[idx++] = fm10k_read_reg(hw, FM10K_SRRCTL(i));
317 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRC(i));
318 buff[idx++] = fm10k_read_reg(hw, FM10K_QPRDC(i));
319 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_L(i));
320 buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_H(i));
321 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAL(i));
322 buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAH(i));
323 buff[idx++] = fm10k_read_reg(hw, FM10K_TDLEN(i));
324 buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_TXCTRL(i));
325 buff[idx++] = fm10k_read_reg(hw, FM10K_TDH(i));
326 buff[idx++] = fm10k_read_reg(hw, FM10K_TDT(i));
327 buff[idx++] = fm10k_read_reg(hw, FM10K_TXDCTL(i));
328 buff[idx++] = fm10k_read_reg(hw, FM10K_TXQCTL(i));
329 buff[idx++] = fm10k_read_reg(hw, FM10K_TXINT(i));
330 buff[idx++] = fm10k_read_reg(hw, FM10K_QPTC(i));
331 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_L(i));
332 buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_H(i));
333 buff[idx++] = fm10k_read_reg(hw, FM10K_TQDLOC(i));
334 buff[idx++] = fm10k_read_reg(hw, FM10K_TX_SGLORT(i));
335 buff[idx++] = fm10k_read_reg(hw, FM10K_PFVTCTL(i));
336
337 BUG_ON(idx != FM10K_REGS_LEN_Q);
338}
339
340/* If function above adds more registers this define needs to be updated */
341#define FM10K_REGS_LEN_VSI 43
342
343static void fm10k_get_reg_vsi(struct fm10k_hw *hw, u32 *buff, int i)
344{
345 int idx = 0, j;
346
347 buff[idx++] = fm10k_read_reg(hw, FM10K_MRQC(i));
348 for (j = 0; j < 10; j++)
349 buff[idx++] = fm10k_read_reg(hw, FM10K_RSSRK(i, j));
350 for (j = 0; j < 32; j++)
351 buff[idx++] = fm10k_read_reg(hw, FM10K_RETA(i, j));
352
353 BUG_ON(idx != FM10K_REGS_LEN_VSI);
354}
355
356static void fm10k_get_regs(struct net_device *netdev,
357 struct ethtool_regs *regs, void *p)
358{
359 struct fm10k_intfc *interface = netdev_priv(netdev);
360 struct fm10k_hw *hw = &interface->hw;
361 u32 *buff = p;
362 u16 i;
363
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800364 regs->version = BIT(24) | (hw->revision_id << 16) | hw->device_id;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400365
366 switch (hw->mac.type) {
367 case fm10k_mac_pf:
368 /* General PF Registers */
369 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL);
370 *(buff++) = fm10k_read_reg(hw, FM10K_CTRL_EXT);
371 *(buff++) = fm10k_read_reg(hw, FM10K_GCR);
372 *(buff++) = fm10k_read_reg(hw, FM10K_GCR_EXT);
373
374 for (i = 0; i < 8; i++) {
375 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTMAP(i));
376 *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTDEC(i));
377 }
378
379 for (i = 0; i < 65; i++) {
380 fm10k_get_reg_vsi(hw, buff, i);
381 buff += FM10K_REGS_LEN_VSI;
382 }
383
384 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL);
385 *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
386
387 for (i = 0; i < FM10K_MAX_QUEUES_PF; i++) {
388 fm10k_get_reg_q(hw, buff, i);
389 buff += FM10K_REGS_LEN_Q;
390 }
391
392 *(buff++) = fm10k_read_reg(hw, FM10K_TPH_CTRL);
393
394 for (i = 0; i < 8; i++)
395 *(buff++) = fm10k_read_reg(hw, FM10K_INT_MAP(i));
396
397 /* Interrupt Throttling Registers */
398 for (i = 0; i < 130; i++)
399 *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
400
401 break;
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400402 case fm10k_mac_vf:
403 /* General VF registers */
404 *(buff++) = fm10k_read_reg(hw, FM10K_VFCTRL);
405 *(buff++) = fm10k_read_reg(hw, FM10K_VFINT_MAP);
406 *(buff++) = fm10k_read_reg(hw, FM10K_VFSYSTIME);
407
408 /* Interrupt Throttling Registers */
409 for (i = 0; i < 8; i++)
410 *(buff++) = fm10k_read_reg(hw, FM10K_VFITR(i));
411
412 fm10k_get_reg_vsi(hw, buff, 0);
413 buff += FM10K_REGS_LEN_VSI;
414
415 for (i = 0; i < FM10K_MAX_QUEUES_POOL; i++) {
416 if (i < hw->mac.max_queues)
417 fm10k_get_reg_q(hw, buff, i);
418 else
419 memset(buff, 0, sizeof(u32) * FM10K_REGS_LEN_Q);
420 buff += FM10K_REGS_LEN_Q;
421 }
422
423 break;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400424 default:
425 return;
426 }
427}
428
429/* If function above adds more registers these define need to be updated */
430#define FM10K_REGS_LEN_PF \
431(162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q))
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400432#define FM10K_REGS_LEN_VF \
433(11 + FM10K_REGS_LEN_VSI + (FM10K_MAX_QUEUES_POOL * FM10K_REGS_LEN_Q))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400434
435static int fm10k_get_regs_len(struct net_device *netdev)
436{
437 struct fm10k_intfc *interface = netdev_priv(netdev);
438 struct fm10k_hw *hw = &interface->hw;
439
440 switch (hw->mac.type) {
441 case fm10k_mac_pf:
442 return FM10K_REGS_LEN_PF * sizeof(u32);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400443 case fm10k_mac_vf:
444 return FM10K_REGS_LEN_VF * sizeof(u32);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400445 default:
446 return 0;
447 }
448}
449
450static void fm10k_get_drvinfo(struct net_device *dev,
451 struct ethtool_drvinfo *info)
452{
453 struct fm10k_intfc *interface = netdev_priv(dev);
454
455 strncpy(info->driver, fm10k_driver_name,
456 sizeof(info->driver) - 1);
457 strncpy(info->version, fm10k_driver_version,
458 sizeof(info->version) - 1);
459 strncpy(info->bus_info, pci_name(interface->pdev),
460 sizeof(info->bus_info) - 1);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400461}
462
463static void fm10k_get_pauseparam(struct net_device *dev,
464 struct ethtool_pauseparam *pause)
465{
466 struct fm10k_intfc *interface = netdev_priv(dev);
467
468 /* record fixed values for autoneg and tx pause */
469 pause->autoneg = 0;
470 pause->tx_pause = 1;
471
472 pause->rx_pause = interface->rx_pause ? 1 : 0;
473}
474
475static int fm10k_set_pauseparam(struct net_device *dev,
476 struct ethtool_pauseparam *pause)
477{
478 struct fm10k_intfc *interface = netdev_priv(dev);
479 struct fm10k_hw *hw = &interface->hw;
480
481 if (pause->autoneg || !pause->tx_pause)
482 return -EINVAL;
483
484 /* we can only support pause on the PF to avoid head-of-line blocking */
485 if (hw->mac.type == fm10k_mac_pf)
486 interface->rx_pause = pause->rx_pause ? ~0 : 0;
487 else if (pause->rx_pause)
488 return -EINVAL;
489
490 if (netif_running(dev))
491 fm10k_update_rx_drop_en(interface);
492
493 return 0;
494}
495
496static u32 fm10k_get_msglevel(struct net_device *netdev)
497{
498 struct fm10k_intfc *interface = netdev_priv(netdev);
499
500 return interface->msg_enable;
501}
502
503static void fm10k_set_msglevel(struct net_device *netdev, u32 data)
504{
505 struct fm10k_intfc *interface = netdev_priv(netdev);
506
507 interface->msg_enable = data;
508}
509
510static void fm10k_get_ringparam(struct net_device *netdev,
511 struct ethtool_ringparam *ring)
512{
513 struct fm10k_intfc *interface = netdev_priv(netdev);
514
515 ring->rx_max_pending = FM10K_MAX_RXD;
516 ring->tx_max_pending = FM10K_MAX_TXD;
517 ring->rx_mini_max_pending = 0;
518 ring->rx_jumbo_max_pending = 0;
519 ring->rx_pending = interface->rx_ring_count;
520 ring->tx_pending = interface->tx_ring_count;
521 ring->rx_mini_pending = 0;
522 ring->rx_jumbo_pending = 0;
523}
524
525static int fm10k_set_ringparam(struct net_device *netdev,
526 struct ethtool_ringparam *ring)
527{
528 struct fm10k_intfc *interface = netdev_priv(netdev);
529 struct fm10k_ring *temp_ring;
530 int i, err = 0;
531 u32 new_rx_count, new_tx_count;
532
533 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
534 return -EINVAL;
535
536 new_tx_count = clamp_t(u32, ring->tx_pending,
537 FM10K_MIN_TXD, FM10K_MAX_TXD);
538 new_tx_count = ALIGN(new_tx_count, FM10K_REQ_TX_DESCRIPTOR_MULTIPLE);
539
540 new_rx_count = clamp_t(u32, ring->rx_pending,
541 FM10K_MIN_RXD, FM10K_MAX_RXD);
542 new_rx_count = ALIGN(new_rx_count, FM10K_REQ_RX_DESCRIPTOR_MULTIPLE);
543
544 if ((new_tx_count == interface->tx_ring_count) &&
545 (new_rx_count == interface->rx_ring_count)) {
546 /* nothing to do */
547 return 0;
548 }
549
Jacob Keller46929552017-01-12 15:59:39 -0800550 while (test_and_set_bit(__FM10K_RESETTING, interface->state))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400551 usleep_range(1000, 2000);
552
553 if (!netif_running(interface->netdev)) {
554 for (i = 0; i < interface->num_tx_queues; i++)
555 interface->tx_ring[i]->count = new_tx_count;
556 for (i = 0; i < interface->num_rx_queues; i++)
557 interface->rx_ring[i]->count = new_rx_count;
558 interface->tx_ring_count = new_tx_count;
559 interface->rx_ring_count = new_rx_count;
560 goto clear_reset;
561 }
562
563 /* allocate temporary buffer to store rings in */
564 i = max_t(int, interface->num_tx_queues, interface->num_rx_queues);
565 temp_ring = vmalloc(i * sizeof(struct fm10k_ring));
566
567 if (!temp_ring) {
568 err = -ENOMEM;
569 goto clear_reset;
570 }
571
572 fm10k_down(interface);
573
574 /* Setup new Tx resources and free the old Tx resources in that order.
575 * We can then assign the new resources to the rings via a memcpy.
576 * The advantage to this approach is that we are guaranteed to still
577 * have resources even in the case of an allocation failure.
578 */
579 if (new_tx_count != interface->tx_ring_count) {
580 for (i = 0; i < interface->num_tx_queues; i++) {
581 memcpy(&temp_ring[i], interface->tx_ring[i],
582 sizeof(struct fm10k_ring));
583
584 temp_ring[i].count = new_tx_count;
585 err = fm10k_setup_tx_resources(&temp_ring[i]);
586 if (err) {
587 while (i) {
588 i--;
589 fm10k_free_tx_resources(&temp_ring[i]);
590 }
591 goto err_setup;
592 }
593 }
594
595 for (i = 0; i < interface->num_tx_queues; i++) {
596 fm10k_free_tx_resources(interface->tx_ring[i]);
597
598 memcpy(interface->tx_ring[i], &temp_ring[i],
599 sizeof(struct fm10k_ring));
600 }
601
602 interface->tx_ring_count = new_tx_count;
603 }
604
605 /* Repeat the process for the Rx rings if needed */
606 if (new_rx_count != interface->rx_ring_count) {
607 for (i = 0; i < interface->num_rx_queues; i++) {
608 memcpy(&temp_ring[i], interface->rx_ring[i],
609 sizeof(struct fm10k_ring));
610
611 temp_ring[i].count = new_rx_count;
612 err = fm10k_setup_rx_resources(&temp_ring[i]);
613 if (err) {
614 while (i) {
615 i--;
616 fm10k_free_rx_resources(&temp_ring[i]);
617 }
618 goto err_setup;
619 }
620 }
621
622 for (i = 0; i < interface->num_rx_queues; i++) {
623 fm10k_free_rx_resources(interface->rx_ring[i]);
624
625 memcpy(interface->rx_ring[i], &temp_ring[i],
626 sizeof(struct fm10k_ring));
627 }
628
629 interface->rx_ring_count = new_rx_count;
630 }
631
632err_setup:
633 fm10k_up(interface);
634 vfree(temp_ring);
635clear_reset:
Jacob Keller46929552017-01-12 15:59:39 -0800636 clear_bit(__FM10K_RESETTING, interface->state);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400637 return err;
638}
639
640static int fm10k_get_coalesce(struct net_device *dev,
641 struct ethtool_coalesce *ec)
642{
643 struct fm10k_intfc *interface = netdev_priv(dev);
644
Jacob Keller584373f2015-10-16 10:57:06 -0700645 ec->use_adaptive_tx_coalesce = ITR_IS_ADAPTIVE(interface->tx_itr);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400646 ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;
647
Jacob Keller584373f2015-10-16 10:57:06 -0700648 ec->use_adaptive_rx_coalesce = ITR_IS_ADAPTIVE(interface->rx_itr);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400649 ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;
650
651 return 0;
652}
653
654static int fm10k_set_coalesce(struct net_device *dev,
655 struct ethtool_coalesce *ec)
656{
657 struct fm10k_intfc *interface = netdev_priv(dev);
658 struct fm10k_q_vector *qv;
659 u16 tx_itr, rx_itr;
660 int i;
661
662 /* verify limits */
663 if ((ec->rx_coalesce_usecs > FM10K_ITR_MAX) ||
664 (ec->tx_coalesce_usecs > FM10K_ITR_MAX))
665 return -EINVAL;
666
667 /* record settings */
668 tx_itr = ec->tx_coalesce_usecs;
669 rx_itr = ec->rx_coalesce_usecs;
670
671 /* set initial values for adaptive ITR */
672 if (ec->use_adaptive_tx_coalesce)
Jacob Keller436ea952015-10-16 10:57:08 -0700673 tx_itr = FM10K_ITR_ADAPTIVE | FM10K_TX_ITR_DEFAULT;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400674
675 if (ec->use_adaptive_rx_coalesce)
Jacob Keller436ea952015-10-16 10:57:08 -0700676 rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400677
678 /* update interface */
679 interface->tx_itr = tx_itr;
680 interface->rx_itr = rx_itr;
681
682 /* update q_vectors */
683 for (i = 0; i < interface->num_q_vectors; i++) {
684 qv = interface->q_vector[i];
685 qv->tx.itr = tx_itr;
686 qv->rx.itr = rx_itr;
687 }
688
689 return 0;
690}
691
692static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
693 struct ethtool_rxnfc *cmd)
694{
695 cmd->data = 0;
696
697 /* Report default options for RSS on fm10k */
698 switch (cmd->flow_type) {
699 case TCP_V4_FLOW:
700 case TCP_V6_FLOW:
701 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
702 /* fall through */
703 case UDP_V4_FLOW:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800704 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
705 interface->flags))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400706 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
707 /* fall through */
708 case SCTP_V4_FLOW:
709 case SCTP_V6_FLOW:
710 case AH_ESP_V4_FLOW:
711 case AH_ESP_V6_FLOW:
712 case AH_V4_FLOW:
713 case AH_V6_FLOW:
714 case ESP_V4_FLOW:
715 case ESP_V6_FLOW:
716 case IPV4_FLOW:
717 case IPV6_FLOW:
718 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
719 break;
720 case UDP_V6_FLOW:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800721 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
722 interface->flags))
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400723 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
724 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
725 break;
726 default:
727 return -EINVAL;
728 }
729
730 return 0;
731}
732
733static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
Jeff Kirsherde445192015-04-03 13:26:56 -0700734 u32 __always_unused *rule_locs)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400735{
736 struct fm10k_intfc *interface = netdev_priv(dev);
737 int ret = -EOPNOTSUPP;
738
739 switch (cmd->cmd) {
740 case ETHTOOL_GRXRINGS:
741 cmd->data = interface->num_rx_queues;
742 ret = 0;
743 break;
744 case ETHTOOL_GRXFH:
745 ret = fm10k_get_rss_hash_opts(interface, cmd);
746 break;
747 default:
748 break;
749 }
750
751 return ret;
752}
753
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400754static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
755 struct ethtool_rxnfc *nfc)
756{
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800757 int rss_ipv4_udp = test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
758 interface->flags);
759 int rss_ipv6_udp = test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
760 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400761
762 /* RSS does not support anything other than hashing
763 * to queues on src and dst IPs and ports
764 */
765 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
766 RXH_L4_B_0_1 | RXH_L4_B_2_3))
767 return -EINVAL;
768
769 switch (nfc->flow_type) {
770 case TCP_V4_FLOW:
771 case TCP_V6_FLOW:
772 if (!(nfc->data & RXH_IP_SRC) ||
773 !(nfc->data & RXH_IP_DST) ||
774 !(nfc->data & RXH_L4_B_0_1) ||
775 !(nfc->data & RXH_L4_B_2_3))
776 return -EINVAL;
777 break;
778 case UDP_V4_FLOW:
779 if (!(nfc->data & RXH_IP_SRC) ||
780 !(nfc->data & RXH_IP_DST))
781 return -EINVAL;
782 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
783 case 0:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800784 clear_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
785 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400786 break;
787 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800788 set_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
789 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400790 break;
791 default:
792 return -EINVAL;
793 }
794 break;
795 case UDP_V6_FLOW:
796 if (!(nfc->data & RXH_IP_SRC) ||
797 !(nfc->data & RXH_IP_DST))
798 return -EINVAL;
799 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
800 case 0:
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800801 clear_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
802 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400803 break;
804 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800805 set_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
806 interface->flags);
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400807 break;
808 default:
809 return -EINVAL;
810 }
811 break;
812 case AH_ESP_V4_FLOW:
813 case AH_V4_FLOW:
814 case ESP_V4_FLOW:
815 case SCTP_V4_FLOW:
816 case AH_ESP_V6_FLOW:
817 case AH_V6_FLOW:
818 case ESP_V6_FLOW:
819 case SCTP_V6_FLOW:
820 if (!(nfc->data & RXH_IP_SRC) ||
821 !(nfc->data & RXH_IP_DST) ||
822 (nfc->data & RXH_L4_B_0_1) ||
823 (nfc->data & RXH_L4_B_2_3))
824 return -EINVAL;
825 break;
826 default:
827 return -EINVAL;
828 }
829
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800830 /* If something changed we need to update the MRQC register. Note that
831 * test_bit() is guaranteed to return strictly 0 or 1, so testing for
832 * equality is safe.
833 */
834 if ((rss_ipv4_udp != test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
835 interface->flags)) ||
836 (rss_ipv6_udp != test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
837 interface->flags))) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400838 struct fm10k_hw *hw = &interface->hw;
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800839 bool warn = false;
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400840 u32 mrqc;
841
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400842 /* Perform hash on these packet types */
843 mrqc = FM10K_MRQC_IPV4 |
844 FM10K_MRQC_TCP_IPV4 |
845 FM10K_MRQC_IPV6 |
846 FM10K_MRQC_TCP_IPV6;
847
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800848 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
849 interface->flags)) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400850 mrqc |= FM10K_MRQC_UDP_IPV4;
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800851 warn = true;
852 }
853 if (test_bit(FM10K_FLAG_RSS_FIELD_IPV6_UDP,
854 interface->flags)) {
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400855 mrqc |= FM10K_MRQC_UDP_IPV6;
Jacob Keller3ee7b3a2017-01-12 15:59:38 -0800856 warn = true;
857 }
858
859 /* If we enable UDP RSS display a warning that this may cause
860 * fragmented UDP packets to arrive out of order.
861 */
862 if (warn)
863 netif_warn(interface, drv, interface->netdev,
864 "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400865
866 fm10k_write_reg(hw, FM10K_MRQC(0), mrqc);
867 }
868
869 return 0;
870}
871
872static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
873{
874 struct fm10k_intfc *interface = netdev_priv(dev);
875 int ret = -EOPNOTSUPP;
876
877 switch (cmd->cmd) {
878 case ETHTOOL_SRXFH:
879 ret = fm10k_set_rss_hash_opt(interface, cmd);
880 break;
881 default:
882 break;
883 }
884
885 return ret;
886}
887
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400888static int fm10k_mbx_test(struct fm10k_intfc *interface, u64 *data)
889{
890 struct fm10k_hw *hw = &interface->hw;
891 struct fm10k_mbx_info *mbx = &hw->mbx;
892 u32 attr_flag, test_msg[6];
893 unsigned long timeout;
Bruce Allanc4114e32016-02-10 14:45:47 -0800894 int err = -EINVAL;
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400895
896 /* For now this is a VF only feature */
897 if (hw->mac.type != fm10k_mac_vf)
898 return 0;
899
900 /* loop through both nested and unnested attribute types */
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800901 for (attr_flag = BIT(FM10K_TEST_MSG_UNSET);
902 attr_flag < BIT(2 * FM10K_TEST_MSG_NESTED);
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400903 attr_flag += attr_flag) {
904 /* generate message to be tested */
905 fm10k_tlv_msg_test_create(test_msg, attr_flag);
906
907 fm10k_mbx_lock(interface);
908 mbx->test_result = FM10K_NOT_IMPLEMENTED;
909 err = mbx->ops.enqueue_tx(hw, mbx, test_msg);
910 fm10k_mbx_unlock(interface);
911
912 /* wait up to 1 second for response */
913 timeout = jiffies + HZ;
914 do {
915 if (err < 0)
916 goto err_out;
917
918 usleep_range(500, 1000);
919
920 fm10k_mbx_lock(interface);
921 mbx->ops.process(hw, mbx);
922 fm10k_mbx_unlock(interface);
923
924 err = mbx->test_result;
925 if (!err)
926 break;
927 } while (time_is_after_jiffies(timeout));
928
929 /* reporting errors */
930 if (err)
931 goto err_out;
932 }
933
934err_out:
935 *data = err < 0 ? (attr_flag) : (err > 0);
936 return err;
937}
938
939static void fm10k_self_test(struct net_device *dev,
940 struct ethtool_test *eth_test, u64 *data)
941{
942 struct fm10k_intfc *interface = netdev_priv(dev);
943 struct fm10k_hw *hw = &interface->hw;
944
945 memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
946
Phil Turnbull540fca32016-11-23 13:33:58 -0500947 if (FM10K_REMOVED(hw->hw_addr)) {
Alexander Duyck5cb8db42014-09-20 19:51:40 -0400948 netif_err(interface, drv, dev,
949 "Interface removed - test blocked\n");
950 eth_test->flags |= ETH_TEST_FL_FAILED;
951 return;
952 }
953
954 if (fm10k_mbx_test(interface, &data[FM10K_TEST_MBX]))
955 eth_test->flags |= ETH_TEST_FL_FAILED;
956}
957
Jacob Keller80043f32015-07-01 17:38:36 -0700958static u32 fm10k_get_priv_flags(struct net_device *netdev)
959{
Jacob Keller3ef2f562016-03-04 15:37:48 -0800960 return 0;
Jacob Keller80043f32015-07-01 17:38:36 -0700961}
962
963static int fm10k_set_priv_flags(struct net_device *netdev, u32 priv_flags)
964{
Bruce Allanfcdb0a92015-12-22 13:43:49 -0800965 if (priv_flags >= BIT(FM10K_PRV_FLAG_LEN))
Jacob Keller80043f32015-07-01 17:38:36 -0700966 return -EINVAL;
967
Jacob Keller80043f32015-07-01 17:38:36 -0700968 return 0;
969}
970
Jacob Keller88cdcfe2016-06-17 14:36:45 -0700971static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -0400972{
973 return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
974}
975
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800976void fm10k_write_reta(struct fm10k_intfc *interface, const u32 *indir)
977{
Jacob Keller540a5d82016-04-07 08:21:20 -0700978 u16 rss_i = interface->ring_feature[RING_F_RSS].indices;
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800979 struct fm10k_hw *hw = &interface->hw;
Jacob Keller540a5d82016-04-07 08:21:20 -0700980 u32 table[4];
981 int i, j;
Jacob Keller0ea7fae2016-02-16 16:19:24 -0800982
983 /* record entries to reta table */
Jacob Keller540a5d82016-04-07 08:21:20 -0700984 for (i = 0; i < FM10K_RETA_SIZE; i++) {
985 u32 reta, n;
986
987 /* generate a new table if we weren't given one */
988 for (j = 0; j < 4; j++) {
989 if (indir)
Jacob Keller34875882016-04-18 15:45:00 -0700990 n = indir[4 * i + j];
Jacob Keller540a5d82016-04-07 08:21:20 -0700991 else
Jacob Keller34875882016-04-18 15:45:00 -0700992 n = ethtool_rxfh_indir_default(4 * i + j,
993 rss_i);
Jacob Keller540a5d82016-04-07 08:21:20 -0700994
995 table[j] = n;
996 }
997
998 reta = table[0] |
999 (table[1] << 8) |
1000 (table[2] << 16) |
1001 (table[3] << 24);
Jacob Keller0ea7fae2016-02-16 16:19:24 -08001002
1003 if (interface->reta[i] == reta)
1004 continue;
1005
1006 interface->reta[i] = reta;
1007 fm10k_write_reg(hw, FM10K_RETA(0, i), reta);
1008 }
1009}
1010
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001011static int fm10k_get_reta(struct net_device *netdev, u32 *indir)
1012{
1013 struct fm10k_intfc *interface = netdev_priv(netdev);
1014 int i;
1015
1016 if (!indir)
1017 return 0;
1018
1019 for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
1020 u32 reta = interface->reta[i];
1021
1022 indir[0] = (reta << 24) >> 24;
1023 indir[1] = (reta << 16) >> 24;
1024 indir[2] = (reta << 8) >> 24;
1025 indir[3] = (reta) >> 24;
1026 }
1027
1028 return 0;
1029}
1030
1031static int fm10k_set_reta(struct net_device *netdev, const u32 *indir)
1032{
1033 struct fm10k_intfc *interface = netdev_priv(netdev);
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001034 int i;
1035 u16 rss_i;
1036
1037 if (!indir)
1038 return 0;
1039
1040 /* Verify user input. */
1041 rss_i = interface->ring_feature[RING_F_RSS].indices;
1042 for (i = fm10k_get_reta_size(netdev); i--;) {
1043 if (indir[i] < rss_i)
1044 continue;
1045 return -EINVAL;
1046 }
1047
Jacob Keller0ea7fae2016-02-16 16:19:24 -08001048 fm10k_write_reta(interface, indir);
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001049
1050 return 0;
1051}
1052
Jeff Kirsherde445192015-04-03 13:26:56 -07001053static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001054{
1055 return FM10K_RSSRK_SIZE * FM10K_RSSRK_ENTRIES_PER_REG;
1056}
1057
Eyal Perry892311f2014-12-02 18:12:10 +02001058static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
1059 u8 *hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001060{
1061 struct fm10k_intfc *interface = netdev_priv(netdev);
1062 int i, err;
1063
Eyal Perry892311f2014-12-02 18:12:10 +02001064 if (hfunc)
1065 *hfunc = ETH_RSS_HASH_TOP;
1066
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001067 err = fm10k_get_reta(netdev, indir);
1068 if (err || !key)
1069 return err;
1070
1071 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4)
1072 *(__le32 *)key = cpu_to_le32(interface->rssrk[i]);
1073
1074 return 0;
1075}
1076
1077static int fm10k_set_rssh(struct net_device *netdev, const u32 *indir,
Eyal Perry892311f2014-12-02 18:12:10 +02001078 const u8 *key, const u8 hfunc)
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001079{
1080 struct fm10k_intfc *interface = netdev_priv(netdev);
1081 struct fm10k_hw *hw = &interface->hw;
1082 int i, err;
1083
Eyal Perry892311f2014-12-02 18:12:10 +02001084 /* We do not allow change in unsupported parameters */
1085 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1086 return -EOPNOTSUPP;
1087
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001088 err = fm10k_set_reta(netdev, indir);
1089 if (err || !key)
1090 return err;
1091
1092 for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4) {
1093 u32 rssrk = le32_to_cpu(*(__le32 *)key);
1094
1095 if (interface->rssrk[i] == rssrk)
1096 continue;
1097
1098 interface->rssrk[i] = rssrk;
1099 fm10k_write_reg(hw, FM10K_RSSRK(0, i), rssrk);
1100 }
1101
1102 return 0;
1103}
1104
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001105static unsigned int fm10k_max_channels(struct net_device *dev)
1106{
1107 struct fm10k_intfc *interface = netdev_priv(dev);
1108 unsigned int max_combined = interface->hw.mac.max_queues;
1109 u8 tcs = netdev_get_num_tc(dev);
1110
1111 /* For QoS report channels per traffic class */
1112 if (tcs > 1)
Bruce Allanfcdb0a92015-12-22 13:43:49 -08001113 max_combined = BIT((fls(max_combined / tcs) - 1));
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001114
1115 return max_combined;
1116}
1117
1118static void fm10k_get_channels(struct net_device *dev,
1119 struct ethtool_channels *ch)
1120{
1121 struct fm10k_intfc *interface = netdev_priv(dev);
1122 struct fm10k_hw *hw = &interface->hw;
1123
1124 /* report maximum channels */
1125 ch->max_combined = fm10k_max_channels(dev);
1126
1127 /* report info for other vector */
1128 ch->max_other = NON_Q_VECTORS(hw);
1129 ch->other_count = ch->max_other;
1130
1131 /* record RSS queues */
1132 ch->combined_count = interface->ring_feature[RING_F_RSS].indices;
1133}
1134
1135static int fm10k_set_channels(struct net_device *dev,
1136 struct ethtool_channels *ch)
1137{
1138 struct fm10k_intfc *interface = netdev_priv(dev);
1139 unsigned int count = ch->combined_count;
1140 struct fm10k_hw *hw = &interface->hw;
1141
1142 /* verify they are not requesting separate vectors */
1143 if (!count || ch->rx_count || ch->tx_count)
1144 return -EINVAL;
1145
1146 /* verify other_count has not changed */
1147 if (ch->other_count != NON_Q_VECTORS(hw))
1148 return -EINVAL;
1149
1150 /* verify the number of channels does not exceed hardware limits */
1151 if (count > fm10k_max_channels(dev))
1152 return -EINVAL;
1153
1154 interface->ring_feature[RING_F_RSS].limit = count;
1155
1156 /* use setup TC to update any traffic class queue mapping */
1157 return fm10k_setup_tc(dev, netdev_get_num_tc(dev));
1158}
1159
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001160static const struct ethtool_ops fm10k_ethtool_ops = {
1161 .get_strings = fm10k_get_strings,
1162 .get_sset_count = fm10k_get_sset_count,
1163 .get_ethtool_stats = fm10k_get_ethtool_stats,
1164 .get_drvinfo = fm10k_get_drvinfo,
1165 .get_link = ethtool_op_get_link,
1166 .get_pauseparam = fm10k_get_pauseparam,
1167 .set_pauseparam = fm10k_set_pauseparam,
1168 .get_msglevel = fm10k_get_msglevel,
1169 .set_msglevel = fm10k_set_msglevel,
1170 .get_ringparam = fm10k_get_ringparam,
1171 .set_ringparam = fm10k_set_ringparam,
1172 .get_coalesce = fm10k_get_coalesce,
1173 .set_coalesce = fm10k_set_coalesce,
1174 .get_rxnfc = fm10k_get_rxnfc,
1175 .set_rxnfc = fm10k_set_rxnfc,
1176 .get_regs = fm10k_get_regs,
1177 .get_regs_len = fm10k_get_regs_len,
Alexander Duyck5cb8db42014-09-20 19:51:40 -04001178 .self_test = fm10k_self_test,
Jacob Keller80043f32015-07-01 17:38:36 -07001179 .get_priv_flags = fm10k_get_priv_flags,
1180 .set_priv_flags = fm10k_set_priv_flags,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001181 .get_rxfh_indir_size = fm10k_get_reta_size,
1182 .get_rxfh_key_size = fm10k_get_rssrk_size,
1183 .get_rxfh = fm10k_get_rssh,
1184 .set_rxfh = fm10k_set_rssh,
Alexander Duyckaa3ac822014-09-20 19:50:42 -04001185 .get_channels = fm10k_get_channels,
1186 .set_channels = fm10k_set_channels,
Jacob Kellerbab02a62016-08-25 14:06:54 -07001187 .get_ts_info = ethtool_op_get_ts_info,
Alexander Duyck82dd0f72014-09-20 19:50:15 -04001188};
1189
1190void fm10k_set_ethtool_ops(struct net_device *dev)
1191{
1192 dev->ethtool_ops = &fm10k_ethtool_ops;
1193}