0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/ethtool_netlink.h>
0034
0035 #include "en.h"
0036 #include "en/port.h"
0037 #include "en/params.h"
0038 #include "en/xsk/pool.h"
0039 #include "en/ptp.h"
0040 #include "lib/clock.h"
0041
0042 void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
0043 struct ethtool_drvinfo *drvinfo)
0044 {
0045 struct mlx5_core_dev *mdev = priv->mdev;
0046
0047 strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
0048 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
0049 "%d.%d.%04d (%.16s)",
0050 fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev),
0051 mdev->board_id);
0052 strlcpy(drvinfo->bus_info, dev_name(mdev->device),
0053 sizeof(drvinfo->bus_info));
0054 }
0055
0056 static void mlx5e_get_drvinfo(struct net_device *dev,
0057 struct ethtool_drvinfo *drvinfo)
0058 {
0059 struct mlx5e_priv *priv = netdev_priv(dev);
0060
0061 mlx5e_ethtool_get_drvinfo(priv, drvinfo);
0062 }
0063
0064 struct ptys2ethtool_config {
0065 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
0066 __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
0067 };
0068
0069 static
0070 struct ptys2ethtool_config ptys2legacy_ethtool_table[MLX5E_LINK_MODES_NUMBER];
0071 static
0072 struct ptys2ethtool_config ptys2ext_ethtool_table[MLX5E_EXT_LINK_MODES_NUMBER];
0073
0074 #define MLX5_BUILD_PTYS2ETHTOOL_CONFIG(reg_, table, ...) \
0075 ({ \
0076 struct ptys2ethtool_config *cfg; \
0077 const unsigned int modes[] = { __VA_ARGS__ }; \
0078 unsigned int i, bit, idx; \
0079 cfg = &ptys2##table##_ethtool_table[reg_]; \
0080 bitmap_zero(cfg->supported, \
0081 __ETHTOOL_LINK_MODE_MASK_NBITS); \
0082 bitmap_zero(cfg->advertised, \
0083 __ETHTOOL_LINK_MODE_MASK_NBITS); \
0084 for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) { \
0085 bit = modes[i] % 64; \
0086 idx = modes[i] / 64; \
0087 __set_bit(bit, &cfg->supported[idx]); \
0088 __set_bit(bit, &cfg->advertised[idx]); \
0089 } \
0090 })
0091
0092 void mlx5e_build_ptys2ethtool_map(void)
0093 {
0094 memset(ptys2legacy_ethtool_table, 0, sizeof(ptys2legacy_ethtool_table));
0095 memset(ptys2ext_ethtool_table, 0, sizeof(ptys2ext_ethtool_table));
0096 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_CX_SGMII, legacy,
0097 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
0098 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_KX, legacy,
0099 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
0100 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CX4, legacy,
0101 ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
0102 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KX4, legacy,
0103 ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
0104 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KR, legacy,
0105 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
0106 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_20GBASE_KR2, legacy,
0107 ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);
0108 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_CR4, legacy,
0109 ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT);
0110 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_KR4, legacy,
0111 ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT);
0112 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_56GBASE_R4, legacy,
0113 ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT);
0114 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CR, legacy,
0115 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
0116 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_SR, legacy,
0117 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
0118 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_ER, legacy,
0119 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
0120 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_SR4, legacy,
0121 ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT);
0122 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_LR4, legacy,
0123 ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
0124 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_SR2, legacy,
0125 ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
0126 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_CR4, legacy,
0127 ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT);
0128 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_SR4, legacy,
0129 ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT);
0130 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_KR4, legacy,
0131 ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT);
0132 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4, legacy,
0133 ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
0134 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T, legacy,
0135 ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
0136 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR, legacy,
0137 ETHTOOL_LINK_MODE_25000baseCR_Full_BIT);
0138 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_KR, legacy,
0139 ETHTOOL_LINK_MODE_25000baseKR_Full_BIT);
0140 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_SR, legacy,
0141 ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
0142 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_CR2, legacy,
0143 ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT);
0144 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_KR2, legacy,
0145 ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT);
0146 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_SGMII_100M, ext,
0147 ETHTOOL_LINK_MODE_100baseT_Full_BIT);
0148 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_X_SGMII, ext,
0149 ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
0150 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
0151 ETHTOOL_LINK_MODE_1000baseX_Full_BIT);
0152 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_5GBASE_R, ext,
0153 ETHTOOL_LINK_MODE_5000baseT_Full_BIT);
0154 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_XFI_XAUI_1, ext,
0155 ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
0156 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
0157 ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
0158 ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
0159 ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
0160 ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
0161 ETHTOOL_LINK_MODE_10000baseER_Full_BIT);
0162 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_XLAUI_4_XLPPI_4, ext,
0163 ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
0164 ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
0165 ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
0166 ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
0167 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GAUI_1_25GBASE_CR_KR, ext,
0168 ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
0169 ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
0170 ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
0171 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
0172 ext,
0173 ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
0174 ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
0175 ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
0176 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR, ext,
0177 ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
0178 ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
0179 ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
0180 ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
0181 ETHTOOL_LINK_MODE_50000baseDR_Full_BIT);
0182 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_CAUI_4_100GBASE_CR4_KR4, ext,
0183 ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
0184 ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
0185 ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
0186 ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
0187 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_2_100GBASE_CR2_KR2, ext,
0188 ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
0189 ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
0190 ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
0191 ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
0192 ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT);
0193 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_200GAUI_4_200GBASE_CR4_KR4, ext,
0194 ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
0195 ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
0196 ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
0197 ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
0198 ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT);
0199 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_1_100GBASE_CR_KR, ext,
0200 ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
0201 ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
0202 ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
0203 ETHTOOL_LINK_MODE_100000baseDR_Full_BIT,
0204 ETHTOOL_LINK_MODE_100000baseCR_Full_BIT);
0205 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_200GAUI_2_200GBASE_CR2_KR2, ext,
0206 ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT,
0207 ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT,
0208 ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
0209 ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT,
0210 ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT);
0211 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_400GAUI_4_400GBASE_CR4_KR4, ext,
0212 ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT,
0213 ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT,
0214 ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
0215 ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT,
0216 ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT);
0217 }
0218
0219 static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev,
0220 struct ptys2ethtool_config **arr,
0221 u32 *size)
0222 {
0223 bool ext = mlx5e_ptys_ext_supported(mdev);
0224
0225 *arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
0226 *size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
0227 ARRAY_SIZE(ptys2legacy_ethtool_table);
0228 }
0229
0230 typedef int (*mlx5e_pflag_handler)(struct net_device *netdev, bool enable);
0231
0232 struct pflag_desc {
0233 char name[ETH_GSTRING_LEN];
0234 mlx5e_pflag_handler handler;
0235 };
0236
0237 static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS];
0238
0239 int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
0240 {
0241 switch (sset) {
0242 case ETH_SS_STATS:
0243 return mlx5e_stats_total_num(priv);
0244 case ETH_SS_PRIV_FLAGS:
0245 return MLX5E_NUM_PFLAGS;
0246 case ETH_SS_TEST:
0247 return mlx5e_self_test_num(priv);
0248 default:
0249 return -EOPNOTSUPP;
0250 }
0251 }
0252
0253 static int mlx5e_get_sset_count(struct net_device *dev, int sset)
0254 {
0255 struct mlx5e_priv *priv = netdev_priv(dev);
0256
0257 return mlx5e_ethtool_get_sset_count(priv, sset);
0258 }
0259
0260 void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
0261 {
0262 int i;
0263
0264 switch (stringset) {
0265 case ETH_SS_PRIV_FLAGS:
0266 for (i = 0; i < MLX5E_NUM_PFLAGS; i++)
0267 strcpy(data + i * ETH_GSTRING_LEN,
0268 mlx5e_priv_flags[i].name);
0269 break;
0270
0271 case ETH_SS_TEST:
0272 mlx5e_self_test_fill_strings(priv, data);
0273 break;
0274
0275 case ETH_SS_STATS:
0276 mlx5e_stats_fill_strings(priv, data);
0277 break;
0278 }
0279 }
0280
0281 static void mlx5e_get_strings(struct net_device *dev, u32 stringset, u8 *data)
0282 {
0283 struct mlx5e_priv *priv = netdev_priv(dev);
0284
0285 mlx5e_ethtool_get_strings(priv, stringset, data);
0286 }
0287
0288 void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
0289 struct ethtool_stats *stats, u64 *data)
0290 {
0291 int idx = 0;
0292
0293 mutex_lock(&priv->state_lock);
0294 mlx5e_stats_update(priv);
0295 mutex_unlock(&priv->state_lock);
0296
0297 mlx5e_stats_fill(priv, data, idx);
0298 }
0299
0300 static void mlx5e_get_ethtool_stats(struct net_device *dev,
0301 struct ethtool_stats *stats,
0302 u64 *data)
0303 {
0304 struct mlx5e_priv *priv = netdev_priv(dev);
0305
0306 mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
0307 }
0308
0309 void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
0310 struct ethtool_ringparam *param,
0311 struct kernel_ethtool_ringparam *kernel_param)
0312 {
0313 param->rx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
0314 param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
0315 param->rx_pending = 1 << priv->channels.params.log_rq_mtu_frames;
0316 param->tx_pending = 1 << priv->channels.params.log_sq_size;
0317
0318 kernel_param->tcp_data_split =
0319 (priv->channels.params.packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO) ?
0320 ETHTOOL_TCP_DATA_SPLIT_ENABLED :
0321 ETHTOOL_TCP_DATA_SPLIT_DISABLED;
0322 }
0323
0324 static void mlx5e_get_ringparam(struct net_device *dev,
0325 struct ethtool_ringparam *param,
0326 struct kernel_ethtool_ringparam *kernel_param,
0327 struct netlink_ext_ack *extack)
0328 {
0329 struct mlx5e_priv *priv = netdev_priv(dev);
0330
0331 mlx5e_ethtool_get_ringparam(priv, param, kernel_param);
0332 }
0333
0334 int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
0335 struct ethtool_ringparam *param)
0336 {
0337 struct mlx5e_params new_params;
0338 u8 log_rq_size;
0339 u8 log_sq_size;
0340 int err = 0;
0341
0342 if (param->rx_jumbo_pending) {
0343 netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n",
0344 __func__);
0345 return -EINVAL;
0346 }
0347 if (param->rx_mini_pending) {
0348 netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n",
0349 __func__);
0350 return -EINVAL;
0351 }
0352
0353 if (param->rx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) {
0354 netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n",
0355 __func__, param->rx_pending,
0356 1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
0357 return -EINVAL;
0358 }
0359
0360 if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
0361 netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
0362 __func__, param->tx_pending,
0363 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
0364 return -EINVAL;
0365 }
0366
0367 log_rq_size = order_base_2(param->rx_pending);
0368 log_sq_size = order_base_2(param->tx_pending);
0369
0370 if (log_rq_size == priv->channels.params.log_rq_mtu_frames &&
0371 log_sq_size == priv->channels.params.log_sq_size)
0372 return 0;
0373
0374 mutex_lock(&priv->state_lock);
0375
0376 new_params = priv->channels.params;
0377 new_params.log_rq_mtu_frames = log_rq_size;
0378 new_params.log_sq_size = log_sq_size;
0379
0380 err = mlx5e_validate_params(priv->mdev, &new_params);
0381 if (err)
0382 goto unlock;
0383
0384 err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
0385
0386 unlock:
0387 mutex_unlock(&priv->state_lock);
0388
0389 return err;
0390 }
0391
0392 static int mlx5e_set_ringparam(struct net_device *dev,
0393 struct ethtool_ringparam *param,
0394 struct kernel_ethtool_ringparam *kernel_param,
0395 struct netlink_ext_ack *extack)
0396 {
0397 struct mlx5e_priv *priv = netdev_priv(dev);
0398
0399 return mlx5e_ethtool_set_ringparam(priv, param);
0400 }
0401
0402 void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
0403 struct ethtool_channels *ch)
0404 {
0405 mutex_lock(&priv->state_lock);
0406
0407 ch->max_combined = priv->max_nch;
0408 ch->combined_count = priv->channels.params.num_channels;
0409 if (priv->xsk.refcnt) {
0410
0411 ch->max_combined *= 2;
0412 ch->combined_count *= 2;
0413 }
0414
0415 mutex_unlock(&priv->state_lock);
0416 }
0417
0418 static void mlx5e_get_channels(struct net_device *dev,
0419 struct ethtool_channels *ch)
0420 {
0421 struct mlx5e_priv *priv = netdev_priv(dev);
0422
0423 mlx5e_ethtool_get_channels(priv, ch);
0424 }
0425
0426 int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
0427 struct ethtool_channels *ch)
0428 {
0429 struct mlx5e_params *cur_params = &priv->channels.params;
0430 unsigned int count = ch->combined_count;
0431 struct mlx5e_params new_params;
0432 bool arfs_enabled;
0433 int rss_cnt;
0434 bool opened;
0435 int err = 0;
0436
0437 if (!count) {
0438 netdev_info(priv->netdev, "%s: combined_count=0 not supported\n",
0439 __func__);
0440 return -EINVAL;
0441 }
0442
0443 if (cur_params->num_channels == count)
0444 return 0;
0445
0446 mutex_lock(&priv->state_lock);
0447
0448
0449
0450
0451 if (priv->xsk.refcnt) {
0452 err = -EINVAL;
0453 netdev_err(priv->netdev, "%s: AF_XDP is active, cannot change the number of channels\n",
0454 __func__);
0455 goto out;
0456 }
0457
0458
0459
0460
0461
0462 if (mlx5e_selq_is_htb_enabled(&priv->selq)) {
0463 err = -EINVAL;
0464 netdev_err(priv->netdev, "%s: HTB offload is active, cannot change the number of channels\n",
0465 __func__);
0466 goto out;
0467 }
0468
0469
0470
0471
0472 rss_cnt = mlx5e_rx_res_rss_cnt(priv->rx_res) - 1;
0473 if (rss_cnt) {
0474 err = -EINVAL;
0475 netdev_err(priv->netdev, "%s: Non-default RSS contexts exist (%d), cannot change the number of channels\n",
0476 __func__, rss_cnt);
0477 goto out;
0478 }
0479
0480
0481
0482
0483 if (cur_params->mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
0484 err = -EINVAL;
0485 netdev_err(priv->netdev, "%s: MQPRIO mode channel offload is active, cannot change the number of channels\n",
0486 __func__);
0487 goto out;
0488 }
0489
0490 new_params = *cur_params;
0491 new_params.num_channels = count;
0492
0493 opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
0494
0495 arfs_enabled = opened && (priv->netdev->features & NETIF_F_NTUPLE);
0496 if (arfs_enabled)
0497 mlx5e_arfs_disable(priv);
0498
0499
0500 err = mlx5e_safe_switch_params(priv, &new_params,
0501 mlx5e_num_channels_changed_ctx, NULL, true);
0502
0503 if (arfs_enabled) {
0504 int err2 = mlx5e_arfs_enable(priv);
0505
0506 if (err2)
0507 netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
0508 __func__, err2);
0509 }
0510
0511 out:
0512 mutex_unlock(&priv->state_lock);
0513
0514 return err;
0515 }
0516
0517 static int mlx5e_set_channels(struct net_device *dev,
0518 struct ethtool_channels *ch)
0519 {
0520 struct mlx5e_priv *priv = netdev_priv(dev);
0521
0522 return mlx5e_ethtool_set_channels(priv, ch);
0523 }
0524
0525 int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
0526 struct ethtool_coalesce *coal,
0527 struct kernel_ethtool_coalesce *kernel_coal)
0528 {
0529 struct dim_cq_moder *rx_moder, *tx_moder;
0530
0531 if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
0532 return -EOPNOTSUPP;
0533
0534 rx_moder = &priv->channels.params.rx_cq_moderation;
0535 coal->rx_coalesce_usecs = rx_moder->usec;
0536 coal->rx_max_coalesced_frames = rx_moder->pkts;
0537 coal->use_adaptive_rx_coalesce = priv->channels.params.rx_dim_enabled;
0538
0539 tx_moder = &priv->channels.params.tx_cq_moderation;
0540 coal->tx_coalesce_usecs = tx_moder->usec;
0541 coal->tx_max_coalesced_frames = tx_moder->pkts;
0542 coal->use_adaptive_tx_coalesce = priv->channels.params.tx_dim_enabled;
0543
0544 kernel_coal->use_cqe_mode_rx =
0545 MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_BASED_MODER);
0546 kernel_coal->use_cqe_mode_tx =
0547 MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_CQE_BASED_MODER);
0548
0549 return 0;
0550 }
0551
0552 static int mlx5e_get_coalesce(struct net_device *netdev,
0553 struct ethtool_coalesce *coal,
0554 struct kernel_ethtool_coalesce *kernel_coal,
0555 struct netlink_ext_ack *extack)
0556 {
0557 struct mlx5e_priv *priv = netdev_priv(netdev);
0558
0559 return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
0560 }
0561
0562 #define MLX5E_MAX_COAL_TIME MLX5_MAX_CQ_PERIOD
0563 #define MLX5E_MAX_COAL_FRAMES MLX5_MAX_CQ_COUNT
0564
0565 static void
0566 mlx5e_set_priv_channels_tx_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
0567 {
0568 struct mlx5_core_dev *mdev = priv->mdev;
0569 int tc;
0570 int i;
0571
0572 for (i = 0; i < priv->channels.num; ++i) {
0573 struct mlx5e_channel *c = priv->channels.c[i];
0574
0575 for (tc = 0; tc < c->num_tc; tc++) {
0576 mlx5_core_modify_cq_moderation(mdev,
0577 &c->sq[tc].cq.mcq,
0578 coal->tx_coalesce_usecs,
0579 coal->tx_max_coalesced_frames);
0580 }
0581 }
0582 }
0583
0584 static void
0585 mlx5e_set_priv_channels_rx_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
0586 {
0587 struct mlx5_core_dev *mdev = priv->mdev;
0588 int i;
0589
0590 for (i = 0; i < priv->channels.num; ++i) {
0591 struct mlx5e_channel *c = priv->channels.c[i];
0592
0593 mlx5_core_modify_cq_moderation(mdev, &c->rq.cq.mcq,
0594 coal->rx_coalesce_usecs,
0595 coal->rx_max_coalesced_frames);
0596 }
0597 }
0598
0599
0600
0601
0602
0603 static int cqe_mode_to_period_mode(bool val)
0604 {
0605 return val ? MLX5_CQ_PERIOD_MODE_START_FROM_CQE : MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
0606 }
0607
0608 int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
0609 struct ethtool_coalesce *coal,
0610 struct kernel_ethtool_coalesce *kernel_coal,
0611 struct netlink_ext_ack *extack)
0612 {
0613 struct dim_cq_moder *rx_moder, *tx_moder;
0614 struct mlx5_core_dev *mdev = priv->mdev;
0615 struct mlx5e_params new_params;
0616 bool reset_rx, reset_tx;
0617 bool reset = true;
0618 u8 cq_period_mode;
0619 int err = 0;
0620
0621 if (!MLX5_CAP_GEN(mdev, cq_moderation))
0622 return -EOPNOTSUPP;
0623
0624 if (coal->tx_coalesce_usecs > MLX5E_MAX_COAL_TIME ||
0625 coal->rx_coalesce_usecs > MLX5E_MAX_COAL_TIME) {
0626 netdev_info(priv->netdev, "%s: maximum coalesce time supported is %lu usecs\n",
0627 __func__, MLX5E_MAX_COAL_TIME);
0628 return -ERANGE;
0629 }
0630
0631 if (coal->tx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES ||
0632 coal->rx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES) {
0633 netdev_info(priv->netdev, "%s: maximum coalesced frames supported is %lu\n",
0634 __func__, MLX5E_MAX_COAL_FRAMES);
0635 return -ERANGE;
0636 }
0637
0638 if ((kernel_coal->use_cqe_mode_rx || kernel_coal->use_cqe_mode_tx) &&
0639 !MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) {
0640 NL_SET_ERR_MSG_MOD(extack, "cqe_mode_rx/tx is not supported on this device");
0641 return -EOPNOTSUPP;
0642 }
0643
0644 mutex_lock(&priv->state_lock);
0645 new_params = priv->channels.params;
0646
0647 rx_moder = &new_params.rx_cq_moderation;
0648 rx_moder->usec = coal->rx_coalesce_usecs;
0649 rx_moder->pkts = coal->rx_max_coalesced_frames;
0650 new_params.rx_dim_enabled = !!coal->use_adaptive_rx_coalesce;
0651
0652 tx_moder = &new_params.tx_cq_moderation;
0653 tx_moder->usec = coal->tx_coalesce_usecs;
0654 tx_moder->pkts = coal->tx_max_coalesced_frames;
0655 new_params.tx_dim_enabled = !!coal->use_adaptive_tx_coalesce;
0656
0657 reset_rx = !!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_dim_enabled;
0658 reset_tx = !!coal->use_adaptive_tx_coalesce != priv->channels.params.tx_dim_enabled;
0659
0660 cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_rx);
0661 if (cq_period_mode != rx_moder->cq_period_mode) {
0662 mlx5e_set_rx_cq_mode_params(&new_params, cq_period_mode);
0663 reset_rx = true;
0664 }
0665
0666 cq_period_mode = cqe_mode_to_period_mode(kernel_coal->use_cqe_mode_tx);
0667 if (cq_period_mode != tx_moder->cq_period_mode) {
0668 mlx5e_set_tx_cq_mode_params(&new_params, cq_period_mode);
0669 reset_tx = true;
0670 }
0671
0672 if (reset_rx) {
0673 u8 mode = MLX5E_GET_PFLAG(&new_params,
0674 MLX5E_PFLAG_RX_CQE_BASED_MODER);
0675
0676 mlx5e_reset_rx_moderation(&new_params, mode);
0677 }
0678 if (reset_tx) {
0679 u8 mode = MLX5E_GET_PFLAG(&new_params,
0680 MLX5E_PFLAG_TX_CQE_BASED_MODER);
0681
0682 mlx5e_reset_tx_moderation(&new_params, mode);
0683 }
0684
0685
0686
0687
0688 if (!reset_rx && !reset_tx && test_bit(MLX5E_STATE_OPENED, &priv->state)) {
0689 if (!coal->use_adaptive_rx_coalesce)
0690 mlx5e_set_priv_channels_rx_coalesce(priv, coal);
0691 if (!coal->use_adaptive_tx_coalesce)
0692 mlx5e_set_priv_channels_tx_coalesce(priv, coal);
0693 reset = false;
0694 }
0695
0696 err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, reset);
0697
0698 mutex_unlock(&priv->state_lock);
0699 return err;
0700 }
0701
0702 static int mlx5e_set_coalesce(struct net_device *netdev,
0703 struct ethtool_coalesce *coal,
0704 struct kernel_ethtool_coalesce *kernel_coal,
0705 struct netlink_ext_ack *extack)
0706 {
0707 struct mlx5e_priv *priv = netdev_priv(netdev);
0708
0709 return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
0710 }
0711
0712 static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
0713 unsigned long *supported_modes,
0714 u32 eth_proto_cap)
0715 {
0716 unsigned long proto_cap = eth_proto_cap;
0717 struct ptys2ethtool_config *table;
0718 u32 max_size;
0719 int proto;
0720
0721 mlx5e_ethtool_get_speed_arr(mdev, &table, &max_size);
0722 for_each_set_bit(proto, &proto_cap, max_size)
0723 bitmap_or(supported_modes, supported_modes,
0724 table[proto].supported,
0725 __ETHTOOL_LINK_MODE_MASK_NBITS);
0726 }
0727
0728 static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
0729 u32 eth_proto_cap, bool ext)
0730 {
0731 unsigned long proto_cap = eth_proto_cap;
0732 struct ptys2ethtool_config *table;
0733 u32 max_size;
0734 int proto;
0735
0736 table = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
0737 max_size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
0738 ARRAY_SIZE(ptys2legacy_ethtool_table);
0739
0740 for_each_set_bit(proto, &proto_cap, max_size)
0741 bitmap_or(advertising_modes, advertising_modes,
0742 table[proto].advertised,
0743 __ETHTOOL_LINK_MODE_MASK_NBITS);
0744 }
0745
0746 static const u32 pplm_fec_2_ethtool[] = {
0747 [MLX5E_FEC_NOFEC] = ETHTOOL_FEC_OFF,
0748 [MLX5E_FEC_FIRECODE] = ETHTOOL_FEC_BASER,
0749 [MLX5E_FEC_RS_528_514] = ETHTOOL_FEC_RS,
0750 [MLX5E_FEC_RS_544_514] = ETHTOOL_FEC_RS,
0751 [MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_FEC_LLRS,
0752 };
0753
0754 static u32 pplm2ethtool_fec(u_long fec_mode, unsigned long size)
0755 {
0756 int mode = 0;
0757
0758 if (!fec_mode)
0759 return ETHTOOL_FEC_AUTO;
0760
0761 mode = find_first_bit(&fec_mode, size);
0762
0763 if (mode < ARRAY_SIZE(pplm_fec_2_ethtool))
0764 return pplm_fec_2_ethtool[mode];
0765
0766 return 0;
0767 }
0768
0769 #define MLX5E_ADVERTISE_SUPPORTED_FEC(mlx5_fec, ethtool_fec) \
0770 do { \
0771 if (mlx5e_fec_in_caps(dev, 1 << (mlx5_fec))) \
0772 __set_bit(ethtool_fec, \
0773 link_ksettings->link_modes.supported);\
0774 } while (0)
0775
0776 static const u32 pplm_fec_2_ethtool_linkmodes[] = {
0777 [MLX5E_FEC_NOFEC] = ETHTOOL_LINK_MODE_FEC_NONE_BIT,
0778 [MLX5E_FEC_FIRECODE] = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
0779 [MLX5E_FEC_RS_528_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
0780 [MLX5E_FEC_RS_544_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
0781 [MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
0782 };
0783
0784 static int get_fec_supported_advertised(struct mlx5_core_dev *dev,
0785 struct ethtool_link_ksettings *link_ksettings)
0786 {
0787 unsigned long active_fec_long;
0788 u32 active_fec;
0789 u32 bitn;
0790 int err;
0791
0792 err = mlx5e_get_fec_mode(dev, &active_fec, NULL);
0793 if (err)
0794 return (err == -EOPNOTSUPP) ? 0 : err;
0795
0796 MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_NOFEC,
0797 ETHTOOL_LINK_MODE_FEC_NONE_BIT);
0798 MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_FIRECODE,
0799 ETHTOOL_LINK_MODE_FEC_BASER_BIT);
0800 MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_RS_528_514,
0801 ETHTOOL_LINK_MODE_FEC_RS_BIT);
0802 MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_LLRS_272_257_1,
0803 ETHTOOL_LINK_MODE_FEC_LLRS_BIT);
0804
0805 active_fec_long = active_fec;
0806
0807
0808
0809 bitn = find_first_bit(&active_fec_long, sizeof(active_fec_long) * BITS_PER_BYTE);
0810 if (bitn < ARRAY_SIZE(pplm_fec_2_ethtool_linkmodes))
0811 __set_bit(pplm_fec_2_ethtool_linkmodes[bitn],
0812 link_ksettings->link_modes.advertising);
0813
0814 return 0;
0815 }
0816
0817 static void ptys2ethtool_supported_advertised_port(struct mlx5_core_dev *mdev,
0818 struct ethtool_link_ksettings *link_ksettings,
0819 u32 eth_proto_cap, u8 connector_type)
0820 {
0821 if (!MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type)) {
0822 if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
0823 | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
0824 | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
0825 | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
0826 | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
0827 | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
0828 ethtool_link_ksettings_add_link_mode(link_ksettings,
0829 supported,
0830 FIBRE);
0831 ethtool_link_ksettings_add_link_mode(link_ksettings,
0832 advertising,
0833 FIBRE);
0834 }
0835
0836 if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
0837 | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
0838 | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
0839 | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
0840 | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
0841 ethtool_link_ksettings_add_link_mode(link_ksettings,
0842 supported,
0843 Backplane);
0844 ethtool_link_ksettings_add_link_mode(link_ksettings,
0845 advertising,
0846 Backplane);
0847 }
0848 return;
0849 }
0850
0851 switch (connector_type) {
0852 case MLX5E_PORT_TP:
0853 ethtool_link_ksettings_add_link_mode(link_ksettings,
0854 supported, TP);
0855 ethtool_link_ksettings_add_link_mode(link_ksettings,
0856 advertising, TP);
0857 break;
0858 case MLX5E_PORT_AUI:
0859 ethtool_link_ksettings_add_link_mode(link_ksettings,
0860 supported, AUI);
0861 ethtool_link_ksettings_add_link_mode(link_ksettings,
0862 advertising, AUI);
0863 break;
0864 case MLX5E_PORT_BNC:
0865 ethtool_link_ksettings_add_link_mode(link_ksettings,
0866 supported, BNC);
0867 ethtool_link_ksettings_add_link_mode(link_ksettings,
0868 advertising, BNC);
0869 break;
0870 case MLX5E_PORT_MII:
0871 ethtool_link_ksettings_add_link_mode(link_ksettings,
0872 supported, MII);
0873 ethtool_link_ksettings_add_link_mode(link_ksettings,
0874 advertising, MII);
0875 break;
0876 case MLX5E_PORT_FIBRE:
0877 ethtool_link_ksettings_add_link_mode(link_ksettings,
0878 supported, FIBRE);
0879 ethtool_link_ksettings_add_link_mode(link_ksettings,
0880 advertising, FIBRE);
0881 break;
0882 case MLX5E_PORT_DA:
0883 ethtool_link_ksettings_add_link_mode(link_ksettings,
0884 supported, Backplane);
0885 ethtool_link_ksettings_add_link_mode(link_ksettings,
0886 advertising, Backplane);
0887 break;
0888 case MLX5E_PORT_NONE:
0889 case MLX5E_PORT_OTHER:
0890 default:
0891 break;
0892 }
0893 }
0894
0895 static void get_speed_duplex(struct net_device *netdev,
0896 u32 eth_proto_oper, bool force_legacy,
0897 u16 data_rate_oper,
0898 struct ethtool_link_ksettings *link_ksettings)
0899 {
0900 struct mlx5e_priv *priv = netdev_priv(netdev);
0901 u32 speed = SPEED_UNKNOWN;
0902 u8 duplex = DUPLEX_UNKNOWN;
0903
0904 if (!netif_carrier_ok(netdev))
0905 goto out;
0906
0907 speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper, force_legacy);
0908 if (!speed) {
0909 if (data_rate_oper)
0910 speed = 100 * data_rate_oper;
0911 else
0912 speed = SPEED_UNKNOWN;
0913 goto out;
0914 }
0915
0916 duplex = DUPLEX_FULL;
0917
0918 out:
0919 link_ksettings->base.speed = speed;
0920 link_ksettings->base.duplex = duplex;
0921 }
0922
0923 static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
0924 struct ethtool_link_ksettings *link_ksettings)
0925 {
0926 unsigned long *supported = link_ksettings->link_modes.supported;
0927 ptys2ethtool_supported_link(mdev, supported, eth_proto_cap);
0928
0929 ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
0930 }
0931
0932 static void get_advertising(u32 eth_proto_cap, u8 tx_pause, u8 rx_pause,
0933 struct ethtool_link_ksettings *link_ksettings,
0934 bool ext)
0935 {
0936 unsigned long *advertising = link_ksettings->link_modes.advertising;
0937 ptys2ethtool_adver_link(advertising, eth_proto_cap, ext);
0938
0939 if (rx_pause)
0940 ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
0941 if (tx_pause ^ rx_pause)
0942 ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
0943 }
0944
0945 static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = {
0946 [MLX5E_PORT_UNKNOWN] = PORT_OTHER,
0947 [MLX5E_PORT_NONE] = PORT_NONE,
0948 [MLX5E_PORT_TP] = PORT_TP,
0949 [MLX5E_PORT_AUI] = PORT_AUI,
0950 [MLX5E_PORT_BNC] = PORT_BNC,
0951 [MLX5E_PORT_MII] = PORT_MII,
0952 [MLX5E_PORT_FIBRE] = PORT_FIBRE,
0953 [MLX5E_PORT_DA] = PORT_DA,
0954 [MLX5E_PORT_OTHER] = PORT_OTHER,
0955 };
0956
0957 static u8 get_connector_port(struct mlx5_core_dev *mdev, u32 eth_proto, u8 connector_type)
0958 {
0959 if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type))
0960 return ptys2connector_type[connector_type];
0961
0962 if (eth_proto &
0963 (MLX5E_PROT_MASK(MLX5E_10GBASE_SR) |
0964 MLX5E_PROT_MASK(MLX5E_40GBASE_SR4) |
0965 MLX5E_PROT_MASK(MLX5E_100GBASE_SR4) |
0966 MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
0967 return PORT_FIBRE;
0968 }
0969
0970 if (eth_proto &
0971 (MLX5E_PROT_MASK(MLX5E_40GBASE_CR4) |
0972 MLX5E_PROT_MASK(MLX5E_10GBASE_CR) |
0973 MLX5E_PROT_MASK(MLX5E_100GBASE_CR4))) {
0974 return PORT_DA;
0975 }
0976
0977 if (eth_proto &
0978 (MLX5E_PROT_MASK(MLX5E_10GBASE_KX4) |
0979 MLX5E_PROT_MASK(MLX5E_10GBASE_KR) |
0980 MLX5E_PROT_MASK(MLX5E_40GBASE_KR4) |
0981 MLX5E_PROT_MASK(MLX5E_100GBASE_KR4))) {
0982 return PORT_NONE;
0983 }
0984
0985 return PORT_OTHER;
0986 }
0987
0988 static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
0989 struct ethtool_link_ksettings *link_ksettings)
0990 {
0991 unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising;
0992 bool ext = mlx5e_ptys_ext_supported(mdev);
0993
0994 ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext);
0995 }
0996
0997 int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
0998 struct ethtool_link_ksettings *link_ksettings)
0999 {
1000 struct mlx5_core_dev *mdev = priv->mdev;
1001 u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {};
1002 u32 eth_proto_admin;
1003 u8 an_disable_admin;
1004 u16 data_rate_oper;
1005 u32 eth_proto_oper;
1006 u32 eth_proto_cap;
1007 u8 connector_type;
1008 u32 rx_pause = 0;
1009 u32 tx_pause = 0;
1010 u32 eth_proto_lp;
1011 bool admin_ext;
1012 u8 an_status;
1013 bool ext;
1014 int err;
1015
1016 err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
1017 if (err) {
1018 netdev_err(priv->netdev, "%s: query port ptys failed: %d\n",
1019 __func__, err);
1020 goto err_query_regs;
1021 }
1022 ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability);
1023 eth_proto_cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
1024 eth_proto_capability);
1025 eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
1026 eth_proto_admin);
1027
1028
1029
1030
1031
1032
1033 admin_ext = ext;
1034 if (ext && !eth_proto_admin) {
1035 eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, false,
1036 eth_proto_admin);
1037 admin_ext = false;
1038 }
1039
1040 eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, admin_ext,
1041 eth_proto_oper);
1042 eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
1043 an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin);
1044 an_status = MLX5_GET(ptys_reg, out, an_status);
1045 connector_type = MLX5_GET(ptys_reg, out, connector_type);
1046 data_rate_oper = MLX5_GET(ptys_reg, out, data_rate_oper);
1047
1048 mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
1049
1050 ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
1051 ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
1052
1053 get_supported(mdev, eth_proto_cap, link_ksettings);
1054 get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings,
1055 admin_ext);
1056 get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext,
1057 data_rate_oper, link_ksettings);
1058
1059 eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
1060 connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ?
1061 connector_type : MLX5E_PORT_UNKNOWN;
1062 link_ksettings->base.port = get_connector_port(mdev, eth_proto_oper, connector_type);
1063 ptys2ethtool_supported_advertised_port(mdev, link_ksettings, eth_proto_admin,
1064 connector_type);
1065 get_lp_advertising(mdev, eth_proto_lp, link_ksettings);
1066
1067 if (an_status == MLX5_AN_COMPLETE)
1068 ethtool_link_ksettings_add_link_mode(link_ksettings,
1069 lp_advertising, Autoneg);
1070
1071 link_ksettings->base.autoneg = an_disable_admin ? AUTONEG_DISABLE :
1072 AUTONEG_ENABLE;
1073 ethtool_link_ksettings_add_link_mode(link_ksettings, supported,
1074 Autoneg);
1075
1076 err = get_fec_supported_advertised(mdev, link_ksettings);
1077 if (err) {
1078 netdev_dbg(priv->netdev, "%s: FEC caps query failed: %d\n",
1079 __func__, err);
1080 err = 0;
1081 }
1082
1083 if (!an_disable_admin)
1084 ethtool_link_ksettings_add_link_mode(link_ksettings,
1085 advertising, Autoneg);
1086
1087 err_query_regs:
1088 return err;
1089 }
1090
1091 static int mlx5e_get_link_ksettings(struct net_device *netdev,
1092 struct ethtool_link_ksettings *link_ksettings)
1093 {
1094 struct mlx5e_priv *priv = netdev_priv(netdev);
1095
1096 return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
1097 }
1098
1099 static int mlx5e_speed_validate(struct net_device *netdev, bool ext,
1100 const unsigned long link_modes, u8 autoneg)
1101 {
1102
1103 if (ext)
1104 return 0;
1105
1106 if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) &&
1107 autoneg != AUTONEG_ENABLE) {
1108 netdev_err(netdev, "%s: 56G link speed requires autoneg enabled\n",
1109 __func__);
1110 return -EINVAL;
1111 }
1112 return 0;
1113 }
1114
1115 static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
1116 {
1117 u32 i, ptys_modes = 0;
1118
1119 for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
1120 if (*ptys2legacy_ethtool_table[i].advertised == 0)
1121 continue;
1122 if (bitmap_intersects(ptys2legacy_ethtool_table[i].advertised,
1123 link_modes,
1124 __ETHTOOL_LINK_MODE_MASK_NBITS))
1125 ptys_modes |= MLX5E_PROT_MASK(i);
1126 }
1127
1128 return ptys_modes;
1129 }
1130
1131 static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes)
1132 {
1133 u32 i, ptys_modes = 0;
1134 unsigned long modes[2];
1135
1136 for (i = 0; i < MLX5E_EXT_LINK_MODES_NUMBER; ++i) {
1137 if (ptys2ext_ethtool_table[i].advertised[0] == 0 &&
1138 ptys2ext_ethtool_table[i].advertised[1] == 0)
1139 continue;
1140 memset(modes, 0, sizeof(modes));
1141 bitmap_and(modes, ptys2ext_ethtool_table[i].advertised,
1142 link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
1143
1144 if (modes[0] == ptys2ext_ethtool_table[i].advertised[0] &&
1145 modes[1] == ptys2ext_ethtool_table[i].advertised[1])
1146 ptys_modes |= MLX5E_PROT_MASK(i);
1147 }
1148 return ptys_modes;
1149 }
1150
1151 static bool ext_link_mode_requested(const unsigned long *adver)
1152 {
1153 #define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT
1154 int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT;
1155 __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = {0,};
1156
1157 bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size);
1158 return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
1159 }
1160
1161 static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported)
1162 {
1163 bool ext_link_mode = ext_link_mode_requested(adver);
1164
1165 return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported;
1166 }
1167
1168 int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
1169 const struct ethtool_link_ksettings *link_ksettings)
1170 {
1171 struct mlx5_core_dev *mdev = priv->mdev;
1172 struct mlx5e_port_eth_proto eproto;
1173 const unsigned long *adver;
1174 bool an_changes = false;
1175 u8 an_disable_admin;
1176 bool ext_supported;
1177 u8 an_disable_cap;
1178 bool an_disable;
1179 u32 link_modes;
1180 u8 an_status;
1181 u8 autoneg;
1182 u32 speed;
1183 bool ext;
1184 int err;
1185
1186 u32 (*ethtool2ptys_adver_func)(const unsigned long *adver);
1187
1188 adver = link_ksettings->link_modes.advertising;
1189 autoneg = link_ksettings->base.autoneg;
1190 speed = link_ksettings->base.speed;
1191
1192 ext_supported = mlx5e_ptys_ext_supported(mdev);
1193 ext = ext_requested(autoneg, adver, ext_supported);
1194 if (!ext_supported && ext)
1195 return -EOPNOTSUPP;
1196
1197 ethtool2ptys_adver_func = ext ? mlx5e_ethtool2ptys_ext_adver_link :
1198 mlx5e_ethtool2ptys_adver_link;
1199 err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
1200 if (err) {
1201 netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
1202 __func__, err);
1203 goto out;
1204 }
1205 link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
1206 mlx5e_port_speed2linkmodes(mdev, speed, !ext);
1207
1208 err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg);
1209 if (err)
1210 goto out;
1211
1212 link_modes = link_modes & eproto.cap;
1213 if (!link_modes) {
1214 netdev_err(priv->netdev, "%s: Not supported link mode(s) requested",
1215 __func__);
1216 err = -EINVAL;
1217 goto out;
1218 }
1219
1220 mlx5_port_query_eth_autoneg(mdev, &an_status, &an_disable_cap,
1221 &an_disable_admin);
1222
1223 an_disable = autoneg == AUTONEG_DISABLE;
1224 an_changes = ((!an_disable && an_disable_admin) ||
1225 (an_disable && !an_disable_admin));
1226
1227 if (!an_changes && link_modes == eproto.admin)
1228 goto out;
1229
1230 mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext);
1231 mlx5_toggle_port_link(mdev);
1232
1233 out:
1234 return err;
1235 }
1236
1237 static int mlx5e_set_link_ksettings(struct net_device *netdev,
1238 const struct ethtool_link_ksettings *link_ksettings)
1239 {
1240 struct mlx5e_priv *priv = netdev_priv(netdev);
1241
1242 return mlx5e_ethtool_set_link_ksettings(priv, link_ksettings);
1243 }
1244
1245 u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv)
1246 {
1247 return sizeof_field(struct mlx5e_rss_params_hash, toeplitz_hash_key);
1248 }
1249
1250 static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
1251 {
1252 struct mlx5e_priv *priv = netdev_priv(netdev);
1253
1254 return mlx5e_ethtool_get_rxfh_key_size(priv);
1255 }
1256
1257 u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv)
1258 {
1259 return MLX5E_INDIR_RQT_SIZE;
1260 }
1261
1262 static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
1263 {
1264 struct mlx5e_priv *priv = netdev_priv(netdev);
1265
1266 return mlx5e_ethtool_get_rxfh_indir_size(priv);
1267 }
1268
1269 static int mlx5e_get_rxfh_context(struct net_device *dev, u32 *indir,
1270 u8 *key, u8 *hfunc, u32 rss_context)
1271 {
1272 struct mlx5e_priv *priv = netdev_priv(dev);
1273 int err;
1274
1275 mutex_lock(&priv->state_lock);
1276 err = mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rss_context, indir, key, hfunc);
1277 mutex_unlock(&priv->state_lock);
1278 return err;
1279 }
1280
1281 static int mlx5e_set_rxfh_context(struct net_device *dev, const u32 *indir,
1282 const u8 *key, const u8 hfunc,
1283 u32 *rss_context, bool delete)
1284 {
1285 struct mlx5e_priv *priv = netdev_priv(dev);
1286 int err;
1287
1288 mutex_lock(&priv->state_lock);
1289 if (delete) {
1290 err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
1291 goto unlock;
1292 }
1293
1294 if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
1295 unsigned int count = priv->channels.params.num_channels;
1296
1297 err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
1298 if (err)
1299 goto unlock;
1300 }
1301
1302 err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, *rss_context, indir, key,
1303 hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc);
1304
1305 unlock:
1306 mutex_unlock(&priv->state_lock);
1307 return err;
1308 }
1309
1310 int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
1311 u8 *hfunc)
1312 {
1313 return mlx5e_get_rxfh_context(netdev, indir, key, hfunc, 0);
1314 }
1315
1316 int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
1317 const u8 *key, const u8 hfunc)
1318 {
1319 struct mlx5e_priv *priv = netdev_priv(dev);
1320 int err;
1321
1322 mutex_lock(&priv->state_lock);
1323 err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, 0, indir, key,
1324 hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc);
1325 mutex_unlock(&priv->state_lock);
1326 return err;
1327 }
1328
1329 #define MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC 100
1330 #define MLX5E_PFC_PREVEN_TOUT_MAX_MSEC 8000
1331 #define MLX5E_PFC_PREVEN_MINOR_PRECENT 85
1332 #define MLX5E_PFC_PREVEN_TOUT_MIN_MSEC 80
1333 #define MLX5E_DEVICE_STALL_MINOR_WATERMARK(critical_tout) \
1334 max_t(u16, MLX5E_PFC_PREVEN_TOUT_MIN_MSEC, \
1335 (critical_tout * MLX5E_PFC_PREVEN_MINOR_PRECENT) / 100)
1336
1337 static int mlx5e_get_pfc_prevention_tout(struct net_device *netdev,
1338 u16 *pfc_prevention_tout)
1339 {
1340 struct mlx5e_priv *priv = netdev_priv(netdev);
1341 struct mlx5_core_dev *mdev = priv->mdev;
1342
1343 if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) ||
1344 !MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
1345 return -EOPNOTSUPP;
1346
1347 return mlx5_query_port_stall_watermark(mdev, pfc_prevention_tout, NULL);
1348 }
1349
1350 static int mlx5e_set_pfc_prevention_tout(struct net_device *netdev,
1351 u16 pfc_preven)
1352 {
1353 struct mlx5e_priv *priv = netdev_priv(netdev);
1354 struct mlx5_core_dev *mdev = priv->mdev;
1355 u16 critical_tout;
1356 u16 minor;
1357
1358 if (!MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) ||
1359 !MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
1360 return -EOPNOTSUPP;
1361
1362 critical_tout = (pfc_preven == PFC_STORM_PREVENTION_AUTO) ?
1363 MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC :
1364 pfc_preven;
1365
1366 if (critical_tout != PFC_STORM_PREVENTION_DISABLE &&
1367 (critical_tout > MLX5E_PFC_PREVEN_TOUT_MAX_MSEC ||
1368 critical_tout < MLX5E_PFC_PREVEN_TOUT_MIN_MSEC)) {
1369 netdev_info(netdev, "%s: pfc prevention tout not in range (%d-%d)\n",
1370 __func__, MLX5E_PFC_PREVEN_TOUT_MIN_MSEC,
1371 MLX5E_PFC_PREVEN_TOUT_MAX_MSEC);
1372 return -EINVAL;
1373 }
1374
1375 minor = MLX5E_DEVICE_STALL_MINOR_WATERMARK(critical_tout);
1376 return mlx5_set_port_stall_watermark(mdev, critical_tout,
1377 minor);
1378 }
1379
1380 static int mlx5e_get_tunable(struct net_device *dev,
1381 const struct ethtool_tunable *tuna,
1382 void *data)
1383 {
1384 int err;
1385
1386 switch (tuna->id) {
1387 case ETHTOOL_PFC_PREVENTION_TOUT:
1388 err = mlx5e_get_pfc_prevention_tout(dev, data);
1389 break;
1390 default:
1391 err = -EINVAL;
1392 break;
1393 }
1394
1395 return err;
1396 }
1397
1398 static int mlx5e_set_tunable(struct net_device *dev,
1399 const struct ethtool_tunable *tuna,
1400 const void *data)
1401 {
1402 struct mlx5e_priv *priv = netdev_priv(dev);
1403 int err;
1404
1405 mutex_lock(&priv->state_lock);
1406
1407 switch (tuna->id) {
1408 case ETHTOOL_PFC_PREVENTION_TOUT:
1409 err = mlx5e_set_pfc_prevention_tout(dev, *(u16 *)data);
1410 break;
1411 default:
1412 err = -EINVAL;
1413 break;
1414 }
1415
1416 mutex_unlock(&priv->state_lock);
1417 return err;
1418 }
1419
1420 static void mlx5e_get_pause_stats(struct net_device *netdev,
1421 struct ethtool_pause_stats *pause_stats)
1422 {
1423 struct mlx5e_priv *priv = netdev_priv(netdev);
1424
1425 mlx5e_stats_pause_get(priv, pause_stats);
1426 }
1427
1428 void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
1429 struct ethtool_pauseparam *pauseparam)
1430 {
1431 struct mlx5_core_dev *mdev = priv->mdev;
1432 int err;
1433
1434 err = mlx5_query_port_pause(mdev, &pauseparam->rx_pause,
1435 &pauseparam->tx_pause);
1436 if (err) {
1437 netdev_err(priv->netdev, "%s: mlx5_query_port_pause failed:0x%x\n",
1438 __func__, err);
1439 }
1440 }
1441
1442 static void mlx5e_get_pauseparam(struct net_device *netdev,
1443 struct ethtool_pauseparam *pauseparam)
1444 {
1445 struct mlx5e_priv *priv = netdev_priv(netdev);
1446
1447 mlx5e_ethtool_get_pauseparam(priv, pauseparam);
1448 }
1449
1450 int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
1451 struct ethtool_pauseparam *pauseparam)
1452 {
1453 struct mlx5_core_dev *mdev = priv->mdev;
1454 int err;
1455
1456 if (!MLX5_CAP_GEN(mdev, vport_group_manager))
1457 return -EOPNOTSUPP;
1458
1459 if (pauseparam->autoneg)
1460 return -EINVAL;
1461
1462 err = mlx5_set_port_pause(mdev,
1463 pauseparam->rx_pause ? 1 : 0,
1464 pauseparam->tx_pause ? 1 : 0);
1465 if (err) {
1466 netdev_err(priv->netdev, "%s: mlx5_set_port_pause failed:0x%x\n",
1467 __func__, err);
1468 }
1469
1470 return err;
1471 }
1472
1473 static int mlx5e_set_pauseparam(struct net_device *netdev,
1474 struct ethtool_pauseparam *pauseparam)
1475 {
1476 struct mlx5e_priv *priv = netdev_priv(netdev);
1477
1478 return mlx5e_ethtool_set_pauseparam(priv, pauseparam);
1479 }
1480
1481 int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
1482 struct ethtool_ts_info *info)
1483 {
1484 struct mlx5_core_dev *mdev = priv->mdev;
1485
1486 info->phc_index = mlx5_clock_get_ptp_index(mdev);
1487
1488 if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz) ||
1489 info->phc_index == -1)
1490 return 0;
1491
1492 info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1493 SOF_TIMESTAMPING_RX_HARDWARE |
1494 SOF_TIMESTAMPING_RAW_HARDWARE;
1495
1496 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1497 BIT(HWTSTAMP_TX_ON);
1498
1499 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1500 BIT(HWTSTAMP_FILTER_ALL);
1501
1502 return 0;
1503 }
1504
1505 static int mlx5e_get_ts_info(struct net_device *dev,
1506 struct ethtool_ts_info *info)
1507 {
1508 struct mlx5e_priv *priv = netdev_priv(dev);
1509
1510 return mlx5e_ethtool_get_ts_info(priv, info);
1511 }
1512
1513 static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
1514 {
1515 __u32 ret = 0;
1516
1517 if (MLX5_CAP_GEN(mdev, wol_g))
1518 ret |= WAKE_MAGIC;
1519
1520 if (MLX5_CAP_GEN(mdev, wol_s))
1521 ret |= WAKE_MAGICSECURE;
1522
1523 if (MLX5_CAP_GEN(mdev, wol_a))
1524 ret |= WAKE_ARP;
1525
1526 if (MLX5_CAP_GEN(mdev, wol_b))
1527 ret |= WAKE_BCAST;
1528
1529 if (MLX5_CAP_GEN(mdev, wol_m))
1530 ret |= WAKE_MCAST;
1531
1532 if (MLX5_CAP_GEN(mdev, wol_u))
1533 ret |= WAKE_UCAST;
1534
1535 if (MLX5_CAP_GEN(mdev, wol_p))
1536 ret |= WAKE_PHY;
1537
1538 return ret;
1539 }
1540
1541 static __u32 mlx5e_reformat_wol_mode_mlx5_to_linux(u8 mode)
1542 {
1543 __u32 ret = 0;
1544
1545 if (mode & MLX5_WOL_MAGIC)
1546 ret |= WAKE_MAGIC;
1547
1548 if (mode & MLX5_WOL_SECURED_MAGIC)
1549 ret |= WAKE_MAGICSECURE;
1550
1551 if (mode & MLX5_WOL_ARP)
1552 ret |= WAKE_ARP;
1553
1554 if (mode & MLX5_WOL_BROADCAST)
1555 ret |= WAKE_BCAST;
1556
1557 if (mode & MLX5_WOL_MULTICAST)
1558 ret |= WAKE_MCAST;
1559
1560 if (mode & MLX5_WOL_UNICAST)
1561 ret |= WAKE_UCAST;
1562
1563 if (mode & MLX5_WOL_PHY_ACTIVITY)
1564 ret |= WAKE_PHY;
1565
1566 return ret;
1567 }
1568
1569 static u8 mlx5e_reformat_wol_mode_linux_to_mlx5(__u32 mode)
1570 {
1571 u8 ret = 0;
1572
1573 if (mode & WAKE_MAGIC)
1574 ret |= MLX5_WOL_MAGIC;
1575
1576 if (mode & WAKE_MAGICSECURE)
1577 ret |= MLX5_WOL_SECURED_MAGIC;
1578
1579 if (mode & WAKE_ARP)
1580 ret |= MLX5_WOL_ARP;
1581
1582 if (mode & WAKE_BCAST)
1583 ret |= MLX5_WOL_BROADCAST;
1584
1585 if (mode & WAKE_MCAST)
1586 ret |= MLX5_WOL_MULTICAST;
1587
1588 if (mode & WAKE_UCAST)
1589 ret |= MLX5_WOL_UNICAST;
1590
1591 if (mode & WAKE_PHY)
1592 ret |= MLX5_WOL_PHY_ACTIVITY;
1593
1594 return ret;
1595 }
1596
1597 static void mlx5e_get_wol(struct net_device *netdev,
1598 struct ethtool_wolinfo *wol)
1599 {
1600 struct mlx5e_priv *priv = netdev_priv(netdev);
1601 struct mlx5_core_dev *mdev = priv->mdev;
1602 u8 mlx5_wol_mode;
1603 int err;
1604
1605 memset(wol, 0, sizeof(*wol));
1606
1607 wol->supported = mlx5e_get_wol_supported(mdev);
1608 if (!wol->supported)
1609 return;
1610
1611 err = mlx5_query_port_wol(mdev, &mlx5_wol_mode);
1612 if (err)
1613 return;
1614
1615 wol->wolopts = mlx5e_reformat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
1616 }
1617
1618 static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1619 {
1620 struct mlx5e_priv *priv = netdev_priv(netdev);
1621 struct mlx5_core_dev *mdev = priv->mdev;
1622 __u32 wol_supported = mlx5e_get_wol_supported(mdev);
1623 u32 mlx5_wol_mode;
1624
1625 if (!wol_supported)
1626 return -EOPNOTSUPP;
1627
1628 if (wol->wolopts & ~wol_supported)
1629 return -EINVAL;
1630
1631 mlx5_wol_mode = mlx5e_reformat_wol_mode_linux_to_mlx5(wol->wolopts);
1632
1633 return mlx5_set_port_wol(mdev, mlx5_wol_mode);
1634 }
1635
1636 static void mlx5e_get_fec_stats(struct net_device *netdev,
1637 struct ethtool_fec_stats *fec_stats)
1638 {
1639 struct mlx5e_priv *priv = netdev_priv(netdev);
1640
1641 mlx5e_stats_fec_get(priv, fec_stats);
1642 }
1643
1644 static int mlx5e_get_fecparam(struct net_device *netdev,
1645 struct ethtool_fecparam *fecparam)
1646 {
1647 struct mlx5e_priv *priv = netdev_priv(netdev);
1648 struct mlx5_core_dev *mdev = priv->mdev;
1649 u16 fec_configured;
1650 u32 fec_active;
1651 int err;
1652
1653 err = mlx5e_get_fec_mode(mdev, &fec_active, &fec_configured);
1654
1655 if (err)
1656 return err;
1657
1658 fecparam->active_fec = pplm2ethtool_fec((unsigned long)fec_active,
1659 sizeof(unsigned long) * BITS_PER_BYTE);
1660
1661 if (!fecparam->active_fec)
1662 return -EOPNOTSUPP;
1663
1664 fecparam->fec = pplm2ethtool_fec((unsigned long)fec_configured,
1665 sizeof(unsigned long) * BITS_PER_BYTE);
1666
1667 return 0;
1668 }
1669
1670 static int mlx5e_set_fecparam(struct net_device *netdev,
1671 struct ethtool_fecparam *fecparam)
1672 {
1673 struct mlx5e_priv *priv = netdev_priv(netdev);
1674 struct mlx5_core_dev *mdev = priv->mdev;
1675 unsigned long fec_bitmap;
1676 u16 fec_policy = 0;
1677 int mode;
1678 int err;
1679
1680 bitmap_from_arr32(&fec_bitmap, &fecparam->fec, sizeof(fecparam->fec) * BITS_PER_BYTE);
1681 if (bitmap_weight(&fec_bitmap, ETHTOOL_FEC_LLRS_BIT + 1) > 1)
1682 return -EOPNOTSUPP;
1683
1684 for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) {
1685 if (!(pplm_fec_2_ethtool[mode] & fecparam->fec))
1686 continue;
1687 fec_policy |= (1 << mode);
1688 break;
1689 }
1690
1691 err = mlx5e_set_fec_mode(mdev, fec_policy);
1692
1693 if (err)
1694 return err;
1695
1696 mlx5_toggle_port_link(mdev);
1697
1698 return 0;
1699 }
1700
1701 static u32 mlx5e_get_msglevel(struct net_device *dev)
1702 {
1703 return ((struct mlx5e_priv *)netdev_priv(dev))->msglevel;
1704 }
1705
1706 static void mlx5e_set_msglevel(struct net_device *dev, u32 val)
1707 {
1708 ((struct mlx5e_priv *)netdev_priv(dev))->msglevel = val;
1709 }
1710
1711 static int mlx5e_set_phys_id(struct net_device *dev,
1712 enum ethtool_phys_id_state state)
1713 {
1714 struct mlx5e_priv *priv = netdev_priv(dev);
1715 struct mlx5_core_dev *mdev = priv->mdev;
1716 u16 beacon_duration;
1717
1718 if (!MLX5_CAP_GEN(mdev, beacon_led))
1719 return -EOPNOTSUPP;
1720
1721 switch (state) {
1722 case ETHTOOL_ID_ACTIVE:
1723 beacon_duration = MLX5_BEACON_DURATION_INF;
1724 break;
1725 case ETHTOOL_ID_INACTIVE:
1726 beacon_duration = MLX5_BEACON_DURATION_OFF;
1727 break;
1728 default:
1729 return -EOPNOTSUPP;
1730 }
1731
1732 return mlx5_set_port_beacon(mdev, beacon_duration);
1733 }
1734
1735 static int mlx5e_get_module_info(struct net_device *netdev,
1736 struct ethtool_modinfo *modinfo)
1737 {
1738 struct mlx5e_priv *priv = netdev_priv(netdev);
1739 struct mlx5_core_dev *dev = priv->mdev;
1740 int size_read = 0;
1741 u8 data[4] = {0};
1742
1743 size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
1744 if (size_read < 2)
1745 return -EIO;
1746
1747
1748 switch (data[0]) {
1749 case MLX5_MODULE_ID_QSFP:
1750 modinfo->type = ETH_MODULE_SFF_8436;
1751 modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
1752 break;
1753 case MLX5_MODULE_ID_QSFP_PLUS:
1754 case MLX5_MODULE_ID_QSFP28:
1755
1756 if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
1757 modinfo->type = ETH_MODULE_SFF_8636;
1758 modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
1759 } else {
1760 modinfo->type = ETH_MODULE_SFF_8436;
1761 modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
1762 }
1763 break;
1764 case MLX5_MODULE_ID_SFP:
1765 modinfo->type = ETH_MODULE_SFF_8472;
1766 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1767 break;
1768 default:
1769 netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
1770 __func__, data[0]);
1771 return -EINVAL;
1772 }
1773
1774 return 0;
1775 }
1776
1777 static int mlx5e_get_module_eeprom(struct net_device *netdev,
1778 struct ethtool_eeprom *ee,
1779 u8 *data)
1780 {
1781 struct mlx5e_priv *priv = netdev_priv(netdev);
1782 struct mlx5_core_dev *mdev = priv->mdev;
1783 int offset = ee->offset;
1784 int size_read;
1785 int i = 0;
1786
1787 if (!ee->len)
1788 return -EINVAL;
1789
1790 memset(data, 0, ee->len);
1791
1792 while (i < ee->len) {
1793 size_read = mlx5_query_module_eeprom(mdev, offset, ee->len - i,
1794 data + i);
1795
1796 if (!size_read)
1797
1798 return 0;
1799
1800 if (size_read < 0) {
1801 netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n",
1802 __func__, size_read);
1803 return size_read;
1804 }
1805
1806 i += size_read;
1807 offset += size_read;
1808 }
1809
1810 return 0;
1811 }
1812
1813 static int mlx5e_get_module_eeprom_by_page(struct net_device *netdev,
1814 const struct ethtool_module_eeprom *page_data,
1815 struct netlink_ext_ack *extack)
1816 {
1817 struct mlx5e_priv *priv = netdev_priv(netdev);
1818 struct mlx5_module_eeprom_query_params query;
1819 struct mlx5_core_dev *mdev = priv->mdev;
1820 u8 *data = page_data->data;
1821 int size_read;
1822 int i = 0;
1823
1824 if (!page_data->length)
1825 return -EINVAL;
1826
1827 memset(data, 0, page_data->length);
1828
1829 query.offset = page_data->offset;
1830 query.i2c_address = page_data->i2c_address;
1831 query.bank = page_data->bank;
1832 query.page = page_data->page;
1833 while (i < page_data->length) {
1834 query.size = page_data->length - i;
1835 size_read = mlx5_query_module_eeprom_by_page(mdev, &query, data + i);
1836
1837
1838 if (!size_read)
1839 return i;
1840
1841 if (size_read == -EINVAL)
1842 return -EINVAL;
1843 if (size_read < 0) {
1844 netdev_err(priv->netdev, "%s: mlx5_query_module_eeprom_by_page failed:0x%x\n",
1845 __func__, size_read);
1846 return i;
1847 }
1848
1849 i += size_read;
1850 query.offset += size_read;
1851 }
1852
1853 return i;
1854 }
1855
1856 int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
1857 struct ethtool_flash *flash)
1858 {
1859 struct mlx5_core_dev *mdev = priv->mdev;
1860 struct net_device *dev = priv->netdev;
1861 const struct firmware *fw;
1862 int err;
1863
1864 if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
1865 return -EOPNOTSUPP;
1866
1867 err = request_firmware_direct(&fw, flash->data, &dev->dev);
1868 if (err)
1869 return err;
1870
1871 dev_hold(dev);
1872 rtnl_unlock();
1873
1874 err = mlx5_firmware_flash(mdev, fw, NULL);
1875 release_firmware(fw);
1876
1877 rtnl_lock();
1878 dev_put(dev);
1879 return err;
1880 }
1881
1882 static int mlx5e_flash_device(struct net_device *dev,
1883 struct ethtool_flash *flash)
1884 {
1885 struct mlx5e_priv *priv = netdev_priv(dev);
1886
1887 return mlx5e_ethtool_flash_device(priv, flash);
1888 }
1889
1890 static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
1891 bool is_rx_cq)
1892 {
1893 struct mlx5e_priv *priv = netdev_priv(netdev);
1894 u8 cq_period_mode, current_cq_period_mode;
1895 struct mlx5e_params new_params;
1896
1897 if (enable && !MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe))
1898 return -EOPNOTSUPP;
1899
1900 cq_period_mode = cqe_mode_to_period_mode(enable);
1901
1902 current_cq_period_mode = is_rx_cq ?
1903 priv->channels.params.rx_cq_moderation.cq_period_mode :
1904 priv->channels.params.tx_cq_moderation.cq_period_mode;
1905
1906 if (cq_period_mode == current_cq_period_mode)
1907 return 0;
1908
1909 new_params = priv->channels.params;
1910 if (is_rx_cq)
1911 mlx5e_set_rx_cq_mode_params(&new_params, cq_period_mode);
1912 else
1913 mlx5e_set_tx_cq_mode_params(&new_params, cq_period_mode);
1914
1915 return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
1916 }
1917
1918 static int set_pflag_tx_cqe_based_moder(struct net_device *netdev, bool enable)
1919 {
1920 return set_pflag_cqe_based_moder(netdev, enable, false);
1921 }
1922
1923 static int set_pflag_rx_cqe_based_moder(struct net_device *netdev, bool enable)
1924 {
1925 return set_pflag_cqe_based_moder(netdev, enable, true);
1926 }
1927
1928 int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val, bool rx_filter)
1929 {
1930 bool curr_val = MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS);
1931 struct mlx5e_params new_params;
1932 int err = 0;
1933
1934 if (!MLX5_CAP_GEN(priv->mdev, cqe_compression))
1935 return new_val ? -EOPNOTSUPP : 0;
1936
1937 if (curr_val == new_val)
1938 return 0;
1939
1940 if (new_val && !mlx5e_profile_feature_cap(priv->profile, PTP_RX) && rx_filter) {
1941 netdev_err(priv->netdev,
1942 "Profile doesn't support enabling of CQE compression while hardware time-stamping is enabled.\n");
1943 return -EINVAL;
1944 }
1945
1946 if (priv->channels.params.packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO) {
1947 netdev_warn(priv->netdev, "Can't set CQE compression with HW-GRO, disable it first.\n");
1948 return -EINVAL;
1949 }
1950
1951 new_params = priv->channels.params;
1952 MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val);
1953 if (rx_filter)
1954 new_params.ptp_rx = new_val;
1955
1956 if (new_params.ptp_rx == priv->channels.params.ptp_rx)
1957 err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
1958 else
1959 err = mlx5e_safe_switch_params(priv, &new_params, mlx5e_ptp_rx_manage_fs_ctx,
1960 &new_params.ptp_rx, true);
1961 if (err)
1962 return err;
1963
1964 mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
1965 MLX5E_GET_PFLAG(&priv->channels.params,
1966 MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
1967
1968 return 0;
1969 }
1970
1971 static int set_pflag_rx_cqe_compress(struct net_device *netdev,
1972 bool enable)
1973 {
1974 struct mlx5e_priv *priv = netdev_priv(netdev);
1975 struct mlx5_core_dev *mdev = priv->mdev;
1976 bool rx_filter;
1977 int err;
1978
1979 if (!MLX5_CAP_GEN(mdev, cqe_compression))
1980 return -EOPNOTSUPP;
1981
1982 rx_filter = priv->tstamp.rx_filter != HWTSTAMP_FILTER_NONE;
1983 err = mlx5e_modify_rx_cqe_compression_locked(priv, enable, rx_filter);
1984 if (err)
1985 return err;
1986
1987 priv->channels.params.rx_cqe_compress_def = enable;
1988
1989 return 0;
1990 }
1991
1992 static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
1993 {
1994 struct mlx5e_priv *priv = netdev_priv(netdev);
1995 struct mlx5_core_dev *mdev = priv->mdev;
1996 struct mlx5e_params new_params;
1997
1998 if (enable) {
1999 if (!mlx5e_check_fragmented_striding_rq_cap(mdev))
2000 return -EOPNOTSUPP;
2001 if (!mlx5e_striding_rq_possible(mdev, &priv->channels.params))
2002 return -EINVAL;
2003 } else if (priv->channels.params.packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
2004 netdev_warn(netdev, "Can't set legacy RQ with HW-GRO/LRO, disable them first\n");
2005 return -EINVAL;
2006 }
2007
2008 new_params = priv->channels.params;
2009
2010 MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_RX_STRIDING_RQ, enable);
2011 mlx5e_set_rq_type(mdev, &new_params);
2012
2013 return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
2014 }
2015
2016 static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
2017 {
2018 struct mlx5e_priv *priv = netdev_priv(netdev);
2019 struct mlx5e_channels *channels = &priv->channels;
2020 struct mlx5e_channel *c;
2021 int i;
2022
2023 if (!test_bit(MLX5E_STATE_OPENED, &priv->state) ||
2024 priv->channels.params.xdp_prog)
2025 return 0;
2026
2027 for (i = 0; i < channels->num; i++) {
2028 c = channels->c[i];
2029 if (enable)
2030 __set_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);
2031 else
2032 __clear_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);
2033 }
2034
2035 return 0;
2036 }
2037
2038 static int set_pflag_tx_mpwqe_common(struct net_device *netdev, u32 flag, bool enable)
2039 {
2040 struct mlx5e_priv *priv = netdev_priv(netdev);
2041 struct mlx5_core_dev *mdev = priv->mdev;
2042 struct mlx5e_params new_params;
2043
2044 if (enable && !mlx5e_tx_mpwqe_supported(mdev))
2045 return -EOPNOTSUPP;
2046
2047 new_params = priv->channels.params;
2048
2049 MLX5E_SET_PFLAG(&new_params, flag, enable);
2050
2051 return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
2052 }
2053
2054 static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
2055 {
2056 return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_XDP_TX_MPWQE, enable);
2057 }
2058
2059 static int set_pflag_skb_tx_mpwqe(struct net_device *netdev, bool enable)
2060 {
2061 return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_SKB_TX_MPWQE, enable);
2062 }
2063
2064 static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable)
2065 {
2066 struct mlx5e_priv *priv = netdev_priv(netdev);
2067 struct mlx5_core_dev *mdev = priv->mdev;
2068 struct mlx5e_params new_params;
2069 int err;
2070
2071 if (!MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn))
2072 return -EOPNOTSUPP;
2073
2074
2075
2076
2077
2078 if (mlx5e_selq_is_htb_enabled(&priv->selq)) {
2079 netdev_err(priv->netdev, "%s: HTB offload is active, cannot change the PTP state\n",
2080 __func__);
2081 return -EINVAL;
2082 }
2083
2084 new_params = priv->channels.params;
2085
2086
2087
2088
2089
2090 if (enable && new_params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
2091 netdev_err(priv->netdev,
2092 "%s: MQPRIO mode channel offload is active, cannot set the TX-port-TS\n",
2093 __func__);
2094 return -EINVAL;
2095 }
2096 MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_PORT_TS, enable);
2097
2098
2099
2100
2101
2102 err = mlx5e_safe_switch_params(priv, &new_params,
2103 mlx5e_num_channels_changed_ctx, NULL, true);
2104 if (!err)
2105 priv->tx_ptp_opened = true;
2106
2107 return err;
2108 }
2109
2110 static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
2111 { "rx_cqe_moder", set_pflag_rx_cqe_based_moder },
2112 { "tx_cqe_moder", set_pflag_tx_cqe_based_moder },
2113 { "rx_cqe_compress", set_pflag_rx_cqe_compress },
2114 { "rx_striding_rq", set_pflag_rx_striding_rq },
2115 { "rx_no_csum_complete", set_pflag_rx_no_csum_complete },
2116 { "xdp_tx_mpwqe", set_pflag_xdp_tx_mpwqe },
2117 { "skb_tx_mpwqe", set_pflag_skb_tx_mpwqe },
2118 { "tx_port_ts", set_pflag_tx_port_ts },
2119 };
2120
2121 static int mlx5e_handle_pflag(struct net_device *netdev,
2122 u32 wanted_flags,
2123 enum mlx5e_priv_flag flag)
2124 {
2125 struct mlx5e_priv *priv = netdev_priv(netdev);
2126 bool enable = !!(wanted_flags & BIT(flag));
2127 u32 changes = wanted_flags ^ priv->channels.params.pflags;
2128 int err;
2129
2130 if (!(changes & BIT(flag)))
2131 return 0;
2132
2133 err = mlx5e_priv_flags[flag].handler(netdev, enable);
2134 if (err) {
2135 netdev_err(netdev, "%s private flag '%s' failed err %d\n",
2136 enable ? "Enable" : "Disable", mlx5e_priv_flags[flag].name, err);
2137 return err;
2138 }
2139
2140 MLX5E_SET_PFLAG(&priv->channels.params, flag, enable);
2141 return 0;
2142 }
2143
2144 static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
2145 {
2146 struct mlx5e_priv *priv = netdev_priv(netdev);
2147 enum mlx5e_priv_flag pflag;
2148 int err;
2149
2150 mutex_lock(&priv->state_lock);
2151
2152 for (pflag = 0; pflag < MLX5E_NUM_PFLAGS; pflag++) {
2153 err = mlx5e_handle_pflag(netdev, pflags, pflag);
2154 if (err)
2155 break;
2156 }
2157
2158 mutex_unlock(&priv->state_lock);
2159
2160
2161 netdev_update_features(netdev);
2162
2163 return err;
2164 }
2165
2166 static u32 mlx5e_get_priv_flags(struct net_device *netdev)
2167 {
2168 struct mlx5e_priv *priv = netdev_priv(netdev);
2169
2170 return priv->channels.params.pflags;
2171 }
2172
2173 int mlx5e_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
2174 u32 *rule_locs)
2175 {
2176 struct mlx5e_priv *priv = netdev_priv(dev);
2177
2178
2179
2180
2181
2182
2183 if (info->cmd == ETHTOOL_GRXRINGS) {
2184 info->data = priv->channels.params.num_channels;
2185 return 0;
2186 }
2187
2188 return mlx5e_ethtool_get_rxnfc(priv, info, rule_locs);
2189 }
2190
2191 int mlx5e_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
2192 {
2193 struct mlx5e_priv *priv = netdev_priv(dev);
2194
2195 return mlx5e_ethtool_set_rxnfc(priv, cmd);
2196 }
2197
2198 static int query_port_status_opcode(struct mlx5_core_dev *mdev, u32 *status_opcode)
2199 {
2200 struct mlx5_ifc_pddr_troubleshooting_page_bits *pddr_troubleshooting_page;
2201 u32 in[MLX5_ST_SZ_DW(pddr_reg)] = {};
2202 u32 out[MLX5_ST_SZ_DW(pddr_reg)];
2203 int err;
2204
2205 MLX5_SET(pddr_reg, in, local_port, 1);
2206 MLX5_SET(pddr_reg, in, page_select,
2207 MLX5_PDDR_REG_PAGE_SELECT_TROUBLESHOOTING_INFO_PAGE);
2208
2209 pddr_troubleshooting_page = MLX5_ADDR_OF(pddr_reg, in, page_data);
2210 MLX5_SET(pddr_troubleshooting_page, pddr_troubleshooting_page,
2211 group_opcode, MLX5_PDDR_REG_TRBLSH_GROUP_OPCODE_MONITOR);
2212 err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
2213 sizeof(out), MLX5_REG_PDDR, 0, 0);
2214 if (err)
2215 return err;
2216
2217 pddr_troubleshooting_page = MLX5_ADDR_OF(pddr_reg, out, page_data);
2218 *status_opcode = MLX5_GET(pddr_troubleshooting_page, pddr_troubleshooting_page,
2219 status_opcode);
2220 return 0;
2221 }
2222
2223 struct mlx5e_ethtool_link_ext_state_opcode_mapping {
2224 u32 status_opcode;
2225 enum ethtool_link_ext_state link_ext_state;
2226 u8 link_ext_substate;
2227 };
2228
2229 static const struct mlx5e_ethtool_link_ext_state_opcode_mapping
2230 mlx5e_link_ext_state_opcode_map[] = {
2231
2232 {2, ETHTOOL_LINK_EXT_STATE_AUTONEG,
2233 ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED},
2234 {3, ETHTOOL_LINK_EXT_STATE_AUTONEG,
2235 ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED},
2236 {4, ETHTOOL_LINK_EXT_STATE_AUTONEG,
2237 ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED},
2238 {36, ETHTOOL_LINK_EXT_STATE_AUTONEG,
2239 ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE},
2240 {38, ETHTOOL_LINK_EXT_STATE_AUTONEG,
2241 ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE},
2242 {39, ETHTOOL_LINK_EXT_STATE_AUTONEG,
2243 ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD},
2244
2245
2246 {5, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
2247 ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED},
2248 {6, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
2249 ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT},
2250 {7, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
2251 ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY},
2252 {8, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 0},
2253 {14, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
2254 ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT},
2255
2256
2257 {9, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
2258 ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK},
2259 {10, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
2260 ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK},
2261 {11, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
2262 ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS},
2263 {12, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
2264 ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED},
2265 {13, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
2266 ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED},
2267
2268
2269 {15, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, 0},
2270 {17, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
2271 ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS},
2272 {42, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
2273 ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE},
2274
2275
2276 {1024, ETHTOOL_LINK_EXT_STATE_NO_CABLE, 0},
2277
2278
2279 {16, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
2280 ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
2281 {20, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
2282 ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
2283 {29, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
2284 ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
2285 {1025, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
2286 ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
2287 {1029, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
2288 ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
2289 {1031, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 0},
2290
2291
2292 {1027, ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, 0},
2293
2294
2295 {23, ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE, 0},
2296
2297
2298 {1032, ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED, 0},
2299
2300
2301 {1030, ETHTOOL_LINK_EXT_STATE_OVERHEAT, 0},
2302 };
2303
2304 static void
2305 mlx5e_set_link_ext_state(struct mlx5e_ethtool_link_ext_state_opcode_mapping
2306 link_ext_state_mapping,
2307 struct ethtool_link_ext_state_info *link_ext_state_info)
2308 {
2309 switch (link_ext_state_mapping.link_ext_state) {
2310 case ETHTOOL_LINK_EXT_STATE_AUTONEG:
2311 link_ext_state_info->autoneg =
2312 link_ext_state_mapping.link_ext_substate;
2313 break;
2314 case ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE:
2315 link_ext_state_info->link_training =
2316 link_ext_state_mapping.link_ext_substate;
2317 break;
2318 case ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH:
2319 link_ext_state_info->link_logical_mismatch =
2320 link_ext_state_mapping.link_ext_substate;
2321 break;
2322 case ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY:
2323 link_ext_state_info->bad_signal_integrity =
2324 link_ext_state_mapping.link_ext_substate;
2325 break;
2326 case ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE:
2327 link_ext_state_info->cable_issue =
2328 link_ext_state_mapping.link_ext_substate;
2329 break;
2330 default:
2331 break;
2332 }
2333
2334 link_ext_state_info->link_ext_state = link_ext_state_mapping.link_ext_state;
2335 }
2336
2337 static int
2338 mlx5e_get_link_ext_state(struct net_device *dev,
2339 struct ethtool_link_ext_state_info *link_ext_state_info)
2340 {
2341 struct mlx5e_ethtool_link_ext_state_opcode_mapping link_ext_state_mapping;
2342 struct mlx5e_priv *priv = netdev_priv(dev);
2343 u32 status_opcode = 0;
2344 int i;
2345
2346
2347
2348
2349 if (netif_carrier_ok(dev))
2350 return -ENODATA;
2351
2352 if (query_port_status_opcode(priv->mdev, &status_opcode) ||
2353 !status_opcode)
2354 return -ENODATA;
2355
2356 for (i = 0; i < ARRAY_SIZE(mlx5e_link_ext_state_opcode_map); i++) {
2357 link_ext_state_mapping = mlx5e_link_ext_state_opcode_map[i];
2358 if (link_ext_state_mapping.status_opcode == status_opcode) {
2359 mlx5e_set_link_ext_state(link_ext_state_mapping,
2360 link_ext_state_info);
2361 return 0;
2362 }
2363 }
2364
2365 return -ENODATA;
2366 }
2367
2368 static void mlx5e_get_eth_phy_stats(struct net_device *netdev,
2369 struct ethtool_eth_phy_stats *phy_stats)
2370 {
2371 struct mlx5e_priv *priv = netdev_priv(netdev);
2372
2373 mlx5e_stats_eth_phy_get(priv, phy_stats);
2374 }
2375
2376 static void mlx5e_get_eth_mac_stats(struct net_device *netdev,
2377 struct ethtool_eth_mac_stats *mac_stats)
2378 {
2379 struct mlx5e_priv *priv = netdev_priv(netdev);
2380
2381 mlx5e_stats_eth_mac_get(priv, mac_stats);
2382 }
2383
2384 static void mlx5e_get_eth_ctrl_stats(struct net_device *netdev,
2385 struct ethtool_eth_ctrl_stats *ctrl_stats)
2386 {
2387 struct mlx5e_priv *priv = netdev_priv(netdev);
2388
2389 mlx5e_stats_eth_ctrl_get(priv, ctrl_stats);
2390 }
2391
2392 static void mlx5e_get_rmon_stats(struct net_device *netdev,
2393 struct ethtool_rmon_stats *rmon_stats,
2394 const struct ethtool_rmon_hist_range **ranges)
2395 {
2396 struct mlx5e_priv *priv = netdev_priv(netdev);
2397
2398 mlx5e_stats_rmon_get(priv, rmon_stats, ranges);
2399 }
2400
2401 const struct ethtool_ops mlx5e_ethtool_ops = {
2402 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
2403 ETHTOOL_COALESCE_MAX_FRAMES |
2404 ETHTOOL_COALESCE_USE_ADAPTIVE |
2405 ETHTOOL_COALESCE_USE_CQE,
2406 .get_drvinfo = mlx5e_get_drvinfo,
2407 .get_link = ethtool_op_get_link,
2408 .get_link_ext_state = mlx5e_get_link_ext_state,
2409 .get_strings = mlx5e_get_strings,
2410 .get_sset_count = mlx5e_get_sset_count,
2411 .get_ethtool_stats = mlx5e_get_ethtool_stats,
2412 .get_ringparam = mlx5e_get_ringparam,
2413 .set_ringparam = mlx5e_set_ringparam,
2414 .get_channels = mlx5e_get_channels,
2415 .set_channels = mlx5e_set_channels,
2416 .get_coalesce = mlx5e_get_coalesce,
2417 .set_coalesce = mlx5e_set_coalesce,
2418 .get_link_ksettings = mlx5e_get_link_ksettings,
2419 .set_link_ksettings = mlx5e_set_link_ksettings,
2420 .get_rxfh_key_size = mlx5e_get_rxfh_key_size,
2421 .get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
2422 .get_rxfh = mlx5e_get_rxfh,
2423 .set_rxfh = mlx5e_set_rxfh,
2424 .get_rxfh_context = mlx5e_get_rxfh_context,
2425 .set_rxfh_context = mlx5e_set_rxfh_context,
2426 .get_rxnfc = mlx5e_get_rxnfc,
2427 .set_rxnfc = mlx5e_set_rxnfc,
2428 .get_tunable = mlx5e_get_tunable,
2429 .set_tunable = mlx5e_set_tunable,
2430 .get_pause_stats = mlx5e_get_pause_stats,
2431 .get_pauseparam = mlx5e_get_pauseparam,
2432 .set_pauseparam = mlx5e_set_pauseparam,
2433 .get_ts_info = mlx5e_get_ts_info,
2434 .set_phys_id = mlx5e_set_phys_id,
2435 .get_wol = mlx5e_get_wol,
2436 .set_wol = mlx5e_set_wol,
2437 .get_module_info = mlx5e_get_module_info,
2438 .get_module_eeprom = mlx5e_get_module_eeprom,
2439 .get_module_eeprom_by_page = mlx5e_get_module_eeprom_by_page,
2440 .flash_device = mlx5e_flash_device,
2441 .get_priv_flags = mlx5e_get_priv_flags,
2442 .set_priv_flags = mlx5e_set_priv_flags,
2443 .self_test = mlx5e_self_test,
2444 .get_msglevel = mlx5e_get_msglevel,
2445 .set_msglevel = mlx5e_set_msglevel,
2446 .get_fec_stats = mlx5e_get_fec_stats,
2447 .get_fecparam = mlx5e_get_fecparam,
2448 .set_fecparam = mlx5e_set_fecparam,
2449 .get_eth_phy_stats = mlx5e_get_eth_phy_stats,
2450 .get_eth_mac_stats = mlx5e_get_eth_mac_stats,
2451 .get_eth_ctrl_stats = mlx5e_get_eth_ctrl_stats,
2452 .get_rmon_stats = mlx5e_get_rmon_stats,
2453 };