]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Merge remote-tracking branch 'asoc/topic/pcm512x' into asoc-next
[mirror_ubuntu-focal-kernel.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_ethtool.c
CommitLineData
f62b8bb8
AV
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
076b0936
ES
35void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
36 struct ethtool_drvinfo *drvinfo)
f62b8bb8 37{
f62b8bb8
AV
38 struct mlx5_core_dev *mdev = priv->mdev;
39
40 strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
7913d205 41 strlcpy(drvinfo->version, DRIVER_VERSION,
f62b8bb8
AV
42 sizeof(drvinfo->version));
43 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
84e11edb
IK
44 "%d.%d.%04d (%.16s)",
45 fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev),
46 mdev->board_id);
f62b8bb8
AV
47 strlcpy(drvinfo->bus_info, pci_name(mdev->pdev),
48 sizeof(drvinfo->bus_info));
49}
50
076b0936
ES
51static void mlx5e_get_drvinfo(struct net_device *dev,
52 struct ethtool_drvinfo *drvinfo)
53{
54 struct mlx5e_priv *priv = netdev_priv(dev);
55
56 mlx5e_ethtool_get_drvinfo(priv, drvinfo);
57}
58
665bc539
GP
59struct ptys2ethtool_config {
60 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
61 __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
f62b8bb8 62 u32 speed;
f62b8bb8
AV
63};
64
665bc539
GP
65static struct ptys2ethtool_config ptys2ethtool_table[MLX5E_LINK_MODES_NUMBER];
66
67#define MLX5_BUILD_PTYS2ETHTOOL_CONFIG(reg_, speed_, ...) \
68 ({ \
69 struct ptys2ethtool_config *cfg; \
70 const unsigned int modes[] = { __VA_ARGS__ }; \
71 unsigned int i; \
72 cfg = &ptys2ethtool_table[reg_]; \
73 cfg->speed = speed_; \
74 bitmap_zero(cfg->supported, \
75 __ETHTOOL_LINK_MODE_MASK_NBITS); \
76 bitmap_zero(cfg->advertised, \
77 __ETHTOOL_LINK_MODE_MASK_NBITS); \
78 for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) { \
79 __set_bit(modes[i], cfg->supported); \
80 __set_bit(modes[i], cfg->advertised); \
81 } \
82 })
83
84void mlx5e_build_ptys2ethtool_map(void)
85{
86 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_CX_SGMII, SPEED_1000,
87 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
88 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_KX, SPEED_1000,
89 ETHTOOL_LINK_MODE_1000baseKX_Full_BIT);
90 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CX4, SPEED_10000,
91 ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
92 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KX4, SPEED_10000,
93 ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT);
94 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_KR, SPEED_10000,
95 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
96 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_20GBASE_KR2, SPEED_20000,
97 ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT);
98 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_CR4, SPEED_40000,
99 ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT);
100 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_KR4, SPEED_40000,
101 ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT);
102 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_56GBASE_R4, SPEED_56000,
103 ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT);
104 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_CR, SPEED_10000,
105 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
106 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_SR, SPEED_10000,
107 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
108 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_ER, SPEED_10000,
109 ETHTOOL_LINK_MODE_10000baseKR_Full_BIT);
110 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_SR4, SPEED_40000,
111 ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT);
112 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_40GBASE_LR4, SPEED_40000,
113 ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT);
114 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_SR2, SPEED_50000,
115 ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT);
116 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_CR4, SPEED_100000,
117 ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT);
118 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_SR4, SPEED_100000,
119 ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT);
120 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_KR4, SPEED_100000,
121 ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT);
122 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4, SPEED_100000,
123 ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
124 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T, SPEED_10000,
125 ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
126 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR, SPEED_25000,
127 ETHTOOL_LINK_MODE_25000baseCR_Full_BIT);
128 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_KR, SPEED_25000,
129 ETHTOOL_LINK_MODE_25000baseKR_Full_BIT);
130 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_SR, SPEED_25000,
131 ETHTOOL_LINK_MODE_25000baseSR_Full_BIT);
132 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_CR2, SPEED_50000,
133 ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT);
134 MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_50GBASE_KR2, SPEED_50000,
135 ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT);
136}
137
076b0936 138int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
f62b8bb8 139{
c0752f2b
KH
140 int i, num_stats = 0;
141
f62b8bb8
AV
142 switch (sset) {
143 case ETH_SS_STATS:
c0752f2b
KH
144 for (i = 0; i < mlx5e_num_stats_grps; i++)
145 num_stats += mlx5e_stats_grps[i].get_num_stats(priv);
1fe85006 146 return num_stats;
4e59e288
GP
147 case ETH_SS_PRIV_FLAGS:
148 return ARRAY_SIZE(mlx5e_priv_flags);
d605d668
KH
149 case ETH_SS_TEST:
150 return mlx5e_self_test_num(priv);
f62b8bb8
AV
151 /* fallthrough */
152 default:
153 return -EOPNOTSUPP;
154 }
155}
156
076b0936
ES
157static int mlx5e_get_sset_count(struct net_device *dev, int sset)
158{
159 struct mlx5e_priv *priv = netdev_priv(dev);
160
161 return mlx5e_ethtool_get_sset_count(priv, sset);
162}
163
c045deef 164static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, u8 *data)
9218b44d 165{
1fe85006 166 int i, idx = 0;
9218b44d 167
c0752f2b
KH
168 for (i = 0; i < mlx5e_num_stats_grps; i++)
169 idx = mlx5e_stats_grps[i].fill_strings(priv, data, idx);
9218b44d
GP
170}
171
c045deef 172void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv, u32 stringset, u8 *data)
f62b8bb8 173{
4e59e288 174 int i;
f62b8bb8
AV
175
176 switch (stringset) {
177 case ETH_SS_PRIV_FLAGS:
4e59e288
GP
178 for (i = 0; i < ARRAY_SIZE(mlx5e_priv_flags); i++)
179 strcpy(data + i * ETH_GSTRING_LEN, mlx5e_priv_flags[i]);
f62b8bb8
AV
180 break;
181
182 case ETH_SS_TEST:
d605d668
KH
183 for (i = 0; i < mlx5e_self_test_num(priv); i++)
184 strcpy(data + i * ETH_GSTRING_LEN,
185 mlx5e_self_tests[i]);
f62b8bb8
AV
186 break;
187
188 case ETH_SS_STATS:
9218b44d 189 mlx5e_fill_stats_strings(priv, data);
f62b8bb8
AV
190 break;
191 }
192}
193
c045deef 194static void mlx5e_get_strings(struct net_device *dev, u32 stringset, u8 *data)
f62b8bb8
AV
195{
196 struct mlx5e_priv *priv = netdev_priv(dev);
076b0936
ES
197
198 mlx5e_ethtool_get_strings(priv, stringset, data);
199}
200
201void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
202 struct ethtool_stats *stats, u64 *data)
203{
1fe85006 204 int i, idx = 0;
f62b8bb8
AV
205
206 if (!data)
207 return;
208
209 mutex_lock(&priv->state_lock);
210 if (test_bit(MLX5E_STATE_OPENED, &priv->state))
3834a5e6 211 mlx5e_update_stats(priv, true);
f62b8bb8
AV
212 mutex_unlock(&priv->state_lock);
213
c0752f2b
KH
214 for (i = 0; i < mlx5e_num_stats_grps; i++)
215 idx = mlx5e_stats_grps[i].fill_stats(priv, data, idx);
f62b8bb8
AV
216}
217
076b0936
ES
218static void mlx5e_get_ethtool_stats(struct net_device *dev,
219 struct ethtool_stats *stats,
220 u64 *data)
221{
222 struct mlx5e_priv *priv = netdev_priv(dev);
223
224 mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
225}
226
cc8e9ebf
EBE
227static u32 mlx5e_rx_wqes_to_packets(struct mlx5e_priv *priv, int rq_wq_type,
228 int num_wqe)
229{
230 int packets_per_wqe;
231 int stride_size;
232 int num_strides;
233 int wqe_size;
234
235 if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
236 return num_wqe;
237
6a9764ef
SM
238 stride_size = 1 << priv->channels.params.mpwqe_log_stride_sz;
239 num_strides = 1 << priv->channels.params.mpwqe_log_num_strides;
cc8e9ebf
EBE
240 wqe_size = stride_size * num_strides;
241
242 packets_per_wqe = wqe_size /
243 ALIGN(ETH_DATA_LEN, stride_size);
244 return (1 << (order_base_2(num_wqe * packets_per_wqe) - 1));
245}
246
247static u32 mlx5e_packets_to_rx_wqes(struct mlx5e_priv *priv, int rq_wq_type,
248 int num_packets)
249{
250 int packets_per_wqe;
251 int stride_size;
252 int num_strides;
253 int wqe_size;
254 int num_wqes;
255
256 if (rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
257 return num_packets;
258
6a9764ef
SM
259 stride_size = 1 << priv->channels.params.mpwqe_log_stride_sz;
260 num_strides = 1 << priv->channels.params.mpwqe_log_num_strides;
cc8e9ebf
EBE
261 wqe_size = stride_size * num_strides;
262
263 num_packets = (1 << order_base_2(num_packets));
264
265 packets_per_wqe = wqe_size /
266 ALIGN(ETH_DATA_LEN, stride_size);
267 num_wqes = DIV_ROUND_UP(num_packets, packets_per_wqe);
268 return 1 << (order_base_2(num_wqes));
269}
270
076b0936
ES
271void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
272 struct ethtool_ringparam *param)
f62b8bb8 273{
6a9764ef 274 int rq_wq_type = priv->channels.params.rq_wq_type;
f62b8bb8 275
cc8e9ebf
EBE
276 param->rx_max_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type,
277 1 << mlx5_max_log_rq_size(rq_wq_type));
f62b8bb8 278 param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
cc8e9ebf 279 param->rx_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type,
6a9764ef
SM
280 1 << priv->channels.params.log_rq_size);
281 param->tx_pending = 1 << priv->channels.params.log_sq_size;
f62b8bb8
AV
282}
283
076b0936
ES
284static void mlx5e_get_ringparam(struct net_device *dev,
285 struct ethtool_ringparam *param)
f62b8bb8
AV
286{
287 struct mlx5e_priv *priv = netdev_priv(dev);
076b0936
ES
288
289 mlx5e_ethtool_get_ringparam(priv, param);
290}
291
292int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
293 struct ethtool_ringparam *param)
294{
6a9764ef 295 int rq_wq_type = priv->channels.params.rq_wq_type;
546f18ed 296 struct mlx5e_channels new_channels = {};
cc8e9ebf
EBE
297 u32 rx_pending_wqes;
298 u32 min_rq_size;
299 u32 max_rq_size;
f62b8bb8
AV
300 u8 log_rq_size;
301 u8 log_sq_size;
fe4c988b 302 u32 num_mtts;
f62b8bb8
AV
303 int err = 0;
304
305 if (param->rx_jumbo_pending) {
076b0936 306 netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n",
f62b8bb8
AV
307 __func__);
308 return -EINVAL;
309 }
310 if (param->rx_mini_pending) {
076b0936 311 netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n",
f62b8bb8
AV
312 __func__);
313 return -EINVAL;
314 }
cc8e9ebf
EBE
315
316 min_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type,
317 1 << mlx5_min_log_rq_size(rq_wq_type));
318 max_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type,
319 1 << mlx5_max_log_rq_size(rq_wq_type));
320 rx_pending_wqes = mlx5e_packets_to_rx_wqes(priv, rq_wq_type,
321 param->rx_pending);
322
323 if (param->rx_pending < min_rq_size) {
076b0936 324 netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n",
f62b8bb8 325 __func__, param->rx_pending,
cc8e9ebf 326 min_rq_size);
f62b8bb8
AV
327 return -EINVAL;
328 }
cc8e9ebf 329 if (param->rx_pending > max_rq_size) {
076b0936 330 netdev_info(priv->netdev, "%s: rx_pending (%d) > max (%d)\n",
f62b8bb8 331 __func__, param->rx_pending,
cc8e9ebf 332 max_rq_size);
f62b8bb8
AV
333 return -EINVAL;
334 }
fe4c988b 335
ec8b9981 336 num_mtts = MLX5E_REQUIRED_MTTS(rx_pending_wqes);
6a9764ef 337 if (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
fe4c988b 338 !MLX5E_VALID_NUM_MTTS(num_mtts)) {
076b0936 339 netdev_info(priv->netdev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n",
fe4c988b
SM
340 __func__, param->rx_pending);
341 return -EINVAL;
342 }
343
f62b8bb8 344 if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
076b0936 345 netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
f62b8bb8
AV
346 __func__, param->tx_pending,
347 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
348 return -EINVAL;
349 }
350 if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) {
076b0936 351 netdev_info(priv->netdev, "%s: tx_pending (%d) > max (%d)\n",
f62b8bb8
AV
352 __func__, param->tx_pending,
353 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE);
354 return -EINVAL;
355 }
356
cc8e9ebf 357 log_rq_size = order_base_2(rx_pending_wqes);
f62b8bb8 358 log_sq_size = order_base_2(param->tx_pending);
f62b8bb8 359
6a9764ef
SM
360 if (log_rq_size == priv->channels.params.log_rq_size &&
361 log_sq_size == priv->channels.params.log_sq_size)
f62b8bb8
AV
362 return 0;
363
364 mutex_lock(&priv->state_lock);
98e81b0a 365
546f18ed
SM
366 new_channels.params = priv->channels.params;
367 new_channels.params.log_rq_size = log_rq_size;
368 new_channels.params.log_sq_size = log_sq_size;
98e81b0a 369
546f18ed
SM
370 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
371 priv->channels.params = new_channels.params;
372 goto unlock;
373 }
98e81b0a 374
546f18ed
SM
375 err = mlx5e_open_channels(priv, &new_channels);
376 if (err)
377 goto unlock;
378
2e20a151 379 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
98e81b0a 380
546f18ed 381unlock:
f62b8bb8
AV
382 mutex_unlock(&priv->state_lock);
383
384 return err;
385}
386
076b0936
ES
387static int mlx5e_set_ringparam(struct net_device *dev,
388 struct ethtool_ringparam *param)
f62b8bb8
AV
389{
390 struct mlx5e_priv *priv = netdev_priv(dev);
f62b8bb8 391
076b0936
ES
392 return mlx5e_ethtool_set_ringparam(priv, param);
393}
394
395void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
396 struct ethtool_channels *ch)
397{
b4e029da 398 ch->max_combined = priv->profile->max_nch(priv->mdev);
6a9764ef 399 ch->combined_count = priv->channels.params.num_channels;
f62b8bb8
AV
400}
401
076b0936
ES
402static void mlx5e_get_channels(struct net_device *dev,
403 struct ethtool_channels *ch)
f62b8bb8
AV
404{
405 struct mlx5e_priv *priv = netdev_priv(dev);
076b0936
ES
406
407 mlx5e_ethtool_get_channels(priv, ch);
408}
409
410int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
411 struct ethtool_channels *ch)
412{
f62b8bb8 413 unsigned int count = ch->combined_count;
55c2503d 414 struct mlx5e_channels new_channels = {};
45bf454a 415 bool arfs_enabled;
f62b8bb8
AV
416 int err = 0;
417
418 if (!count) {
076b0936 419 netdev_info(priv->netdev, "%s: combined_count=0 not supported\n",
f62b8bb8
AV
420 __func__);
421 return -EINVAL;
422 }
f62b8bb8 423
6a9764ef 424 if (priv->channels.params.num_channels == count)
f62b8bb8
AV
425 return 0;
426
427 mutex_lock(&priv->state_lock);
98e81b0a 428
55c2503d
SM
429 new_channels.params = priv->channels.params;
430 new_channels.params.num_channels = count;
5a8e1267 431 if (!netif_is_rxfh_configured(priv->netdev))
d4b6c488 432 mlx5e_build_default_indir_rqt(new_channels.params.indirection_rqt,
5a8e1267 433 MLX5E_INDIR_RQT_SIZE, count);
55c2503d
SM
434
435 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
436 priv->channels.params = new_channels.params;
437 goto out;
438 }
439
440 /* Create fresh channels with new parameters */
441 err = mlx5e_open_channels(priv, &new_channels);
442 if (err)
443 goto out;
98e81b0a 444
076b0936 445 arfs_enabled = priv->netdev->features & NETIF_F_NTUPLE;
45bf454a
MG
446 if (arfs_enabled)
447 mlx5e_arfs_disable(priv);
448
55c2503d 449 /* Switch to new channels, set new parameters and close old ones */
2e20a151 450 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
45bf454a
MG
451
452 if (arfs_enabled) {
453 err = mlx5e_arfs_enable(priv);
454 if (err)
076b0936 455 netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
45bf454a
MG
456 __func__, err);
457 }
98e81b0a 458
45bf454a 459out:
f62b8bb8
AV
460 mutex_unlock(&priv->state_lock);
461
462 return err;
463}
464
076b0936
ES
465static int mlx5e_set_channels(struct net_device *dev,
466 struct ethtool_channels *ch)
f62b8bb8 467{
076b0936
ES
468 struct mlx5e_priv *priv = netdev_priv(dev);
469
470 return mlx5e_ethtool_set_channels(priv, ch);
471}
f62b8bb8 472
076b0936
ES
473int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
474 struct ethtool_coalesce *coal)
475{
7524a5d8 476 if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
9eb78923 477 return -EOPNOTSUPP;
7524a5d8 478
6a9764ef
SM
479 coal->rx_coalesce_usecs = priv->channels.params.rx_cq_moderation.usec;
480 coal->rx_max_coalesced_frames = priv->channels.params.rx_cq_moderation.pkts;
481 coal->tx_coalesce_usecs = priv->channels.params.tx_cq_moderation.usec;
482 coal->tx_max_coalesced_frames = priv->channels.params.tx_cq_moderation.pkts;
483 coal->use_adaptive_rx_coalesce = priv->channels.params.rx_am_enabled;
f62b8bb8
AV
484
485 return 0;
486}
487
076b0936
ES
488static int mlx5e_get_coalesce(struct net_device *netdev,
489 struct ethtool_coalesce *coal)
490{
491 struct mlx5e_priv *priv = netdev_priv(netdev);
492
493 return mlx5e_ethtool_get_coalesce(priv, coal);
494}
495
546f18ed
SM
496static void
497mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
f62b8bb8 498{
f62b8bb8 499 struct mlx5_core_dev *mdev = priv->mdev;
f62b8bb8
AV
500 int tc;
501 int i;
502
ff9c852f
SM
503 for (i = 0; i < priv->channels.num; ++i) {
504 struct mlx5e_channel *c = priv->channels.c[i];
f62b8bb8
AV
505
506 for (tc = 0; tc < c->num_tc; tc++) {
507 mlx5_core_modify_cq_moderation(mdev,
508 &c->sq[tc].cq.mcq,
509 coal->tx_coalesce_usecs,
510 coal->tx_max_coalesced_frames);
511 }
512
513 mlx5_core_modify_cq_moderation(mdev, &c->rq.cq.mcq,
514 coal->rx_coalesce_usecs,
515 coal->rx_max_coalesced_frames);
516 }
546f18ed 517}
f62b8bb8 518
076b0936
ES
519int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
520 struct ethtool_coalesce *coal)
546f18ed 521{
546f18ed
SM
522 struct mlx5_core_dev *mdev = priv->mdev;
523 struct mlx5e_channels new_channels = {};
524 int err = 0;
525 bool reset;
cb3c7fd4 526
546f18ed
SM
527 if (!MLX5_CAP_GEN(mdev, cq_moderation))
528 return -EOPNOTSUPP;
529
530 mutex_lock(&priv->state_lock);
531 new_channels.params = priv->channels.params;
532
533 new_channels.params.tx_cq_moderation.usec = coal->tx_coalesce_usecs;
534 new_channels.params.tx_cq_moderation.pkts = coal->tx_max_coalesced_frames;
535 new_channels.params.rx_cq_moderation.usec = coal->rx_coalesce_usecs;
536 new_channels.params.rx_cq_moderation.pkts = coal->rx_max_coalesced_frames;
537 new_channels.params.rx_am_enabled = !!coal->use_adaptive_rx_coalesce;
538
539 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
540 priv->channels.params = new_channels.params;
541 goto out;
542 }
543 /* we are opened */
544
545 reset = !!coal->use_adaptive_rx_coalesce != priv->channels.params.rx_am_enabled;
546 if (!reset) {
547 mlx5e_set_priv_channels_coalesce(priv, coal);
548 priv->channels.params = new_channels.params;
549 goto out;
550 }
551
552 /* open fresh channels with new coal parameters */
553 err = mlx5e_open_channels(priv, &new_channels);
554 if (err)
555 goto out;
556
2e20a151 557 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
546f18ed
SM
558
559out:
2fcb92fb 560 mutex_unlock(&priv->state_lock);
cb3c7fd4 561 return err;
f62b8bb8
AV
562}
563
076b0936
ES
564static int mlx5e_set_coalesce(struct net_device *netdev,
565 struct ethtool_coalesce *coal)
566{
567 struct mlx5e_priv *priv = netdev_priv(netdev);
568
569 return mlx5e_ethtool_set_coalesce(priv, coal);
570}
571
665bc539
GP
572static void ptys2ethtool_supported_link(unsigned long *supported_modes,
573 u32 eth_proto_cap)
f62b8bb8 574{
7abc2110 575 unsigned long proto_cap = eth_proto_cap;
665bc539 576 int proto;
f62b8bb8 577
7abc2110 578 for_each_set_bit(proto, &proto_cap, MLX5E_LINK_MODES_NUMBER)
665bc539
GP
579 bitmap_or(supported_modes, supported_modes,
580 ptys2ethtool_table[proto].supported,
581 __ETHTOOL_LINK_MODE_MASK_NBITS);
f62b8bb8
AV
582}
583
665bc539
GP
584static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
585 u32 eth_proto_cap)
f62b8bb8 586{
7abc2110 587 unsigned long proto_cap = eth_proto_cap;
665bc539 588 int proto;
f62b8bb8 589
7abc2110 590 for_each_set_bit(proto, &proto_cap, MLX5E_LINK_MODES_NUMBER)
665bc539
GP
591 bitmap_or(advertising_modes, advertising_modes,
592 ptys2ethtool_table[proto].advertised,
593 __ETHTOOL_LINK_MODE_MASK_NBITS);
f62b8bb8
AV
594}
595
46e9d0b6
EBE
596static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings *link_ksettings,
597 u32 eth_proto_cap,
598 u8 connector_type)
f62b8bb8 599{
46e9d0b6
EBE
600 if (!connector_type || connector_type >= MLX5E_CONNECTOR_TYPE_NUMBER) {
601 if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
602 | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
603 | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
604 | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
605 | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
606 | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
607 ethtool_link_ksettings_add_link_mode(link_ksettings,
608 supported,
609 FIBRE);
610 ethtool_link_ksettings_add_link_mode(link_ksettings,
611 advertising,
612 FIBRE);
613 }
614
615 if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
616 | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
617 | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
618 | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
619 | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
620 ethtool_link_ksettings_add_link_mode(link_ksettings,
621 supported,
622 Backplane);
623 ethtool_link_ksettings_add_link_mode(link_ksettings,
624 advertising,
625 Backplane);
626 }
627 return;
f62b8bb8
AV
628 }
629
46e9d0b6
EBE
630 switch (connector_type) {
631 case MLX5E_PORT_TP:
632 ethtool_link_ksettings_add_link_mode(link_ksettings,
633 supported, TP);
634 ethtool_link_ksettings_add_link_mode(link_ksettings,
635 advertising, TP);
636 break;
637 case MLX5E_PORT_AUI:
638 ethtool_link_ksettings_add_link_mode(link_ksettings,
639 supported, AUI);
640 ethtool_link_ksettings_add_link_mode(link_ksettings,
641 advertising, AUI);
642 break;
643 case MLX5E_PORT_BNC:
644 ethtool_link_ksettings_add_link_mode(link_ksettings,
645 supported, BNC);
646 ethtool_link_ksettings_add_link_mode(link_ksettings,
647 advertising, BNC);
648 break;
649 case MLX5E_PORT_MII:
650 ethtool_link_ksettings_add_link_mode(link_ksettings,
651 supported, MII);
652 ethtool_link_ksettings_add_link_mode(link_ksettings,
653 advertising, MII);
654 break;
655 case MLX5E_PORT_FIBRE:
656 ethtool_link_ksettings_add_link_mode(link_ksettings,
657 supported, FIBRE);
658 ethtool_link_ksettings_add_link_mode(link_ksettings,
659 advertising, FIBRE);
660 break;
661 case MLX5E_PORT_DA:
662 ethtool_link_ksettings_add_link_mode(link_ksettings,
663 supported, Backplane);
664 ethtool_link_ksettings_add_link_mode(link_ksettings,
665 advertising, Backplane);
666 break;
667 case MLX5E_PORT_NONE:
668 case MLX5E_PORT_OTHER:
669 default:
670 break;
f62b8bb8 671 }
f62b8bb8
AV
672}
673
b797a684
SM
674int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
675{
676 u32 max_speed = 0;
677 u32 proto_cap;
678 int err;
679 int i;
680
681 err = mlx5_query_port_proto_cap(mdev, &proto_cap, MLX5_PTYS_EN);
682 if (err)
683 return err;
684
685 for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i)
686 if (proto_cap & MLX5E_PROT_MASK(i))
687 max_speed = max(max_speed, ptys2ethtool_table[i].speed);
688
689 *speed = max_speed;
690 return 0;
691}
692
f62b8bb8
AV
693static void get_speed_duplex(struct net_device *netdev,
694 u32 eth_proto_oper,
665bc539 695 struct ethtool_link_ksettings *link_ksettings)
f62b8bb8
AV
696{
697 int i;
698 u32 speed = SPEED_UNKNOWN;
699 u8 duplex = DUPLEX_UNKNOWN;
700
701 if (!netif_carrier_ok(netdev))
702 goto out;
703
704 for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
705 if (eth_proto_oper & MLX5E_PROT_MASK(i)) {
706 speed = ptys2ethtool_table[i].speed;
707 duplex = DUPLEX_FULL;
708 break;
709 }
710 }
711out:
665bc539
GP
712 link_ksettings->base.speed = speed;
713 link_ksettings->base.duplex = duplex;
f62b8bb8
AV
714}
715
665bc539
GP
716static void get_supported(u32 eth_proto_cap,
717 struct ethtool_link_ksettings *link_ksettings)
f62b8bb8 718{
665bc539
GP
719 unsigned long *supported = link_ksettings->link_modes.supported;
720
665bc539
GP
721 ptys2ethtool_supported_link(supported, eth_proto_cap);
722 ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
f62b8bb8
AV
723}
724
725static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
665bc539
GP
726 u8 rx_pause,
727 struct ethtool_link_ksettings *link_ksettings)
f62b8bb8 728{
665bc539
GP
729 unsigned long *advertising = link_ksettings->link_modes.advertising;
730
731 ptys2ethtool_adver_link(advertising, eth_proto_cap);
e3c19503 732 if (rx_pause)
665bc539
GP
733 ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
734 if (tx_pause ^ rx_pause)
735 ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
f62b8bb8
AV
736}
737
5b4793f8
EBE
738static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = {
739 [MLX5E_PORT_UNKNOWN] = PORT_OTHER,
740 [MLX5E_PORT_NONE] = PORT_NONE,
741 [MLX5E_PORT_TP] = PORT_TP,
742 [MLX5E_PORT_AUI] = PORT_AUI,
743 [MLX5E_PORT_BNC] = PORT_BNC,
744 [MLX5E_PORT_MII] = PORT_MII,
745 [MLX5E_PORT_FIBRE] = PORT_FIBRE,
746 [MLX5E_PORT_DA] = PORT_DA,
747 [MLX5E_PORT_OTHER] = PORT_OTHER,
748 };
749
750static u8 get_connector_port(u32 eth_proto, u8 connector_type)
f62b8bb8 751{
5b4793f8
EBE
752 if (connector_type && connector_type < MLX5E_CONNECTOR_TYPE_NUMBER)
753 return ptys2connector_type[connector_type];
754
61bf2125
OG
755 if (eth_proto &
756 (MLX5E_PROT_MASK(MLX5E_10GBASE_SR) |
757 MLX5E_PROT_MASK(MLX5E_40GBASE_SR4) |
758 MLX5E_PROT_MASK(MLX5E_100GBASE_SR4) |
759 MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
760 return PORT_FIBRE;
f62b8bb8
AV
761 }
762
61bf2125
OG
763 if (eth_proto &
764 (MLX5E_PROT_MASK(MLX5E_40GBASE_CR4) |
765 MLX5E_PROT_MASK(MLX5E_10GBASE_CR) |
766 MLX5E_PROT_MASK(MLX5E_100GBASE_CR4))) {
767 return PORT_DA;
f62b8bb8
AV
768 }
769
61bf2125
OG
770 if (eth_proto &
771 (MLX5E_PROT_MASK(MLX5E_10GBASE_KX4) |
772 MLX5E_PROT_MASK(MLX5E_10GBASE_KR) |
773 MLX5E_PROT_MASK(MLX5E_40GBASE_KR4) |
774 MLX5E_PROT_MASK(MLX5E_100GBASE_KR4))) {
775 return PORT_NONE;
f62b8bb8
AV
776 }
777
778 return PORT_OTHER;
779}
780
665bc539
GP
781static void get_lp_advertising(u32 eth_proto_lp,
782 struct ethtool_link_ksettings *link_ksettings)
f62b8bb8 783{
665bc539
GP
784 unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising;
785
786 ptys2ethtool_adver_link(lp_advertising, eth_proto_lp);
f62b8bb8
AV
787}
788
665bc539
GP
789static int mlx5e_get_link_ksettings(struct net_device *netdev,
790 struct ethtool_link_ksettings *link_ksettings)
f62b8bb8
AV
791{
792 struct mlx5e_priv *priv = netdev_priv(netdev);
793 struct mlx5_core_dev *mdev = priv->mdev;
c4f287c4 794 u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
b383b544
GP
795 u32 rx_pause = 0;
796 u32 tx_pause = 0;
f62b8bb8
AV
797 u32 eth_proto_cap;
798 u32 eth_proto_admin;
799 u32 eth_proto_lp;
800 u32 eth_proto_oper;
52244d96
GP
801 u8 an_disable_admin;
802 u8 an_status;
5b4793f8 803 u8 connector_type;
f62b8bb8
AV
804 int err;
805
a05bdefa 806 err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
f62b8bb8
AV
807 if (err) {
808 netdev_err(netdev, "%s: query port ptys failed: %d\n",
809 __func__, err);
810 goto err_query_ptys;
811 }
812
52244d96
GP
813 eth_proto_cap = MLX5_GET(ptys_reg, out, eth_proto_capability);
814 eth_proto_admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
815 eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
816 eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
817 an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin);
818 an_status = MLX5_GET(ptys_reg, out, an_status);
5b4793f8 819 connector_type = MLX5_GET(ptys_reg, out, connector_type);
f62b8bb8 820
b383b544
GP
821 mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
822
665bc539
GP
823 ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
824 ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
f62b8bb8 825
665bc539 826 get_supported(eth_proto_cap, link_ksettings);
b383b544 827 get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings);
665bc539 828 get_speed_duplex(netdev, eth_proto_oper, link_ksettings);
f62b8bb8
AV
829
830 eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
831
5b4793f8
EBE
832 link_ksettings->base.port = get_connector_port(eth_proto_oper,
833 connector_type);
46e9d0b6
EBE
834 ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin,
835 connector_type);
665bc539 836 get_lp_advertising(eth_proto_lp, link_ksettings);
f62b8bb8 837
52244d96
GP
838 if (an_status == MLX5_AN_COMPLETE)
839 ethtool_link_ksettings_add_link_mode(link_ksettings,
840 lp_advertising, Autoneg);
841
842 link_ksettings->base.autoneg = an_disable_admin ? AUTONEG_DISABLE :
843 AUTONEG_ENABLE;
844 ethtool_link_ksettings_add_link_mode(link_ksettings, supported,
845 Autoneg);
846 if (!an_disable_admin)
847 ethtool_link_ksettings_add_link_mode(link_ksettings,
848 advertising, Autoneg);
849
f62b8bb8
AV
850err_query_ptys:
851 return err;
852}
853
665bc539 854static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes)
f62b8bb8
AV
855{
856 u32 i, ptys_modes = 0;
857
858 for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
665bc539
GP
859 if (bitmap_intersects(ptys2ethtool_table[i].advertised,
860 link_modes,
861 __ETHTOOL_LINK_MODE_MASK_NBITS))
f62b8bb8
AV
862 ptys_modes |= MLX5E_PROT_MASK(i);
863 }
864
865 return ptys_modes;
866}
867
868static u32 mlx5e_ethtool2ptys_speed_link(u32 speed)
869{
870 u32 i, speed_links = 0;
871
872 for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
873 if (ptys2ethtool_table[i].speed == speed)
874 speed_links |= MLX5E_PROT_MASK(i);
875 }
876
877 return speed_links;
878}
879
665bc539
GP
880static int mlx5e_set_link_ksettings(struct net_device *netdev,
881 const struct ethtool_link_ksettings *link_ksettings)
f62b8bb8
AV
882{
883 struct mlx5e_priv *priv = netdev_priv(netdev);
884 struct mlx5_core_dev *mdev = priv->mdev;
52244d96
GP
885 u32 eth_proto_cap, eth_proto_admin;
886 bool an_changes = false;
887 u8 an_disable_admin;
888 u8 an_disable_cap;
889 bool an_disable;
f62b8bb8 890 u32 link_modes;
52244d96 891 u8 an_status;
f62b8bb8 892 u32 speed;
f62b8bb8
AV
893 int err;
894
665bc539 895 speed = link_ksettings->base.speed;
f62b8bb8 896
665bc539
GP
897 link_modes = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
898 mlx5e_ethtool2ptys_adver_link(link_ksettings->link_modes.advertising) :
f62b8bb8
AV
899 mlx5e_ethtool2ptys_speed_link(speed);
900
901 err = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
902 if (err) {
903 netdev_err(netdev, "%s: query port eth proto cap failed: %d\n",
904 __func__, err);
905 goto out;
906 }
907
908 link_modes = link_modes & eth_proto_cap;
909 if (!link_modes) {
910 netdev_err(netdev, "%s: Not supported link mode(s) requested",
911 __func__);
912 err = -EINVAL;
913 goto out;
914 }
915
916 err = mlx5_query_port_proto_admin(mdev, &eth_proto_admin, MLX5_PTYS_EN);
917 if (err) {
918 netdev_err(netdev, "%s: query port eth proto admin failed: %d\n",
919 __func__, err);
920 goto out;
921 }
922
52244d96
GP
923 mlx5_query_port_autoneg(mdev, MLX5_PTYS_EN, &an_status,
924 &an_disable_cap, &an_disable_admin);
925
926 an_disable = link_ksettings->base.autoneg == AUTONEG_DISABLE;
927 an_changes = ((!an_disable && an_disable_admin) ||
928 (an_disable && !an_disable_admin));
929
930 if (!an_changes && link_modes == eth_proto_admin)
f62b8bb8
AV
931 goto out;
932
52244d96 933 mlx5_set_port_ptys(mdev, an_disable, link_modes, MLX5_PTYS_EN);
667daeda 934 mlx5_toggle_port_link(mdev);
f62b8bb8 935
f62b8bb8
AV
936out:
937 return err;
938}
939
2d75b2bc
AS
940static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
941{
942 struct mlx5e_priv *priv = netdev_priv(netdev);
943
6a9764ef 944 return sizeof(priv->channels.params.toeplitz_hash_key);
2d75b2bc
AS
945}
946
947static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
948{
949 return MLX5E_INDIR_RQT_SIZE;
950}
951
2be6967c
SM
952static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
953 u8 *hfunc)
954{
955 struct mlx5e_priv *priv = netdev_priv(netdev);
956
2d75b2bc 957 if (indir)
6a9764ef
SM
958 memcpy(indir, priv->channels.params.indirection_rqt,
959 sizeof(priv->channels.params.indirection_rqt));
2d75b2bc
AS
960
961 if (key)
6a9764ef
SM
962 memcpy(key, priv->channels.params.toeplitz_hash_key,
963 sizeof(priv->channels.params.toeplitz_hash_key));
2d75b2bc 964
2be6967c 965 if (hfunc)
6a9764ef 966 *hfunc = priv->channels.params.rss_hfunc;
2be6967c
SM
967
968 return 0;
969}
970
bdfc028d
TT
971static void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
972{
bdfc028d 973 void *tirc = MLX5_ADDR_OF(modify_tir_in, in, ctx);
a100ff3e
GP
974 struct mlx5_core_dev *mdev = priv->mdev;
975 int ctxlen = MLX5_ST_SZ_BYTES(tirc);
976 int tt;
bdfc028d
TT
977
978 MLX5_SET(modify_tir_in, in, bitmask.hash, 1);
bdfc028d 979
a100ff3e
GP
980 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
981 memset(tirc, 0, ctxlen);
7b3722fa 982 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, false);
a100ff3e
GP
983 mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen);
984 }
7b3722fa
GP
985
986 if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
987 return;
988
989 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
990 memset(tirc, 0, ctxlen);
991 mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, true);
992 mlx5_core_modify_tir(mdev, priv->inner_indir_tir[tt].tirn, in, inlen);
993 }
bdfc028d
TT
994}
995
98e81b0a 996static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
2be6967c
SM
997 const u8 *key, const u8 hfunc)
998{
98e81b0a 999 struct mlx5e_priv *priv = netdev_priv(dev);
bdfc028d 1000 int inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
1d3398fa 1001 bool hash_changed = false;
bdfc028d 1002 void *in;
2be6967c 1003
2d75b2bc
AS
1004 if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
1005 (hfunc != ETH_RSS_HASH_XOR) &&
2be6967c
SM
1006 (hfunc != ETH_RSS_HASH_TOP))
1007 return -EINVAL;
1008
1b9a07ee 1009 in = kvzalloc(inlen, GFP_KERNEL);
bdfc028d
TT
1010 if (!in)
1011 return -ENOMEM;
1012
2be6967c
SM
1013 mutex_lock(&priv->state_lock);
1014
1d3398fa 1015 if (hfunc != ETH_RSS_HASH_NO_CHANGE &&
6a9764ef
SM
1016 hfunc != priv->channels.params.rss_hfunc) {
1017 priv->channels.params.rss_hfunc = hfunc;
1d3398fa
GP
1018 hash_changed = true;
1019 }
1020
a5f97fee 1021 if (indir) {
6a9764ef
SM
1022 memcpy(priv->channels.params.indirection_rqt, indir,
1023 sizeof(priv->channels.params.indirection_rqt));
a5f97fee
SM
1024
1025 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1026 u32 rqtn = priv->indir_rqt.rqtn;
1027 struct mlx5e_redirect_rqt_param rrp = {
1028 .is_rss = true,
e270e966
AM
1029 {
1030 .rss = {
1031 .hfunc = priv->channels.params.rss_hfunc,
1032 .channels = &priv->channels,
1033 },
1034 },
a5f97fee
SM
1035 };
1036
1037 mlx5e_redirect_rqt(priv, rqtn, MLX5E_INDIR_RQT_SIZE, rrp);
1038 }
1039 }
1040
1d3398fa 1041 if (key) {
6a9764ef
SM
1042 memcpy(priv->channels.params.toeplitz_hash_key, key,
1043 sizeof(priv->channels.params.toeplitz_hash_key));
1d3398fa 1044 hash_changed = hash_changed ||
6a9764ef 1045 priv->channels.params.rss_hfunc == ETH_RSS_HASH_TOP;
1d3398fa 1046 }
2d75b2bc 1047
1d3398fa
GP
1048 if (hash_changed)
1049 mlx5e_modify_tirs_hash(priv, in, inlen);
2d75b2bc 1050
2be6967c
SM
1051 mutex_unlock(&priv->state_lock);
1052
bdfc028d
TT
1053 kvfree(in);
1054
1055 return 0;
2be6967c
SM
1056}
1057
2d75b2bc
AS
1058static int mlx5e_get_rxnfc(struct net_device *netdev,
1059 struct ethtool_rxnfc *info, u32 *rule_locs)
1060{
1061 struct mlx5e_priv *priv = netdev_priv(netdev);
1062 int err = 0;
1063
1064 switch (info->cmd) {
1065 case ETHTOOL_GRXRINGS:
6a9764ef 1066 info->data = priv->channels.params.num_channels;
2d75b2bc 1067 break;
f913a72a
MG
1068 case ETHTOOL_GRXCLSRLCNT:
1069 info->rule_cnt = priv->fs.ethtool.tot_num_rules;
1070 break;
1071 case ETHTOOL_GRXCLSRULE:
1072 err = mlx5e_ethtool_get_flow(priv, info, info->fs.location);
1073 break;
1074 case ETHTOOL_GRXCLSRLALL:
1075 err = mlx5e_ethtool_get_all_flows(priv, info, rule_locs);
1076 break;
2d75b2bc
AS
1077 default:
1078 err = -EOPNOTSUPP;
1079 break;
1080 }
1081
1082 return err;
1083}
1084
58d52291
AS
1085static int mlx5e_get_tunable(struct net_device *dev,
1086 const struct ethtool_tunable *tuna,
1087 void *data)
1088{
1089 const struct mlx5e_priv *priv = netdev_priv(dev);
1090 int err = 0;
1091
1092 switch (tuna->id) {
1093 case ETHTOOL_TX_COPYBREAK:
6a9764ef 1094 *(u32 *)data = priv->channels.params.tx_max_inline;
58d52291
AS
1095 break;
1096 default:
1097 err = -EINVAL;
1098 break;
1099 }
1100
1101 return err;
1102}
1103
1104static int mlx5e_set_tunable(struct net_device *dev,
1105 const struct ethtool_tunable *tuna,
1106 const void *data)
1107{
1108 struct mlx5e_priv *priv = netdev_priv(dev);
1109 struct mlx5_core_dev *mdev = priv->mdev;
546f18ed 1110 struct mlx5e_channels new_channels = {};
58d52291 1111 int err = 0;
546f18ed
SM
1112 u32 val;
1113
1114 mutex_lock(&priv->state_lock);
58d52291
AS
1115
1116 switch (tuna->id) {
1117 case ETHTOOL_TX_COPYBREAK:
1118 val = *(u32 *)data;
1119 if (val > mlx5e_get_max_inline_cap(mdev)) {
1120 err = -EINVAL;
1121 break;
1122 }
1123
546f18ed
SM
1124 new_channels.params = priv->channels.params;
1125 new_channels.params.tx_max_inline = val;
98e81b0a 1126
546f18ed
SM
1127 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1128 priv->channels.params = new_channels.params;
1129 break;
1130 }
98e81b0a 1131
546f18ed
SM
1132 err = mlx5e_open_channels(priv, &new_channels);
1133 if (err)
1134 break;
2e20a151 1135 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
98e81b0a 1136
58d52291
AS
1137 break;
1138 default:
1139 err = -EINVAL;
1140 break;
1141 }
1142
546f18ed 1143 mutex_unlock(&priv->state_lock);
58d52291
AS
1144 return err;
1145}
1146
3c2d18ef
AS
1147static void mlx5e_get_pauseparam(struct net_device *netdev,
1148 struct ethtool_pauseparam *pauseparam)
1149{
1150 struct mlx5e_priv *priv = netdev_priv(netdev);
1151 struct mlx5_core_dev *mdev = priv->mdev;
1152 int err;
1153
1154 err = mlx5_query_port_pause(mdev, &pauseparam->rx_pause,
1155 &pauseparam->tx_pause);
1156 if (err) {
1157 netdev_err(netdev, "%s: mlx5_query_port_pause failed:0x%x\n",
1158 __func__, err);
1159 }
1160}
1161
1162static int mlx5e_set_pauseparam(struct net_device *netdev,
1163 struct ethtool_pauseparam *pauseparam)
1164{
1165 struct mlx5e_priv *priv = netdev_priv(netdev);
1166 struct mlx5_core_dev *mdev = priv->mdev;
1167 int err;
1168
1169 if (pauseparam->autoneg)
1170 return -EINVAL;
1171
1172 err = mlx5_set_port_pause(mdev,
1173 pauseparam->rx_pause ? 1 : 0,
1174 pauseparam->tx_pause ? 1 : 0);
1175 if (err) {
1176 netdev_err(netdev, "%s: mlx5_set_port_pause failed:0x%x\n",
1177 __func__, err);
1178 }
1179
1180 return err;
1181}
1182
3844b07e
FD
1183int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
1184 struct ethtool_ts_info *info)
ef9814de 1185{
7c39afb3 1186 struct mlx5_core_dev *mdev = priv->mdev;
ef9814de
EBE
1187 int ret;
1188
3844b07e 1189 ret = ethtool_op_get_ts_info(priv->netdev, info);
ef9814de
EBE
1190 if (ret)
1191 return ret;
1192
7c39afb3
FD
1193 info->phc_index = mdev->clock.ptp ?
1194 ptp_clock_index(mdev->clock.ptp) : -1;
ef9814de
EBE
1195
1196 if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz))
1197 return 0;
1198
1199 info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
1200 SOF_TIMESTAMPING_RX_HARDWARE |
1201 SOF_TIMESTAMPING_RAW_HARDWARE;
1202
f0b38117
MD
1203 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1204 BIT(HWTSTAMP_TX_ON);
ef9814de 1205
f0b38117
MD
1206 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1207 BIT(HWTSTAMP_FILTER_ALL);
ef9814de
EBE
1208
1209 return 0;
1210}
1211
3844b07e
FD
1212static int mlx5e_get_ts_info(struct net_device *dev,
1213 struct ethtool_ts_info *info)
1214{
1215 struct mlx5e_priv *priv = netdev_priv(dev);
1216
1217 return mlx5e_ethtool_get_ts_info(priv, info);
1218}
1219
928cfe87
TT
1220static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
1221{
1222 __u32 ret = 0;
1223
1224 if (MLX5_CAP_GEN(mdev, wol_g))
1225 ret |= WAKE_MAGIC;
1226
1227 if (MLX5_CAP_GEN(mdev, wol_s))
1228 ret |= WAKE_MAGICSECURE;
1229
1230 if (MLX5_CAP_GEN(mdev, wol_a))
1231 ret |= WAKE_ARP;
1232
1233 if (MLX5_CAP_GEN(mdev, wol_b))
1234 ret |= WAKE_BCAST;
1235
1236 if (MLX5_CAP_GEN(mdev, wol_m))
1237 ret |= WAKE_MCAST;
1238
1239 if (MLX5_CAP_GEN(mdev, wol_u))
1240 ret |= WAKE_UCAST;
1241
1242 if (MLX5_CAP_GEN(mdev, wol_p))
1243 ret |= WAKE_PHY;
1244
1245 return ret;
1246}
1247
1248static __u32 mlx5e_refomrat_wol_mode_mlx5_to_linux(u8 mode)
1249{
1250 __u32 ret = 0;
1251
1252 if (mode & MLX5_WOL_MAGIC)
1253 ret |= WAKE_MAGIC;
1254
1255 if (mode & MLX5_WOL_SECURED_MAGIC)
1256 ret |= WAKE_MAGICSECURE;
1257
1258 if (mode & MLX5_WOL_ARP)
1259 ret |= WAKE_ARP;
1260
1261 if (mode & MLX5_WOL_BROADCAST)
1262 ret |= WAKE_BCAST;
1263
1264 if (mode & MLX5_WOL_MULTICAST)
1265 ret |= WAKE_MCAST;
1266
1267 if (mode & MLX5_WOL_UNICAST)
1268 ret |= WAKE_UCAST;
1269
1270 if (mode & MLX5_WOL_PHY_ACTIVITY)
1271 ret |= WAKE_PHY;
1272
1273 return ret;
1274}
1275
1276static u8 mlx5e_refomrat_wol_mode_linux_to_mlx5(__u32 mode)
1277{
1278 u8 ret = 0;
1279
1280 if (mode & WAKE_MAGIC)
1281 ret |= MLX5_WOL_MAGIC;
1282
1283 if (mode & WAKE_MAGICSECURE)
1284 ret |= MLX5_WOL_SECURED_MAGIC;
1285
1286 if (mode & WAKE_ARP)
1287 ret |= MLX5_WOL_ARP;
1288
1289 if (mode & WAKE_BCAST)
1290 ret |= MLX5_WOL_BROADCAST;
1291
1292 if (mode & WAKE_MCAST)
1293 ret |= MLX5_WOL_MULTICAST;
1294
1295 if (mode & WAKE_UCAST)
1296 ret |= MLX5_WOL_UNICAST;
1297
1298 if (mode & WAKE_PHY)
1299 ret |= MLX5_WOL_PHY_ACTIVITY;
1300
1301 return ret;
1302}
1303
1304static void mlx5e_get_wol(struct net_device *netdev,
1305 struct ethtool_wolinfo *wol)
1306{
1307 struct mlx5e_priv *priv = netdev_priv(netdev);
1308 struct mlx5_core_dev *mdev = priv->mdev;
1309 u8 mlx5_wol_mode;
1310 int err;
1311
1312 memset(wol, 0, sizeof(*wol));
1313
1314 wol->supported = mlx5e_get_wol_supported(mdev);
1315 if (!wol->supported)
1316 return;
1317
1318 err = mlx5_query_port_wol(mdev, &mlx5_wol_mode);
1319 if (err)
1320 return;
1321
1322 wol->wolopts = mlx5e_refomrat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
1323}
1324
1325static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1326{
1327 struct mlx5e_priv *priv = netdev_priv(netdev);
1328 struct mlx5_core_dev *mdev = priv->mdev;
1329 __u32 wol_supported = mlx5e_get_wol_supported(mdev);
1330 u32 mlx5_wol_mode;
1331
1332 if (!wol_supported)
9eb78923 1333 return -EOPNOTSUPP;
928cfe87
TT
1334
1335 if (wol->wolopts & ~wol_supported)
1336 return -EINVAL;
1337
1338 mlx5_wol_mode = mlx5e_refomrat_wol_mode_linux_to_mlx5(wol->wolopts);
1339
1340 return mlx5_set_port_wol(mdev, mlx5_wol_mode);
1341}
1342
79c48764
GP
1343static u32 mlx5e_get_msglevel(struct net_device *dev)
1344{
1345 return ((struct mlx5e_priv *)netdev_priv(dev))->msglevel;
1346}
1347
1348static void mlx5e_set_msglevel(struct net_device *dev, u32 val)
1349{
1350 ((struct mlx5e_priv *)netdev_priv(dev))->msglevel = val;
1351}
1352
da54d24e
GP
1353static int mlx5e_set_phys_id(struct net_device *dev,
1354 enum ethtool_phys_id_state state)
1355{
1356 struct mlx5e_priv *priv = netdev_priv(dev);
1357 struct mlx5_core_dev *mdev = priv->mdev;
1358 u16 beacon_duration;
1359
1360 if (!MLX5_CAP_GEN(mdev, beacon_led))
1361 return -EOPNOTSUPP;
1362
1363 switch (state) {
1364 case ETHTOOL_ID_ACTIVE:
1365 beacon_duration = MLX5_BEACON_DURATION_INF;
1366 break;
1367 case ETHTOOL_ID_INACTIVE:
1368 beacon_duration = MLX5_BEACON_DURATION_OFF;
1369 break;
1370 default:
1371 return -EOPNOTSUPP;
1372 }
1373
1374 return mlx5_set_port_beacon(mdev, beacon_duration);
1375}
1376
bb64143e
GP
1377static int mlx5e_get_module_info(struct net_device *netdev,
1378 struct ethtool_modinfo *modinfo)
1379{
1380 struct mlx5e_priv *priv = netdev_priv(netdev);
1381 struct mlx5_core_dev *dev = priv->mdev;
1382 int size_read = 0;
1383 u8 data[4];
1384
1385 size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
1386 if (size_read < 2)
1387 return -EIO;
1388
1389 /* data[0] = identifier byte */
1390 switch (data[0]) {
1391 case MLX5_MODULE_ID_QSFP:
1392 modinfo->type = ETH_MODULE_SFF_8436;
1393 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1394 break;
1395 case MLX5_MODULE_ID_QSFP_PLUS:
1396 case MLX5_MODULE_ID_QSFP28:
1397 /* data[1] = revision id */
1398 if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
1399 modinfo->type = ETH_MODULE_SFF_8636;
1400 modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
1401 } else {
1402 modinfo->type = ETH_MODULE_SFF_8436;
1403 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1404 }
1405 break;
1406 case MLX5_MODULE_ID_SFP:
1407 modinfo->type = ETH_MODULE_SFF_8472;
1408 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1409 break;
1410 default:
1411 netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
1412 __func__, data[0]);
1413 return -EINVAL;
1414 }
1415
1416 return 0;
1417}
1418
1419static int mlx5e_get_module_eeprom(struct net_device *netdev,
1420 struct ethtool_eeprom *ee,
1421 u8 *data)
1422{
1423 struct mlx5e_priv *priv = netdev_priv(netdev);
1424 struct mlx5_core_dev *mdev = priv->mdev;
1425 int offset = ee->offset;
1426 int size_read;
1427 int i = 0;
1428
1429 if (!ee->len)
1430 return -EINVAL;
1431
1432 memset(data, 0, ee->len);
1433
1434 while (i < ee->len) {
1435 size_read = mlx5_query_module_eeprom(mdev, offset, ee->len - i,
1436 data + i);
1437
1438 if (!size_read)
1439 /* Done reading */
1440 return 0;
1441
1442 if (size_read < 0) {
1443 netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n",
1444 __func__, size_read);
1445 return 0;
1446 }
1447
1448 i += size_read;
1449 offset += size_read;
1450 }
1451
1452 return 0;
1453}
1454
4e59e288
GP
1455typedef int (*mlx5e_pflag_handler)(struct net_device *netdev, bool enable);
1456
0088cbbc
TG
1457static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
1458 bool is_rx_cq)
4e59e288 1459{
9908aa29
TT
1460 struct mlx5e_priv *priv = netdev_priv(netdev);
1461 struct mlx5_core_dev *mdev = priv->mdev;
be7e87f9 1462 struct mlx5e_channels new_channels = {};
0088cbbc
TG
1463 bool mode_changed;
1464 u8 cq_period_mode, current_cq_period_mode;
9908aa29 1465 int err = 0;
9908aa29 1466
0088cbbc 1467 cq_period_mode = enable ?
9908aa29
TT
1468 MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
1469 MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
0088cbbc
TG
1470 current_cq_period_mode = is_rx_cq ?
1471 priv->channels.params.rx_cq_moderation.cq_period_mode :
1472 priv->channels.params.tx_cq_moderation.cq_period_mode;
1473 mode_changed = cq_period_mode != current_cq_period_mode;
9908aa29 1474
0088cbbc 1475 if (cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE &&
9908aa29 1476 !MLX5_CAP_GEN(mdev, cq_period_start_from_cqe))
9eb78923 1477 return -EOPNOTSUPP;
9908aa29 1478
0088cbbc 1479 if (!mode_changed)
9908aa29
TT
1480 return 0;
1481
be7e87f9 1482 new_channels.params = priv->channels.params;
0088cbbc
TG
1483 if (is_rx_cq)
1484 mlx5e_set_rx_cq_mode_params(&new_channels.params, cq_period_mode);
1485 else
1486 mlx5e_set_tx_cq_mode_params(&new_channels.params, cq_period_mode);
9908aa29 1487
be7e87f9
SM
1488 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1489 priv->channels.params = new_channels.params;
1490 return 0;
1491 }
1492
1493 err = mlx5e_open_channels(priv, &new_channels);
1494 if (err)
1495 return err;
9908aa29 1496
2e20a151 1497 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
be7e87f9
SM
1498 return 0;
1499}
9908aa29 1500
0088cbbc
TG
1501static int set_pflag_tx_cqe_based_moder(struct net_device *netdev, bool enable)
1502{
1503 return set_pflag_cqe_based_moder(netdev, enable, false);
1504}
1505
1506static int set_pflag_rx_cqe_based_moder(struct net_device *netdev, bool enable)
1507{
1508 return set_pflag_cqe_based_moder(netdev, enable, true);
1509}
1510
be7e87f9
SM
1511int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val)
1512{
1513 bool curr_val = MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS);
1514 struct mlx5e_channels new_channels = {};
1515 int err = 0;
1516
1517 if (!MLX5_CAP_GEN(priv->mdev, cqe_compression))
1518 return new_val ? -EOPNOTSUPP : 0;
1519
1520 if (curr_val == new_val)
1521 return 0;
1522
1523 new_channels.params = priv->channels.params;
1524 MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val);
1525
696a97cf
EE
1526 new_channels.params.mpwqe_log_stride_sz =
1527 MLX5E_MPWQE_STRIDE_SZ(priv->mdev, new_val);
1528 new_channels.params.mpwqe_log_num_strides =
1529 MLX5_MPWRQ_LOG_WQE_SZ - new_channels.params.mpwqe_log_stride_sz;
be7e87f9
SM
1530
1531 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1532 priv->channels.params = new_channels.params;
1533 return 0;
1534 }
1535
1536 err = mlx5e_open_channels(priv, &new_channels);
1537 if (err)
1538 return err;
1539
2e20a151 1540 mlx5e_switch_priv_channels(priv, &new_channels, NULL);
696a97cf
EE
1541 mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
1542 MLX5E_GET_PFLAG(&priv->channels.params,
1543 MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
1544
be7e87f9 1545 return 0;
4e59e288
GP
1546}
1547
9bcc8606
SD
1548static int set_pflag_rx_cqe_compress(struct net_device *netdev,
1549 bool enable)
1550{
1551 struct mlx5e_priv *priv = netdev_priv(netdev);
1552 struct mlx5_core_dev *mdev = priv->mdev;
9bcc8606
SD
1553
1554 if (!MLX5_CAP_GEN(mdev, cqe_compression))
9eb78923 1555 return -EOPNOTSUPP;
9bcc8606 1556
7c39afb3 1557 if (enable && priv->tstamp.rx_filter != HWTSTAMP_FILTER_NONE) {
9bcc8606
SD
1558 netdev_err(netdev, "Can't enable cqe compression while timestamping is enabled.\n");
1559 return -EINVAL;
1560 }
1561
5eb0249b 1562 mlx5e_modify_rx_cqe_compression_locked(priv, enable);
6a9764ef 1563 priv->channels.params.rx_cqe_compress_def = enable;
9bcc8606 1564
5eb0249b 1565 return 0;
9bcc8606
SD
1566}
1567
4e59e288
GP
1568static int mlx5e_handle_pflag(struct net_device *netdev,
1569 u32 wanted_flags,
1570 enum mlx5e_priv_flag flag,
1571 mlx5e_pflag_handler pflag_handler)
1572{
1573 struct mlx5e_priv *priv = netdev_priv(netdev);
1574 bool enable = !!(wanted_flags & flag);
6a9764ef 1575 u32 changes = wanted_flags ^ priv->channels.params.pflags;
4e59e288
GP
1576 int err;
1577
1578 if (!(changes & flag))
1579 return 0;
1580
1581 err = pflag_handler(netdev, enable);
1582 if (err) {
1583 netdev_err(netdev, "%s private flag 0x%x failed err %d\n",
1584 enable ? "Enable" : "Disable", flag, err);
1585 return err;
1586 }
1587
6a9764ef 1588 MLX5E_SET_PFLAG(&priv->channels.params, flag, enable);
4e59e288
GP
1589 return 0;
1590}
1591
1592static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
1593{
1594 struct mlx5e_priv *priv = netdev_priv(netdev);
1595 int err;
1596
1597 mutex_lock(&priv->state_lock);
9908aa29
TT
1598 err = mlx5e_handle_pflag(netdev, pflags,
1599 MLX5E_PFLAG_RX_CQE_BASED_MODER,
1600 set_pflag_rx_cqe_based_moder);
9bcc8606
SD
1601 if (err)
1602 goto out;
4e59e288 1603
0088cbbc
TG
1604 err = mlx5e_handle_pflag(netdev, pflags,
1605 MLX5E_PFLAG_TX_CQE_BASED_MODER,
1606 set_pflag_tx_cqe_based_moder);
1607 if (err)
1608 goto out;
1609
9bcc8606
SD
1610 err = mlx5e_handle_pflag(netdev, pflags,
1611 MLX5E_PFLAG_RX_CQE_COMPRESS,
1612 set_pflag_rx_cqe_compress);
1613
1614out:
4e59e288 1615 mutex_unlock(&priv->state_lock);
9bcc8606 1616 return err;
4e59e288
GP
1617}
1618
1619static u32 mlx5e_get_priv_flags(struct net_device *netdev)
1620{
1621 struct mlx5e_priv *priv = netdev_priv(netdev);
1622
6a9764ef 1623 return priv->channels.params.pflags;
4e59e288
GP
1624}
1625
6dc6071c
MG
1626static int mlx5e_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
1627{
1628 int err = 0;
1629 struct mlx5e_priv *priv = netdev_priv(dev);
1630
1631 switch (cmd->cmd) {
1632 case ETHTOOL_SRXCLSRLINS:
1633 err = mlx5e_ethtool_flow_replace(priv, &cmd->fs);
1634 break;
1635 case ETHTOOL_SRXCLSRLDEL:
1636 err = mlx5e_ethtool_flow_remove(priv, cmd->fs.location);
1637 break;
1638 default:
1639 err = -EOPNOTSUPP;
1640 break;
1641 }
1642
1643 return err;
1644}
1645
3ffaabec
OG
1646int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
1647 struct ethtool_flash *flash)
1648{
1649 struct mlx5_core_dev *mdev = priv->mdev;
1650 struct net_device *dev = priv->netdev;
1651 const struct firmware *fw;
1652 int err;
1653
1654 if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
1655 return -EOPNOTSUPP;
1656
1657 err = request_firmware_direct(&fw, flash->data, &dev->dev);
1658 if (err)
1659 return err;
1660
1661 dev_hold(dev);
1662 rtnl_unlock();
1663
1664 err = mlx5_firmware_flash(mdev, fw);
1665 release_firmware(fw);
1666
1667 rtnl_lock();
1668 dev_put(dev);
1669 return err;
1670}
1671
1672static int mlx5e_flash_device(struct net_device *dev,
1673 struct ethtool_flash *flash)
1674{
1675 struct mlx5e_priv *priv = netdev_priv(dev);
1676
1677 return mlx5e_ethtool_flash_device(priv, flash);
1678}
1679
f62b8bb8
AV
1680const struct ethtool_ops mlx5e_ethtool_ops = {
1681 .get_drvinfo = mlx5e_get_drvinfo,
1682 .get_link = ethtool_op_get_link,
1683 .get_strings = mlx5e_get_strings,
1684 .get_sset_count = mlx5e_get_sset_count,
1685 .get_ethtool_stats = mlx5e_get_ethtool_stats,
1686 .get_ringparam = mlx5e_get_ringparam,
1687 .set_ringparam = mlx5e_set_ringparam,
1688 .get_channels = mlx5e_get_channels,
1689 .set_channels = mlx5e_set_channels,
1690 .get_coalesce = mlx5e_get_coalesce,
1691 .set_coalesce = mlx5e_set_coalesce,
665bc539
GP
1692 .get_link_ksettings = mlx5e_get_link_ksettings,
1693 .set_link_ksettings = mlx5e_set_link_ksettings,
2d75b2bc
AS
1694 .get_rxfh_key_size = mlx5e_get_rxfh_key_size,
1695 .get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
2be6967c
SM
1696 .get_rxfh = mlx5e_get_rxfh,
1697 .set_rxfh = mlx5e_set_rxfh,
2d75b2bc 1698 .get_rxnfc = mlx5e_get_rxnfc,
6dc6071c 1699 .set_rxnfc = mlx5e_set_rxnfc,
3ffaabec 1700 .flash_device = mlx5e_flash_device,
58d52291
AS
1701 .get_tunable = mlx5e_get_tunable,
1702 .set_tunable = mlx5e_set_tunable,
3c2d18ef
AS
1703 .get_pauseparam = mlx5e_get_pauseparam,
1704 .set_pauseparam = mlx5e_set_pauseparam,
ef9814de 1705 .get_ts_info = mlx5e_get_ts_info,
da54d24e 1706 .set_phys_id = mlx5e_set_phys_id,
928cfe87
TT
1707 .get_wol = mlx5e_get_wol,
1708 .set_wol = mlx5e_set_wol,
bb64143e
GP
1709 .get_module_info = mlx5e_get_module_info,
1710 .get_module_eeprom = mlx5e_get_module_eeprom,
4e59e288 1711 .get_priv_flags = mlx5e_get_priv_flags,
d605d668
KH
1712 .set_priv_flags = mlx5e_set_priv_flags,
1713 .self_test = mlx5e_self_test,
79c48764
GP
1714 .get_msglevel = mlx5e_get_msglevel,
1715 .set_msglevel = mlx5e_set_msglevel,
1716
f62b8bb8 1717};