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