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