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

en_ethtool.c (74012B)


      1/*
      2 * Copyright (c) 2015, 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 "en/port.h"
     35#include "en/params.h"
     36#include "en/xsk/pool.h"
     37#include "en/ptp.h"
     38#include "lib/clock.h"
     39
     40void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
     41			       struct ethtool_drvinfo *drvinfo)
     42{
     43	struct mlx5_core_dev *mdev = priv->mdev;
     44
     45	strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
     46	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
     47		 "%d.%d.%04d (%.16s)",
     48		 fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev),
     49		 mdev->board_id);
     50	strlcpy(drvinfo->bus_info, dev_name(mdev->device),
     51		sizeof(drvinfo->bus_info));
     52}
     53
     54static void mlx5e_get_drvinfo(struct net_device *dev,
     55			      struct ethtool_drvinfo *drvinfo)
     56{
     57	struct mlx5e_priv *priv = netdev_priv(dev);
     58
     59	mlx5e_ethtool_get_drvinfo(priv, drvinfo);
     60}
     61
     62struct ptys2ethtool_config {
     63	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
     64	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
     65};
     66
     67static
     68struct ptys2ethtool_config ptys2legacy_ethtool_table[MLX5E_LINK_MODES_NUMBER];
     69static
     70struct ptys2ethtool_config ptys2ext_ethtool_table[MLX5E_EXT_LINK_MODES_NUMBER];
     71
     72#define MLX5_BUILD_PTYS2ETHTOOL_CONFIG(reg_, table, ...)                  \
     73	({                                                              \
     74		struct ptys2ethtool_config *cfg;                        \
     75		const unsigned int modes[] = { __VA_ARGS__ };           \
     76		unsigned int i, bit, idx;                               \
     77		cfg = &ptys2##table##_ethtool_table[reg_];		\
     78		bitmap_zero(cfg->supported,                             \
     79			    __ETHTOOL_LINK_MODE_MASK_NBITS);            \
     80		bitmap_zero(cfg->advertised,                            \
     81			    __ETHTOOL_LINK_MODE_MASK_NBITS);            \
     82		for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) {             \
     83			bit = modes[i] % 64;                            \
     84			idx = modes[i] / 64;                            \
     85			__set_bit(bit, &cfg->supported[idx]);           \
     86			__set_bit(bit, &cfg->advertised[idx]);          \
     87		}                                                       \
     88	})
     89
     90void mlx5e_build_ptys2ethtool_map(void)
     91{
     92	memset(ptys2legacy_ethtool_table, 0, sizeof(ptys2legacy_ethtool_table));
     93	memset(ptys2ext_ethtool_table, 0, sizeof(ptys2ext_ethtool_table));
     94	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_CX_SGMII, legacy,
     95				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
     96	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_KX, legacy,
     97				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
     98	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CX4, legacy,
     99				       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
    100	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KX4, legacy,
    101				       ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
    102	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KR, legacy,
    103				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
    104	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_20GBASE_KR2, legacy,
    105				       ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);
    106	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_CR4, legacy,
    107				       ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT);
    108	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_KR4, legacy,
    109				       ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT);
    110	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_56GBASE_R4, legacy,
    111				       ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT);
    112	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CR, legacy,
    113				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
    114	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_SR, legacy,
    115				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
    116	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_ER, legacy,
    117				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
    118	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_SR4, legacy,
    119				       ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT);
    120	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_LR4, legacy,
    121				       ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
    122	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_SR2, legacy,
    123				       ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
    124	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_CR4, legacy,
    125				       ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT);
    126	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_SR4, legacy,
    127				       ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT);
    128	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_KR4, legacy,
    129				       ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT);
    130	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4, legacy,
    131				       ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
    132	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T, legacy,
    133				       ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
    134	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR, legacy,
    135				       ETHTOOL_LINK_MODE_25000baseCR_Full_BIT);
    136	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_KR, legacy,
    137				       ETHTOOL_LINK_MODE_25000baseKR_Full_BIT);
    138	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_SR, legacy,
    139				       ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
    140	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_CR2, legacy,
    141				       ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT);
    142	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_KR2, legacy,
    143				       ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT);
    144	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_SGMII_100M, ext,
    145				       ETHTOOL_LINK_MODE_100baseT_Full_BIT);
    146	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_X_SGMII, ext,
    147				       ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
    148				       ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
    149				       ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
    150	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_5GBASE_R, ext,
    151				       ETHTOOL_LINK_MODE_5000baseT_Full_BIT);
    152	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_XFI_XAUI_1, ext,
    153				       ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
    154				       ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
    155				       ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
    156				       ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
    157				       ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
    158				       ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
    159				       ETHTOOL_LINK_MODE_10000baseER_Full_BIT);
    160	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_XLAUI_4_XLPPI_4, ext,
    161				       ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
    162				       ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
    163				       ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
    164				       ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
    165	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GAUI_1_25GBASE_CR_KR, ext,
    166				       ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
    167				       ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
    168				       ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
    169	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
    170				       ext,
    171				       ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
    172				       ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
    173				       ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
    174	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR, ext,
    175				       ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
    176				       ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
    177				       ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
    178				       ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
    179				       ETHTOOL_LINK_MODE_50000baseDR_Full_BIT);
    180	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_CAUI_4_100GBASE_CR4_KR4, ext,
    181				       ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
    182				       ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
    183				       ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
    184				       ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
    185	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_2_100GBASE_CR2_KR2, ext,
    186				       ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
    187				       ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
    188				       ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
    189				       ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
    190				       ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT);
    191	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_200GAUI_4_200GBASE_CR4_KR4, ext,
    192				       ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
    193				       ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
    194				       ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
    195				       ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
    196				       ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT);
    197	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_1_100GBASE_CR_KR, ext,
    198				       ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
    199				       ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
    200				       ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
    201				       ETHTOOL_LINK_MODE_100000baseDR_Full_BIT,
    202				       ETHTOOL_LINK_MODE_100000baseCR_Full_BIT);
    203	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_200GAUI_2_200GBASE_CR2_KR2, ext,
    204				       ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT,
    205				       ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT,
    206				       ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
    207				       ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT,
    208				       ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT);
    209	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_400GAUI_4_400GBASE_CR4_KR4, ext,
    210				       ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT,
    211				       ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT,
    212				       ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
    213				       ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT,
    214				       ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT);
    215}
    216
    217static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev,
    218					struct ptys2ethtool_config **arr,
    219					u32 *size)
    220{
    221	bool ext = mlx5e_ptys_ext_supported(mdev);
    222
    223	*arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
    224	*size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
    225		      ARRAY_SIZE(ptys2legacy_ethtool_table);
    226}
    227
    228typedef int (*mlx5e_pflag_handler)(struct net_device *netdev, bool enable);
    229
    230struct pflag_desc {
    231	char name[ETH_GSTRING_LEN];
    232	mlx5e_pflag_handler handler;
    233};
    234
    235static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS];
    236
    237int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
    238{
    239	switch (sset) {
    240	case ETH_SS_STATS:
    241		return mlx5e_stats_total_num(priv);
    242	case ETH_SS_PRIV_FLAGS:
    243		return MLX5E_NUM_PFLAGS;
    244	case ETH_SS_TEST:
    245		return mlx5e_self_test_num(priv);
    246	default:
    247		return -EOPNOTSUPP;
    248	}
    249}
    250
    251static int mlx5e_get_sset_count(struct net_device *dev, int sset)
    252{
    253	struct mlx5e_priv *priv = netdev_priv(dev);
    254
    255	return mlx5e_ethtool_get_sset_count(priv, sset);
    256}
    257
    258void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
    259{
    260	int i;
    261
    262	switch (stringset) {
    263	case ETH_SS_PRIV_FLAGS:
    264		for (i = 0; i < MLX5E_NUM_PFLAGS; i++)
    265			strcpy(data + i * ETH_GSTRING_LEN,
    266			       mlx5e_priv_flags[i].name);
    267		break;
    268
    269	case ETH_SS_TEST:
    270		mlx5e_self_test_fill_strings(priv, data);
    271		break;
    272
    273	case ETH_SS_STATS:
    274		mlx5e_stats_fill_strings(priv, data);
    275		break;
    276	}
    277}
    278
    279static void mlx5e_get_strings(struct net_device *dev, u32 stringset, u8 *data)
    280{
    281	struct mlx5e_priv *priv = netdev_priv(dev);
    282
    283	mlx5e_ethtool_get_strings(priv, stringset, data);
    284}
    285
    286void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
    287				     struct ethtool_stats *stats, u64 *data)
    288{
    289	int idx = 0;
    290
    291	mutex_lock(&priv->state_lock);
    292	mlx5e_stats_update(priv);
    293	mutex_unlock(&priv->state_lock);
    294
    295	mlx5e_stats_fill(priv, data, idx);
    296}
    297
    298static void mlx5e_get_ethtool_stats(struct net_device *dev,
    299				    struct ethtool_stats *stats,
    300				    u64 *data)
    301{
    302	struct mlx5e_priv *priv = netdev_priv(dev);
    303
    304	mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
    305}
    306
    307void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
    308				 struct ethtool_ringparam *param)
    309{
    310	param->rx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
    311	param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
    312	param->rx_pending     = 1 << priv->channels.params.log_rq_mtu_frames;
    313	param->tx_pending     = 1 << priv->channels.params.log_sq_size;
    314}
    315
    316static void mlx5e_get_ringparam(struct net_device *dev,
    317				struct ethtool_ringparam *param,
    318				struct kernel_ethtool_ringparam *kernel_param,
    319				struct netlink_ext_ack *extack)
    320{
    321	struct mlx5e_priv *priv = netdev_priv(dev);
    322
    323	mlx5e_ethtool_get_ringparam(priv, param);
    324}
    325
    326int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
    327				struct ethtool_ringparam *param)
    328{
    329	struct mlx5e_params new_params;
    330	u8 log_rq_size;
    331	u8 log_sq_size;
    332	int err = 0;
    333
    334	if (param->rx_jumbo_pending) {
    335		netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n",
    336			    __func__);
    337		return -EINVAL;
    338	}
    339	if (param->rx_mini_pending) {
    340		netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n",
    341			    __func__);
    342		return -EINVAL;
    343	}
    344
    345	if (param->rx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) {
    346		netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n",
    347			    __func__, param->rx_pending,
    348			    1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
    349		return -EINVAL;
    350	}
    351
    352	if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
    353		netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
    354			    __func__, param->tx_pending,
    355			    1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
    356		return -EINVAL;
    357	}
    358
    359	log_rq_size = order_base_2(param->rx_pending);
    360	log_sq_size = order_base_2(param->tx_pending);
    361
    362	if (log_rq_size == priv->channels.params.log_rq_mtu_frames &&
    363	    log_sq_size == priv->channels.params.log_sq_size)
    364		return 0;
    365
    366	mutex_lock(&priv->state_lock);
    367
    368	new_params = priv->channels.params;
    369	new_params.log_rq_mtu_frames = log_rq_size;
    370	new_params.log_sq_size = log_sq_size;
    371
    372	err = mlx5e_validate_params(priv->mdev, &new_params);
    373	if (err)
    374		goto unlock;
    375
    376	err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
    377
    378unlock:
    379	mutex_unlock(&priv->state_lock);
    380
    381	return err;
    382}
    383
    384static int mlx5e_set_ringparam(struct net_device *dev,
    385			       struct ethtool_ringparam *param,
    386			       struct kernel_ethtool_ringparam *kernel_param,
    387			       struct netlink_ext_ack *extack)
    388{
    389	struct mlx5e_priv *priv = netdev_priv(dev);
    390
    391	return mlx5e_ethtool_set_ringparam(priv, param);
    392}
    393
    394void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
    395				struct ethtool_channels *ch)
    396{
    397	mutex_lock(&priv->state_lock);
    398
    399	ch->max_combined   = priv->max_nch;
    400	ch->combined_count = priv->channels.params.num_channels;
    401	if (priv->xsk.refcnt) {
    402		/* The upper half are XSK queues. */
    403		ch->max_combined *= 2;
    404		ch->combined_count *= 2;
    405	}
    406
    407	mutex_unlock(&priv->state_lock);
    408}
    409
    410static void mlx5e_get_channels(struct net_device *dev,
    411			       struct ethtool_channels *ch)
    412{
    413	struct mlx5e_priv *priv = netdev_priv(dev);
    414
    415	mlx5e_ethtool_get_channels(priv, ch);
    416}
    417
    418int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
    419			       struct ethtool_channels *ch)
    420{
    421	struct mlx5e_params *cur_params = &priv->channels.params;
    422	unsigned int count = ch->combined_count;
    423	struct mlx5e_params new_params;
    424	bool arfs_enabled;
    425	int rss_cnt;
    426	bool opened;
    427	int err = 0;
    428
    429	if (!count) {
    430		netdev_info(priv->netdev, "%s: combined_count=0 not supported\n",
    431			    __func__);
    432		return -EINVAL;
    433	}
    434
    435	if (cur_params->num_channels == count)
    436		return 0;
    437
    438	mutex_lock(&priv->state_lock);
    439
    440	/* Don't allow changing the number of channels if there is an active
    441	 * XSK, because the numeration of the XSK and regular RQs will change.
    442	 */
    443	if (priv->xsk.refcnt) {
    444		err = -EINVAL;
    445		netdev_err(priv->netdev, "%s: AF_XDP is active, cannot change the number of channels\n",
    446			   __func__);
    447		goto out;
    448	}
    449
    450	/* Don't allow changing the number of channels if HTB offload is active,
    451	 * because the numeration of the QoS SQs will change, while per-queue
    452	 * qdiscs are attached.
    453	 */
    454	if (priv->htb.maj_id) {
    455		err = -EINVAL;
    456		netdev_err(priv->netdev, "%s: HTB offload is active, cannot change the number of channels\n",
    457			   __func__);
    458		goto out;
    459	}
    460
    461	/* Don't allow changing the number of channels if non-default RSS contexts exist,
    462	 * the kernel doesn't protect against set_channels operations that break them.
    463	 */
    464	rss_cnt = mlx5e_rx_res_rss_cnt(priv->rx_res) - 1;
    465	if (rss_cnt) {
    466		err = -EINVAL;
    467		netdev_err(priv->netdev, "%s: Non-default RSS contexts exist (%d), cannot change the number of channels\n",
    468			   __func__, rss_cnt);
    469		goto out;
    470	}
    471
    472	/* Don't allow changing the number of channels if MQPRIO mode channel offload is active,
    473	 * because it defines a partition over the channels queues.
    474	 */
    475	if (cur_params->mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
    476		err = -EINVAL;
    477		netdev_err(priv->netdev, "%s: MQPRIO mode channel offload is active, cannot change the number of channels\n",
    478			   __func__);
    479		goto out;
    480	}
    481
    482	new_params = *cur_params;
    483	new_params.num_channels = count;
    484
    485	opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
    486
    487	arfs_enabled = opened && (priv->netdev->features & NETIF_F_NTUPLE);
    488	if (arfs_enabled)
    489		mlx5e_arfs_disable(priv);
    490
    491	/* Switch to new channels, set new parameters and close old ones */
    492	err = mlx5e_safe_switch_params(priv, &new_params,
    493				       mlx5e_num_channels_changed_ctx, NULL, true);
    494
    495	if (arfs_enabled) {
    496		int err2 = mlx5e_arfs_enable(priv);
    497
    498		if (err2)
    499			netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
    500				   __func__, err2);
    501	}
    502
    503out:
    504	mutex_unlock(&priv->state_lock);
    505
    506	return err;
    507}
    508
    509static int mlx5e_set_channels(struct net_device *dev,
    510			      struct ethtool_channels *ch)
    511{
    512	struct mlx5e_priv *priv = netdev_priv(dev);
    513
    514	return mlx5e_ethtool_set_channels(priv, ch);
    515}
    516
    517int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
    518			       struct ethtool_coalesce *coal,
    519			       struct kernel_ethtool_coalesce *kernel_coal)
    520{
    521	struct dim_cq_moder *rx_moder, *tx_moder;
    522
    523	if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
    524		return -EOPNOTSUPP;
    525
    526	rx_moder = &priv->channels.params.rx_cq_moderation;
    527	coal->rx_coalesce_usecs		= rx_moder->usec;
    528	coal->rx_max_coalesced_frames	= rx_moder->pkts;
    529	coal->use_adaptive_rx_coalesce	= priv->channels.params.rx_dim_enabled;
    530
    531	tx_moder = &priv->channels.params.tx_cq_moderation;
    532	coal->tx_coalesce_usecs		= tx_moder->usec;
    533	coal->tx_max_coalesced_frames	= tx_moder->pkts;
    534	coal->use_adaptive_tx_coalesce	= priv->channels.params.tx_dim_enabled;
    535
    536	kernel_coal->use_cqe_mode_rx =
    537		MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_BASED_MODER);
    538	kernel_coal->use_cqe_mode_tx =
    539		MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_CQE_BASED_MODER);
    540
    541	return 0;
    542}
    543
    544static int mlx5e_get_coalesce(struct net_device *netdev,
    545			      struct ethtool_coalesce *coal,
    546			      struct kernel_ethtool_coalesce *kernel_coal,
    547			      struct netlink_ext_ack *extack)
    548{
    549	struct mlx5e_priv *priv = netdev_priv(netdev);
    550
    551	return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
    552}
    553
    554#define MLX5E_MAX_COAL_TIME		MLX5_MAX_CQ_PERIOD
    555#define MLX5E_MAX_COAL_FRAMES		MLX5_MAX_CQ_COUNT
    556
    557static void
    558mlx5e_set_priv_channels_tx_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
    559{
    560	struct mlx5_core_dev *mdev = priv->mdev;
    561	int tc;
    562	int i;
    563
    564	for (i = 0; i < priv->channels.num; ++i) {
    565		struct mlx5e_channel *c = priv->channels.c[i];
    566
    567		for (tc = 0; tc < c->num_tc; tc++) {
    568			mlx5_core_modify_cq_moderation(mdev,
    569						&c->sq[tc].cq.mcq,
    570						coal->tx_coalesce_usecs,
    571						coal->tx_max_coalesced_frames);
    572		}
    573	}
    574}
    575
    576static void
    577mlx5e_set_priv_channels_rx_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
    578{
    579	struct mlx5_core_dev *mdev = priv->mdev;
    580	int i;
    581
    582	for (i = 0; i < priv->channels.num; ++i) {
    583		struct mlx5e_channel *c = priv->channels.c[i];
    584
    585		mlx5_core_modify_cq_moderation(mdev, &c->rq.cq.mcq,
    586					       coal->rx_coalesce_usecs,
    587					       coal->rx_max_coalesced_frames);
    588	}
    589}
    590
    591/* convert a boolean value of cq_mode to mlx5 period mode
    592 * true  : MLX5_CQ_PERIOD_MODE_START_FROM_CQE
    593 * false : MLX5_CQ_PERIOD_MODE_START_FROM_EQE
    594 */
    595static int cqe_mode_to_period_mode(bool val)
    596{
    597	return val ? MLX5_CQ_PERIOD_MODE_START_FROM_CQE : MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
    598}
    599
    600int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
    601			       struct ethtool_coalesce *coal,
    602			       struct kernel_ethtool_coalesce *kernel_coal,
    603			       struct netlink_ext_ack *extack)
    604{
    605	struct dim_cq_moder *rx_moder, *tx_moder;
    606	struct mlx5_core_dev *mdev = priv->mdev;
    607	struct mlx5e_params new_params;
    608	bool reset_rx, reset_tx;
    609	bool reset = true;
    610	u8 cq_period_mode;
    611	int err = 0;
    612
    613	if (!MLX5_CAP_GEN(mdev, cq_moderation))
    614		return -EOPNOTSUPP;
    615
    616	if (coal->tx_coalesce_usecs > MLX5E_MAX_COAL_TIME ||
    617	    coal->rx_coalesce_usecs > MLX5E_MAX_COAL_TIME) {
    618		netdev_info(priv->netdev, "%s: maximum coalesce time supported is %lu usecs\n",
    619			    __func__, MLX5E_MAX_COAL_TIME);
    620		return -ERANGE;
    621	}
    622
    623	if (coal->tx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES ||
    624	    coal->rx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES) {
    625		netdev_info(priv->netdev, "%s: maximum coalesced frames supported is %lu\n",
    626			    __func__, MLX5E_MAX_COAL_FRAMES);
    627		return -ERANGE;
    628	}
    629
    630	if ((kernel_coal->use_cqe_mode_rx || kernel_coal->use_cqe_mode_tx) &&
    631	    !MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) {
    632		NL_SET_ERR_MSG_MOD(extack, "cqe_mode_rx/tx is not supported on this device");
    633		return -EOPNOTSUPP;
    634	}
    635
    636	mutex_lock(&priv->state_lock);
    637	new_params = priv->channels.params;
    638
    639	rx_moder          = &new_params.rx_cq_moderation;
    640	rx_moder->usec    = coal->rx_coalesce_usecs;
    641	rx_moder->pkts    = coal->rx_max_coalesced_frames;
    642	new_params.rx_dim_enabled = !!coal->use_adaptive_rx_coalesce;
    643
    644	tx_moder          = &new_params.tx_cq_moderation;
    645	tx_moder->usec    = coal->tx_coalesce_usecs;
    646	tx_moder->pkts    = coal->tx_max_coalesced_frames;
    647	new_params.tx_dim_enabled = !!coal->use_adaptive_tx_coalesce;
    648
    649	reset_rx = !!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_dim_enabled;
    650	reset_tx = !!coal->use_adaptive_tx_coalesce != priv->channels.params.tx_dim_enabled;
    651
    652	cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_rx);
    653	if (cq_period_mode != rx_moder->cq_period_mode) {
    654		mlx5e_set_rx_cq_mode_params(&new_params, cq_period_mode);
    655		reset_rx = true;
    656	}
    657
    658	cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_tx);
    659	if (cq_period_mode != tx_moder->cq_period_mode) {
    660		mlx5e_set_tx_cq_mode_params(&new_params, cq_period_mode);
    661		reset_tx = true;
    662	}
    663
    664	if (reset_rx) {
    665		u8 mode = MLX5E_GET_PFLAG(&new_params,
    666					  MLX5E_PFLAG_RX_CQE_BASED_MODER);
    667
    668		mlx5e_reset_rx_moderation(&new_params, mode);
    669	}
    670	if (reset_tx) {
    671		u8 mode = MLX5E_GET_PFLAG(&new_params,
    672					  MLX5E_PFLAG_TX_CQE_BASED_MODER);
    673
    674		mlx5e_reset_tx_moderation(&new_params, mode);
    675	}
    676
    677	/* If DIM state hasn't changed, it's possible to modify interrupt
    678	 * moderation parameters on the fly, even if the channels are open.
    679	 */
    680	if (!reset_rx && !reset_tx && test_bit(MLX5E_STATE_OPENED, &priv->state)) {
    681		if (!coal->use_adaptive_rx_coalesce)
    682			mlx5e_set_priv_channels_rx_coalesce(priv, coal);
    683		if (!coal->use_adaptive_tx_coalesce)
    684			mlx5e_set_priv_channels_tx_coalesce(priv, coal);
    685		reset = false;
    686	}
    687
    688	err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, reset);
    689
    690	mutex_unlock(&priv->state_lock);
    691	return err;
    692}
    693
    694static int mlx5e_set_coalesce(struct net_device *netdev,
    695			      struct ethtool_coalesce *coal,
    696			      struct kernel_ethtool_coalesce *kernel_coal,
    697			      struct netlink_ext_ack *extack)
    698{
    699	struct mlx5e_priv *priv = netdev_priv(netdev);
    700
    701	return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
    702}
    703
    704static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
    705					unsigned long *supported_modes,
    706					u32 eth_proto_cap)
    707{
    708	unsigned long proto_cap = eth_proto_cap;
    709	struct ptys2ethtool_config *table;
    710	u32 max_size;
    711	int proto;
    712
    713	mlx5e_ethtool_get_speed_arr(mdev, &table, &max_size);
    714	for_each_set_bit(proto, &proto_cap, max_size)
    715		bitmap_or(supported_modes, supported_modes,
    716			  table[proto].supported,
    717			  __ETHTOOL_LINK_MODE_MASK_NBITS);
    718}
    719
    720static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
    721				    u32 eth_proto_cap, bool ext)
    722{
    723	unsigned long proto_cap = eth_proto_cap;
    724	struct ptys2ethtool_config *table;
    725	u32 max_size;
    726	int proto;
    727
    728	table = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
    729	max_size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
    730			 ARRAY_SIZE(ptys2legacy_ethtool_table);
    731
    732	for_each_set_bit(proto, &proto_cap, max_size)
    733		bitmap_or(advertising_modes, advertising_modes,
    734			  table[proto].advertised,
    735			  __ETHTOOL_LINK_MODE_MASK_NBITS);
    736}
    737
    738static const u32 pplm_fec_2_ethtool[] = {
    739	[MLX5E_FEC_NOFEC] = ETHTOOL_FEC_OFF,
    740	[MLX5E_FEC_FIRECODE] = ETHTOOL_FEC_BASER,
    741	[MLX5E_FEC_RS_528_514] = ETHTOOL_FEC_RS,
    742	[MLX5E_FEC_RS_544_514] = ETHTOOL_FEC_RS,
    743	[MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_FEC_LLRS,
    744};
    745
    746static u32 pplm2ethtool_fec(u_long fec_mode, unsigned long size)
    747{
    748	int mode = 0;
    749
    750	if (!fec_mode)
    751		return ETHTOOL_FEC_AUTO;
    752
    753	mode = find_first_bit(&fec_mode, size);
    754
    755	if (mode < ARRAY_SIZE(pplm_fec_2_ethtool))
    756		return pplm_fec_2_ethtool[mode];
    757
    758	return 0;
    759}
    760
    761#define MLX5E_ADVERTISE_SUPPORTED_FEC(mlx5_fec, ethtool_fec)		\
    762	do {								\
    763		if (mlx5e_fec_in_caps(dev, 1 << (mlx5_fec)))		\
    764			__set_bit(ethtool_fec,				\
    765				  link_ksettings->link_modes.supported);\
    766	} while (0)
    767
    768static const u32 pplm_fec_2_ethtool_linkmodes[] = {
    769	[MLX5E_FEC_NOFEC] = ETHTOOL_LINK_MODE_FEC_NONE_BIT,
    770	[MLX5E_FEC_FIRECODE] = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
    771	[MLX5E_FEC_RS_528_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
    772	[MLX5E_FEC_RS_544_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
    773	[MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
    774};
    775
    776static int get_fec_supported_advertised(struct mlx5_core_dev *dev,
    777					struct ethtool_link_ksettings *link_ksettings)
    778{
    779	unsigned long active_fec_long;
    780	u32 active_fec;
    781	u32 bitn;
    782	int err;
    783
    784	err = mlx5e_get_fec_mode(dev, &active_fec, NULL);
    785	if (err)
    786		return (err == -EOPNOTSUPP) ? 0 : err;
    787
    788	MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_NOFEC,
    789				      ETHTOOL_LINK_MODE_FEC_NONE_BIT);
    790	MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_FIRECODE,
    791				      ETHTOOL_LINK_MODE_FEC_BASER_BIT);
    792	MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_RS_528_514,
    793				      ETHTOOL_LINK_MODE_FEC_RS_BIT);
    794	MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_LLRS_272_257_1,
    795				      ETHTOOL_LINK_MODE_FEC_LLRS_BIT);
    796
    797	active_fec_long = active_fec;
    798	/* active fec is a bit set, find out which bit is set and
    799	 * advertise the corresponding ethtool bit
    800	 */
    801	bitn = find_first_bit(&active_fec_long, sizeof(active_fec_long) * BITS_PER_BYTE);
    802	if (bitn < ARRAY_SIZE(pplm_fec_2_ethtool_linkmodes))
    803		__set_bit(pplm_fec_2_ethtool_linkmodes[bitn],
    804			  link_ksettings->link_modes.advertising);
    805
    806	return 0;
    807}
    808
    809static void ptys2ethtool_supported_advertised_port(struct mlx5_core_dev *mdev,
    810						   struct ethtool_link_ksettings *link_ksettings,
    811						   u32 eth_proto_cap, u8 connector_type)
    812{
    813	if (!MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type)) {
    814		if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
    815				   | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
    816				   | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
    817				   | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
    818				   | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
    819				   | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
    820			ethtool_link_ksettings_add_link_mode(link_ksettings,
    821							     supported,
    822							     FIBRE);
    823			ethtool_link_ksettings_add_link_mode(link_ksettings,
    824							     advertising,
    825							     FIBRE);
    826		}
    827
    828		if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
    829				   | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
    830				   | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
    831				   | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
    832				   | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
    833			ethtool_link_ksettings_add_link_mode(link_ksettings,
    834							     supported,
    835							     Backplane);
    836			ethtool_link_ksettings_add_link_mode(link_ksettings,
    837							     advertising,
    838							     Backplane);
    839		}
    840		return;
    841	}
    842
    843	switch (connector_type) {
    844	case MLX5E_PORT_TP:
    845		ethtool_link_ksettings_add_link_mode(link_ksettings,
    846						     supported, TP);
    847		ethtool_link_ksettings_add_link_mode(link_ksettings,
    848						     advertising, TP);
    849		break;
    850	case MLX5E_PORT_AUI:
    851		ethtool_link_ksettings_add_link_mode(link_ksettings,
    852						     supported, AUI);
    853		ethtool_link_ksettings_add_link_mode(link_ksettings,
    854						     advertising, AUI);
    855		break;
    856	case MLX5E_PORT_BNC:
    857		ethtool_link_ksettings_add_link_mode(link_ksettings,
    858						     supported, BNC);
    859		ethtool_link_ksettings_add_link_mode(link_ksettings,
    860						     advertising, BNC);
    861		break;
    862	case MLX5E_PORT_MII:
    863		ethtool_link_ksettings_add_link_mode(link_ksettings,
    864						     supported, MII);
    865		ethtool_link_ksettings_add_link_mode(link_ksettings,
    866						     advertising, MII);
    867		break;
    868	case MLX5E_PORT_FIBRE:
    869		ethtool_link_ksettings_add_link_mode(link_ksettings,
    870						     supported, FIBRE);
    871		ethtool_link_ksettings_add_link_mode(link_ksettings,
    872						     advertising, FIBRE);
    873		break;
    874	case MLX5E_PORT_DA:
    875		ethtool_link_ksettings_add_link_mode(link_ksettings,
    876						     supported, Backplane);
    877		ethtool_link_ksettings_add_link_mode(link_ksettings,
    878						     advertising, Backplane);
    879		break;
    880	case MLX5E_PORT_NONE:
    881	case MLX5E_PORT_OTHER:
    882	default:
    883		break;
    884	}
    885}
    886
    887static void get_speed_duplex(struct net_device *netdev,
    888			     u32 eth_proto_oper, bool force_legacy,
    889			     u16 data_rate_oper,
    890			     struct ethtool_link_ksettings *link_ksettings)
    891{
    892	struct mlx5e_priv *priv = netdev_priv(netdev);
    893	u32 speed = SPEED_UNKNOWN;
    894	u8 duplex = DUPLEX_UNKNOWN;
    895
    896	if (!netif_carrier_ok(netdev))
    897		goto out;
    898
    899	speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper, force_legacy);
    900	if (!speed) {
    901		if (data_rate_oper)
    902			speed = 100 * data_rate_oper;
    903		else
    904			speed = SPEED_UNKNOWN;
    905		goto out;
    906	}
    907
    908	duplex = DUPLEX_FULL;
    909
    910out:
    911	link_ksettings->base.speed = speed;
    912	link_ksettings->base.duplex = duplex;
    913}
    914
    915static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
    916			  struct ethtool_link_ksettings *link_ksettings)
    917{
    918	unsigned long *supported = link_ksettings->link_modes.supported;
    919	ptys2ethtool_supported_link(mdev, supported, eth_proto_cap);
    920
    921	ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
    922}
    923
    924static void get_advertising(u32 eth_proto_cap, u8 tx_pause, u8 rx_pause,
    925			    struct ethtool_link_ksettings *link_ksettings,
    926			    bool ext)
    927{
    928	unsigned long *advertising = link_ksettings->link_modes.advertising;
    929	ptys2ethtool_adver_link(advertising, eth_proto_cap, ext);
    930
    931	if (rx_pause)
    932		ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
    933	if (tx_pause ^ rx_pause)
    934		ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
    935}
    936
    937static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = {
    938		[MLX5E_PORT_UNKNOWN]            = PORT_OTHER,
    939		[MLX5E_PORT_NONE]               = PORT_NONE,
    940		[MLX5E_PORT_TP]                 = PORT_TP,
    941		[MLX5E_PORT_AUI]                = PORT_AUI,
    942		[MLX5E_PORT_BNC]                = PORT_BNC,
    943		[MLX5E_PORT_MII]                = PORT_MII,
    944		[MLX5E_PORT_FIBRE]              = PORT_FIBRE,
    945		[MLX5E_PORT_DA]                 = PORT_DA,
    946		[MLX5E_PORT_OTHER]              = PORT_OTHER,
    947	};
    948
    949static u8 get_connector_port(struct mlx5_core_dev *mdev, u32 eth_proto, u8 connector_type)
    950{
    951	if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type))
    952		return ptys2connector_type[connector_type];
    953
    954	if (eth_proto &
    955	    (MLX5E_PROT_MASK(MLX5E_10GBASE_SR)   |
    956	     MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)  |
    957	     MLX5E_PROT_MASK(MLX5E_100GBASE_SR4) |
    958	     MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
    959		return PORT_FIBRE;
    960	}
    961
    962	if (eth_proto &
    963	    (MLX5E_PROT_MASK(MLX5E_40GBASE_CR4) |
    964	     MLX5E_PROT_MASK(MLX5E_10GBASE_CR)  |
    965	     MLX5E_PROT_MASK(MLX5E_100GBASE_CR4))) {
    966		return PORT_DA;
    967	}
    968
    969	if (eth_proto &
    970	    (MLX5E_PROT_MASK(MLX5E_10GBASE_KX4) |
    971	     MLX5E_PROT_MASK(MLX5E_10GBASE_KR)  |
    972	     MLX5E_PROT_MASK(MLX5E_40GBASE_KR4) |
    973	     MLX5E_PROT_MASK(MLX5E_100GBASE_KR4))) {
    974		return PORT_NONE;
    975	}
    976
    977	return PORT_OTHER;
    978}
    979
    980static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
    981			       struct ethtool_link_ksettings *link_ksettings)
    982{
    983	unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising;
    984	bool ext = mlx5e_ptys_ext_supported(mdev);
    985
    986	ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext);
    987}
    988
    989int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
    990				     struct ethtool_link_ksettings *link_ksettings)
    991{
    992	struct mlx5_core_dev *mdev = priv->mdev;
    993	u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {};
    994	u32 eth_proto_admin;
    995	u8 an_disable_admin;
    996	u16 data_rate_oper;
    997	u32 eth_proto_oper;
    998	u32 eth_proto_cap;
    999	u8 connector_type;
   1000	u32 rx_pause = 0;
   1001	u32 tx_pause = 0;
   1002	u32 eth_proto_lp;
   1003	bool admin_ext;
   1004	u8 an_status;
   1005	bool ext;
   1006	int err;
   1007
   1008	err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
   1009	if (err) {
   1010		netdev_err(priv->netdev, "%s: query port ptys failed: %d\n",
   1011			   __func__, err);
   1012		goto err_query_regs;
   1013	}
   1014	ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability);
   1015	eth_proto_cap    = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
   1016					      eth_proto_capability);
   1017	eth_proto_admin  = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
   1018					      eth_proto_admin);
   1019	/* Fields: eth_proto_admin and ext_eth_proto_admin  are
   1020	 * mutually exclusive. Hence try reading legacy advertising
   1021	 * when extended advertising is zero.
   1022	 * admin_ext indicates which proto_admin (ext vs. legacy)
   1023	 * should be read and interpreted
   1024	 */
   1025	admin_ext = ext;
   1026	if (ext && !eth_proto_admin) {
   1027		eth_proto_admin  = MLX5_GET_ETH_PROTO(ptys_reg, out, false,
   1028						      eth_proto_admin);
   1029		admin_ext = false;
   1030	}
   1031
   1032	eth_proto_oper   = MLX5_GET_ETH_PROTO(ptys_reg, out, admin_ext,
   1033					      eth_proto_oper);
   1034	eth_proto_lp	    = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
   1035	an_disable_admin    = MLX5_GET(ptys_reg, out, an_disable_admin);
   1036	an_status	    = MLX5_GET(ptys_reg, out, an_status);
   1037	connector_type	    = MLX5_GET(ptys_reg, out, connector_type);
   1038	data_rate_oper	    = MLX5_GET(ptys_reg, out, data_rate_oper);
   1039
   1040	mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
   1041
   1042	ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
   1043	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
   1044
   1045	get_supported(mdev, eth_proto_cap, link_ksettings);
   1046	get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings,
   1047			admin_ext);
   1048	get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext,
   1049			 data_rate_oper, link_ksettings);
   1050
   1051	eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
   1052	connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ?
   1053			 connector_type : MLX5E_PORT_UNKNOWN;
   1054	link_ksettings->base.port = get_connector_port(mdev, eth_proto_oper, connector_type);
   1055	ptys2ethtool_supported_advertised_port(mdev, link_ksettings, eth_proto_admin,
   1056					       connector_type);
   1057	get_lp_advertising(mdev, eth_proto_lp, link_ksettings);
   1058
   1059	if (an_status == MLX5_AN_COMPLETE)
   1060		ethtool_link_ksettings_add_link_mode(link_ksettings,
   1061						     lp_advertising, Autoneg);
   1062
   1063	link_ksettings->base.autoneg = an_disable_admin ? AUTONEG_DISABLE :
   1064							  AUTONEG_ENABLE;
   1065	ethtool_link_ksettings_add_link_mode(link_ksettings, supported,
   1066					     Autoneg);
   1067
   1068	err = get_fec_supported_advertised(mdev, link_ksettings);
   1069	if (err) {
   1070		netdev_dbg(priv->netdev, "%s: FEC caps query failed: %d\n",
   1071			   __func__, err);
   1072		err = 0; /* don't fail caps query because of FEC error */
   1073	}
   1074
   1075	if (!an_disable_admin)
   1076		ethtool_link_ksettings_add_link_mode(link_ksettings,
   1077						     advertising, Autoneg);
   1078
   1079err_query_regs:
   1080	return err;
   1081}
   1082
   1083static int mlx5e_get_link_ksettings(struct net_device *netdev,
   1084				    struct ethtool_link_ksettings *link_ksettings)
   1085{
   1086	struct mlx5e_priv *priv = netdev_priv(netdev);
   1087
   1088	return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
   1089}
   1090
   1091static int mlx5e_speed_validate(struct net_device *netdev, bool ext,
   1092				const unsigned long link_modes, u8 autoneg)
   1093{
   1094	/* Extended link-mode has no speed limitations. */
   1095	if (ext)
   1096		return 0;
   1097
   1098	if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) &&
   1099	    autoneg != AUTONEG_ENABLE) {
   1100		netdev_err(netdev, "%s: 56G link speed requires autoneg enabled\n",
   1101			   __func__);
   1102		return -EINVAL;
   1103	}
   1104	return 0;
   1105}
   1106
   1107static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
   1108{
   1109	u32 i, ptys_modes = 0;
   1110
   1111	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
   1112		if (*ptys2legacy_ethtool_table[i].advertised == 0)
   1113			continue;
   1114		if (bitmap_intersects(ptys2legacy_ethtool_table[i].advertised,
   1115				      link_modes,
   1116				      __ETHTOOL_LINK_MODE_MASK_NBITS))
   1117			ptys_modes |= MLX5E_PROT_MASK(i);
   1118	}
   1119
   1120	return ptys_modes;
   1121}
   1122
   1123static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes)
   1124{
   1125	u32 i, ptys_modes = 0;
   1126	unsigned long modes[2];
   1127
   1128	for (i = 0; i < MLX5E_EXT_LINK_MODES_NUMBER; ++i) {
   1129		if (ptys2ext_ethtool_table[i].advertised[0] == 0 &&
   1130		    ptys2ext_ethtool_table[i].advertised[1] == 0)
   1131			continue;
   1132		memset(modes, 0, sizeof(modes));
   1133		bitmap_and(modes, ptys2ext_ethtool_table[i].advertised,
   1134			   link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
   1135
   1136		if (modes[0] == ptys2ext_ethtool_table[i].advertised[0] &&
   1137		    modes[1] == ptys2ext_ethtool_table[i].advertised[1])
   1138			ptys_modes |= MLX5E_PROT_MASK(i);
   1139	}
   1140	return ptys_modes;
   1141}
   1142
   1143static bool ext_link_mode_requested(const unsigned long *adver)
   1144{
   1145#define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT
   1146	int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT;
   1147	__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = {0,};
   1148
   1149	bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size);
   1150	return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
   1151}
   1152
   1153static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported)
   1154{
   1155	bool ext_link_mode = ext_link_mode_requested(adver);
   1156
   1157	return  autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported;
   1158}
   1159
   1160int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
   1161				     const struct ethtool_link_ksettings *link_ksettings)
   1162{
   1163	struct mlx5_core_dev *mdev = priv->mdev;
   1164	struct mlx5e_port_eth_proto eproto;
   1165	const unsigned long *adver;
   1166	bool an_changes = false;
   1167	u8 an_disable_admin;
   1168	bool ext_supported;
   1169	u8 an_disable_cap;
   1170	bool an_disable;
   1171	u32 link_modes;
   1172	u8 an_status;
   1173	u8 autoneg;
   1174	u32 speed;
   1175	bool ext;
   1176	int err;
   1177
   1178	u32 (*ethtool2ptys_adver_func)(const unsigned long *adver);
   1179
   1180	adver = link_ksettings->link_modes.advertising;
   1181	autoneg = link_ksettings->base.autoneg;
   1182	speed = link_ksettings->base.speed;
   1183
   1184	ext_supported = mlx5e_ptys_ext_supported(mdev);
   1185	ext = ext_requested(autoneg, adver, ext_supported);
   1186	if (!ext_supported && ext)
   1187		return -EOPNOTSUPP;
   1188
   1189	ethtool2ptys_adver_func = ext ? mlx5e_ethtool2ptys_ext_adver_link :
   1190				  mlx5e_ethtool2ptys_adver_link;
   1191	err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
   1192	if (err) {
   1193		netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
   1194			   __func__, err);
   1195		goto out;
   1196	}
   1197	link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
   1198		mlx5e_port_speed2linkmodes(mdev, speed, !ext);
   1199
   1200	err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg);
   1201	if (err)
   1202		goto out;
   1203
   1204	link_modes = link_modes & eproto.cap;
   1205	if (!link_modes) {
   1206		netdev_err(priv->netdev, "%s: Not supported link mode(s) requested",
   1207			   __func__);
   1208		err = -EINVAL;
   1209		goto out;
   1210	}
   1211
   1212	mlx5_port_query_eth_autoneg(mdev, &an_status, &an_disable_cap,
   1213				    &an_disable_admin);
   1214
   1215	an_disable = autoneg == AUTONEG_DISABLE;
   1216	an_changes = ((!an_disable && an_disable_admin) ||
   1217		      (an_disable && !an_disable_admin));
   1218
   1219	if (!an_changes && link_modes == eproto.admin)
   1220		goto out;
   1221
   1222	mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext);
   1223	mlx5_toggle_port_link(mdev);
   1224
   1225out:
   1226	return err;
   1227}
   1228
   1229static int mlx5e_set_link_ksettings(struct net_device *netdev,
   1230				    const struct ethtool_link_ksettings *link_ksettings)
   1231{
   1232	struct mlx5e_priv *priv = netdev_priv(netdev);
   1233
   1234	return mlx5e_ethtool_set_link_ksettings(priv, link_ksettings);
   1235}
   1236
   1237u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv)
   1238{
   1239	return sizeof_field(struct mlx5e_rss_params_hash, toeplitz_hash_key);
   1240}
   1241
   1242static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
   1243{
   1244	struct mlx5e_priv *priv = netdev_priv(netdev);
   1245
   1246	return mlx5e_ethtool_get_rxfh_key_size(priv);
   1247}
   1248
   1249u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv)
   1250{
   1251	return MLX5E_INDIR_RQT_SIZE;
   1252}
   1253
   1254static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
   1255{
   1256	struct mlx5e_priv *priv = netdev_priv(netdev);
   1257
   1258	return mlx5e_ethtool_get_rxfh_indir_size(priv);
   1259}
   1260
   1261static int mlx5e_get_rxfh_context(struct net_device *dev, u32 *indir,
   1262				  u8 *key, u8 *hfunc, u32 rss_context)
   1263{
   1264	struct mlx5e_priv *priv = netdev_priv(dev);
   1265	int err;
   1266
   1267	mutex_lock(&priv->state_lock);
   1268	err = mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rss_context, indir, key, hfunc);
   1269	mutex_unlock(&priv->state_lock);
   1270	return err;
   1271}
   1272
   1273static int mlx5e_set_rxfh_context(struct net_device *dev, const u32 *indir,
   1274				  const u8 *key, const u8 hfunc,
   1275				  u32 *rss_context, bool delete)
   1276{
   1277	struct mlx5e_priv *priv = netdev_priv(dev);
   1278	int err;
   1279
   1280	mutex_lock(&priv->state_lock);
   1281	if (delete) {
   1282		err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
   1283		goto unlock;
   1284	}
   1285
   1286	if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
   1287		unsigned int count = priv->channels.params.num_channels;
   1288
   1289		err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
   1290		if (err)
   1291			goto unlock;
   1292	}
   1293
   1294	err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, *rss_context, indir, key,
   1295					hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc);
   1296
   1297unlock:
   1298	mutex_unlock(&priv->state_lock);
   1299	return err;
   1300}
   1301
   1302int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
   1303		   u8 *hfunc)
   1304{
   1305	return mlx5e_get_rxfh_context(netdev, indir, key, hfunc, 0);
   1306}
   1307
   1308int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
   1309		   const u8 *key, const u8 hfunc)
   1310{
   1311	struct mlx5e_priv *priv = netdev_priv(dev);
   1312	int err;
   1313
   1314	mutex_lock(&priv->state_lock);
   1315	err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, 0, indir, key,
   1316					hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc);
   1317	mutex_unlock(&priv->state_lock);
   1318	return err;
   1319}
   1320
   1321#define MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC		100
   1322#define MLX5E_PFC_PREVEN_TOUT_MAX_MSEC		8000
   1323#define MLX5E_PFC_PREVEN_MINOR_PRECENT		85
   1324#define MLX5E_PFC_PREVEN_TOUT_MIN_MSEC		80
   1325#define MLX5E_DEVICE_STALL_MINOR_WATERMARK(critical_tout) \
   1326	max_t(u16, MLX5E_PFC_PREVEN_TOUT_MIN_MSEC, \
   1327	      (critical_tout * MLX5E_PFC_PREVEN_MINOR_PRECENT) / 100)
   1328
   1329static int mlx5e_get_pfc_prevention_tout(struct net_device *netdev,
   1330					 u16 *pfc_prevention_tout)
   1331{
   1332	struct mlx5e_priv *priv    = netdev_priv(netdev);
   1333	struct mlx5_core_dev *mdev = priv->mdev;
   1334
   1335	if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) ||
   1336	    !MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
   1337		return -EOPNOTSUPP;
   1338
   1339	return mlx5_query_port_stall_watermark(mdev, pfc_prevention_tout, NULL);
   1340}
   1341
   1342static int mlx5e_set_pfc_prevention_tout(struct net_device *netdev,
   1343					 u16 pfc_preven)
   1344{
   1345	struct mlx5e_priv *priv = netdev_priv(netdev);
   1346	struct mlx5_core_dev *mdev = priv->mdev;
   1347	u16 critical_tout;
   1348	u16 minor;
   1349
   1350	if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) ||
   1351	    !MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
   1352		return -EOPNOTSUPP;
   1353
   1354	critical_tout = (pfc_preven == PFC_STORM_PREVENTION_AUTO) ?
   1355			MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC :
   1356			pfc_preven;
   1357
   1358	if (critical_tout != PFC_STORM_PREVENTION_DISABLE &&
   1359	    (critical_tout > MLX5E_PFC_PREVEN_TOUT_MAX_MSEC ||
   1360	     critical_tout < MLX5E_PFC_PREVEN_TOUT_MIN_MSEC)) {
   1361		netdev_info(netdev, "%s: pfc prevention tout not in range (%d-%d)\n",
   1362			    __func__, MLX5E_PFC_PREVEN_TOUT_MIN_MSEC,
   1363			    MLX5E_PFC_PREVEN_TOUT_MAX_MSEC);
   1364		return -EINVAL;
   1365	}
   1366
   1367	minor = MLX5E_DEVICE_STALL_MINOR_WATERMARK(critical_tout);
   1368	return mlx5_set_port_stall_watermark(mdev, critical_tout,
   1369					     minor);
   1370}
   1371
   1372static int mlx5e_get_tunable(struct net_device *dev,
   1373			     const struct ethtool_tunable *tuna,
   1374			     void *data)
   1375{
   1376	int err;
   1377
   1378	switch (tuna->id) {
   1379	case ETHTOOL_PFC_PREVENTION_TOUT:
   1380		err = mlx5e_get_pfc_prevention_tout(dev, data);
   1381		break;
   1382	default:
   1383		err = -EINVAL;
   1384		break;
   1385	}
   1386
   1387	return err;
   1388}
   1389
   1390static int mlx5e_set_tunable(struct net_device *dev,
   1391			     const struct ethtool_tunable *tuna,
   1392			     const void *data)
   1393{
   1394	struct mlx5e_priv *priv = netdev_priv(dev);
   1395	int err;
   1396
   1397	mutex_lock(&priv->state_lock);
   1398
   1399	switch (tuna->id) {
   1400	case ETHTOOL_PFC_PREVENTION_TOUT:
   1401		err = mlx5e_set_pfc_prevention_tout(dev, *(u16 *)data);
   1402		break;
   1403	default:
   1404		err = -EINVAL;
   1405		break;
   1406	}
   1407
   1408	mutex_unlock(&priv->state_lock);
   1409	return err;
   1410}
   1411
   1412static void mlx5e_get_pause_stats(struct net_device *netdev,
   1413				  struct ethtool_pause_stats *pause_stats)
   1414{
   1415	struct mlx5e_priv *priv = netdev_priv(netdev);
   1416
   1417	mlx5e_stats_pause_get(priv, pause_stats);
   1418}
   1419
   1420void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
   1421				  struct ethtool_pauseparam *pauseparam)
   1422{
   1423	struct mlx5_core_dev *mdev = priv->mdev;
   1424	int err;
   1425
   1426	err = mlx5_query_port_pause(mdev, &pauseparam->rx_pause,
   1427				    &pauseparam->tx_pause);
   1428	if (err) {
   1429		netdev_err(priv->netdev, "%s: mlx5_query_port_pause failed:0x%x\n",
   1430			   __func__, err);
   1431	}
   1432}
   1433
   1434static void mlx5e_get_pauseparam(struct net_device *netdev,
   1435				 struct ethtool_pauseparam *pauseparam)
   1436{
   1437	struct mlx5e_priv *priv = netdev_priv(netdev);
   1438
   1439	mlx5e_ethtool_get_pauseparam(priv, pauseparam);
   1440}
   1441
   1442int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
   1443				 struct ethtool_pauseparam *pauseparam)
   1444{
   1445	struct mlx5_core_dev *mdev = priv->mdev;
   1446	int err;
   1447
   1448	if (!MLX5_CAP_GEN(mdev, vport_group_manager))
   1449		return -EOPNOTSUPP;
   1450
   1451	if (pauseparam->autoneg)
   1452		return -EINVAL;
   1453
   1454	err = mlx5_set_port_pause(mdev,
   1455				  pauseparam->rx_pause ? 1 : 0,
   1456				  pauseparam->tx_pause ? 1 : 0);
   1457	if (err) {
   1458		netdev_err(priv->netdev, "%s: mlx5_set_port_pause failed:0x%x\n",
   1459			   __func__, err);
   1460	}
   1461
   1462	return err;
   1463}
   1464
   1465static int mlx5e_set_pauseparam(struct net_device *netdev,
   1466				struct ethtool_pauseparam *pauseparam)
   1467{
   1468	struct mlx5e_priv *priv = netdev_priv(netdev);
   1469
   1470	return mlx5e_ethtool_set_pauseparam(priv, pauseparam);
   1471}
   1472
   1473int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
   1474			      struct ethtool_ts_info *info)
   1475{
   1476	struct mlx5_core_dev *mdev = priv->mdev;
   1477
   1478	info->phc_index = mlx5_clock_get_ptp_index(mdev);
   1479
   1480	if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz) ||
   1481	    info->phc_index == -1)
   1482		return 0;
   1483
   1484	info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
   1485				SOF_TIMESTAMPING_RX_HARDWARE |
   1486				SOF_TIMESTAMPING_RAW_HARDWARE;
   1487
   1488	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
   1489			 BIT(HWTSTAMP_TX_ON);
   1490
   1491	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
   1492			   BIT(HWTSTAMP_FILTER_ALL);
   1493
   1494	return 0;
   1495}
   1496
   1497static int mlx5e_get_ts_info(struct net_device *dev,
   1498			     struct ethtool_ts_info *info)
   1499{
   1500	struct mlx5e_priv *priv = netdev_priv(dev);
   1501
   1502	return mlx5e_ethtool_get_ts_info(priv, info);
   1503}
   1504
   1505static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
   1506{
   1507	__u32 ret = 0;
   1508
   1509	if (MLX5_CAP_GEN(mdev, wol_g))
   1510		ret |= WAKE_MAGIC;
   1511
   1512	if (MLX5_CAP_GEN(mdev, wol_s))
   1513		ret |= WAKE_MAGICSECURE;
   1514
   1515	if (MLX5_CAP_GEN(mdev, wol_a))
   1516		ret |= WAKE_ARP;
   1517
   1518	if (MLX5_CAP_GEN(mdev, wol_b))
   1519		ret |= WAKE_BCAST;
   1520
   1521	if (MLX5_CAP_GEN(mdev, wol_m))
   1522		ret |= WAKE_MCAST;
   1523
   1524	if (MLX5_CAP_GEN(mdev, wol_u))
   1525		ret |= WAKE_UCAST;
   1526
   1527	if (MLX5_CAP_GEN(mdev, wol_p))
   1528		ret |= WAKE_PHY;
   1529
   1530	return ret;
   1531}
   1532
   1533static __u32 mlx5e_reformat_wol_mode_mlx5_to_linux(u8 mode)
   1534{
   1535	__u32 ret = 0;
   1536
   1537	if (mode & MLX5_WOL_MAGIC)
   1538		ret |= WAKE_MAGIC;
   1539
   1540	if (mode & MLX5_WOL_SECURED_MAGIC)
   1541		ret |= WAKE_MAGICSECURE;
   1542
   1543	if (mode & MLX5_WOL_ARP)
   1544		ret |= WAKE_ARP;
   1545
   1546	if (mode & MLX5_WOL_BROADCAST)
   1547		ret |= WAKE_BCAST;
   1548
   1549	if (mode & MLX5_WOL_MULTICAST)
   1550		ret |= WAKE_MCAST;
   1551
   1552	if (mode & MLX5_WOL_UNICAST)
   1553		ret |= WAKE_UCAST;
   1554
   1555	if (mode & MLX5_WOL_PHY_ACTIVITY)
   1556		ret |= WAKE_PHY;
   1557
   1558	return ret;
   1559}
   1560
   1561static u8 mlx5e_reformat_wol_mode_linux_to_mlx5(__u32 mode)
   1562{
   1563	u8 ret = 0;
   1564
   1565	if (mode & WAKE_MAGIC)
   1566		ret |= MLX5_WOL_MAGIC;
   1567
   1568	if (mode & WAKE_MAGICSECURE)
   1569		ret |= MLX5_WOL_SECURED_MAGIC;
   1570
   1571	if (mode & WAKE_ARP)
   1572		ret |= MLX5_WOL_ARP;
   1573
   1574	if (mode & WAKE_BCAST)
   1575		ret |= MLX5_WOL_BROADCAST;
   1576
   1577	if (mode & WAKE_MCAST)
   1578		ret |= MLX5_WOL_MULTICAST;
   1579
   1580	if (mode & WAKE_UCAST)
   1581		ret |= MLX5_WOL_UNICAST;
   1582
   1583	if (mode & WAKE_PHY)
   1584		ret |= MLX5_WOL_PHY_ACTIVITY;
   1585
   1586	return ret;
   1587}
   1588
   1589static void mlx5e_get_wol(struct net_device *netdev,
   1590			  struct ethtool_wolinfo *wol)
   1591{
   1592	struct mlx5e_priv *priv = netdev_priv(netdev);
   1593	struct mlx5_core_dev *mdev = priv->mdev;
   1594	u8 mlx5_wol_mode;
   1595	int err;
   1596
   1597	memset(wol, 0, sizeof(*wol));
   1598
   1599	wol->supported = mlx5e_get_wol_supported(mdev);
   1600	if (!wol->supported)
   1601		return;
   1602
   1603	err = mlx5_query_port_wol(mdev, &mlx5_wol_mode);
   1604	if (err)
   1605		return;
   1606
   1607	wol->wolopts = mlx5e_reformat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
   1608}
   1609
   1610static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
   1611{
   1612	struct mlx5e_priv *priv = netdev_priv(netdev);
   1613	struct mlx5_core_dev *mdev = priv->mdev;
   1614	__u32 wol_supported = mlx5e_get_wol_supported(mdev);
   1615	u32 mlx5_wol_mode;
   1616
   1617	if (!wol_supported)
   1618		return -EOPNOTSUPP;
   1619
   1620	if (wol->wolopts & ~wol_supported)
   1621		return -EINVAL;
   1622
   1623	mlx5_wol_mode = mlx5e_reformat_wol_mode_linux_to_mlx5(wol->wolopts);
   1624
   1625	return mlx5_set_port_wol(mdev, mlx5_wol_mode);
   1626}
   1627
   1628static void mlx5e_get_fec_stats(struct net_device *netdev,
   1629				struct ethtool_fec_stats *fec_stats)
   1630{
   1631	struct mlx5e_priv *priv = netdev_priv(netdev);
   1632
   1633	mlx5e_stats_fec_get(priv, fec_stats);
   1634}
   1635
   1636static int mlx5e_get_fecparam(struct net_device *netdev,
   1637			      struct ethtool_fecparam *fecparam)
   1638{
   1639	struct mlx5e_priv *priv = netdev_priv(netdev);
   1640	struct mlx5_core_dev *mdev = priv->mdev;
   1641	u16 fec_configured;
   1642	u32 fec_active;
   1643	int err;
   1644
   1645	err = mlx5e_get_fec_mode(mdev, &fec_active, &fec_configured);
   1646
   1647	if (err)
   1648		return err;
   1649
   1650	fecparam->active_fec = pplm2ethtool_fec((unsigned long)fec_active,
   1651						sizeof(unsigned long) * BITS_PER_BYTE);
   1652
   1653	if (!fecparam->active_fec)
   1654		return -EOPNOTSUPP;
   1655
   1656	fecparam->fec = pplm2ethtool_fec((unsigned long)fec_configured,
   1657					 sizeof(unsigned long) * BITS_PER_BYTE);
   1658
   1659	return 0;
   1660}
   1661
   1662static int mlx5e_set_fecparam(struct net_device *netdev,
   1663			      struct ethtool_fecparam *fecparam)
   1664{
   1665	struct mlx5e_priv *priv = netdev_priv(netdev);
   1666	struct mlx5_core_dev *mdev = priv->mdev;
   1667	unsigned long fec_bitmap;
   1668	u16 fec_policy = 0;
   1669	int mode;
   1670	int err;
   1671
   1672	bitmap_from_arr32(&fec_bitmap, &fecparam->fec, sizeof(fecparam->fec) * BITS_PER_BYTE);
   1673	if (bitmap_weight(&fec_bitmap, ETHTOOL_FEC_LLRS_BIT + 1) > 1)
   1674		return -EOPNOTSUPP;
   1675
   1676	for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) {
   1677		if (!(pplm_fec_2_ethtool[mode] & fecparam->fec))
   1678			continue;
   1679		fec_policy |= (1 << mode);
   1680		break;
   1681	}
   1682
   1683	err = mlx5e_set_fec_mode(mdev, fec_policy);
   1684
   1685	if (err)
   1686		return err;
   1687
   1688	mlx5_toggle_port_link(mdev);
   1689
   1690	return 0;
   1691}
   1692
   1693static u32 mlx5e_get_msglevel(struct net_device *dev)
   1694{
   1695	return ((struct mlx5e_priv *)netdev_priv(dev))->msglevel;
   1696}
   1697
   1698static void mlx5e_set_msglevel(struct net_device *dev, u32 val)
   1699{
   1700	((struct mlx5e_priv *)netdev_priv(dev))->msglevel = val;
   1701}
   1702
   1703static int mlx5e_set_phys_id(struct net_device *dev,
   1704			     enum ethtool_phys_id_state state)
   1705{
   1706	struct mlx5e_priv *priv = netdev_priv(dev);
   1707	struct mlx5_core_dev *mdev = priv->mdev;
   1708	u16 beacon_duration;
   1709
   1710	if (!MLX5_CAP_GEN(mdev, beacon_led))
   1711		return -EOPNOTSUPP;
   1712
   1713	switch (state) {
   1714	case ETHTOOL_ID_ACTIVE:
   1715		beacon_duration = MLX5_BEACON_DURATION_INF;
   1716		break;
   1717	case ETHTOOL_ID_INACTIVE:
   1718		beacon_duration = MLX5_BEACON_DURATION_OFF;
   1719		break;
   1720	default:
   1721		return -EOPNOTSUPP;
   1722	}
   1723
   1724	return mlx5_set_port_beacon(mdev, beacon_duration);
   1725}
   1726
   1727static int mlx5e_get_module_info(struct net_device *netdev,
   1728				 struct ethtool_modinfo *modinfo)
   1729{
   1730	struct mlx5e_priv *priv = netdev_priv(netdev);
   1731	struct mlx5_core_dev *dev = priv->mdev;
   1732	int size_read = 0;
   1733	u8 data[4] = {0};
   1734
   1735	size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
   1736	if (size_read < 2)
   1737		return -EIO;
   1738
   1739	/* data[0] = identifier byte */
   1740	switch (data[0]) {
   1741	case MLX5_MODULE_ID_QSFP:
   1742		modinfo->type       = ETH_MODULE_SFF_8436;
   1743		modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
   1744		break;
   1745	case MLX5_MODULE_ID_QSFP_PLUS:
   1746	case MLX5_MODULE_ID_QSFP28:
   1747		/* data[1] = revision id */
   1748		if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
   1749			modinfo->type       = ETH_MODULE_SFF_8636;
   1750			modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
   1751		} else {
   1752			modinfo->type       = ETH_MODULE_SFF_8436;
   1753			modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
   1754		}
   1755		break;
   1756	case MLX5_MODULE_ID_SFP:
   1757		modinfo->type       = ETH_MODULE_SFF_8472;
   1758		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
   1759		break;
   1760	default:
   1761		netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
   1762			   __func__, data[0]);
   1763		return -EINVAL;
   1764	}
   1765
   1766	return 0;
   1767}
   1768
   1769static int mlx5e_get_module_eeprom(struct net_device *netdev,
   1770				   struct ethtool_eeprom *ee,
   1771				   u8 *data)
   1772{
   1773	struct mlx5e_priv *priv = netdev_priv(netdev);
   1774	struct mlx5_core_dev *mdev = priv->mdev;
   1775	int offset = ee->offset;
   1776	int size_read;
   1777	int i = 0;
   1778
   1779	if (!ee->len)
   1780		return -EINVAL;
   1781
   1782	memset(data, 0, ee->len);
   1783
   1784	while (i < ee->len) {
   1785		size_read = mlx5_query_module_eeprom(mdev, offset, ee->len - i,
   1786						     data + i);
   1787
   1788		if (!size_read)
   1789			/* Done reading */
   1790			return 0;
   1791
   1792		if (size_read < 0) {
   1793			netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n",
   1794				   __func__, size_read);
   1795			return size_read;
   1796		}
   1797
   1798		i += size_read;
   1799		offset += size_read;
   1800	}
   1801
   1802	return 0;
   1803}
   1804
   1805static int mlx5e_get_module_eeprom_by_page(struct net_device *netdev,
   1806					   const struct ethtool_module_eeprom *page_data,
   1807					   struct netlink_ext_ack *extack)
   1808{
   1809	struct mlx5e_priv *priv = netdev_priv(netdev);
   1810	struct mlx5_module_eeprom_query_params query;
   1811	struct mlx5_core_dev *mdev = priv->mdev;
   1812	u8 *data = page_data->data;
   1813	int size_read;
   1814	int i = 0;
   1815
   1816	if (!page_data->length)
   1817		return -EINVAL;
   1818
   1819	memset(data, 0, page_data->length);
   1820
   1821	query.offset = page_data->offset;
   1822	query.i2c_address = page_data->i2c_address;
   1823	query.bank = page_data->bank;
   1824	query.page = page_data->page;
   1825	while (i < page_data->length) {
   1826		query.size = page_data->length - i;
   1827		size_read = mlx5_query_module_eeprom_by_page(mdev, &query, data + i);
   1828
   1829		/* Done reading, return how many bytes was read */
   1830		if (!size_read)
   1831			return i;
   1832
   1833		if (size_read == -EINVAL)
   1834			return -EINVAL;
   1835		if (size_read < 0) {
   1836			netdev_err(priv->netdev, "%s: mlx5_query_module_eeprom_by_page failed:0x%x\n",
   1837				   __func__, size_read);
   1838			return i;
   1839		}
   1840
   1841		i += size_read;
   1842		query.offset += size_read;
   1843	}
   1844
   1845	return i;
   1846}
   1847
   1848int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
   1849			       struct ethtool_flash *flash)
   1850{
   1851	struct mlx5_core_dev *mdev = priv->mdev;
   1852	struct net_device *dev = priv->netdev;
   1853	const struct firmware *fw;
   1854	int err;
   1855
   1856	if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
   1857		return -EOPNOTSUPP;
   1858
   1859	err = request_firmware_direct(&fw, flash->data, &dev->dev);
   1860	if (err)
   1861		return err;
   1862
   1863	dev_hold(dev);
   1864	rtnl_unlock();
   1865
   1866	err = mlx5_firmware_flash(mdev, fw, NULL);
   1867	release_firmware(fw);
   1868
   1869	rtnl_lock();
   1870	dev_put(dev);
   1871	return err;
   1872}
   1873
   1874static int mlx5e_flash_device(struct net_device *dev,
   1875			      struct ethtool_flash *flash)
   1876{
   1877	struct mlx5e_priv *priv = netdev_priv(dev);
   1878
   1879	return mlx5e_ethtool_flash_device(priv, flash);
   1880}
   1881
   1882static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
   1883				     bool is_rx_cq)
   1884{
   1885	struct mlx5e_priv *priv = netdev_priv(netdev);
   1886	u8 cq_period_mode, current_cq_period_mode;
   1887	struct mlx5e_params new_params;
   1888
   1889	if (enable && !MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe))
   1890		return -EOPNOTSUPP;
   1891
   1892	cq_period_mode = cqe_mode_to_period_mode(enable);
   1893
   1894	current_cq_period_mode = is_rx_cq ?
   1895		priv->channels.params.rx_cq_moderation.cq_period_mode :
   1896		priv->channels.params.tx_cq_moderation.cq_period_mode;
   1897
   1898	if (cq_period_mode == current_cq_period_mode)
   1899		return 0;
   1900
   1901	new_params = priv->channels.params;
   1902	if (is_rx_cq)
   1903		mlx5e_set_rx_cq_mode_params(&new_params, cq_period_mode);
   1904	else
   1905		mlx5e_set_tx_cq_mode_params(&new_params, cq_period_mode);
   1906
   1907	return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
   1908}
   1909
   1910static int set_pflag_tx_cqe_based_moder(struct net_device *netdev, bool enable)
   1911{
   1912	return set_pflag_cqe_based_moder(netdev, enable, false);
   1913}
   1914
   1915static int set_pflag_rx_cqe_based_moder(struct net_device *netdev, bool enable)
   1916{
   1917	return set_pflag_cqe_based_moder(netdev, enable, true);
   1918}
   1919
   1920int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val, bool rx_filter)
   1921{
   1922	bool curr_val = MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS);
   1923	struct mlx5e_params new_params;
   1924	int err = 0;
   1925
   1926	if (!MLX5_CAP_GEN(priv->mdev, cqe_compression))
   1927		return new_val ? -EOPNOTSUPP : 0;
   1928
   1929	if (curr_val == new_val)
   1930		return 0;
   1931
   1932	if (new_val && !mlx5e_profile_feature_cap(priv->profile, PTP_RX) && rx_filter) {
   1933		netdev_err(priv->netdev,
   1934			   "Profile doesn't support enabling of CQE compression while hardware time-stamping is enabled.\n");
   1935		return -EINVAL;
   1936	}
   1937
   1938	if (priv->channels.params.packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO) {
   1939		netdev_warn(priv->netdev, "Can't set CQE compression with HW-GRO, disable it first.\n");
   1940		return -EINVAL;
   1941	}
   1942
   1943	new_params = priv->channels.params;
   1944	MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val);
   1945	if (rx_filter)
   1946		new_params.ptp_rx = new_val;
   1947
   1948	if (new_params.ptp_rx == priv->channels.params.ptp_rx)
   1949		err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
   1950	else
   1951		err = mlx5e_safe_switch_params(priv, &new_params, mlx5e_ptp_rx_manage_fs_ctx,
   1952					       &new_params.ptp_rx, true);
   1953	if (err)
   1954		return err;
   1955
   1956	mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
   1957		  MLX5E_GET_PFLAG(&priv->channels.params,
   1958				  MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
   1959
   1960	return 0;
   1961}
   1962
   1963static int set_pflag_rx_cqe_compress(struct net_device *netdev,
   1964				     bool enable)
   1965{
   1966	struct mlx5e_priv *priv = netdev_priv(netdev);
   1967	struct mlx5_core_dev *mdev = priv->mdev;
   1968	bool rx_filter;
   1969	int err;
   1970
   1971	if (!MLX5_CAP_GEN(mdev, cqe_compression))
   1972		return -EOPNOTSUPP;
   1973
   1974	rx_filter = priv->tstamp.rx_filter != HWTSTAMP_FILTER_NONE;
   1975	err = mlx5e_modify_rx_cqe_compression_locked(priv, enable, rx_filter);
   1976	if (err)
   1977		return err;
   1978
   1979	priv->channels.params.rx_cqe_compress_def = enable;
   1980
   1981	return 0;
   1982}
   1983
   1984static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
   1985{
   1986	struct mlx5e_priv *priv = netdev_priv(netdev);
   1987	struct mlx5_core_dev *mdev = priv->mdev;
   1988	struct mlx5e_params new_params;
   1989
   1990	if (enable) {
   1991		if (!mlx5e_check_fragmented_striding_rq_cap(mdev))
   1992			return -EOPNOTSUPP;
   1993		if (!mlx5e_striding_rq_possible(mdev, &priv->channels.params))
   1994			return -EINVAL;
   1995	} else if (priv->channels.params.packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
   1996		netdev_warn(netdev, "Can't set legacy RQ with HW-GRO/LRO, disable them first\n");
   1997		return -EINVAL;
   1998	}
   1999
   2000	new_params = priv->channels.params;
   2001
   2002	MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_RX_STRIDING_RQ, enable);
   2003	mlx5e_set_rq_type(mdev, &new_params);
   2004
   2005	return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
   2006}
   2007
   2008static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
   2009{
   2010	struct mlx5e_priv *priv = netdev_priv(netdev);
   2011	struct mlx5e_channels *channels = &priv->channels;
   2012	struct mlx5e_channel *c;
   2013	int i;
   2014
   2015	if (!test_bit(MLX5E_STATE_OPENED, &priv->state) ||
   2016	    priv->channels.params.xdp_prog)
   2017		return 0;
   2018
   2019	for (i = 0; i < channels->num; i++) {
   2020		c = channels->c[i];
   2021		if (enable)
   2022			__set_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);
   2023		else
   2024			__clear_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);
   2025	}
   2026
   2027	return 0;
   2028}
   2029
   2030static int set_pflag_tx_mpwqe_common(struct net_device *netdev, u32 flag, bool enable)
   2031{
   2032	struct mlx5e_priv *priv = netdev_priv(netdev);
   2033	struct mlx5_core_dev *mdev = priv->mdev;
   2034	struct mlx5e_params new_params;
   2035
   2036	if (enable && !mlx5e_tx_mpwqe_supported(mdev))
   2037		return -EOPNOTSUPP;
   2038
   2039	new_params = priv->channels.params;
   2040
   2041	MLX5E_SET_PFLAG(&new_params, flag, enable);
   2042
   2043	return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
   2044}
   2045
   2046static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
   2047{
   2048	return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_XDP_TX_MPWQE, enable);
   2049}
   2050
   2051static int set_pflag_skb_tx_mpwqe(struct net_device *netdev, bool enable)
   2052{
   2053	return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_SKB_TX_MPWQE, enable);
   2054}
   2055
   2056static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable)
   2057{
   2058	struct mlx5e_priv *priv = netdev_priv(netdev);
   2059	struct mlx5_core_dev *mdev = priv->mdev;
   2060	struct mlx5e_params new_params;
   2061	int err;
   2062
   2063	if (!MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn))
   2064		return -EOPNOTSUPP;
   2065
   2066	/* Don't allow changing the PTP state if HTB offload is active, because
   2067	 * the numeration of the QoS SQs will change, while per-queue qdiscs are
   2068	 * attached.
   2069	 */
   2070	if (priv->htb.maj_id) {
   2071		netdev_err(priv->netdev, "%s: HTB offload is active, cannot change the PTP state\n",
   2072			   __func__);
   2073		return -EINVAL;
   2074	}
   2075
   2076	new_params = priv->channels.params;
   2077	/* Don't allow enabling TX-port-TS if MQPRIO mode channel  offload is
   2078	 * active, since it defines explicitly which TC accepts the packet.
   2079	 * This conflicts with TX-port-TS hijacking the PTP traffic to a specific
   2080	 * HW TX-queue.
   2081	 */
   2082	if (enable && new_params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
   2083		netdev_err(priv->netdev,
   2084			   "%s: MQPRIO mode channel offload is active, cannot set the TX-port-TS\n",
   2085			   __func__);
   2086		return -EINVAL;
   2087	}
   2088	MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_PORT_TS, enable);
   2089	/* No need to verify SQ stop room as
   2090	 * ptpsq.txqsq.stop_room <= generic_sq->stop_room, and both
   2091	 * has the same log_sq_size.
   2092	 */
   2093
   2094	err = mlx5e_safe_switch_params(priv, &new_params,
   2095				       mlx5e_num_channels_changed_ctx, NULL, true);
   2096	if (!err)
   2097		priv->tx_ptp_opened = true;
   2098
   2099	return err;
   2100}
   2101
   2102static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
   2103	{ "rx_cqe_moder",        set_pflag_rx_cqe_based_moder },
   2104	{ "tx_cqe_moder",        set_pflag_tx_cqe_based_moder },
   2105	{ "rx_cqe_compress",     set_pflag_rx_cqe_compress },
   2106	{ "rx_striding_rq",      set_pflag_rx_striding_rq },
   2107	{ "rx_no_csum_complete", set_pflag_rx_no_csum_complete },
   2108	{ "xdp_tx_mpwqe",        set_pflag_xdp_tx_mpwqe },
   2109	{ "skb_tx_mpwqe",        set_pflag_skb_tx_mpwqe },
   2110	{ "tx_port_ts",          set_pflag_tx_port_ts },
   2111};
   2112
   2113static int mlx5e_handle_pflag(struct net_device *netdev,
   2114			      u32 wanted_flags,
   2115			      enum mlx5e_priv_flag flag)
   2116{
   2117	struct mlx5e_priv *priv = netdev_priv(netdev);
   2118	bool enable = !!(wanted_flags & BIT(flag));
   2119	u32 changes = wanted_flags ^ priv->channels.params.pflags;
   2120	int err;
   2121
   2122	if (!(changes & BIT(flag)))
   2123		return 0;
   2124
   2125	err = mlx5e_priv_flags[flag].handler(netdev, enable);
   2126	if (err) {
   2127		netdev_err(netdev, "%s private flag '%s' failed err %d\n",
   2128			   enable ? "Enable" : "Disable", mlx5e_priv_flags[flag].name, err);
   2129		return err;
   2130	}
   2131
   2132	MLX5E_SET_PFLAG(&priv->channels.params, flag, enable);
   2133	return 0;
   2134}
   2135
   2136static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
   2137{
   2138	struct mlx5e_priv *priv = netdev_priv(netdev);
   2139	enum mlx5e_priv_flag pflag;
   2140	int err;
   2141
   2142	mutex_lock(&priv->state_lock);
   2143
   2144	for (pflag = 0; pflag < MLX5E_NUM_PFLAGS; pflag++) {
   2145		err = mlx5e_handle_pflag(netdev, pflags, pflag);
   2146		if (err)
   2147			break;
   2148	}
   2149
   2150	mutex_unlock(&priv->state_lock);
   2151
   2152	/* Need to fix some features.. */
   2153	netdev_update_features(netdev);
   2154
   2155	return err;
   2156}
   2157
   2158static u32 mlx5e_get_priv_flags(struct net_device *netdev)
   2159{
   2160	struct mlx5e_priv *priv = netdev_priv(netdev);
   2161
   2162	return priv->channels.params.pflags;
   2163}
   2164
   2165int mlx5e_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
   2166		    u32 *rule_locs)
   2167{
   2168	struct mlx5e_priv *priv = netdev_priv(dev);
   2169
   2170	/* ETHTOOL_GRXRINGS is needed by ethtool -x which is not part
   2171	 * of rxnfc. We keep this logic out of mlx5e_ethtool_get_rxnfc,
   2172	 * to avoid breaking "ethtool -x" when mlx5e_ethtool_get_rxnfc
   2173	 * is compiled out via CONFIG_MLX5_EN_RXNFC=n.
   2174	 */
   2175	if (info->cmd == ETHTOOL_GRXRINGS) {
   2176		info->data = priv->channels.params.num_channels;
   2177		return 0;
   2178	}
   2179
   2180	return mlx5e_ethtool_get_rxnfc(priv, info, rule_locs);
   2181}
   2182
   2183int mlx5e_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
   2184{
   2185	struct mlx5e_priv *priv = netdev_priv(dev);
   2186
   2187	return mlx5e_ethtool_set_rxnfc(priv, cmd);
   2188}
   2189
   2190static int query_port_status_opcode(struct mlx5_core_dev *mdev, u32 *status_opcode)
   2191{
   2192	struct mlx5_ifc_pddr_troubleshooting_page_bits *pddr_troubleshooting_page;
   2193	u32 in[MLX5_ST_SZ_DW(pddr_reg)] = {};
   2194	u32 out[MLX5_ST_SZ_DW(pddr_reg)];
   2195	int err;
   2196
   2197	MLX5_SET(pddr_reg, in, local_port, 1);
   2198	MLX5_SET(pddr_reg, in, page_select,
   2199		 MLX5_PDDR_REG_PAGE_SELECT_TROUBLESHOOTING_INFO_PAGE);
   2200
   2201	pddr_troubleshooting_page = MLX5_ADDR_OF(pddr_reg, in, page_data);
   2202	MLX5_SET(pddr_troubleshooting_page, pddr_troubleshooting_page,
   2203		 group_opcode, MLX5_PDDR_REG_TRBLSH_GROUP_OPCODE_MONITOR);
   2204	err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
   2205				   sizeof(out), MLX5_REG_PDDR, 0, 0);
   2206	if (err)
   2207		return err;
   2208
   2209	pddr_troubleshooting_page = MLX5_ADDR_OF(pddr_reg, out, page_data);
   2210	*status_opcode = MLX5_GET(pddr_troubleshooting_page, pddr_troubleshooting_page,
   2211				  status_opcode);
   2212	return 0;
   2213}
   2214
   2215struct mlx5e_ethtool_link_ext_state_opcode_mapping {
   2216	u32 status_opcode;
   2217	enum ethtool_link_ext_state link_ext_state;
   2218	u8 link_ext_substate;
   2219};
   2220
   2221static const struct mlx5e_ethtool_link_ext_state_opcode_mapping
   2222mlx5e_link_ext_state_opcode_map[] = {
   2223	/* States relating to the autonegotiation or issues therein */
   2224	{2, ETHTOOL_LINK_EXT_STATE_AUTONEG,
   2225		ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED},
   2226	{3, ETHTOOL_LINK_EXT_STATE_AUTONEG,
   2227		ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED},
   2228	{4, ETHTOOL_LINK_EXT_STATE_AUTONEG,
   2229		ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED},
   2230	{36, ETHTOOL_LINK_EXT_STATE_AUTONEG,
   2231		ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE},
   2232	{38, ETHTOOL_LINK_EXT_STATE_AUTONEG,
   2233		ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE},
   2234	{39, ETHTOOL_LINK_EXT_STATE_AUTONEG,
   2235		ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD},
   2236
   2237	/* Failure during link training */
   2238	{5, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
   2239		ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED},
   2240	{6, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
   2241		ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT},
   2242	{7, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
   2243		ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY},
   2244	{8, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 0},
   2245	{14, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
   2246		ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT},
   2247
   2248	/* Logical mismatch in physical coding sublayer or forward error correction sublayer */
   2249	{9, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
   2250		ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK},
   2251	{10, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
   2252		ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK},
   2253	{11, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
   2254		ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS},
   2255	{12, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
   2256		ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED},
   2257	{13, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
   2258		ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED},
   2259
   2260	/* Signal integrity issues */
   2261	{15, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, 0},
   2262	{17, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
   2263		ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS},
   2264	{42, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
   2265		ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE},
   2266
   2267	/* No cable connected */
   2268	{1024, ETHTOOL_LINK_EXT_STATE_NO_CABLE, 0},
   2269
   2270	/* Failure is related to cable, e.g., unsupported cable */
   2271	{16, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
   2272		ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
   2273	{20, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
   2274		ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
   2275	{29, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
   2276		ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
   2277	{1025, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
   2278		ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
   2279	{1029, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
   2280		ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
   2281	{1031, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 0},
   2282
   2283	/* Failure is related to EEPROM, e.g., failure during reading or parsing the data */
   2284	{1027, ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, 0},
   2285
   2286	/* Failure during calibration algorithm */
   2287	{23, ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE, 0},
   2288
   2289	/* The hardware is not able to provide the power required from cable or module */
   2290	{1032, ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED, 0},
   2291
   2292	/* The module is overheated */
   2293	{1030, ETHTOOL_LINK_EXT_STATE_OVERHEAT, 0},
   2294};
   2295
   2296static void
   2297mlx5e_set_link_ext_state(struct mlx5e_ethtool_link_ext_state_opcode_mapping
   2298			 link_ext_state_mapping,
   2299			 struct ethtool_link_ext_state_info *link_ext_state_info)
   2300{
   2301	switch (link_ext_state_mapping.link_ext_state) {
   2302	case ETHTOOL_LINK_EXT_STATE_AUTONEG:
   2303		link_ext_state_info->autoneg =
   2304			link_ext_state_mapping.link_ext_substate;
   2305		break;
   2306	case ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE:
   2307		link_ext_state_info->link_training =
   2308			link_ext_state_mapping.link_ext_substate;
   2309		break;
   2310	case ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH:
   2311		link_ext_state_info->link_logical_mismatch =
   2312			link_ext_state_mapping.link_ext_substate;
   2313		break;
   2314	case ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY:
   2315		link_ext_state_info->bad_signal_integrity =
   2316			link_ext_state_mapping.link_ext_substate;
   2317		break;
   2318	case ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE:
   2319		link_ext_state_info->cable_issue =
   2320			link_ext_state_mapping.link_ext_substate;
   2321		break;
   2322	default:
   2323		break;
   2324	}
   2325
   2326	link_ext_state_info->link_ext_state = link_ext_state_mapping.link_ext_state;
   2327}
   2328
   2329static int
   2330mlx5e_get_link_ext_state(struct net_device *dev,
   2331			 struct ethtool_link_ext_state_info *link_ext_state_info)
   2332{
   2333	struct mlx5e_ethtool_link_ext_state_opcode_mapping link_ext_state_mapping;
   2334	struct mlx5e_priv *priv = netdev_priv(dev);
   2335	u32 status_opcode = 0;
   2336	int i;
   2337
   2338	/* Exit without data if the interface state is OK, since no extended data is
   2339	 * available in such case
   2340	 */
   2341	if (netif_carrier_ok(dev))
   2342		return -ENODATA;
   2343
   2344	if (query_port_status_opcode(priv->mdev, &status_opcode) ||
   2345	    !status_opcode)
   2346		return -ENODATA;
   2347
   2348	for (i = 0; i < ARRAY_SIZE(mlx5e_link_ext_state_opcode_map); i++) {
   2349		link_ext_state_mapping = mlx5e_link_ext_state_opcode_map[i];
   2350		if (link_ext_state_mapping.status_opcode == status_opcode) {
   2351			mlx5e_set_link_ext_state(link_ext_state_mapping,
   2352						 link_ext_state_info);
   2353			return 0;
   2354		}
   2355	}
   2356
   2357	return -ENODATA;
   2358}
   2359
   2360static void mlx5e_get_eth_phy_stats(struct net_device *netdev,
   2361				    struct ethtool_eth_phy_stats *phy_stats)
   2362{
   2363	struct mlx5e_priv *priv = netdev_priv(netdev);
   2364
   2365	mlx5e_stats_eth_phy_get(priv, phy_stats);
   2366}
   2367
   2368static void mlx5e_get_eth_mac_stats(struct net_device *netdev,
   2369				    struct ethtool_eth_mac_stats *mac_stats)
   2370{
   2371	struct mlx5e_priv *priv = netdev_priv(netdev);
   2372
   2373	mlx5e_stats_eth_mac_get(priv, mac_stats);
   2374}
   2375
   2376static void mlx5e_get_eth_ctrl_stats(struct net_device *netdev,
   2377				     struct ethtool_eth_ctrl_stats *ctrl_stats)
   2378{
   2379	struct mlx5e_priv *priv = netdev_priv(netdev);
   2380
   2381	mlx5e_stats_eth_ctrl_get(priv, ctrl_stats);
   2382}
   2383
   2384static void mlx5e_get_rmon_stats(struct net_device *netdev,
   2385				 struct ethtool_rmon_stats *rmon_stats,
   2386				 const struct ethtool_rmon_hist_range **ranges)
   2387{
   2388	struct mlx5e_priv *priv = netdev_priv(netdev);
   2389
   2390	mlx5e_stats_rmon_get(priv, rmon_stats, ranges);
   2391}
   2392
   2393const struct ethtool_ops mlx5e_ethtool_ops = {
   2394	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
   2395				     ETHTOOL_COALESCE_MAX_FRAMES |
   2396				     ETHTOOL_COALESCE_USE_ADAPTIVE |
   2397				     ETHTOOL_COALESCE_USE_CQE,
   2398	.get_drvinfo       = mlx5e_get_drvinfo,
   2399	.get_link          = ethtool_op_get_link,
   2400	.get_link_ext_state  = mlx5e_get_link_ext_state,
   2401	.get_strings       = mlx5e_get_strings,
   2402	.get_sset_count    = mlx5e_get_sset_count,
   2403	.get_ethtool_stats = mlx5e_get_ethtool_stats,
   2404	.get_ringparam     = mlx5e_get_ringparam,
   2405	.set_ringparam     = mlx5e_set_ringparam,
   2406	.get_channels      = mlx5e_get_channels,
   2407	.set_channels      = mlx5e_set_channels,
   2408	.get_coalesce      = mlx5e_get_coalesce,
   2409	.set_coalesce      = mlx5e_set_coalesce,
   2410	.get_link_ksettings  = mlx5e_get_link_ksettings,
   2411	.set_link_ksettings  = mlx5e_set_link_ksettings,
   2412	.get_rxfh_key_size   = mlx5e_get_rxfh_key_size,
   2413	.get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
   2414	.get_rxfh          = mlx5e_get_rxfh,
   2415	.set_rxfh          = mlx5e_set_rxfh,
   2416	.get_rxfh_context  = mlx5e_get_rxfh_context,
   2417	.set_rxfh_context  = mlx5e_set_rxfh_context,
   2418	.get_rxnfc         = mlx5e_get_rxnfc,
   2419	.set_rxnfc         = mlx5e_set_rxnfc,
   2420	.get_tunable       = mlx5e_get_tunable,
   2421	.set_tunable       = mlx5e_set_tunable,
   2422	.get_pause_stats   = mlx5e_get_pause_stats,
   2423	.get_pauseparam    = mlx5e_get_pauseparam,
   2424	.set_pauseparam    = mlx5e_set_pauseparam,
   2425	.get_ts_info       = mlx5e_get_ts_info,
   2426	.set_phys_id       = mlx5e_set_phys_id,
   2427	.get_wol	   = mlx5e_get_wol,
   2428	.set_wol	   = mlx5e_set_wol,
   2429	.get_module_info   = mlx5e_get_module_info,
   2430	.get_module_eeprom = mlx5e_get_module_eeprom,
   2431	.get_module_eeprom_by_page = mlx5e_get_module_eeprom_by_page,
   2432	.flash_device      = mlx5e_flash_device,
   2433	.get_priv_flags    = mlx5e_get_priv_flags,
   2434	.set_priv_flags    = mlx5e_set_priv_flags,
   2435	.self_test         = mlx5e_self_test,
   2436	.get_msglevel      = mlx5e_get_msglevel,
   2437	.set_msglevel      = mlx5e_set_msglevel,
   2438	.get_fec_stats     = mlx5e_get_fec_stats,
   2439	.get_fecparam      = mlx5e_get_fecparam,
   2440	.set_fecparam      = mlx5e_set_fecparam,
   2441	.get_eth_phy_stats = mlx5e_get_eth_phy_stats,
   2442	.get_eth_mac_stats = mlx5e_get_eth_mac_stats,
   2443	.get_eth_ctrl_stats = mlx5e_get_eth_ctrl_stats,
   2444	.get_rmon_stats    = mlx5e_get_rmon_stats,
   2445};