cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ethtool.c (8438B)


      1/*
      2 * Copyright (c) 2017, Mellanox Technologies. All rights reserved.
      3 *
      4 * This software is available to you under a choice of one of two
      5 * licenses.  You may choose to be licensed under the terms of the GNU
      6 * General Public License (GPL) Version 2, available from the file
      7 * COPYING in the main directory of this source tree, or the
      8 * OpenIB.org BSD license below:
      9 *
     10 *     Redistribution and use in source and binary forms, with or
     11 *     without modification, are permitted provided that the following
     12 *     conditions are met:
     13 *
     14 *      - Redistributions of source code must retain the above
     15 *        copyright notice, this list of conditions and the following
     16 *        disclaimer.
     17 *
     18 *      - Redistributions in binary form must reproduce the above
     19 *        copyright notice, this list of conditions and the following
     20 *        disclaimer in the documentation and/or other materials
     21 *        provided with the distribution.
     22 *
     23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     30 * SOFTWARE.
     31 */
     32
     33#include "en.h"
     34#include "ipoib.h"
     35
     36static void mlx5i_get_drvinfo(struct net_device *dev,
     37			      struct ethtool_drvinfo *drvinfo)
     38{
     39	struct mlx5e_priv *priv = mlx5i_epriv(dev);
     40
     41	mlx5e_ethtool_get_drvinfo(priv, drvinfo);
     42	strlcpy(drvinfo->driver, KBUILD_MODNAME "[ib_ipoib]",
     43		sizeof(drvinfo->driver));
     44}
     45
     46static void mlx5i_get_strings(struct net_device *dev, u32 stringset, u8 *data)
     47{
     48	struct mlx5e_priv *priv  = mlx5i_epriv(dev);
     49
     50	mlx5e_ethtool_get_strings(priv, stringset, data);
     51}
     52
     53static int mlx5i_get_sset_count(struct net_device *dev, int sset)
     54{
     55	struct mlx5e_priv *priv = mlx5i_epriv(dev);
     56
     57	return mlx5e_ethtool_get_sset_count(priv, sset);
     58}
     59
     60static void mlx5i_get_ethtool_stats(struct net_device *dev,
     61				    struct ethtool_stats *stats,
     62				    u64 *data)
     63{
     64	struct mlx5e_priv *priv = mlx5i_epriv(dev);
     65
     66	mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
     67}
     68
     69static int mlx5i_set_ringparam(struct net_device *dev,
     70			       struct ethtool_ringparam *param,
     71			       struct kernel_ethtool_ringparam *kernel_param,
     72			       struct netlink_ext_ack *extack)
     73{
     74	struct mlx5e_priv *priv = mlx5i_epriv(dev);
     75
     76	return mlx5e_ethtool_set_ringparam(priv, param);
     77}
     78
     79static void mlx5i_get_ringparam(struct net_device *dev,
     80				struct ethtool_ringparam *param,
     81				struct kernel_ethtool_ringparam *kernel_param,
     82				struct netlink_ext_ack *extack)
     83{
     84	struct mlx5e_priv *priv = mlx5i_epriv(dev);
     85
     86	mlx5e_ethtool_get_ringparam(priv, param);
     87}
     88
     89static int mlx5i_set_channels(struct net_device *dev,
     90			      struct ethtool_channels *ch)
     91{
     92	struct mlx5e_priv *priv = mlx5i_epriv(dev);
     93
     94	return mlx5e_ethtool_set_channels(priv, ch);
     95}
     96
     97static void mlx5i_get_channels(struct net_device *dev,
     98			       struct ethtool_channels *ch)
     99{
    100	struct mlx5e_priv *priv = mlx5i_epriv(dev);
    101
    102	mlx5e_ethtool_get_channels(priv, ch);
    103}
    104
    105static int mlx5i_set_coalesce(struct net_device *netdev,
    106			      struct ethtool_coalesce *coal,
    107			      struct kernel_ethtool_coalesce *kernel_coal,
    108			      struct netlink_ext_ack *extack)
    109{
    110	struct mlx5e_priv *priv = mlx5i_epriv(netdev);
    111
    112	return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
    113}
    114
    115static int mlx5i_get_coalesce(struct net_device *netdev,
    116			      struct ethtool_coalesce *coal,
    117			      struct kernel_ethtool_coalesce *kernel_coal,
    118			      struct netlink_ext_ack *extack)
    119{
    120	struct mlx5e_priv *priv = mlx5i_epriv(netdev);
    121
    122	return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
    123}
    124
    125static int mlx5i_get_ts_info(struct net_device *netdev,
    126			     struct ethtool_ts_info *info)
    127{
    128	struct mlx5e_priv *priv = mlx5i_epriv(netdev);
    129
    130	return mlx5e_ethtool_get_ts_info(priv, info);
    131}
    132
    133static int mlx5i_flash_device(struct net_device *netdev,
    134			      struct ethtool_flash *flash)
    135{
    136	struct mlx5e_priv *priv = mlx5i_epriv(netdev);
    137
    138	return mlx5e_ethtool_flash_device(priv, flash);
    139}
    140
    141static inline int mlx5_ptys_width_enum_to_int(enum mlx5_ptys_width width)
    142{
    143	switch (width) {
    144	case MLX5_PTYS_WIDTH_1X:  return  1;
    145	case MLX5_PTYS_WIDTH_2X:  return  2;
    146	case MLX5_PTYS_WIDTH_4X:  return  4;
    147	case MLX5_PTYS_WIDTH_8X:  return  8;
    148	case MLX5_PTYS_WIDTH_12X: return 12;
    149	default:		  return -1;
    150	}
    151}
    152
    153enum mlx5_ptys_rate {
    154	MLX5_PTYS_RATE_SDR	= 1 << 0,
    155	MLX5_PTYS_RATE_DDR	= 1 << 1,
    156	MLX5_PTYS_RATE_QDR	= 1 << 2,
    157	MLX5_PTYS_RATE_FDR10	= 1 << 3,
    158	MLX5_PTYS_RATE_FDR	= 1 << 4,
    159	MLX5_PTYS_RATE_EDR	= 1 << 5,
    160	MLX5_PTYS_RATE_HDR	= 1 << 6,
    161	MLX5_PTYS_RATE_NDR	= 1 << 7,
    162};
    163
    164static inline int mlx5_ptys_rate_enum_to_int(enum mlx5_ptys_rate rate)
    165{
    166	switch (rate) {
    167	case MLX5_PTYS_RATE_SDR:   return 2500;
    168	case MLX5_PTYS_RATE_DDR:   return 5000;
    169	case MLX5_PTYS_RATE_QDR:
    170	case MLX5_PTYS_RATE_FDR10: return 10000;
    171	case MLX5_PTYS_RATE_FDR:   return 14000;
    172	case MLX5_PTYS_RATE_EDR:   return 25000;
    173	case MLX5_PTYS_RATE_HDR:   return 50000;
    174	case MLX5_PTYS_RATE_NDR:   return 100000;
    175	default:		   return -1;
    176	}
    177}
    178
    179static int mlx5i_get_speed_settings(u16 ib_link_width_oper, u16 ib_proto_oper)
    180{
    181	int rate, width;
    182
    183	rate = mlx5_ptys_rate_enum_to_int(ib_proto_oper);
    184	if (rate < 0)
    185		return -EINVAL;
    186	width = mlx5_ptys_width_enum_to_int(ib_link_width_oper);
    187	if (width < 0)
    188		return -EINVAL;
    189
    190	return rate * width;
    191}
    192
    193static int mlx5i_get_link_ksettings(struct net_device *netdev,
    194				    struct ethtool_link_ksettings *link_ksettings)
    195{
    196	struct mlx5e_priv *priv = mlx5i_epriv(netdev);
    197	struct mlx5_core_dev *mdev = priv->mdev;
    198	u16 ib_link_width_oper;
    199	u16 ib_proto_oper;
    200	int speed, ret;
    201
    202	ret = mlx5_query_ib_port_oper(mdev, &ib_link_width_oper, &ib_proto_oper,
    203				      1);
    204	if (ret)
    205		return ret;
    206
    207	ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
    208	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
    209
    210	speed = mlx5i_get_speed_settings(ib_link_width_oper, ib_proto_oper);
    211	if (speed < 0)
    212		return -EINVAL;
    213
    214	link_ksettings->base.duplex = DUPLEX_FULL;
    215	link_ksettings->base.port = PORT_OTHER;
    216
    217	link_ksettings->base.autoneg = AUTONEG_DISABLE;
    218
    219	link_ksettings->base.speed = speed;
    220
    221	return 0;
    222}
    223
    224static u32 mlx5i_flow_type_mask(u32 flow_type)
    225{
    226	return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
    227}
    228
    229static int mlx5i_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
    230{
    231	struct mlx5e_priv *priv = mlx5i_epriv(dev);
    232	struct ethtool_rx_flow_spec *fs = &cmd->fs;
    233
    234	if (mlx5i_flow_type_mask(fs->flow_type) == ETHER_FLOW)
    235		return -EINVAL;
    236
    237	return mlx5e_ethtool_set_rxnfc(priv, cmd);
    238}
    239
    240static int mlx5i_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
    241			   u32 *rule_locs)
    242{
    243	struct mlx5e_priv *priv = mlx5i_epriv(dev);
    244
    245	/* ETHTOOL_GRXRINGS is needed by ethtool -x which is not part
    246	 * of rxnfc. We keep this logic out of mlx5e_ethtool_get_rxnfc,
    247	 * to avoid breaking "ethtool -x" when mlx5e_ethtool_get_rxnfc
    248	 * is compiled out via CONFIG_MLX5_EN_RXNFC=n.
    249	 */
    250	if (info->cmd == ETHTOOL_GRXRINGS) {
    251		info->data = priv->channels.params.num_channels;
    252		return 0;
    253	}
    254
    255	return mlx5e_ethtool_get_rxnfc(priv, info, rule_locs);
    256}
    257
    258const struct ethtool_ops mlx5i_ethtool_ops = {
    259	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
    260				     ETHTOOL_COALESCE_MAX_FRAMES |
    261				     ETHTOOL_COALESCE_USE_ADAPTIVE,
    262	.get_drvinfo        = mlx5i_get_drvinfo,
    263	.get_strings        = mlx5i_get_strings,
    264	.get_sset_count     = mlx5i_get_sset_count,
    265	.get_ethtool_stats  = mlx5i_get_ethtool_stats,
    266	.get_ringparam      = mlx5i_get_ringparam,
    267	.set_ringparam      = mlx5i_set_ringparam,
    268	.flash_device       = mlx5i_flash_device,
    269	.get_channels       = mlx5i_get_channels,
    270	.set_channels       = mlx5i_set_channels,
    271	.get_coalesce       = mlx5i_get_coalesce,
    272	.set_coalesce       = mlx5i_set_coalesce,
    273	.get_ts_info        = mlx5i_get_ts_info,
    274	.get_rxnfc          = mlx5i_get_rxnfc,
    275	.set_rxnfc          = mlx5i_set_rxnfc,
    276	.get_link_ksettings = mlx5i_get_link_ksettings,
    277	.get_link           = ethtool_op_get_link,
    278};
    279
    280const struct ethtool_ops mlx5i_pkey_ethtool_ops = {
    281	.get_drvinfo        = mlx5i_get_drvinfo,
    282	.get_link           = ethtool_op_get_link,
    283	.get_ts_info        = mlx5i_get_ts_info,
    284};