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/xsk/umem.h"
  36#include "lib/clock.h"
  37
  38void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
  39                               struct ethtool_drvinfo *drvinfo)
  40{
  41        struct mlx5_core_dev *mdev = priv->mdev;
  42
  43        strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
  44        strlcpy(drvinfo->version, DRIVER_VERSION,
  45                sizeof(drvinfo->version));
  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}
 198
 199static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev,
 200                                        struct ptys2ethtool_config **arr,
 201                                        u32 *size)
 202{
 203        bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
 204
 205        *arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
 206        *size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
 207                      ARRAY_SIZE(ptys2legacy_ethtool_table);
 208}
 209
 210typedef int (*mlx5e_pflag_handler)(struct net_device *netdev, bool enable);
 211
 212struct pflag_desc {
 213        char name[ETH_GSTRING_LEN];
 214        mlx5e_pflag_handler handler;
 215};
 216
 217static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS];
 218
 219int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
 220{
 221        switch (sset) {
 222        case ETH_SS_STATS:
 223                return mlx5e_stats_total_num(priv);
 224        case ETH_SS_PRIV_FLAGS:
 225                return MLX5E_NUM_PFLAGS;
 226        case ETH_SS_TEST:
 227                return mlx5e_self_test_num(priv);
 228        /* fallthrough */
 229        default:
 230                return -EOPNOTSUPP;
 231        }
 232}
 233
 234static int mlx5e_get_sset_count(struct net_device *dev, int sset)
 235{
 236        struct mlx5e_priv *priv = netdev_priv(dev);
 237
 238        return mlx5e_ethtool_get_sset_count(priv, sset);
 239}
 240
 241void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
 242{
 243        int i;
 244
 245        switch (stringset) {
 246        case ETH_SS_PRIV_FLAGS:
 247                for (i = 0; i < MLX5E_NUM_PFLAGS; i++)
 248                        strcpy(data + i * ETH_GSTRING_LEN,
 249                               mlx5e_priv_flags[i].name);
 250                break;
 251
 252        case ETH_SS_TEST:
 253                for (i = 0; i < mlx5e_self_test_num(priv); i++)
 254                        strcpy(data + i * ETH_GSTRING_LEN,
 255                               mlx5e_self_tests[i]);
 256                break;
 257
 258        case ETH_SS_STATS:
 259                mlx5e_stats_fill_strings(priv, data);
 260                break;
 261        }
 262}
 263
 264static void mlx5e_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 265{
 266        struct mlx5e_priv *priv = netdev_priv(dev);
 267
 268        mlx5e_ethtool_get_strings(priv, stringset, data);
 269}
 270
 271void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
 272                                     struct ethtool_stats *stats, u64 *data)
 273{
 274        int idx = 0;
 275
 276        mutex_lock(&priv->state_lock);
 277        mlx5e_stats_update(priv);
 278        mutex_unlock(&priv->state_lock);
 279
 280        mlx5e_stats_fill(priv, data, idx);
 281}
 282
 283static void mlx5e_get_ethtool_stats(struct net_device *dev,
 284                                    struct ethtool_stats *stats,
 285                                    u64 *data)
 286{
 287        struct mlx5e_priv *priv = netdev_priv(dev);
 288
 289        mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
 290}
 291
 292void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
 293                                 struct ethtool_ringparam *param)
 294{
 295        param->rx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
 296        param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
 297        param->rx_pending     = 1 << priv->channels.params.log_rq_mtu_frames;
 298        param->tx_pending     = 1 << priv->channels.params.log_sq_size;
 299}
 300
 301static void mlx5e_get_ringparam(struct net_device *dev,
 302                                struct ethtool_ringparam *param)
 303{
 304        struct mlx5e_priv *priv = netdev_priv(dev);
 305
 306        mlx5e_ethtool_get_ringparam(priv, param);
 307}
 308
 309int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
 310                                struct ethtool_ringparam *param)
 311{
 312        struct mlx5e_channels new_channels = {};
 313        u8 log_rq_size;
 314        u8 log_sq_size;
 315        int err = 0;
 316
 317        if (param->rx_jumbo_pending) {
 318                netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n",
 319                            __func__);
 320                return -EINVAL;
 321        }
 322        if (param->rx_mini_pending) {
 323                netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n",
 324                            __func__);
 325                return -EINVAL;
 326        }
 327
 328        if (param->rx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) {
 329                netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n",
 330                            __func__, param->rx_pending,
 331                            1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
 332                return -EINVAL;
 333        }
 334
 335        if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
 336                netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
 337                            __func__, param->tx_pending,
 338                            1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
 339                return -EINVAL;
 340        }
 341
 342        log_rq_size = order_base_2(param->rx_pending);
 343        log_sq_size = order_base_2(param->tx_pending);
 344
 345        if (log_rq_size == priv->channels.params.log_rq_mtu_frames &&
 346            log_sq_size == priv->channels.params.log_sq_size)
 347                return 0;
 348
 349        mutex_lock(&priv->state_lock);
 350
 351        new_channels.params = priv->channels.params;
 352        new_channels.params.log_rq_mtu_frames = log_rq_size;
 353        new_channels.params.log_sq_size = log_sq_size;
 354
 355        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
 356                priv->channels.params = new_channels.params;
 357                goto unlock;
 358        }
 359
 360        err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
 361
 362unlock:
 363        mutex_unlock(&priv->state_lock);
 364
 365        return err;
 366}
 367
 368static int mlx5e_set_ringparam(struct net_device *dev,
 369                               struct ethtool_ringparam *param)
 370{
 371        struct mlx5e_priv *priv = netdev_priv(dev);
 372
 373        return mlx5e_ethtool_set_ringparam(priv, param);
 374}
 375
 376void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
 377                                struct ethtool_channels *ch)
 378{
 379        mutex_lock(&priv->state_lock);
 380
 381        ch->max_combined   = priv->max_nch;
 382        ch->combined_count = priv->channels.params.num_channels;
 383        if (priv->xsk.refcnt) {
 384                /* The upper half are XSK queues. */
 385                ch->max_combined *= 2;
 386                ch->combined_count *= 2;
 387        }
 388
 389        mutex_unlock(&priv->state_lock);
 390}
 391
 392static void mlx5e_get_channels(struct net_device *dev,
 393                               struct ethtool_channels *ch)
 394{
 395        struct mlx5e_priv *priv = netdev_priv(dev);
 396
 397        mlx5e_ethtool_get_channels(priv, ch);
 398}
 399
 400int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
 401                               struct ethtool_channels *ch)
 402{
 403        struct mlx5e_params *cur_params = &priv->channels.params;
 404        unsigned int count = ch->combined_count;
 405        struct mlx5e_channels new_channels = {};
 406        bool arfs_enabled;
 407        int err = 0;
 408
 409        if (!count) {
 410                netdev_info(priv->netdev, "%s: combined_count=0 not supported\n",
 411                            __func__);
 412                return -EINVAL;
 413        }
 414
 415        if (cur_params->num_channels == count)
 416                return 0;
 417
 418        mutex_lock(&priv->state_lock);
 419
 420        /* Don't allow changing the number of channels if there is an active
 421         * XSK, because the numeration of the XSK and regular RQs will change.
 422         */
 423        if (priv->xsk.refcnt) {
 424                err = -EINVAL;
 425                netdev_err(priv->netdev, "%s: AF_XDP is active, cannot change the number of channels\n",
 426                           __func__);
 427                goto out;
 428        }
 429
 430        new_channels.params = priv->channels.params;
 431        new_channels.params.num_channels = count;
 432
 433        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
 434                *cur_params = new_channels.params;
 435                if (!netif_is_rxfh_configured(priv->netdev))
 436                        mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
 437                                                      MLX5E_INDIR_RQT_SIZE, count);
 438                goto out;
 439        }
 440
 441        arfs_enabled = priv->netdev->features & NETIF_F_NTUPLE;
 442        if (arfs_enabled)
 443                mlx5e_arfs_disable(priv);
 444
 445        if (!netif_is_rxfh_configured(priv->netdev))
 446                mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
 447                                              MLX5E_INDIR_RQT_SIZE, count);
 448
 449        /* Switch to new channels, set new parameters and close old ones */
 450        err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
 451
 452        if (arfs_enabled) {
 453                int err2 = mlx5e_arfs_enable(priv);
 454
 455                if (err2)
 456                        netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
 457                                   __func__, err2);
 458        }
 459
 460out:
 461        mutex_unlock(&priv->state_lock);
 462
 463        return err;
 464}
 465
 466static int mlx5e_set_channels(struct net_device *dev,
 467                              struct ethtool_channels *ch)
 468{
 469        struct mlx5e_priv *priv = netdev_priv(dev);
 470
 471        return mlx5e_ethtool_set_channels(priv, ch);
 472}
 473
 474int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
 475                               struct ethtool_coalesce *coal)
 476{
 477        struct dim_cq_moder *rx_moder, *tx_moder;
 478
 479        if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
 480                return -EOPNOTSUPP;
 481
 482        rx_moder = &priv->channels.params.rx_cq_moderation;
 483        coal->rx_coalesce_usecs         = rx_moder->usec;
 484        coal->rx_max_coalesced_frames   = rx_moder->pkts;
 485        coal->use_adaptive_rx_coalesce  = priv->channels.params.rx_dim_enabled;
 486
 487        tx_moder = &priv->channels.params.tx_cq_moderation;
 488        coal->tx_coalesce_usecs         = tx_moder->usec;
 489        coal->tx_max_coalesced_frames   = tx_moder->pkts;
 490        coal->use_adaptive_tx_coalesce  = priv->channels.params.tx_dim_enabled;
 491
 492        return 0;
 493}
 494
 495static int mlx5e_get_coalesce(struct net_device *netdev,
 496                              struct ethtool_coalesce *coal)
 497{
 498        struct mlx5e_priv *priv = netdev_priv(netdev);
 499
 500        return mlx5e_ethtool_get_coalesce(priv, coal);
 501}
 502
 503#define MLX5E_MAX_COAL_TIME             MLX5_MAX_CQ_PERIOD
 504#define MLX5E_MAX_COAL_FRAMES           MLX5_MAX_CQ_COUNT
 505
 506static void
 507mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
 508{
 509        struct mlx5_core_dev *mdev = priv->mdev;
 510        int tc;
 511        int i;
 512
 513        for (i = 0; i < priv->channels.num; ++i) {
 514                struct mlx5e_channel *c = priv->channels.c[i];
 515
 516                for (tc = 0; tc < c->num_tc; tc++) {
 517                        mlx5_core_modify_cq_moderation(mdev,
 518                                                &c->sq[tc].cq.mcq,
 519                                                coal->tx_coalesce_usecs,
 520                                                coal->tx_max_coalesced_frames);
 521                }
 522
 523                mlx5_core_modify_cq_moderation(mdev, &c->rq.cq.mcq,
 524                                               coal->rx_coalesce_usecs,
 525                                               coal->rx_max_coalesced_frames);
 526        }
 527}
 528
 529int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
 530                               struct ethtool_coalesce *coal)
 531{
 532        struct dim_cq_moder *rx_moder, *tx_moder;
 533        struct mlx5_core_dev *mdev = priv->mdev;
 534        struct mlx5e_channels new_channels = {};
 535        int err = 0;
 536        bool reset;
 537
 538        if (!MLX5_CAP_GEN(mdev, cq_moderation))
 539                return -EOPNOTSUPP;
 540
 541        if (coal->tx_coalesce_usecs > MLX5E_MAX_COAL_TIME ||
 542            coal->rx_coalesce_usecs > MLX5E_MAX_COAL_TIME) {
 543                netdev_info(priv->netdev, "%s: maximum coalesce time supported is %lu usecs\n",
 544                            __func__, MLX5E_MAX_COAL_TIME);
 545                return -ERANGE;
 546        }
 547
 548        if (coal->tx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES ||
 549            coal->rx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES) {
 550                netdev_info(priv->netdev, "%s: maximum coalesced frames supported is %lu\n",
 551                            __func__, MLX5E_MAX_COAL_FRAMES);
 552                return -ERANGE;
 553        }
 554
 555        mutex_lock(&priv->state_lock);
 556        new_channels.params = priv->channels.params;
 557
 558        rx_moder          = &new_channels.params.rx_cq_moderation;
 559        rx_moder->usec    = coal->rx_coalesce_usecs;
 560        rx_moder->pkts    = coal->rx_max_coalesced_frames;
 561        new_channels.params.rx_dim_enabled = !!coal->use_adaptive_rx_coalesce;
 562
 563        tx_moder          = &new_channels.params.tx_cq_moderation;
 564        tx_moder->usec    = coal->tx_coalesce_usecs;
 565        tx_moder->pkts    = coal->tx_max_coalesced_frames;
 566        new_channels.params.tx_dim_enabled = !!coal->use_adaptive_tx_coalesce;
 567
 568        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
 569                priv->channels.params = new_channels.params;
 570                goto out;
 571        }
 572        /* we are opened */
 573
 574        reset = (!!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_dim_enabled) ||
 575                (!!coal->use_adaptive_tx_coalesce != priv->channels.params.tx_dim_enabled);
 576
 577        if (!reset) {
 578                mlx5e_set_priv_channels_coalesce(priv, coal);
 579                priv->channels.params = new_channels.params;
 580                goto out;
 581        }
 582
 583        err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
 584
 585out:
 586        mutex_unlock(&priv->state_lock);
 587        return err;
 588}
 589
 590static int mlx5e_set_coalesce(struct net_device *netdev,
 591                              struct ethtool_coalesce *coal)
 592{
 593        struct mlx5e_priv *priv    = netdev_priv(netdev);
 594
 595        return mlx5e_ethtool_set_coalesce(priv, coal);
 596}
 597
 598static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
 599                                        unsigned long *supported_modes,
 600                                        u32 eth_proto_cap)
 601{
 602        unsigned long proto_cap = eth_proto_cap;
 603        struct ptys2ethtool_config *table;
 604        u32 max_size;
 605        int proto;
 606
 607        mlx5e_ethtool_get_speed_arr(mdev, &table, &max_size);
 608        for_each_set_bit(proto, &proto_cap, max_size)
 609                bitmap_or(supported_modes, supported_modes,
 610                          table[proto].supported,
 611                          __ETHTOOL_LINK_MODE_MASK_NBITS);
 612}
 613
 614static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
 615                                    u32 eth_proto_cap, bool ext)
 616{
 617        unsigned long proto_cap = eth_proto_cap;
 618        struct ptys2ethtool_config *table;
 619        u32 max_size;
 620        int proto;
 621
 622        table = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
 623        max_size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
 624                         ARRAY_SIZE(ptys2legacy_ethtool_table);
 625
 626        for_each_set_bit(proto, &proto_cap, max_size)
 627                bitmap_or(advertising_modes, advertising_modes,
 628                          table[proto].advertised,
 629                          __ETHTOOL_LINK_MODE_MASK_NBITS);
 630}
 631
 632static const u32 pplm_fec_2_ethtool[] = {
 633        [MLX5E_FEC_NOFEC] = ETHTOOL_FEC_OFF,
 634        [MLX5E_FEC_FIRECODE] = ETHTOOL_FEC_BASER,
 635        [MLX5E_FEC_RS_528_514] = ETHTOOL_FEC_RS,
 636};
 637
 638static u32 pplm2ethtool_fec(u_long fec_mode, unsigned long size)
 639{
 640        int mode = 0;
 641
 642        if (!fec_mode)
 643                return ETHTOOL_FEC_AUTO;
 644
 645        mode = find_first_bit(&fec_mode, size);
 646
 647        if (mode < ARRAY_SIZE(pplm_fec_2_ethtool))
 648                return pplm_fec_2_ethtool[mode];
 649
 650        return 0;
 651}
 652
 653/* we use ETHTOOL_FEC_* offset and apply it to ETHTOOL_LINK_MODE_FEC_*_BIT */
 654static u32 ethtool_fec2ethtool_caps(u_long ethtool_fec_code)
 655{
 656        u32 offset;
 657
 658        offset = find_first_bit(&ethtool_fec_code, sizeof(u32));
 659        offset -= ETHTOOL_FEC_OFF_BIT;
 660        offset += ETHTOOL_LINK_MODE_FEC_NONE_BIT;
 661
 662        return offset;
 663}
 664
 665static int get_fec_supported_advertised(struct mlx5_core_dev *dev,
 666                                        struct ethtool_link_ksettings *link_ksettings)
 667{
 668        u_long fec_caps = 0;
 669        u32 active_fec = 0;
 670        u32 offset;
 671        u32 bitn;
 672        int err;
 673
 674        err = mlx5e_get_fec_caps(dev, (u8 *)&fec_caps);
 675        if (err)
 676                return (err == -EOPNOTSUPP) ? 0 : err;
 677
 678        err = mlx5e_get_fec_mode(dev, &active_fec, NULL);
 679        if (err)
 680                return err;
 681
 682        for_each_set_bit(bitn, &fec_caps, ARRAY_SIZE(pplm_fec_2_ethtool)) {
 683                u_long ethtool_bitmask = pplm_fec_2_ethtool[bitn];
 684
 685                offset = ethtool_fec2ethtool_caps(ethtool_bitmask);
 686                __set_bit(offset, link_ksettings->link_modes.supported);
 687        }
 688
 689        active_fec = pplm2ethtool_fec(active_fec, sizeof(u32) * BITS_PER_BYTE);
 690        offset = ethtool_fec2ethtool_caps(active_fec);
 691        __set_bit(offset, link_ksettings->link_modes.advertising);
 692
 693        return 0;
 694}
 695
 696static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings *link_ksettings,
 697                                                   u32 eth_proto_cap,
 698                                                   u8 connector_type, bool ext)
 699{
 700        if ((!connector_type && !ext) || connector_type >= MLX5E_CONNECTOR_TYPE_NUMBER) {
 701                if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
 702                                   | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
 703                                   | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
 704                                   | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
 705                                   | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
 706                                   | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
 707                        ethtool_link_ksettings_add_link_mode(link_ksettings,
 708                                                             supported,
 709                                                             FIBRE);
 710                        ethtool_link_ksettings_add_link_mode(link_ksettings,
 711                                                             advertising,
 712                                                             FIBRE);
 713                }
 714
 715                if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
 716                                   | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
 717                                   | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
 718                                   | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
 719                                   | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
 720                        ethtool_link_ksettings_add_link_mode(link_ksettings,
 721                                                             supported,
 722                                                             Backplane);
 723                        ethtool_link_ksettings_add_link_mode(link_ksettings,
 724                                                             advertising,
 725                                                             Backplane);
 726                }
 727                return;
 728        }
 729
 730        switch (connector_type) {
 731        case MLX5E_PORT_TP:
 732                ethtool_link_ksettings_add_link_mode(link_ksettings,
 733                                                     supported, TP);
 734                ethtool_link_ksettings_add_link_mode(link_ksettings,
 735                                                     advertising, TP);
 736                break;
 737        case MLX5E_PORT_AUI:
 738                ethtool_link_ksettings_add_link_mode(link_ksettings,
 739                                                     supported, AUI);
 740                ethtool_link_ksettings_add_link_mode(link_ksettings,
 741                                                     advertising, AUI);
 742                break;
 743        case MLX5E_PORT_BNC:
 744                ethtool_link_ksettings_add_link_mode(link_ksettings,
 745                                                     supported, BNC);
 746                ethtool_link_ksettings_add_link_mode(link_ksettings,
 747                                                     advertising, BNC);
 748                break;
 749        case MLX5E_PORT_MII:
 750                ethtool_link_ksettings_add_link_mode(link_ksettings,
 751                                                     supported, MII);
 752                ethtool_link_ksettings_add_link_mode(link_ksettings,
 753                                                     advertising, MII);
 754                break;
 755        case MLX5E_PORT_FIBRE:
 756                ethtool_link_ksettings_add_link_mode(link_ksettings,
 757                                                     supported, FIBRE);
 758                ethtool_link_ksettings_add_link_mode(link_ksettings,
 759                                                     advertising, FIBRE);
 760                break;
 761        case MLX5E_PORT_DA:
 762                ethtool_link_ksettings_add_link_mode(link_ksettings,
 763                                                     supported, Backplane);
 764                ethtool_link_ksettings_add_link_mode(link_ksettings,
 765                                                     advertising, Backplane);
 766                break;
 767        case MLX5E_PORT_NONE:
 768        case MLX5E_PORT_OTHER:
 769        default:
 770                break;
 771        }
 772}
 773
 774static void get_speed_duplex(struct net_device *netdev,
 775                             u32 eth_proto_oper, bool force_legacy,
 776                             struct ethtool_link_ksettings *link_ksettings)
 777{
 778        struct mlx5e_priv *priv = netdev_priv(netdev);
 779        u32 speed = SPEED_UNKNOWN;
 780        u8 duplex = DUPLEX_UNKNOWN;
 781
 782        if (!netif_carrier_ok(netdev))
 783                goto out;
 784
 785        speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper, force_legacy);
 786        if (!speed) {
 787                speed = SPEED_UNKNOWN;
 788                goto out;
 789        }
 790
 791        duplex = DUPLEX_FULL;
 792
 793out:
 794        link_ksettings->base.speed = speed;
 795        link_ksettings->base.duplex = duplex;
 796}
 797
 798static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
 799                          struct ethtool_link_ksettings *link_ksettings)
 800{
 801        unsigned long *supported = link_ksettings->link_modes.supported;
 802        ptys2ethtool_supported_link(mdev, supported, eth_proto_cap);
 803
 804        ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
 805}
 806
 807static void get_advertising(u32 eth_proto_cap, u8 tx_pause, u8 rx_pause,
 808                            struct ethtool_link_ksettings *link_ksettings,
 809                            bool ext)
 810{
 811        unsigned long *advertising = link_ksettings->link_modes.advertising;
 812        ptys2ethtool_adver_link(advertising, eth_proto_cap, ext);
 813
 814        if (rx_pause)
 815                ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
 816        if (tx_pause ^ rx_pause)
 817                ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
 818}
 819
 820static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = {
 821                [MLX5E_PORT_UNKNOWN]            = PORT_OTHER,
 822                [MLX5E_PORT_NONE]               = PORT_NONE,
 823                [MLX5E_PORT_TP]                 = PORT_TP,
 824                [MLX5E_PORT_AUI]                = PORT_AUI,
 825                [MLX5E_PORT_BNC]                = PORT_BNC,
 826                [MLX5E_PORT_MII]                = PORT_MII,
 827                [MLX5E_PORT_FIBRE]              = PORT_FIBRE,
 828                [MLX5E_PORT_DA]                 = PORT_DA,
 829                [MLX5E_PORT_OTHER]              = PORT_OTHER,
 830        };
 831
 832static u8 get_connector_port(u32 eth_proto, u8 connector_type, bool ext)
 833{
 834        if ((connector_type || ext) && connector_type < MLX5E_CONNECTOR_TYPE_NUMBER)
 835                return ptys2connector_type[connector_type];
 836
 837        if (eth_proto &
 838            (MLX5E_PROT_MASK(MLX5E_10GBASE_SR)   |
 839             MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)  |
 840             MLX5E_PROT_MASK(MLX5E_100GBASE_SR4) |
 841             MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
 842                return PORT_FIBRE;
 843        }
 844
 845        if (eth_proto &
 846            (MLX5E_PROT_MASK(MLX5E_40GBASE_CR4) |
 847             MLX5E_PROT_MASK(MLX5E_10GBASE_CR)  |
 848             MLX5E_PROT_MASK(MLX5E_100GBASE_CR4))) {
 849                return PORT_DA;
 850        }
 851
 852        if (eth_proto &
 853            (MLX5E_PROT_MASK(MLX5E_10GBASE_KX4) |
 854             MLX5E_PROT_MASK(MLX5E_10GBASE_KR)  |
 855             MLX5E_PROT_MASK(MLX5E_40GBASE_KR4) |
 856             MLX5E_PROT_MASK(MLX5E_100GBASE_KR4))) {
 857                return PORT_NONE;
 858        }
 859
 860        return PORT_OTHER;
 861}
 862
 863static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
 864                               struct ethtool_link_ksettings *link_ksettings)
 865{
 866        unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising;
 867        bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
 868
 869        ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext);
 870}
 871
 872int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
 873                                     struct ethtool_link_ksettings *link_ksettings)
 874{
 875        struct mlx5_core_dev *mdev = priv->mdev;
 876        u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
 877        u32 rx_pause = 0;
 878        u32 tx_pause = 0;
 879        u32 eth_proto_cap;
 880        u32 eth_proto_admin;
 881        u32 eth_proto_lp;
 882        u32 eth_proto_oper;
 883        u8 an_disable_admin;
 884        u8 an_status;
 885        u8 connector_type;
 886        bool admin_ext;
 887        bool ext;
 888        int err;
 889
 890        err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
 891        if (err) {
 892                netdev_err(priv->netdev, "%s: query port ptys failed: %d\n",
 893                           __func__, err);
 894                goto err_query_regs;
 895        }
 896        ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
 897        eth_proto_cap    = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
 898                                              eth_proto_capability);
 899        eth_proto_admin  = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
 900                                              eth_proto_admin);
 901        /* Fields: eth_proto_admin and ext_eth_proto_admin  are
 902         * mutually exclusive. Hence try reading legacy advertising
 903         * when extended advertising is zero.
 904         * admin_ext indicates which proto_admin (ext vs. legacy)
 905         * should be read and interpreted
 906         */
 907        admin_ext = ext;
 908        if (ext && !eth_proto_admin) {
 909                eth_proto_admin  = MLX5_GET_ETH_PROTO(ptys_reg, out, false,
 910                                                      eth_proto_admin);
 911                admin_ext = false;
 912        }
 913
 914        eth_proto_oper   = MLX5_GET_ETH_PROTO(ptys_reg, out, admin_ext,
 915                                              eth_proto_oper);
 916        eth_proto_lp        = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
 917        an_disable_admin    = MLX5_GET(ptys_reg, out, an_disable_admin);
 918        an_status           = MLX5_GET(ptys_reg, out, an_status);
 919        connector_type      = MLX5_GET(ptys_reg, out, connector_type);
 920
 921        mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
 922
 923        ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
 924        ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
 925
 926        get_supported(mdev, eth_proto_cap, link_ksettings);
 927        get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings,
 928                        admin_ext);
 929        get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext,
 930                         link_ksettings);
 931
 932        eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
 933
 934        link_ksettings->base.port = get_connector_port(eth_proto_oper,
 935                                                       connector_type, ext);
 936        ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin,
 937                                               connector_type, ext);
 938        get_lp_advertising(mdev, eth_proto_lp, link_ksettings);
 939
 940        if (an_status == MLX5_AN_COMPLETE)
 941                ethtool_link_ksettings_add_link_mode(link_ksettings,
 942                                                     lp_advertising, Autoneg);
 943
 944        link_ksettings->base.autoneg = an_disable_admin ? AUTONEG_DISABLE :
 945                                                          AUTONEG_ENABLE;
 946        ethtool_link_ksettings_add_link_mode(link_ksettings, supported,
 947                                             Autoneg);
 948
 949        err = get_fec_supported_advertised(mdev, link_ksettings);
 950        if (err) {
 951                netdev_dbg(priv->netdev, "%s: FEC caps query failed: %d\n",
 952                           __func__, err);
 953                err = 0; /* don't fail caps query because of FEC error */
 954        }
 955
 956        if (!an_disable_admin)
 957                ethtool_link_ksettings_add_link_mode(link_ksettings,
 958                                                     advertising, Autoneg);
 959
 960err_query_regs:
 961        return err;
 962}
 963
 964static int mlx5e_get_link_ksettings(struct net_device *netdev,
 965                                    struct ethtool_link_ksettings *link_ksettings)
 966{
 967        struct mlx5e_priv *priv = netdev_priv(netdev);
 968
 969        return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
 970}
 971
 972static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
 973{
 974        u32 i, ptys_modes = 0;
 975
 976        for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
 977                if (*ptys2legacy_ethtool_table[i].advertised == 0)
 978                        continue;
 979                if (bitmap_intersects(ptys2legacy_ethtool_table[i].advertised,
 980                                      link_modes,
 981                                      __ETHTOOL_LINK_MODE_MASK_NBITS))
 982                        ptys_modes |= MLX5E_PROT_MASK(i);
 983        }
 984
 985        return ptys_modes;
 986}
 987
 988static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes)
 989{
 990        u32 i, ptys_modes = 0;
 991        unsigned long modes[2];
 992
 993        for (i = 0; i < MLX5E_EXT_LINK_MODES_NUMBER; ++i) {
 994                if (*ptys2ext_ethtool_table[i].advertised == 0)
 995                        continue;
 996                memset(modes, 0, sizeof(modes));
 997                bitmap_and(modes, ptys2ext_ethtool_table[i].advertised,
 998                           link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
 999
1000                if (modes[0] == ptys2ext_ethtool_table[i].advertised[0] &&
1001                    modes[1] == ptys2ext_ethtool_table[i].advertised[1])
1002                        ptys_modes |= MLX5E_PROT_MASK(i);
1003        }
1004        return ptys_modes;
1005}
1006
1007static bool ext_link_mode_requested(const unsigned long *adver)
1008{
1009#define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT
1010        int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT;
1011        __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = {0,};
1012
1013        bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size);
1014        return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
1015}
1016
1017static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported)
1018{
1019        bool ext_link_mode = ext_link_mode_requested(adver);
1020
1021        return  autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported;
1022}
1023
1024int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
1025                                     const struct ethtool_link_ksettings *link_ksettings)
1026{
1027        struct mlx5_core_dev *mdev = priv->mdev;
1028        struct mlx5e_port_eth_proto eproto;
1029        const unsigned long *adver;
1030        bool an_changes = false;
1031        u8 an_disable_admin;
1032        bool ext_supported;
1033        u8 an_disable_cap;
1034        bool an_disable;
1035        u32 link_modes;
1036        u8 an_status;
1037        u8 autoneg;
1038        u32 speed;
1039        bool ext;
1040        int err;
1041
1042        u32 (*ethtool2ptys_adver_func)(const unsigned long *adver);
1043
1044        adver = link_ksettings->link_modes.advertising;
1045        autoneg = link_ksettings->base.autoneg;
1046        speed = link_ksettings->base.speed;
1047
1048        ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
1049        ext = ext_requested(autoneg, adver, ext_supported);
1050        if (!ext_supported && ext)
1051                return -EOPNOTSUPP;
1052
1053        ethtool2ptys_adver_func = ext ? mlx5e_ethtool2ptys_ext_adver_link :
1054                                  mlx5e_ethtool2ptys_adver_link;
1055        err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
1056        if (err) {
1057                netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
1058                           __func__, err);
1059                goto out;
1060        }
1061        link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
1062                mlx5e_port_speed2linkmodes(mdev, speed, !ext);
1063
1064        if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) &&
1065            autoneg != AUTONEG_ENABLE) {
1066                netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n",
1067                           __func__);
1068                err = -EINVAL;
1069                goto out;
1070        }
1071
1072        link_modes = link_modes & eproto.cap;
1073        if (!link_modes) {
1074                netdev_err(priv->netdev, "%s: Not supported link mode(s) requested",
1075                           __func__);
1076                err = -EINVAL;
1077                goto out;
1078        }
1079
1080        mlx5_port_query_eth_autoneg(mdev, &an_status, &an_disable_cap,
1081                                    &an_disable_admin);
1082
1083        an_disable = autoneg == AUTONEG_DISABLE;
1084        an_changes = ((!an_disable && an_disable_admin) ||
1085                      (an_disable && !an_disable_admin));
1086
1087        if (!an_changes && link_modes == eproto.admin)
1088                goto out;
1089
1090        mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext);
1091        mlx5_toggle_port_link(mdev);
1092
1093out:
1094        return err;
1095}
1096
1097static int mlx5e_set_link_ksettings(struct net_device *netdev,
1098                                    const struct ethtool_link_ksettings *link_ksettings)
1099{
1100        struct mlx5e_priv *priv = netdev_priv(netdev);
1101
1102        return mlx5e_ethtool_set_link_ksettings(priv, link_ksettings);
1103}
1104
1105u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv)
1106{
1107        return sizeof(priv->rss_params.toeplitz_hash_key);
1108}
1109
1110static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
1111{
1112        struct mlx5e_priv *priv = netdev_priv(netdev);
1113
1114        return mlx5e_ethtool_get_rxfh_key_size(priv);
1115}
1116
1117u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv)
1118{
1119        return MLX5E_INDIR_RQT_SIZE;
1120}
1121
1122static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
1123{
1124        struct mlx5e_priv *priv = netdev_priv(netdev);
1125
1126        return mlx5e_ethtool_get_rxfh_indir_size(priv);
1127}
1128
1129int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
1130                   u8 *hfunc)
1131{
1132        struct mlx5e_priv *priv = netdev_priv(netdev);
1133        struct mlx5e_rss_params *rss = &priv->rss_params;
1134
1135        if (indir)
1136                memcpy(indir, rss->indirection_rqt,
1137                       sizeof(rss->indirection_rqt));
1138
1139        if (key)
1140                memcpy(key, rss->toeplitz_hash_key,
1141                       sizeof(rss->toeplitz_hash_key));
1142
1143        if (hfunc)
1144                *hfunc = rss->hfunc;
1145
1146        return 0;
1147}
1148
1149int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
1150                   const u8 *key, const u8 hfunc)
1151{
1152        struct mlx5e_priv *priv = netdev_priv(dev);
1153        struct mlx5e_rss_params *rss = &priv->rss_params;
1154        int inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
1155        bool hash_changed = false;
1156        void *in;
1157
1158        if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
1159            (hfunc != ETH_RSS_HASH_XOR) &&
1160            (hfunc != ETH_RSS_HASH_TOP))
1161                return -EINVAL;
1162
1163        in = kvzalloc(inlen, GFP_KERNEL);
1164        if (!in)
1165                return -ENOMEM;
1166
1167        mutex_lock(&priv->state_lock);
1168
1169        if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != rss->hfunc) {
1170                rss->hfunc = hfunc;
1171                hash_changed = true;
1172        }
1173
1174        if (indir) {
1175                memcpy(rss->indirection_rqt, indir,
1176                       sizeof(rss->indirection_rqt));
1177
1178                if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1179                        u32 rqtn = priv->indir_rqt.rqtn;
1180                        struct mlx5e_redirect_rqt_param rrp = {
1181                                .is_rss = true,
1182                                {
1183                                        .rss = {
1184                                                .hfunc = rss->hfunc,
1185                                                .channels  = &priv->channels,
1186                                        },
1187                                },
1188                        };
1189
1190                        mlx5e_redirect_rqt(priv, rqtn, MLX5E_INDIR_RQT_SIZE, rrp);
1191                }
1192        }
1193
1194        if (key) {
1195                memcpy(rss->toeplitz_hash_key, key,
1196                       sizeof(rss->toeplitz_hash_key));
1197                hash_changed = hash_changed || rss->hfunc == ETH_RSS_HASH_TOP;
1198        }
1199
1200        if (hash_changed)
1201                mlx5e_modify_tirs_hash(priv, in, inlen);
1202
1203        mutex_unlock(&priv->state_lock);
1204
1205        kvfree(in);
1206
1207        return 0;
1208}
1209
1210#define MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC         100
1211#define MLX5E_PFC_PREVEN_TOUT_MAX_MSEC          8000
1212#define MLX5E_PFC_PREVEN_MINOR_PRECENT          85
1213#define MLX5E_PFC_PREVEN_TOUT_MIN_MSEC          80
1214#define MLX5E_DEVICE_STALL_MINOR_WATERMARK(critical_tout) \
1215        max_t(u16, MLX5E_PFC_PREVEN_TOUT_MIN_MSEC, \
1216              (critical_tout * MLX5E_PFC_PREVEN_MINOR_PRECENT) / 100)
1217
1218static int mlx5e_get_pfc_prevention_tout(struct net_device *netdev,
1219                                         u16 *pfc_prevention_tout)
1220{
1221        struct mlx5e_priv *priv    = netdev_priv(netdev);
1222        struct mlx5_core_dev *mdev = priv->mdev;
1223
1224        if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) ||
1225            !MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
1226                return -EOPNOTSUPP;
1227
1228        return mlx5_query_port_stall_watermark(mdev, pfc_prevention_tout, NULL);
1229}
1230
1231static int mlx5e_set_pfc_prevention_tout(struct net_device *netdev,
1232                                         u16 pfc_preven)
1233{
1234        struct mlx5e_priv *priv = netdev_priv(netdev);
1235        struct mlx5_core_dev *mdev = priv->mdev;
1236        u16 critical_tout;
1237        u16 minor;
1238
1239        if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) ||
1240            !MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
1241                return -EOPNOTSUPP;
1242
1243        critical_tout = (pfc_preven == PFC_STORM_PREVENTION_AUTO) ?
1244                        MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC :
1245                        pfc_preven;
1246
1247        if (critical_tout != PFC_STORM_PREVENTION_DISABLE &&
1248            (critical_tout > MLX5E_PFC_PREVEN_TOUT_MAX_MSEC ||
1249             critical_tout < MLX5E_PFC_PREVEN_TOUT_MIN_MSEC)) {
1250                netdev_info(netdev, "%s: pfc prevention tout not in range (%d-%d)\n",
1251                            __func__, MLX5E_PFC_PREVEN_TOUT_MIN_MSEC,
1252                            MLX5E_PFC_PREVEN_TOUT_MAX_MSEC);
1253                return -EINVAL;
1254        }
1255
1256        minor = MLX5E_DEVICE_STALL_MINOR_WATERMARK(critical_tout);
1257        return mlx5_set_port_stall_watermark(mdev, critical_tout,
1258                                             minor);
1259}
1260
1261static int mlx5e_get_tunable(struct net_device *dev,
1262                             const struct ethtool_tunable *tuna,
1263                             void *data)
1264{
1265        int err;
1266
1267        switch (tuna->id) {
1268        case ETHTOOL_PFC_PREVENTION_TOUT:
1269                err = mlx5e_get_pfc_prevention_tout(dev, data);
1270                break;
1271        default:
1272                err = -EINVAL;
1273                break;
1274        }
1275
1276        return err;
1277}
1278
1279static int mlx5e_set_tunable(struct net_device *dev,
1280                             const struct ethtool_tunable *tuna,
1281                             const void *data)
1282{
1283        struct mlx5e_priv *priv = netdev_priv(dev);
1284        int err;
1285
1286        mutex_lock(&priv->state_lock);
1287
1288        switch (tuna->id) {
1289        case ETHTOOL_PFC_PREVENTION_TOUT:
1290                err = mlx5e_set_pfc_prevention_tout(dev, *(u16 *)data);
1291                break;
1292        default:
1293                err = -EINVAL;
1294                break;
1295        }
1296
1297        mutex_unlock(&priv->state_lock);
1298        return err;
1299}
1300
1301void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
1302                                  struct ethtool_pauseparam *pauseparam)
1303{
1304        struct mlx5_core_dev *mdev = priv->mdev;
1305        int err;
1306
1307        err = mlx5_query_port_pause(mdev, &pauseparam->rx_pause,
1308                                    &pauseparam->tx_pause);
1309        if (err) {
1310                netdev_err(priv->netdev, "%s: mlx5_query_port_pause failed:0x%x\n",
1311                           __func__, err);
1312        }
1313}
1314
1315static void mlx5e_get_pauseparam(struct net_device *netdev,
1316                                 struct ethtool_pauseparam *pauseparam)
1317{
1318        struct mlx5e_priv *priv = netdev_priv(netdev);
1319
1320        mlx5e_ethtool_get_pauseparam(priv, pauseparam);
1321}
1322
1323int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
1324                                 struct ethtool_pauseparam *pauseparam)
1325{
1326        struct mlx5_core_dev *mdev = priv->mdev;
1327        int err;
1328
1329        if (!MLX5_CAP_GEN(mdev, vport_group_manager))
1330                return -EOPNOTSUPP;
1331
1332        if (pauseparam->autoneg)
1333                return -EINVAL;
1334
1335        err = mlx5_set_port_pause(mdev,
1336                                  pauseparam->rx_pause ? 1 : 0,
1337                                  pauseparam->tx_pause ? 1 : 0);
1338        if (err) {
1339                netdev_err(priv->netdev, "%s: mlx5_set_port_pause failed:0x%x\n",
1340                           __func__, err);
1341        }
1342
1343        return err;
1344}
1345
1346static int mlx5e_set_pauseparam(struct net_device *netdev,
1347                                struct ethtool_pauseparam *pauseparam)
1348{
1349        struct mlx5e_priv *priv = netdev_priv(netdev);
1350
1351        return mlx5e_ethtool_set_pauseparam(priv, pauseparam);
1352}
1353
1354int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
1355                              struct ethtool_ts_info *info)
1356{
1357        struct mlx5_core_dev *mdev = priv->mdev;
1358
1359        info->phc_index = mlx5_clock_get_ptp_index(mdev);
1360
1361        if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz) ||
1362            info->phc_index == -1)
1363                return 0;
1364
1365        info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1366                                SOF_TIMESTAMPING_RX_HARDWARE |
1367                                SOF_TIMESTAMPING_RAW_HARDWARE;
1368
1369        info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1370                         BIT(HWTSTAMP_TX_ON);
1371
1372        info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1373                           BIT(HWTSTAMP_FILTER_ALL);
1374
1375        return 0;
1376}
1377
1378static int mlx5e_get_ts_info(struct net_device *dev,
1379                             struct ethtool_ts_info *info)
1380{
1381        struct mlx5e_priv *priv = netdev_priv(dev);
1382
1383        return mlx5e_ethtool_get_ts_info(priv, info);
1384}
1385
1386static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
1387{
1388        __u32 ret = 0;
1389
1390        if (MLX5_CAP_GEN(mdev, wol_g))
1391                ret |= WAKE_MAGIC;
1392
1393        if (MLX5_CAP_GEN(mdev, wol_s))
1394                ret |= WAKE_MAGICSECURE;
1395
1396        if (MLX5_CAP_GEN(mdev, wol_a))
1397                ret |= WAKE_ARP;
1398
1399        if (MLX5_CAP_GEN(mdev, wol_b))
1400                ret |= WAKE_BCAST;
1401
1402        if (MLX5_CAP_GEN(mdev, wol_m))
1403                ret |= WAKE_MCAST;
1404
1405        if (MLX5_CAP_GEN(mdev, wol_u))
1406                ret |= WAKE_UCAST;
1407
1408        if (MLX5_CAP_GEN(mdev, wol_p))
1409                ret |= WAKE_PHY;
1410
1411        return ret;
1412}
1413
1414static __u32 mlx5e_reformat_wol_mode_mlx5_to_linux(u8 mode)
1415{
1416        __u32 ret = 0;
1417
1418        if (mode & MLX5_WOL_MAGIC)
1419                ret |= WAKE_MAGIC;
1420
1421        if (mode & MLX5_WOL_SECURED_MAGIC)
1422                ret |= WAKE_MAGICSECURE;
1423
1424        if (mode & MLX5_WOL_ARP)
1425                ret |= WAKE_ARP;
1426
1427        if (mode & MLX5_WOL_BROADCAST)
1428                ret |= WAKE_BCAST;
1429
1430        if (mode & MLX5_WOL_MULTICAST)
1431                ret |= WAKE_MCAST;
1432
1433        if (mode & MLX5_WOL_UNICAST)
1434                ret |= WAKE_UCAST;
1435
1436        if (mode & MLX5_WOL_PHY_ACTIVITY)
1437                ret |= WAKE_PHY;
1438
1439        return ret;
1440}
1441
1442static u8 mlx5e_reformat_wol_mode_linux_to_mlx5(__u32 mode)
1443{
1444        u8 ret = 0;
1445
1446        if (mode & WAKE_MAGIC)
1447                ret |= MLX5_WOL_MAGIC;
1448
1449        if (mode & WAKE_MAGICSECURE)
1450                ret |= MLX5_WOL_SECURED_MAGIC;
1451
1452        if (mode & WAKE_ARP)
1453                ret |= MLX5_WOL_ARP;
1454
1455        if (mode & WAKE_BCAST)
1456                ret |= MLX5_WOL_BROADCAST;
1457
1458        if (mode & WAKE_MCAST)
1459                ret |= MLX5_WOL_MULTICAST;
1460
1461        if (mode & WAKE_UCAST)
1462                ret |= MLX5_WOL_UNICAST;
1463
1464        if (mode & WAKE_PHY)
1465                ret |= MLX5_WOL_PHY_ACTIVITY;
1466
1467        return ret;
1468}
1469
1470static void mlx5e_get_wol(struct net_device *netdev,
1471                          struct ethtool_wolinfo *wol)
1472{
1473        struct mlx5e_priv *priv = netdev_priv(netdev);
1474        struct mlx5_core_dev *mdev = priv->mdev;
1475        u8 mlx5_wol_mode;
1476        int err;
1477
1478        memset(wol, 0, sizeof(*wol));
1479
1480        wol->supported = mlx5e_get_wol_supported(mdev);
1481        if (!wol->supported)
1482                return;
1483
1484        err = mlx5_query_port_wol(mdev, &mlx5_wol_mode);
1485        if (err)
1486                return;
1487
1488        wol->wolopts = mlx5e_reformat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
1489}
1490
1491static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1492{
1493        struct mlx5e_priv *priv = netdev_priv(netdev);
1494        struct mlx5_core_dev *mdev = priv->mdev;
1495        __u32 wol_supported = mlx5e_get_wol_supported(mdev);
1496        u32 mlx5_wol_mode;
1497
1498        if (!wol_supported)
1499                return -EOPNOTSUPP;
1500
1501        if (wol->wolopts & ~wol_supported)
1502                return -EINVAL;
1503
1504        mlx5_wol_mode = mlx5e_reformat_wol_mode_linux_to_mlx5(wol->wolopts);
1505
1506        return mlx5_set_port_wol(mdev, mlx5_wol_mode);
1507}
1508
1509static int mlx5e_get_fecparam(struct net_device *netdev,
1510                              struct ethtool_fecparam *fecparam)
1511{
1512        struct mlx5e_priv *priv = netdev_priv(netdev);
1513        struct mlx5_core_dev *mdev = priv->mdev;
1514        u8 fec_configured = 0;
1515        u32 fec_active = 0;
1516        int err;
1517
1518        err = mlx5e_get_fec_mode(mdev, &fec_active, &fec_configured);
1519
1520        if (err)
1521                return err;
1522
1523        fecparam->active_fec = pplm2ethtool_fec((u_long)fec_active,
1524                                                sizeof(u32) * BITS_PER_BYTE);
1525
1526        if (!fecparam->active_fec)
1527                return -EOPNOTSUPP;
1528
1529        fecparam->fec = pplm2ethtool_fec((u_long)fec_configured,
1530                                         sizeof(u8) * BITS_PER_BYTE);
1531
1532        return 0;
1533}
1534
1535static int mlx5e_set_fecparam(struct net_device *netdev,
1536                              struct ethtool_fecparam *fecparam)
1537{
1538        struct mlx5e_priv *priv = netdev_priv(netdev);
1539        struct mlx5_core_dev *mdev = priv->mdev;
1540        u8 fec_policy = 0;
1541        int mode;
1542        int err;
1543
1544        for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) {
1545                if (!(pplm_fec_2_ethtool[mode] & fecparam->fec))
1546                        continue;
1547                fec_policy |= (1 << mode);
1548                break;
1549        }
1550
1551        err = mlx5e_set_fec_mode(mdev, fec_policy);
1552
1553        if (err)
1554                return err;
1555
1556        mlx5_toggle_port_link(mdev);
1557
1558        return 0;
1559}
1560
1561static u32 mlx5e_get_msglevel(struct net_device *dev)
1562{
1563        return ((struct mlx5e_priv *)netdev_priv(dev))->msglevel;
1564}
1565
1566static void mlx5e_set_msglevel(struct net_device *dev, u32 val)
1567{
1568        ((struct mlx5e_priv *)netdev_priv(dev))->msglevel = val;
1569}
1570
1571static int mlx5e_set_phys_id(struct net_device *dev,
1572                             enum ethtool_phys_id_state state)
1573{
1574        struct mlx5e_priv *priv = netdev_priv(dev);
1575        struct mlx5_core_dev *mdev = priv->mdev;
1576        u16 beacon_duration;
1577
1578        if (!MLX5_CAP_GEN(mdev, beacon_led))
1579                return -EOPNOTSUPP;
1580
1581        switch (state) {
1582        case ETHTOOL_ID_ACTIVE:
1583                beacon_duration = MLX5_BEACON_DURATION_INF;
1584                break;
1585        case ETHTOOL_ID_INACTIVE:
1586                beacon_duration = MLX5_BEACON_DURATION_OFF;
1587                break;
1588        default:
1589                return -EOPNOTSUPP;
1590        }
1591
1592        return mlx5_set_port_beacon(mdev, beacon_duration);
1593}
1594
1595static int mlx5e_get_module_info(struct net_device *netdev,
1596                                 struct ethtool_modinfo *modinfo)
1597{
1598        struct mlx5e_priv *priv = netdev_priv(netdev);
1599        struct mlx5_core_dev *dev = priv->mdev;
1600        int size_read = 0;
1601        u8 data[4] = {0};
1602
1603        size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
1604        if (size_read < 2)
1605                return -EIO;
1606
1607        /* data[0] = identifier byte */
1608        switch (data[0]) {
1609        case MLX5_MODULE_ID_QSFP:
1610                modinfo->type       = ETH_MODULE_SFF_8436;
1611                modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
1612                break;
1613        case MLX5_MODULE_ID_QSFP_PLUS:
1614        case MLX5_MODULE_ID_QSFP28:
1615                /* data[1] = revision id */
1616                if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
1617                        modinfo->type       = ETH_MODULE_SFF_8636;
1618                        modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
1619                } else {
1620                        modinfo->type       = ETH_MODULE_SFF_8436;
1621                        modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
1622                }
1623                break;
1624        case MLX5_MODULE_ID_SFP:
1625                modinfo->type       = ETH_MODULE_SFF_8472;
1626                modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1627                break;
1628        default:
1629                netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
1630                           __func__, data[0]);
1631                return -EINVAL;
1632        }
1633
1634        return 0;
1635}
1636
1637static int mlx5e_get_module_eeprom(struct net_device *netdev,
1638                                   struct ethtool_eeprom *ee,
1639                                   u8 *data)
1640{
1641        struct mlx5e_priv *priv = netdev_priv(netdev);
1642        struct mlx5_core_dev *mdev = priv->mdev;
1643        int offset = ee->offset;
1644        int size_read;
1645        int i = 0;
1646
1647        if (!ee->len)
1648                return -EINVAL;
1649
1650        memset(data, 0, ee->len);
1651
1652        while (i < ee->len) {
1653                size_read = mlx5_query_module_eeprom(mdev, offset, ee->len - i,
1654                                                     data + i);
1655
1656                if (!size_read)
1657                        /* Done reading */
1658                        return 0;
1659
1660                if (size_read < 0) {
1661                        netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n",
1662                                   __func__, size_read);
1663                        return 0;
1664                }
1665
1666                i += size_read;
1667                offset += size_read;
1668        }
1669
1670        return 0;
1671}
1672
1673int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
1674                               struct ethtool_flash *flash)
1675{
1676        struct mlx5_core_dev *mdev = priv->mdev;
1677        struct net_device *dev = priv->netdev;
1678        const struct firmware *fw;
1679        int err;
1680
1681        if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
1682                return -EOPNOTSUPP;
1683
1684        err = request_firmware_direct(&fw, flash->data, &dev->dev);
1685        if (err)
1686                return err;
1687
1688        dev_hold(dev);
1689        rtnl_unlock();
1690
1691        err = mlx5_firmware_flash(mdev, fw, NULL);
1692        release_firmware(fw);
1693
1694        rtnl_lock();
1695        dev_put(dev);
1696        return err;
1697}
1698
1699static int mlx5e_flash_device(struct net_device *dev,
1700                              struct ethtool_flash *flash)
1701{
1702        struct mlx5e_priv *priv = netdev_priv(dev);
1703
1704        return mlx5e_ethtool_flash_device(priv, flash);
1705}
1706
1707static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
1708                                     bool is_rx_cq)
1709{
1710        struct mlx5e_priv *priv = netdev_priv(netdev);
1711        struct mlx5_core_dev *mdev = priv->mdev;
1712        struct mlx5e_channels new_channels = {};
1713        bool mode_changed;
1714        u8 cq_period_mode, current_cq_period_mode;
1715
1716        cq_period_mode = enable ?
1717                MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
1718                MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
1719        current_cq_period_mode = is_rx_cq ?
1720                priv->channels.params.rx_cq_moderation.cq_period_mode :
1721                priv->channels.params.tx_cq_moderation.cq_period_mode;
1722        mode_changed = cq_period_mode != current_cq_period_mode;
1723
1724        if (cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE &&
1725            !MLX5_CAP_GEN(mdev, cq_period_start_from_cqe))
1726                return -EOPNOTSUPP;
1727
1728        if (!mode_changed)
1729                return 0;
1730
1731        new_channels.params = priv->channels.params;
1732        if (is_rx_cq)
1733                mlx5e_set_rx_cq_mode_params(&new_channels.params, cq_period_mode);
1734        else
1735                mlx5e_set_tx_cq_mode_params(&new_channels.params, cq_period_mode);
1736
1737        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1738                priv->channels.params = new_channels.params;
1739                return 0;
1740        }
1741
1742        return mlx5e_safe_switch_channels(priv, &new_channels, NULL);
1743}
1744
1745static int set_pflag_tx_cqe_based_moder(struct net_device *netdev, bool enable)
1746{
1747        return set_pflag_cqe_based_moder(netdev, enable, false);
1748}
1749
1750static int set_pflag_rx_cqe_based_moder(struct net_device *netdev, bool enable)
1751{
1752        return set_pflag_cqe_based_moder(netdev, enable, true);
1753}
1754
1755int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val)
1756{
1757        bool curr_val = MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS);
1758        struct mlx5e_channels new_channels = {};
1759        int err = 0;
1760
1761        if (!MLX5_CAP_GEN(priv->mdev, cqe_compression))
1762                return new_val ? -EOPNOTSUPP : 0;
1763
1764        if (curr_val == new_val)
1765                return 0;
1766
1767        new_channels.params = priv->channels.params;
1768        MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val);
1769
1770        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1771                priv->channels.params = new_channels.params;
1772                return 0;
1773        }
1774
1775        err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
1776        if (err)
1777                return err;
1778
1779        mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
1780                  MLX5E_GET_PFLAG(&priv->channels.params,
1781                                  MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
1782
1783        return 0;
1784}
1785
1786static int set_pflag_rx_cqe_compress(struct net_device *netdev,
1787                                     bool enable)
1788{
1789        struct mlx5e_priv *priv = netdev_priv(netdev);
1790        struct mlx5_core_dev *mdev = priv->mdev;
1791
1792        if (!MLX5_CAP_GEN(mdev, cqe_compression))
1793                return -EOPNOTSUPP;
1794
1795        if (enable && priv->tstamp.rx_filter != HWTSTAMP_FILTER_NONE) {
1796                netdev_err(netdev, "Can't enable cqe compression while timestamping is enabled.\n");
1797                return -EINVAL;
1798        }
1799
1800        mlx5e_modify_rx_cqe_compression_locked(priv, enable);
1801        priv->channels.params.rx_cqe_compress_def = enable;
1802
1803        return 0;
1804}
1805
1806static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
1807{
1808        struct mlx5e_priv *priv = netdev_priv(netdev);
1809        struct mlx5_core_dev *mdev = priv->mdev;
1810        struct mlx5e_channels new_channels = {};
1811
1812        if (enable) {
1813                if (!mlx5e_check_fragmented_striding_rq_cap(mdev))
1814                        return -EOPNOTSUPP;
1815                if (!mlx5e_striding_rq_possible(mdev, &priv->channels.params))
1816                        return -EINVAL;
1817        } else if (priv->channels.params.lro_en) {
1818                netdev_warn(netdev, "Can't set legacy RQ with LRO, disable LRO first\n");
1819                return -EINVAL;
1820        }
1821
1822        new_channels.params = priv->channels.params;
1823
1824        MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_STRIDING_RQ, enable);
1825        mlx5e_set_rq_type(mdev, &new_channels.params);
1826
1827        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1828                priv->channels.params = new_channels.params;
1829                return 0;
1830        }
1831
1832        return mlx5e_safe_switch_channels(priv, &new_channels, NULL);
1833}
1834
1835static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
1836{
1837        struct mlx5e_priv *priv = netdev_priv(netdev);
1838        struct mlx5e_channels *channels = &priv->channels;
1839        struct mlx5e_channel *c;
1840        int i;
1841
1842        if (!test_bit(MLX5E_STATE_OPENED, &priv->state) ||
1843            priv->channels.params.xdp_prog)
1844                return 0;
1845
1846        for (i = 0; i < channels->num; i++) {
1847                c = channels->c[i];
1848                if (enable)
1849                        __set_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);
1850                else
1851                        __clear_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);
1852        }
1853
1854        return 0;
1855}
1856
1857static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
1858{
1859        struct mlx5e_priv *priv = netdev_priv(netdev);
1860        struct mlx5_core_dev *mdev = priv->mdev;
1861        struct mlx5e_channels new_channels = {};
1862        int err;
1863
1864        if (enable && !MLX5_CAP_ETH(mdev, enhanced_multi_pkt_send_wqe))
1865                return -EOPNOTSUPP;
1866
1867        new_channels.params = priv->channels.params;
1868
1869        MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_XDP_TX_MPWQE, enable);
1870
1871        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1872                priv->channels.params = new_channels.params;
1873                return 0;
1874        }
1875
1876        err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
1877        return err;
1878}
1879
1880static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
1881        { "rx_cqe_moder",        set_pflag_rx_cqe_based_moder },
1882        { "tx_cqe_moder",        set_pflag_tx_cqe_based_moder },
1883        { "rx_cqe_compress",     set_pflag_rx_cqe_compress },
1884        { "rx_striding_rq",      set_pflag_rx_striding_rq },
1885        { "rx_no_csum_complete", set_pflag_rx_no_csum_complete },
1886        { "xdp_tx_mpwqe",        set_pflag_xdp_tx_mpwqe },
1887};
1888
1889static int mlx5e_handle_pflag(struct net_device *netdev,
1890                              u32 wanted_flags,
1891                              enum mlx5e_priv_flag flag)
1892{
1893        struct mlx5e_priv *priv = netdev_priv(netdev);
1894        bool enable = !!(wanted_flags & BIT(flag));
1895        u32 changes = wanted_flags ^ priv->channels.params.pflags;
1896        int err;
1897
1898        if (!(changes & BIT(flag)))
1899                return 0;
1900
1901        err = mlx5e_priv_flags[flag].handler(netdev, enable);
1902        if (err) {
1903                netdev_err(netdev, "%s private flag '%s' failed err %d\n",
1904                           enable ? "Enable" : "Disable", mlx5e_priv_flags[flag].name, err);
1905                return err;
1906        }
1907
1908        MLX5E_SET_PFLAG(&priv->channels.params, flag, enable);
1909        return 0;
1910}
1911
1912static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
1913{
1914        struct mlx5e_priv *priv = netdev_priv(netdev);
1915        enum mlx5e_priv_flag pflag;
1916        int err;
1917
1918        mutex_lock(&priv->state_lock);
1919
1920        for (pflag = 0; pflag < MLX5E_NUM_PFLAGS; pflag++) {
1921                err = mlx5e_handle_pflag(netdev, pflags, pflag);
1922                if (err)
1923                        break;
1924        }
1925
1926        mutex_unlock(&priv->state_lock);
1927
1928        /* Need to fix some features.. */
1929        netdev_update_features(netdev);
1930
1931        return err;
1932}
1933
1934static u32 mlx5e_get_priv_flags(struct net_device *netdev)
1935{
1936        struct mlx5e_priv *priv = netdev_priv(netdev);
1937
1938        return priv->channels.params.pflags;
1939}
1940
1941int mlx5e_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
1942                    u32 *rule_locs)
1943{
1944        struct mlx5e_priv *priv = netdev_priv(dev);
1945
1946        /* ETHTOOL_GRXRINGS is needed by ethtool -x which is not part
1947         * of rxnfc. We keep this logic out of mlx5e_ethtool_get_rxnfc,
1948         * to avoid breaking "ethtool -x" when mlx5e_ethtool_get_rxnfc
1949         * is compiled out via CONFIG_MLX5_EN_RXNFC=n.
1950         */
1951        if (info->cmd == ETHTOOL_GRXRINGS) {
1952                info->data = priv->channels.params.num_channels;
1953                return 0;
1954        }
1955
1956        return mlx5e_ethtool_get_rxnfc(dev, info, rule_locs);
1957}
1958
1959int mlx5e_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
1960{
1961        return mlx5e_ethtool_set_rxnfc(dev, cmd);
1962}
1963
1964const struct ethtool_ops mlx5e_ethtool_ops = {
1965        .get_drvinfo       = mlx5e_get_drvinfo,
1966        .get_link          = ethtool_op_get_link,
1967        .get_strings       = mlx5e_get_strings,
1968        .get_sset_count    = mlx5e_get_sset_count,
1969        .get_ethtool_stats = mlx5e_get_ethtool_stats,
1970        .get_ringparam     = mlx5e_get_ringparam,
1971        .set_ringparam     = mlx5e_set_ringparam,
1972        .get_channels      = mlx5e_get_channels,
1973        .set_channels      = mlx5e_set_channels,
1974        .get_coalesce      = mlx5e_get_coalesce,
1975        .set_coalesce      = mlx5e_set_coalesce,
1976        .get_link_ksettings  = mlx5e_get_link_ksettings,
1977        .set_link_ksettings  = mlx5e_set_link_ksettings,
1978        .get_rxfh_key_size   = mlx5e_get_rxfh_key_size,
1979        .get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
1980        .get_rxfh          = mlx5e_get_rxfh,
1981        .set_rxfh          = mlx5e_set_rxfh,
1982        .get_rxnfc         = mlx5e_get_rxnfc,
1983        .set_rxnfc         = mlx5e_set_rxnfc,
1984        .get_tunable       = mlx5e_get_tunable,
1985        .set_tunable       = mlx5e_set_tunable,
1986        .get_pauseparam    = mlx5e_get_pauseparam,
1987        .set_pauseparam    = mlx5e_set_pauseparam,
1988        .get_ts_info       = mlx5e_get_ts_info,
1989        .set_phys_id       = mlx5e_set_phys_id,
1990        .get_wol           = mlx5e_get_wol,
1991        .set_wol           = mlx5e_set_wol,
1992        .get_module_info   = mlx5e_get_module_info,
1993        .get_module_eeprom = mlx5e_get_module_eeprom,
1994        .flash_device      = mlx5e_flash_device,
1995        .get_priv_flags    = mlx5e_get_priv_flags,
1996        .set_priv_flags    = mlx5e_set_priv_flags,
1997        .self_test         = mlx5e_self_test,
1998        .get_msglevel      = mlx5e_get_msglevel,
1999        .set_msglevel      = mlx5e_set_msglevel,
2000        .get_fecparam      = mlx5e_get_fecparam,
2001        .set_fecparam      = mlx5e_set_fecparam,
2002};
2003