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