Commit 076b0936 authored by Erez Shitrit's avatar Erez Shitrit Committed by Saeed Mahameed

net/mlx5e: IPoIB, Add ethtool support

Add support for the following:
	"ethtool -S" (statistics).
	"ethtool -i" (driver info).
	"ethtool -g/G" (rings parameters).
	"ethtool -l/L" (channels parameters).
	"ethtool -c/C" (coalesce options).
Signed-off-by: default avatarErez Shitrit <erezsh@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent c66f2091
...@@ -15,4 +15,4 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \ ...@@ -15,4 +15,4 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \
mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o
mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib/ipoib.o mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib/ipoib.o ipoib/ethtool.o
...@@ -1021,6 +1021,27 @@ int mlx5e_open(struct net_device *netdev); ...@@ -1021,6 +1021,27 @@ int mlx5e_open(struct net_device *netdev);
void mlx5e_update_stats_work(struct work_struct *work); void mlx5e_update_stats_work(struct work_struct *work);
u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout); u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout);
/* ethtool helpers */
void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
struct ethtool_drvinfo *drvinfo);
void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv,
uint32_t stringset, uint8_t *data);
int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset);
void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
struct ethtool_stats *stats, u64 *data);
void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
struct ethtool_ringparam *param);
int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
struct ethtool_ringparam *param);
void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
struct ethtool_channels *ch);
int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
struct ethtool_channels *ch);
int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal);
int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal);
/* mlx5e generic netdev management API */ /* mlx5e generic netdev management API */
struct net_device* struct net_device*
mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
......
...@@ -32,10 +32,9 @@ ...@@ -32,10 +32,9 @@
#include "en.h" #include "en.h"
static void mlx5e_get_drvinfo(struct net_device *dev, void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
{ {
struct mlx5e_priv *priv = netdev_priv(dev);
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver)); strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
...@@ -49,6 +48,14 @@ static void mlx5e_get_drvinfo(struct net_device *dev, ...@@ -49,6 +48,14 @@ static void mlx5e_get_drvinfo(struct net_device *dev,
sizeof(drvinfo->bus_info)); sizeof(drvinfo->bus_info));
} }
static void mlx5e_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
struct mlx5e_priv *priv = netdev_priv(dev);
mlx5e_ethtool_get_drvinfo(priv, drvinfo);
}
struct ptys2ethtool_config { struct ptys2ethtool_config {
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
__ETHTOOL_DECLARE_LINK_MODE_MASK(advertised); __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
...@@ -166,9 +173,8 @@ static bool mlx5e_query_global_pause_combined(struct mlx5e_priv *priv) ...@@ -166,9 +173,8 @@ static bool mlx5e_query_global_pause_combined(struct mlx5e_priv *priv)
((mlx5e_query_global_pause_combined(priv) + hweight8(mlx5e_query_pfc_combined(priv))) * \ ((mlx5e_query_global_pause_combined(priv) + hweight8(mlx5e_query_pfc_combined(priv))) * \
NUM_PPORT_PER_PRIO_PFC_COUNTERS) NUM_PPORT_PER_PRIO_PFC_COUNTERS)
static int mlx5e_get_sset_count(struct net_device *dev, int sset) int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
{ {
struct mlx5e_priv *priv = netdev_priv(dev);
switch (sset) { switch (sset) {
case ETH_SS_STATS: case ETH_SS_STATS:
...@@ -192,6 +198,13 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset) ...@@ -192,6 +198,13 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
} }
} }
static int mlx5e_get_sset_count(struct net_device *dev, int sset)
{
struct mlx5e_priv *priv = netdev_priv(dev);
return mlx5e_ethtool_get_sset_count(priv, sset);
}
static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data) static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
{ {
int i, j, tc, prio, idx = 0; int i, j, tc, prio, idx = 0;
...@@ -279,10 +292,9 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data) ...@@ -279,10 +292,9 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
priv->channel_tc2txq[i][tc]); priv->channel_tc2txq[i][tc]);
} }
static void mlx5e_get_strings(struct net_device *dev, void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv,
uint32_t stringset, uint8_t *data) uint32_t stringset, uint8_t *data)
{ {
struct mlx5e_priv *priv = netdev_priv(dev);
int i; int i;
switch (stringset) { switch (stringset) {
...@@ -303,10 +315,17 @@ static void mlx5e_get_strings(struct net_device *dev, ...@@ -303,10 +315,17 @@ static void mlx5e_get_strings(struct net_device *dev,
} }
} }
static void mlx5e_get_ethtool_stats(struct net_device *dev, static void mlx5e_get_strings(struct net_device *dev,
struct ethtool_stats *stats, u64 *data) uint32_t stringset, uint8_t *data)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
mlx5e_ethtool_get_strings(priv, stringset, data);
}
void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
struct ethtool_stats *stats, u64 *data)
{
struct mlx5e_channels *channels; struct mlx5e_channels *channels;
struct mlx5_priv *mlx5_priv; struct mlx5_priv *mlx5_priv;
int i, j, tc, prio, idx = 0; int i, j, tc, prio, idx = 0;
...@@ -401,6 +420,15 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev, ...@@ -401,6 +420,15 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
sq_stats_desc, j); sq_stats_desc, j);
} }
static void mlx5e_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats,
u64 *data)
{
struct mlx5e_priv *priv = netdev_priv(dev);
mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
}
static u32 mlx5e_rx_wqes_to_packets(struct mlx5e_priv *priv, int rq_wq_type, static u32 mlx5e_rx_wqes_to_packets(struct mlx5e_priv *priv, int rq_wq_type,
int num_wqe) int num_wqe)
{ {
...@@ -445,10 +473,9 @@ static u32 mlx5e_packets_to_rx_wqes(struct mlx5e_priv *priv, int rq_wq_type, ...@@ -445,10 +473,9 @@ static u32 mlx5e_packets_to_rx_wqes(struct mlx5e_priv *priv, int rq_wq_type,
return 1 << (order_base_2(num_wqes)); return 1 << (order_base_2(num_wqes));
} }
static void mlx5e_get_ringparam(struct net_device *dev, void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
struct ethtool_ringparam *param) struct ethtool_ringparam *param)
{ {
struct mlx5e_priv *priv = netdev_priv(dev);
int rq_wq_type = priv->channels.params.rq_wq_type; int rq_wq_type = priv->channels.params.rq_wq_type;
param->rx_max_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, param->rx_max_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type,
...@@ -459,10 +486,17 @@ static void mlx5e_get_ringparam(struct net_device *dev, ...@@ -459,10 +486,17 @@ static void mlx5e_get_ringparam(struct net_device *dev,
param->tx_pending = 1 << priv->channels.params.log_sq_size; param->tx_pending = 1 << priv->channels.params.log_sq_size;
} }
static int mlx5e_set_ringparam(struct net_device *dev, static void mlx5e_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *param) struct ethtool_ringparam *param)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
mlx5e_ethtool_get_ringparam(priv, param);
}
int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
struct ethtool_ringparam *param)
{
int rq_wq_type = priv->channels.params.rq_wq_type; int rq_wq_type = priv->channels.params.rq_wq_type;
struct mlx5e_channels new_channels = {}; struct mlx5e_channels new_channels = {};
u32 rx_pending_wqes; u32 rx_pending_wqes;
...@@ -474,12 +508,12 @@ static int mlx5e_set_ringparam(struct net_device *dev, ...@@ -474,12 +508,12 @@ static int mlx5e_set_ringparam(struct net_device *dev,
int err = 0; int err = 0;
if (param->rx_jumbo_pending) { if (param->rx_jumbo_pending) {
netdev_info(dev, "%s: rx_jumbo_pending not supported\n", netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n",
__func__); __func__);
return -EINVAL; return -EINVAL;
} }
if (param->rx_mini_pending) { if (param->rx_mini_pending) {
netdev_info(dev, "%s: rx_mini_pending not supported\n", netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n",
__func__); __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -492,13 +526,13 @@ static int mlx5e_set_ringparam(struct net_device *dev, ...@@ -492,13 +526,13 @@ static int mlx5e_set_ringparam(struct net_device *dev,
param->rx_pending); param->rx_pending);
if (param->rx_pending < min_rq_size) { if (param->rx_pending < min_rq_size) {
netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n", netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n",
__func__, param->rx_pending, __func__, param->rx_pending,
min_rq_size); min_rq_size);
return -EINVAL; return -EINVAL;
} }
if (param->rx_pending > max_rq_size) { if (param->rx_pending > max_rq_size) {
netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n", netdev_info(priv->netdev, "%s: rx_pending (%d) > max (%d)\n",
__func__, param->rx_pending, __func__, param->rx_pending,
max_rq_size); max_rq_size);
return -EINVAL; return -EINVAL;
...@@ -507,19 +541,19 @@ static int mlx5e_set_ringparam(struct net_device *dev, ...@@ -507,19 +541,19 @@ static int mlx5e_set_ringparam(struct net_device *dev,
num_mtts = MLX5E_REQUIRED_MTTS(rx_pending_wqes); num_mtts = MLX5E_REQUIRED_MTTS(rx_pending_wqes);
if (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ && if (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
!MLX5E_VALID_NUM_MTTS(num_mtts)) { !MLX5E_VALID_NUM_MTTS(num_mtts)) {
netdev_info(dev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n", netdev_info(priv->netdev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n",
__func__, param->rx_pending); __func__, param->rx_pending);
return -EINVAL; return -EINVAL;
} }
if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n", netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
__func__, param->tx_pending, __func__, param->tx_pending,
1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
return -EINVAL; return -EINVAL;
} }
if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) { if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) {
netdev_info(dev, "%s: tx_pending (%d) > max (%d)\n", netdev_info(priv->netdev, "%s: tx_pending (%d) > max (%d)\n",
__func__, param->tx_pending, __func__, param->tx_pending,
1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE); 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE);
return -EINVAL; return -EINVAL;
...@@ -555,26 +589,39 @@ static int mlx5e_set_ringparam(struct net_device *dev, ...@@ -555,26 +589,39 @@ static int mlx5e_set_ringparam(struct net_device *dev,
return err; return err;
} }
static void mlx5e_get_channels(struct net_device *dev, static int mlx5e_set_ringparam(struct net_device *dev,
struct ethtool_channels *ch) struct ethtool_ringparam *param)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
return mlx5e_ethtool_set_ringparam(priv, param);
}
void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
struct ethtool_channels *ch)
{
ch->max_combined = priv->profile->max_nch(priv->mdev); ch->max_combined = priv->profile->max_nch(priv->mdev);
ch->combined_count = priv->channels.params.num_channels; ch->combined_count = priv->channels.params.num_channels;
} }
static int mlx5e_set_channels(struct net_device *dev, static void mlx5e_get_channels(struct net_device *dev,
struct ethtool_channels *ch) struct ethtool_channels *ch)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
mlx5e_ethtool_get_channels(priv, ch);
}
int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
struct ethtool_channels *ch)
{
unsigned int count = ch->combined_count; unsigned int count = ch->combined_count;
struct mlx5e_channels new_channels = {}; struct mlx5e_channels new_channels = {};
bool arfs_enabled; bool arfs_enabled;
int err = 0; int err = 0;
if (!count) { if (!count) {
netdev_info(dev, "%s: combined_count=0 not supported\n", netdev_info(priv->netdev, "%s: combined_count=0 not supported\n",
__func__); __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -599,7 +646,7 @@ static int mlx5e_set_channels(struct net_device *dev, ...@@ -599,7 +646,7 @@ static int mlx5e_set_channels(struct net_device *dev,
if (err) if (err)
goto out; goto out;
arfs_enabled = dev->features & NETIF_F_NTUPLE; arfs_enabled = priv->netdev->features & NETIF_F_NTUPLE;
if (arfs_enabled) if (arfs_enabled)
mlx5e_arfs_disable(priv); mlx5e_arfs_disable(priv);
...@@ -609,7 +656,7 @@ static int mlx5e_set_channels(struct net_device *dev, ...@@ -609,7 +656,7 @@ static int mlx5e_set_channels(struct net_device *dev,
if (arfs_enabled) { if (arfs_enabled) {
err = mlx5e_arfs_enable(priv); err = mlx5e_arfs_enable(priv);
if (err) if (err)
netdev_err(dev, "%s: mlx5e_arfs_enable failed: %d\n", netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
__func__, err); __func__, err);
} }
...@@ -619,11 +666,17 @@ static int mlx5e_set_channels(struct net_device *dev, ...@@ -619,11 +666,17 @@ static int mlx5e_set_channels(struct net_device *dev,
return err; return err;
} }
static int mlx5e_get_coalesce(struct net_device *netdev, static int mlx5e_set_channels(struct net_device *dev,
struct ethtool_coalesce *coal) struct ethtool_channels *ch)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(dev);
return mlx5e_ethtool_set_channels(priv, ch);
}
int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal)
{
if (!MLX5_CAP_GEN(priv->mdev, cq_moderation)) if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -636,6 +689,14 @@ static int mlx5e_get_coalesce(struct net_device *netdev, ...@@ -636,6 +689,14 @@ static int mlx5e_get_coalesce(struct net_device *netdev,
return 0; return 0;
} }
static int mlx5e_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
return mlx5e_ethtool_get_coalesce(priv, coal);
}
static void static void
mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal) mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
{ {
...@@ -659,10 +720,9 @@ mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesc ...@@ -659,10 +720,9 @@ mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesc
} }
} }
static int mlx5e_set_coalesce(struct net_device *netdev, int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal) struct ethtool_coalesce *coal)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_channels new_channels = {}; struct mlx5e_channels new_channels = {};
int err = 0; int err = 0;
...@@ -705,6 +765,14 @@ static int mlx5e_set_coalesce(struct net_device *netdev, ...@@ -705,6 +765,14 @@ static int mlx5e_set_coalesce(struct net_device *netdev,
return err; return err;
} }
static int mlx5e_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
return mlx5e_ethtool_set_coalesce(priv, coal);
}
static void ptys2ethtool_supported_link(unsigned long *supported_modes, static void ptys2ethtool_supported_link(unsigned long *supported_modes,
u32 eth_proto_cap) u32 eth_proto_cap)
{ {
......
/*
* Copyright (c) 2017, Mellanox Technologies. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "en.h"
#include "ipoib.h"
static void mlx5i_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
mlx5e_ethtool_get_drvinfo(priv, drvinfo);
}
static void mlx5i_get_strings(struct net_device *dev,
uint32_t stringset, uint8_t *data)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
mlx5e_ethtool_get_strings(priv, stringset, data);
}
static int mlx5i_get_sset_count(struct net_device *dev, int sset)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
return mlx5e_ethtool_get_sset_count(priv, sset);
}
static void mlx5i_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats,
u64 *data)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
}
static int mlx5i_set_ringparam(struct net_device *dev,
struct ethtool_ringparam *param)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
return mlx5e_ethtool_set_ringparam(priv, param);
}
static void mlx5i_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *param)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
mlx5e_ethtool_get_ringparam(priv, param);
}
static int mlx5i_set_channels(struct net_device *dev,
struct ethtool_channels *ch)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
return mlx5e_ethtool_set_channels(priv, ch);
}
static void mlx5i_get_channels(struct net_device *dev,
struct ethtool_channels *ch)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
mlx5e_ethtool_get_channels(priv, ch);
}
static int mlx5i_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal)
{
struct mlx5e_priv *priv = mlx5i_epriv(netdev);
return mlx5e_ethtool_set_coalesce(priv, coal);
}
static int mlx5i_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal)
{
struct mlx5e_priv *priv = mlx5i_epriv(netdev);
return mlx5e_ethtool_get_coalesce(priv, coal);
}
const struct ethtool_ops mlx5i_ethtool_ops = {
.get_drvinfo = mlx5i_get_drvinfo,
.get_strings = mlx5i_get_strings,
.get_sset_count = mlx5i_get_sset_count,
.get_ethtool_stats = mlx5i_get_ethtool_stats,
.get_ringparam = mlx5i_get_ringparam,
.set_ringparam = mlx5i_set_ringparam,
.get_channels = mlx5i_get_channels,
.set_channels = mlx5i_set_channels,
.get_coalesce = mlx5i_get_coalesce,
.set_coalesce = mlx5i_set_coalesce,
};
...@@ -82,6 +82,7 @@ static void mlx5i_init(struct mlx5_core_dev *mdev, ...@@ -82,6 +82,7 @@ static void mlx5i_init(struct mlx5_core_dev *mdev,
netdev->hw_features |= NETIF_F_RXHASH; netdev->hw_features |= NETIF_F_RXHASH;
netdev->netdev_ops = &mlx5i_netdev_ops; netdev->netdev_ops = &mlx5i_netdev_ops;
netdev->ethtool_ops = &mlx5i_ethtool_ops;
} }
/* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */ /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
...@@ -510,4 +511,3 @@ void mlx5_rdma_netdev_free(struct net_device *netdev) ...@@ -510,4 +511,3 @@ void mlx5_rdma_netdev_free(struct net_device *netdev)
mlx5e_destroy_mdev_resources(priv->mdev); mlx5e_destroy_mdev_resources(priv->mdev);
} }
EXPORT_SYMBOL(mlx5_rdma_netdev_free); EXPORT_SYMBOL(mlx5_rdma_netdev_free);
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#define MLX5I_MAX_NUM_TC 1 #define MLX5I_MAX_NUM_TC 1
extern const struct ethtool_ops mlx5i_ethtool_ops;
/* ipoib rdma netdev's private data structure */ /* ipoib rdma netdev's private data structure */
struct mlx5i_priv { struct mlx5i_priv {
struct rdma_netdev rn; /* keep this first */ struct rdma_netdev rn; /* keep this first */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment