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