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