1c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin/*
2c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
3c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *
4c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * This software is available to you under a choice of one of two
5c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * licenses.  You may choose to be licensed under the terms of the GNU
6c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * General Public License (GPL) Version 2, available from the file
7c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * COPYING in the main directory of this source tree, or the
8c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * OpenIB.org BSD license below:
9c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *
10c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *     Redistribution and use in source and binary forms, with or
11c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *     without modification, are permitted provided that the following
12c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *     conditions are met:
13c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *
14c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *      - Redistributions of source code must retain the above
15c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *        copyright notice, this list of conditions and the following
16c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *        disclaimer.
17c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *
18c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *      - Redistributions in binary form must reproduce the above
19c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *        copyright notice, this list of conditions and the following
20c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *        disclaimer in the documentation and/or other materials
21c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *        provided with the distribution.
22c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *
23c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * SOFTWARE.
31c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *
32c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin */
33c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
34c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include <linux/kernel.h>
35c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include <linux/ethtool.h>
36c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include <linux/netdevice.h>
37c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
38c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include "mlx4_en.h"
39c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include "en_port.h"
40c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
41c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
42c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void
43c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinmlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
44c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
45c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
46c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_dev *mdev = priv->mdev;
47c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
48612a94d6f24eb2427eabf554392080302da664ddRick Jones	strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
49612a94d6f24eb2427eabf554392080302da664ddRick Jones	strlcpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")",
50612a94d6f24eb2427eabf554392080302da664ddRick Jones		sizeof(drvinfo->version));
51612a94d6f24eb2427eabf554392080302da664ddRick Jones	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
52612a94d6f24eb2427eabf554392080302da664ddRick Jones		"%d.%d.%d",
53c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		(u16) (mdev->dev->caps.fw_ver >> 32),
54c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		(u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff),
55c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		(u16) (mdev->dev->caps.fw_ver & 0xffff));
56612a94d6f24eb2427eabf554392080302da664ddRick Jones	strlcpy(drvinfo->bus_info, pci_name(mdev->dev->pdev),
57612a94d6f24eb2427eabf554392080302da664ddRick Jones		sizeof(drvinfo->bus_info));
58c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	drvinfo->n_stats = 0;
59c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	drvinfo->regdump_len = 0;
60c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	drvinfo->eedump_len = 0;
61c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
62c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
63c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic const char main_strings[][ETH_GSTRING_LEN] = {
64c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
65c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
66c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
67c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
68c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
69c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"tx_heartbeat_errors", "tx_window_errors",
70c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
71c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	/* port statistics */
72fa37a9586f92051de03a13e55e5ec3880bb6783eYevgeny Petrilin	"tso_packets",
73c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
74c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"rx_csum_good", "rx_csum_none", "tx_chksum_offload",
75c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
76c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	/* packet statistics */
77c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
78c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
79c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
80c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	"tx_prio_6", "tx_prio_7",
81c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin};
82d61702f1273b71c2809365a7806d7fe84fd77f15Yevgeny Petrilin#define NUM_MAIN_STATS	21
83c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#define NUM_ALL_STATS	(NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
84c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
85e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilinstatic const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
86e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	"Interupt Test",
87e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	"Link Test",
88e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	"Speed Test",
89e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	"Register Test",
90e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	"Loopback Test",
91e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin};
92e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin
93c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic u32 mlx4_en_get_msglevel(struct net_device *dev)
94c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
95c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
96c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
97c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
98c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_set_msglevel(struct net_device *dev, u32 val)
99c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
100c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable = val;
101c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
102c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
103c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_get_wol(struct net_device *netdev,
104c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin			    struct ethtool_wolinfo *wol)
105c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
10614c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(netdev);
10714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	int err = 0;
10814c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	u64 config = 0;
109559a9f1d354b577af28f84181751820ff7d29febOren Duer	u64 mask;
11014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
111559a9f1d354b577af28f84181751820ff7d29febOren Duer	if ((priv->port < 1) || (priv->port > 2)) {
112559a9f1d354b577af28f84181751820ff7d29febOren Duer		en_err(priv, "Failed to get WoL information\n");
113559a9f1d354b577af28f84181751820ff7d29febOren Duer		return;
114559a9f1d354b577af28f84181751820ff7d29febOren Duer	}
115559a9f1d354b577af28f84181751820ff7d29febOren Duer
116559a9f1d354b577af28f84181751820ff7d29febOren Duer	mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
117559a9f1d354b577af28f84181751820ff7d29febOren Duer		MLX4_DEV_CAP_FLAG_WOL_PORT2;
118559a9f1d354b577af28f84181751820ff7d29febOren Duer
119559a9f1d354b577af28f84181751820ff7d29febOren Duer	if (!(priv->mdev->dev->caps.flags & mask)) {
12014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		wol->supported = 0;
12114c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		wol->wolopts = 0;
12214c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		return;
12314c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	}
12414c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
12514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
12614c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (err) {
12714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		en_err(priv, "Failed to get WoL information\n");
12814c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		return;
12914c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	}
13014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
13114c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (config & MLX4_EN_WOL_MAGIC)
13214c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		wol->supported = WAKE_MAGIC;
13314c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	else
13414c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		wol->supported = 0;
13514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
13614c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (config & MLX4_EN_WOL_ENABLED)
13714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		wol->wolopts = WAKE_MAGIC;
13814c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	else
13914c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		wol->wolopts = 0;
14014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin}
14114c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
14214c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilinstatic int mlx4_en_set_wol(struct net_device *netdev,
14314c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin			    struct ethtool_wolinfo *wol)
14414c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin{
14514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(netdev);
14614c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	u64 config = 0;
14714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	int err = 0;
148559a9f1d354b577af28f84181751820ff7d29febOren Duer	u64 mask;
149559a9f1d354b577af28f84181751820ff7d29febOren Duer
150559a9f1d354b577af28f84181751820ff7d29febOren Duer	if ((priv->port < 1) || (priv->port > 2))
151559a9f1d354b577af28f84181751820ff7d29febOren Duer		return -EOPNOTSUPP;
152559a9f1d354b577af28f84181751820ff7d29febOren Duer
153559a9f1d354b577af28f84181751820ff7d29febOren Duer	mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
154559a9f1d354b577af28f84181751820ff7d29febOren Duer		MLX4_DEV_CAP_FLAG_WOL_PORT2;
15514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
156559a9f1d354b577af28f84181751820ff7d29febOren Duer	if (!(priv->mdev->dev->caps.flags & mask))
15714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		return -EOPNOTSUPP;
15814c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
15914c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (wol->supported & ~WAKE_MAGIC)
16014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		return -EINVAL;
16114c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
16214c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
16314c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (err) {
16414c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		en_err(priv, "Failed to get WoL info, unable to modify\n");
16514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		return err;
16614c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	}
16714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
16814c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (wol->wolopts & WAKE_MAGIC) {
16914c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		config |= MLX4_EN_WOL_DO_MODIFY | MLX4_EN_WOL_ENABLED |
17014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin				MLX4_EN_WOL_MAGIC;
17114c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	} else {
17214c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		config &= ~(MLX4_EN_WOL_ENABLED | MLX4_EN_WOL_MAGIC);
17314c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		config |= MLX4_EN_WOL_DO_MODIFY;
17414c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	}
17514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
17614c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	err = mlx4_wol_write(priv->mdev->dev, config, priv->port);
17714c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	if (err)
17814c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin		en_err(priv, "Failed to set WoL information\n");
17914c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin
18014c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	return err;
181c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
182c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
183c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic int mlx4_en_get_sset_count(struct net_device *dev, int sset)
184c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
185c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
18693ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev	int bit_count = hweight64(priv->stats_bitmap);
187c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
188e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	switch (sset) {
189e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	case ETH_SS_STATS:
19093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) +
191e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			(priv->tx_ring_num + priv->rx_ring_num) * 2;
192e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	case ETH_SS_TEST:
193ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz		return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
194ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz					& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
195e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	default:
196c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		return -EOPNOTSUPP;
197e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	}
198c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
199c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
200c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_get_ethtool_stats(struct net_device *dev,
201c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		struct ethtool_stats *stats, uint64_t *data)
202c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
203c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
204c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	int index = 0;
20593ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev	int i, j = 0;
206c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
207c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	spin_lock_bh(&priv->stats_lock);
208c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
20993ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev	if (!(priv->stats_bitmap)) {
21093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		for (i = 0; i < NUM_MAIN_STATS; i++)
21193ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			data[index++] =
21293ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				((unsigned long *) &priv->stats)[i];
21393ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		for (i = 0; i < NUM_PORT_STATS; i++)
21493ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			data[index++] =
21593ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				((unsigned long *) &priv->port_stats)[i];
21693ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		for (i = 0; i < NUM_PKT_STATS; i++)
21793ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			data[index++] =
21893ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				((unsigned long *) &priv->pkstats)[i];
21993ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev	} else {
22093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		for (i = 0; i < NUM_MAIN_STATS; i++) {
22193ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			if ((priv->stats_bitmap >> j) & 1)
22293ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				data[index++] =
22393ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				((unsigned long *) &priv->stats)[i];
22493ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			j++;
22593ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		}
22693ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		for (i = 0; i < NUM_PORT_STATS; i++) {
22793ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			if ((priv->stats_bitmap >> j) & 1)
22893ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				data[index++] =
22993ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				((unsigned long *) &priv->port_stats)[i];
23093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			j++;
23193ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		}
23293ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev	}
233c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	for (i = 0; i < priv->tx_ring_num; i++) {
234c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		data[index++] = priv->tx_ring[i].packets;
235c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		data[index++] = priv->tx_ring[i].bytes;
236c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	}
237c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	for (i = 0; i < priv->rx_ring_num; i++) {
238c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		data[index++] = priv->rx_ring[i].packets;
239c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		data[index++] = priv->rx_ring[i].bytes;
240c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	}
241c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	spin_unlock_bh(&priv->stats_lock);
242c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
243c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
244c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
245e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilinstatic void mlx4_en_self_test(struct net_device *dev,
246e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			      struct ethtool_test *etest, u64 *buf)
247e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin{
248e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	mlx4_en_ex_selftest(dev, &etest->flags, buf);
249e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin}
250e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin
251c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_get_strings(struct net_device *dev,
252c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				uint32_t stringset, uint8_t *data)
253c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
254c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
255c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	int index = 0;
256c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	int i;
257c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
258e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	switch (stringset) {
259e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	case ETH_SS_TEST:
260e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++)
261e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
262ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz		if (priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UC_LOOPBACK)
263e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			for (; i < MLX4_EN_NUM_SELF_TEST; i++)
264e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin				strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
265e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		break;
266e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin
267e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	case ETH_SS_STATS:
268e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		/* Add main counters */
26993ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		if (!priv->stats_bitmap) {
27093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			for (i = 0; i < NUM_MAIN_STATS; i++)
27193ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				strcpy(data + (index++) * ETH_GSTRING_LEN,
27293ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					main_strings[i]);
27393ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			for (i = 0; i < NUM_PORT_STATS; i++)
27493ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				strcpy(data + (index++) * ETH_GSTRING_LEN,
27593ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					main_strings[i +
27693ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					NUM_MAIN_STATS]);
27793ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			for (i = 0; i < NUM_PKT_STATS; i++)
27893ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				strcpy(data + (index++) * ETH_GSTRING_LEN,
27993ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					main_strings[i +
28093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					NUM_MAIN_STATS +
28193ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					NUM_PORT_STATS]);
28293ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev		} else
28393ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) {
28493ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				if ((priv->stats_bitmap >> i) & 1) {
28593ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					strcpy(data +
28693ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					       (index++) * ETH_GSTRING_LEN,
28793ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					       main_strings[i]);
28893ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				}
28993ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev				if (!(priv->stats_bitmap >> i))
29093ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev					break;
29193ece0c1a7ace88f10411dbb5643d2aa2fe00ebfEugenia Emantayev			}
292e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		for (i = 0; i < priv->tx_ring_num; i++) {
293e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			sprintf(data + (index++) * ETH_GSTRING_LEN,
294e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin				"tx%d_packets", i);
295e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			sprintf(data + (index++) * ETH_GSTRING_LEN,
296e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin				"tx%d_bytes", i);
297e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		}
298e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		for (i = 0; i < priv->rx_ring_num; i++) {
299e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			sprintf(data + (index++) * ETH_GSTRING_LEN,
300e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin				"rx%d_packets", i);
301e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin			sprintf(data + (index++) * ETH_GSTRING_LEN,
302e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin				"rx%d_bytes", i);
303e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		}
304e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin		break;
305e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	}
306c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
307c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
308c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
309c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
3107699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
3117699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	int trans_type;
3127699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin
313c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	cmd->autoneg = AUTONEG_DISABLE;
314c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	cmd->supported = SUPPORTED_10000baseT_Full;
3157699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	cmd->advertising = ADVERTISED_10000baseT_Full;
3167699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin
3177699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
3187699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		return -ENOMEM;
3197699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin
3207699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	trans_type = priv->port_state.transciver;
321c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	if (netif_carrier_ok(dev)) {
322707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny		ethtool_cmd_speed_set(cmd, priv->port_state.link_speed);
323c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		cmd->duplex = DUPLEX_FULL;
324c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	} else {
325707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny		ethtool_cmd_speed_set(cmd, -1);
326c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		cmd->duplex = -1;
327c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	}
3287699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin
3297699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	if (trans_type > 0 && trans_type <= 0xC) {
3307699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->port = PORT_FIBRE;
3317699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->transceiver = XCVR_EXTERNAL;
3327699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->supported |= SUPPORTED_FIBRE;
3337699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->advertising |= ADVERTISED_FIBRE;
3347699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	} else if (trans_type == 0x80 || trans_type == 0) {
3357699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->port = PORT_TP;
3367699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->transceiver = XCVR_INTERNAL;
3377699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->supported |= SUPPORTED_TP;
3387699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->advertising |= ADVERTISED_TP;
3397699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	} else  {
3407699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->port = -1;
3417699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin		cmd->transceiver = -1;
3427699517db435fd24143bd32dd644275e3eeb4c86Yevgeny Petrilin	}
343c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	return 0;
344c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
345c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
346c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
347c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
348c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	if ((cmd->autoneg == AUTONEG_ENABLE) ||
34925db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	    (ethtool_cmd_speed(cmd) != SPEED_10000) ||
35025db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	    (cmd->duplex != DUPLEX_FULL))
351c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		return -EINVAL;
352c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
353c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	/* Nothing to change */
354c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	return 0;
355c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
356c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
357c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic int mlx4_en_get_coalesce(struct net_device *dev,
358c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin			      struct ethtool_coalesce *coal)
359c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
360c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
361c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
362c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->tx_coalesce_usecs = 0;
363c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->tx_max_coalesced_frames = 0;
364c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->rx_coalesce_usecs = priv->rx_usecs;
365c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->rx_max_coalesced_frames = priv->rx_frames;
366c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
367c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->pkt_rate_low = priv->pkt_rate_low;
368c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->rx_coalesce_usecs_low = priv->rx_usecs_low;
369c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->pkt_rate_high = priv->pkt_rate_high;
370c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->rx_coalesce_usecs_high = priv->rx_usecs_high;
371c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->rate_sample_interval = priv->sample_interval;
372c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;
373c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	return 0;
374c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
375c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
376c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic int mlx4_en_set_coalesce(struct net_device *dev,
377c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin			      struct ethtool_coalesce *coal)
378c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
379c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
380c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	int err, i;
381c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
382c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->rx_frames = (coal->rx_max_coalesced_frames ==
383c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin			   MLX4_EN_AUTO_CONF) ?
3843db36fb2c88d68ee28d20845d5bb805ea9a7f6d8Yevgeny Petrilin				MLX4_EN_RX_COAL_TARGET :
385c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				coal->rx_max_coalesced_frames;
386c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->rx_usecs = (coal->rx_coalesce_usecs ==
387c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin			  MLX4_EN_AUTO_CONF) ?
388c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				MLX4_EN_RX_COAL_TIME :
389c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				coal->rx_coalesce_usecs;
390c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
391c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	/* Set adaptive coalescing params */
392c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->pkt_rate_low = coal->pkt_rate_low;
393c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->rx_usecs_low = coal->rx_coalesce_usecs_low;
394c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->pkt_rate_high = coal->pkt_rate_high;
395c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->rx_usecs_high = coal->rx_coalesce_usecs_high;
396c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->sample_interval = coal->rate_sample_interval;
397c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
398c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	if (priv->adaptive_rx_coal)
399c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		return 0;
400c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
401c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	for (i = 0; i < priv->rx_ring_num; i++) {
402c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		priv->rx_cq[i].moder_cnt = priv->rx_frames;
403c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		priv->rx_cq[i].moder_time = priv->rx_usecs;
4046b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller		priv->last_moder_time[i] = MLX4_EN_AUTO_CONF;
405c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]);
406c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin		if (err)
407c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin			return err;
408c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	}
409c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	return 0;
410c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
411c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
412c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic int mlx4_en_set_pauseparam(struct net_device *dev,
413c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				struct ethtool_pauseparam *pause)
414c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
415c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
416c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_dev *mdev = priv->mdev;
417c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	int err;
418c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
419d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin	priv->prof->tx_pause = pause->tx_pause != 0;
420d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin	priv->prof->rx_pause = pause->rx_pause != 0;
421c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	err = mlx4_SET_PORT_general(mdev->dev, priv->port,
422c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				    priv->rx_skb_size + ETH_FCS_LEN,
423d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin				    priv->prof->tx_pause,
424d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin				    priv->prof->tx_ppp,
425d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin				    priv->prof->rx_pause,
426d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin				    priv->prof->rx_ppp);
427c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	if (err)
428453a608277355735190e05c43f909808e0f73641Yevgeny Petrilin		en_err(priv, "Failed setting pause params\n");
429c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
430c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	return err;
431c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
432c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
433c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_get_pauseparam(struct net_device *dev,
434c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				 struct ethtool_pauseparam *pause)
435c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
436c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
437c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
438d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin	pause->tx_pause = priv->prof->tx_pause;
439d53b93f2603554c3420e301bd13ee2c354a15cebYevgeny Petrilin	pause->rx_pause = priv->prof->rx_pause;
440c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
441c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
44218cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilinstatic int mlx4_en_set_ringparam(struct net_device *dev,
44318cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin				 struct ethtool_ringparam *param)
44418cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin{
44518cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
44618cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	struct mlx4_en_dev *mdev = priv->mdev;
44718cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	u32 rx_size, tx_size;
44818cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	int port_up = 0;
44918cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	int err = 0;
4506b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller	int i;
45118cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
45218cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	if (param->rx_jumbo_pending || param->rx_mini_pending)
45318cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		return -EINVAL;
45418cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
45518cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	rx_size = roundup_pow_of_two(param->rx_pending);
45618cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	rx_size = max_t(u32, rx_size, MLX4_EN_MIN_RX_SIZE);
457bd531e36b8aa223aded15493d0a93930e1de51c6Yevgeny Petrilin	rx_size = min_t(u32, rx_size, MLX4_EN_MAX_RX_SIZE);
45818cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	tx_size = roundup_pow_of_two(param->tx_pending);
45918cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
460bd531e36b8aa223aded15493d0a93930e1de51c6Yevgeny Petrilin	tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
46118cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
462bc081cecf3cb3da236061cf353d74c42ba7e37fbYevgeny Petrilin	if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size :
463bc081cecf3cb3da236061cf353d74c42ba7e37fbYevgeny Petrilin					priv->rx_ring[0].size) &&
464bc081cecf3cb3da236061cf353d74c42ba7e37fbYevgeny Petrilin	    tx_size == priv->tx_ring[0].size)
46518cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		return 0;
46618cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
46718cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	mutex_lock(&mdev->state_lock);
46818cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	if (priv->port_up) {
46918cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		port_up = 1;
47018cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		mlx4_en_stop_port(dev);
47118cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	}
47218cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
473fe0af03c69abc2178fc4667664726ec1f688539bAlexander Guller	mlx4_en_free_resources(priv);
47418cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
47518cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	priv->prof->tx_ring_size = tx_size;
47618cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	priv->prof->rx_ring_size = rx_size;
47718cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
47818cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	err = mlx4_en_alloc_resources(priv);
47918cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	if (err) {
480453a608277355735190e05c43f909808e0f73641Yevgeny Petrilin		en_err(priv, "Failed reallocating port resources\n");
48118cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		goto out;
48218cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	}
48318cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	if (port_up) {
48418cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		err = mlx4_en_start_port(dev);
48518cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin		if (err)
486453a608277355735190e05c43f909808e0f73641Yevgeny Petrilin			en_err(priv, "Failed starting port\n");
48718cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	}
48818cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
4896b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller	for (i = 0; i < priv->rx_ring_num; i++) {
4906b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller		priv->rx_cq[i].moder_cnt = priv->rx_frames;
4916b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller		priv->rx_cq[i].moder_time = priv->rx_usecs;
4926b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller		priv->last_moder_time[i] = MLX4_EN_AUTO_CONF;
4936b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller		err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]);
4946b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller		if (err)
4956b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller			goto out;
4966b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller	}
4976b4d8d9fd1acb9ff230810793b363dbdb267b892Alexander Guller
49818cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilinout:
49918cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	mutex_unlock(&mdev->state_lock);
50018cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	return err;
50118cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin}
50218cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin
503c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_get_ringparam(struct net_device *dev,
504c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin				  struct ethtool_ringparam *param)
505c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{
506c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
507c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
508c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	memset(param, 0, sizeof(*param));
509bd531e36b8aa223aded15493d0a93930e1de51c6Yevgeny Petrilin	param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
510bd531e36b8aa223aded15493d0a93930e1de51c6Yevgeny Petrilin	param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
511bc081cecf3cb3da236061cf353d74c42ba7e37fbYevgeny Petrilin	param->rx_pending = priv->port_up ?
512bc081cecf3cb3da236061cf353d74c42ba7e37fbYevgeny Petrilin		priv->rx_ring[0].actual_size : priv->rx_ring[0].size;
513bc081cecf3cb3da236061cf353d74c42ba7e37fbYevgeny Petrilin	param->tx_pending = priv->tx_ring[0].size;
514c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin}
515c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
51693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilinstatic u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
51793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin{
51893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
51993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
52093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	return priv->rx_ring_num;
52193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin}
52293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
52393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilinstatic int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
52493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin{
52593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
52693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	struct mlx4_en_rss_map *rss_map = &priv->rss_map;
52793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int rss_rings;
52893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	size_t n = priv->rx_ring_num;
52993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int err = 0;
53093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
53193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num;
53293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
53393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	while (n--) {
53493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		ring_index[n] = rss_map->qps[n % rss_rings].qpn -
53593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin			rss_map->base_qpn;
53693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	}
53793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
53893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	return err;
53993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin}
54093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
54193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilinstatic int mlx4_en_set_rxfh_indir(struct net_device *dev,
54293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		const u32 *ring_index)
54393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin{
54493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
54593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	struct mlx4_en_dev *mdev = priv->mdev;
54693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int port_up = 0;
54793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int err = 0;
54893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int i;
54993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int rss_rings = 0;
55093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
55193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	/* Calculate RSS table size and make sure flows are spread evenly
55293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	 * between rings
55393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	 */
55493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	for (i = 0; i < priv->rx_ring_num; i++) {
55593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		if (i > 0 && !ring_index[i] && !rss_rings)
55693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin			rss_rings = i;
55793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
55893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		if (ring_index[i] != (i % (rss_rings ?: priv->rx_ring_num)))
55993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin			return -EINVAL;
56093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	}
56193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
56293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	if (!rss_rings)
56393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		rss_rings = priv->rx_ring_num;
56493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
56593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	/* RSS table size must be an order of 2 */
56693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	if (!is_power_of_2(rss_rings))
56793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		return -EINVAL;
56893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
56993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	mutex_lock(&mdev->state_lock);
57093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	if (priv->port_up) {
57193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		port_up = 1;
57293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		mlx4_en_stop_port(dev);
57393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	}
57493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
57593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	priv->prof->rss_rings = rss_rings;
57693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
57793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	if (port_up) {
57893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		err = mlx4_en_start_port(dev);
57993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		if (err)
58093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin			en_err(priv, "Failed starting port\n");
58193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	}
58293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
58393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	mutex_unlock(&mdev->state_lock);
58493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	return err;
58593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin}
58693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
58793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilinstatic int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
58893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin			     u32 *rule_locs)
58993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin{
59093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	struct mlx4_en_priv *priv = netdev_priv(dev);
59193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	int err = 0;
59293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
59393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	switch (cmd->cmd) {
59493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	case ETHTOOL_GRXRINGS:
59593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		cmd->data = priv->rx_ring_num;
59693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		break;
59793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	default:
59893d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		err = -EOPNOTSUPP;
59993d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin		break;
60093d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	}
60193d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
60293d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	return err;
60393d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin}
60493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin
605c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinconst struct ethtool_ops mlx4_en_ethtool_ops = {
606c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_drvinfo = mlx4_en_get_drvinfo,
607c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_settings = mlx4_en_get_settings,
608c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.set_settings = mlx4_en_set_settings,
609c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_link = ethtool_op_get_link,
610c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_strings = mlx4_en_get_strings,
611c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_sset_count = mlx4_en_get_sset_count,
612c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_ethtool_stats = mlx4_en_get_ethtool_stats,
613e7c1c2c46201e46f8ce817196507d2ffd3dafd8eYevgeny Petrilin	.self_test = mlx4_en_self_test,
614c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_wol = mlx4_en_get_wol,
61514c07b1358ede1664652bb9b28d9ace5fe6f7f92Yevgeny Petrilin	.set_wol = mlx4_en_set_wol,
616c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_msglevel = mlx4_en_get_msglevel,
617c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.set_msglevel = mlx4_en_set_msglevel,
618c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_coalesce = mlx4_en_get_coalesce,
619c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.set_coalesce = mlx4_en_set_coalesce,
620c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_pauseparam = mlx4_en_get_pauseparam,
621c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.set_pauseparam = mlx4_en_set_pauseparam,
622c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin	.get_ringparam = mlx4_en_get_ringparam,
62318cc42a3a17d19774b332e933cf34c71b0d3903cYevgeny Petrilin	.set_ringparam = mlx4_en_set_ringparam,
62493d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	.get_rxnfc = mlx4_en_get_rxnfc,
62593d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	.get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
62693d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	.get_rxfh_indir = mlx4_en_get_rxfh_indir,
62793d3e3678f23109363cd6f99f2944d2cda616b23Yevgeny Petrilin	.set_rxfh_indir = mlx4_en_set_rxfh_indir,
628c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin};
629c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
630c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
631c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
632c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
633c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin
634