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