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