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