1 /*
2  * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 #include "en.h"
34 
35 static void mlx5e_get_drvinfo(struct net_device *dev,
36 			      struct ethtool_drvinfo *drvinfo)
37 {
38 	struct mlx5e_priv *priv = netdev_priv(dev);
39 	struct mlx5_core_dev *mdev = priv->mdev;
40 
41 	strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
42 	strlcpy(drvinfo->version, DRIVER_VERSION " (" DRIVER_RELDATE ")",
43 		sizeof(drvinfo->version));
44 	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
45 		 "%d.%d.%d",
46 		 fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev));
47 	strlcpy(drvinfo->bus_info, pci_name(mdev->pdev),
48 		sizeof(drvinfo->bus_info));
49 }
50 
51 static const struct {
52 	u32 supported;
53 	u32 advertised;
54 	u32 speed;
55 } ptys2ethtool_table[MLX5E_LINK_MODES_NUMBER] = {
56 	[MLX5E_1000BASE_CX_SGMII] = {
57 		.supported  = SUPPORTED_1000baseKX_Full,
58 		.advertised = ADVERTISED_1000baseKX_Full,
59 		.speed      = 1000,
60 	},
61 	[MLX5E_1000BASE_KX] = {
62 		.supported  = SUPPORTED_1000baseKX_Full,
63 		.advertised = ADVERTISED_1000baseKX_Full,
64 		.speed      = 1000,
65 	},
66 	[MLX5E_10GBASE_CX4] = {
67 		.supported  = SUPPORTED_10000baseKX4_Full,
68 		.advertised = ADVERTISED_10000baseKX4_Full,
69 		.speed      = 10000,
70 	},
71 	[MLX5E_10GBASE_KX4] = {
72 		.supported  = SUPPORTED_10000baseKX4_Full,
73 		.advertised = ADVERTISED_10000baseKX4_Full,
74 		.speed      = 10000,
75 	},
76 	[MLX5E_10GBASE_KR] = {
77 		.supported  = SUPPORTED_10000baseKR_Full,
78 		.advertised = ADVERTISED_10000baseKR_Full,
79 		.speed      = 10000,
80 	},
81 	[MLX5E_20GBASE_KR2] = {
82 		.supported  = SUPPORTED_20000baseKR2_Full,
83 		.advertised = ADVERTISED_20000baseKR2_Full,
84 		.speed      = 20000,
85 	},
86 	[MLX5E_40GBASE_CR4] = {
87 		.supported  = SUPPORTED_40000baseCR4_Full,
88 		.advertised = ADVERTISED_40000baseCR4_Full,
89 		.speed      = 40000,
90 	},
91 	[MLX5E_40GBASE_KR4] = {
92 		.supported  = SUPPORTED_40000baseKR4_Full,
93 		.advertised = ADVERTISED_40000baseKR4_Full,
94 		.speed      = 40000,
95 	},
96 	[MLX5E_56GBASE_R4] = {
97 		.supported  = SUPPORTED_56000baseKR4_Full,
98 		.advertised = ADVERTISED_56000baseKR4_Full,
99 		.speed      = 56000,
100 	},
101 	[MLX5E_10GBASE_CR] = {
102 		.supported  = SUPPORTED_10000baseKR_Full,
103 		.advertised = ADVERTISED_10000baseKR_Full,
104 		.speed      = 10000,
105 	},
106 	[MLX5E_10GBASE_SR] = {
107 		.supported  = SUPPORTED_10000baseKR_Full,
108 		.advertised = ADVERTISED_10000baseKR_Full,
109 		.speed      = 10000,
110 	},
111 	[MLX5E_10GBASE_ER] = {
112 		.supported  = SUPPORTED_10000baseKR_Full,
113 		.advertised = ADVERTISED_10000baseKR_Full,
114 		.speed      = 10000,
115 	},
116 	[MLX5E_40GBASE_SR4] = {
117 		.supported  = SUPPORTED_40000baseSR4_Full,
118 		.advertised = ADVERTISED_40000baseSR4_Full,
119 		.speed      = 40000,
120 	},
121 	[MLX5E_40GBASE_LR4] = {
122 		.supported  = SUPPORTED_40000baseLR4_Full,
123 		.advertised = ADVERTISED_40000baseLR4_Full,
124 		.speed      = 40000,
125 	},
126 	[MLX5E_100GBASE_CR4] = {
127 		.speed      = 100000,
128 	},
129 	[MLX5E_100GBASE_SR4] = {
130 		.speed      = 100000,
131 	},
132 	[MLX5E_100GBASE_KR4] = {
133 		.speed      = 100000,
134 	},
135 	[MLX5E_100GBASE_LR4] = {
136 		.speed      = 100000,
137 	},
138 	[MLX5E_100BASE_TX]   = {
139 		.speed      = 100,
140 	},
141 	[MLX5E_1000BASE_T]    = {
142 		.supported  = SUPPORTED_1000baseT_Full,
143 		.advertised = ADVERTISED_1000baseT_Full,
144 		.speed      = 1000,
145 	},
146 	[MLX5E_10GBASE_T]    = {
147 		.supported  = SUPPORTED_10000baseT_Full,
148 		.advertised = ADVERTISED_10000baseT_Full,
149 		.speed      = 1000,
150 	},
151 	[MLX5E_25GBASE_CR]   = {
152 		.speed      = 25000,
153 	},
154 	[MLX5E_25GBASE_KR]   = {
155 		.speed      = 25000,
156 	},
157 	[MLX5E_25GBASE_SR]   = {
158 		.speed      = 25000,
159 	},
160 	[MLX5E_50GBASE_CR2]  = {
161 		.speed      = 50000,
162 	},
163 	[MLX5E_50GBASE_KR2]  = {
164 		.speed      = 50000,
165 	},
166 };
167 
168 static unsigned long mlx5e_query_pfc_combined(struct mlx5e_priv *priv)
169 {
170 	struct mlx5_core_dev *mdev = priv->mdev;
171 	u8 pfc_en_tx;
172 	u8 pfc_en_rx;
173 	int err;
174 
175 	err = mlx5_query_port_pfc(mdev, &pfc_en_tx, &pfc_en_rx);
176 
177 	return err ? 0 : pfc_en_tx | pfc_en_rx;
178 }
179 
180 #define MLX5E_NUM_Q_CNTRS(priv) (NUM_Q_COUNTERS * (!!priv->q_counter))
181 #define MLX5E_NUM_RQ_STATS(priv) \
182 	(NUM_RQ_STATS * priv->params.num_channels * \
183 	 test_bit(MLX5E_STATE_OPENED, &priv->state))
184 #define MLX5E_NUM_SQ_STATS(priv) \
185 	(NUM_SQ_STATS * priv->params.num_channels * priv->params.num_tc * \
186 	 test_bit(MLX5E_STATE_OPENED, &priv->state))
187 #define MLX5E_NUM_PFC_COUNTERS(priv) hweight8(mlx5e_query_pfc_combined(priv))
188 
189 static int mlx5e_get_sset_count(struct net_device *dev, int sset)
190 {
191 	struct mlx5e_priv *priv = netdev_priv(dev);
192 
193 	switch (sset) {
194 	case ETH_SS_STATS:
195 		return NUM_SW_COUNTERS +
196 		       MLX5E_NUM_Q_CNTRS(priv) +
197 		       NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
198 		       MLX5E_NUM_RQ_STATS(priv) +
199 		       MLX5E_NUM_SQ_STATS(priv) +
200 		       MLX5E_NUM_PFC_COUNTERS(priv);
201 	/* fallthrough */
202 	default:
203 		return -EOPNOTSUPP;
204 	}
205 }
206 
207 static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
208 {
209 	int i, j, tc, prio, idx = 0;
210 	unsigned long pfc_combined;
211 
212 	/* SW counters */
213 	for (i = 0; i < NUM_SW_COUNTERS; i++)
214 		strcpy(data + (idx++) * ETH_GSTRING_LEN, sw_stats_desc[i].name);
215 
216 	/* Q counters */
217 	for (i = 0; i < MLX5E_NUM_Q_CNTRS(priv); i++)
218 		strcpy(data + (idx++) * ETH_GSTRING_LEN, q_stats_desc[i].name);
219 
220 	/* VPORT counters */
221 	for (i = 0; i < NUM_VPORT_COUNTERS; i++)
222 		strcpy(data + (idx++) * ETH_GSTRING_LEN,
223 		       vport_stats_desc[i].name);
224 
225 	/* PPORT counters */
226 	for (i = 0; i < NUM_PPORT_802_3_COUNTERS; i++)
227 		strcpy(data + (idx++) * ETH_GSTRING_LEN,
228 		       pport_802_3_stats_desc[i].name);
229 
230 	for (i = 0; i < NUM_PPORT_2863_COUNTERS; i++)
231 		strcpy(data + (idx++) * ETH_GSTRING_LEN,
232 		       pport_2863_stats_desc[i].name);
233 
234 	for (i = 0; i < NUM_PPORT_2819_COUNTERS; i++)
235 		strcpy(data + (idx++) * ETH_GSTRING_LEN,
236 		       pport_2819_stats_desc[i].name);
237 
238 	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
239 		for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
240 			sprintf(data + (idx++) * ETH_GSTRING_LEN, "prio%d_%s",
241 				prio,
242 				pport_per_prio_traffic_stats_desc[i].name);
243 	}
244 
245 	pfc_combined = mlx5e_query_pfc_combined(priv);
246 	for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
247 		for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
248 			sprintf(data + (idx++) * ETH_GSTRING_LEN, "prio%d_%s",
249 				prio, pport_per_prio_pfc_stats_desc[i].name);
250 		}
251 	}
252 
253 	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
254 		return;
255 
256 	/* per channel counters */
257 	for (i = 0; i < priv->params.num_channels; i++)
258 		for (j = 0; j < NUM_RQ_STATS; j++)
259 			sprintf(data + (idx++) * ETH_GSTRING_LEN, "rx%d_%s", i,
260 				rq_stats_desc[j].name);
261 
262 	for (tc = 0; tc < priv->params.num_tc; tc++)
263 		for (i = 0; i < priv->params.num_channels; i++)
264 			for (j = 0; j < NUM_SQ_STATS; j++)
265 				sprintf(data + (idx++) * ETH_GSTRING_LEN,
266 					"tx%d_%s",
267 					priv->channeltc_to_txq_map[i][tc],
268 					sq_stats_desc[j].name);
269 }
270 
271 static void mlx5e_get_strings(struct net_device *dev,
272 			      uint32_t stringset, uint8_t *data)
273 {
274 	struct mlx5e_priv *priv = netdev_priv(dev);
275 
276 	switch (stringset) {
277 	case ETH_SS_PRIV_FLAGS:
278 		break;
279 
280 	case ETH_SS_TEST:
281 		break;
282 
283 	case ETH_SS_STATS:
284 		mlx5e_fill_stats_strings(priv, data);
285 		break;
286 	}
287 }
288 
289 static void mlx5e_get_ethtool_stats(struct net_device *dev,
290 				    struct ethtool_stats *stats, u64 *data)
291 {
292 	struct mlx5e_priv *priv = netdev_priv(dev);
293 	int i, j, tc, prio, idx = 0;
294 	unsigned long pfc_combined;
295 
296 	if (!data)
297 		return;
298 
299 	mutex_lock(&priv->state_lock);
300 	if (test_bit(MLX5E_STATE_OPENED, &priv->state))
301 		mlx5e_update_stats(priv);
302 	mutex_unlock(&priv->state_lock);
303 
304 	for (i = 0; i < NUM_SW_COUNTERS; i++)
305 		data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
306 						   sw_stats_desc, i);
307 
308 	for (i = 0; i < MLX5E_NUM_Q_CNTRS(priv); i++)
309 		data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
310 						   q_stats_desc, i);
311 
312 	for (i = 0; i < NUM_VPORT_COUNTERS; i++)
313 		data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vport.query_vport_out,
314 						  vport_stats_desc, i);
315 
316 	for (i = 0; i < NUM_PPORT_802_3_COUNTERS; i++)
317 		data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.IEEE_802_3_counters,
318 						  pport_802_3_stats_desc, i);
319 
320 	for (i = 0; i < NUM_PPORT_2863_COUNTERS; i++)
321 		data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2863_counters,
322 						  pport_2863_stats_desc, i);
323 
324 	for (i = 0; i < NUM_PPORT_2819_COUNTERS; i++)
325 		data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
326 						  pport_2819_stats_desc, i);
327 
328 	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
329 		for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
330 			data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
331 						 pport_per_prio_traffic_stats_desc, i);
332 	}
333 
334 	pfc_combined = mlx5e_query_pfc_combined(priv);
335 	for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
336 		for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
337 			data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
338 							  pport_per_prio_pfc_stats_desc, i);
339 		}
340 	}
341 
342 	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
343 		return;
344 
345 	/* per channel counters */
346 	for (i = 0; i < priv->params.num_channels; i++)
347 		for (j = 0; j < NUM_RQ_STATS; j++)
348 			data[idx++] =
349 			       MLX5E_READ_CTR64_CPU(&priv->channel[i]->rq.stats,
350 						    rq_stats_desc, j);
351 
352 	for (tc = 0; tc < priv->params.num_tc; tc++)
353 		for (i = 0; i < priv->params.num_channels; i++)
354 			for (j = 0; j < NUM_SQ_STATS; j++)
355 				data[idx++] = MLX5E_READ_CTR64_CPU(&priv->channel[i]->sq[tc].stats,
356 								   sq_stats_desc, j);
357 }
358 
359 static void mlx5e_get_ringparam(struct net_device *dev,
360 				struct ethtool_ringparam *param)
361 {
362 	struct mlx5e_priv *priv = netdev_priv(dev);
363 	int rq_wq_type = priv->params.rq_wq_type;
364 
365 	param->rx_max_pending = 1 << mlx5_max_log_rq_size(rq_wq_type);
366 	param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
367 	param->rx_pending     = 1 << priv->params.log_rq_size;
368 	param->tx_pending     = 1 << priv->params.log_sq_size;
369 }
370 
371 static int mlx5e_set_ringparam(struct net_device *dev,
372 			       struct ethtool_ringparam *param)
373 {
374 	struct mlx5e_priv *priv = netdev_priv(dev);
375 	bool was_opened;
376 	int rq_wq_type = priv->params.rq_wq_type;
377 	u16 min_rx_wqes;
378 	u8 log_rq_size;
379 	u8 log_sq_size;
380 	int err = 0;
381 
382 	if (param->rx_jumbo_pending) {
383 		netdev_info(dev, "%s: rx_jumbo_pending not supported\n",
384 			    __func__);
385 		return -EINVAL;
386 	}
387 	if (param->rx_mini_pending) {
388 		netdev_info(dev, "%s: rx_mini_pending not supported\n",
389 			    __func__);
390 		return -EINVAL;
391 	}
392 	if (param->rx_pending < (1 << mlx5_min_log_rq_size(rq_wq_type))) {
393 		netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n",
394 			    __func__, param->rx_pending,
395 			    1 << mlx5_min_log_rq_size(rq_wq_type));
396 		return -EINVAL;
397 	}
398 	if (param->rx_pending > (1 << mlx5_max_log_rq_size(rq_wq_type))) {
399 		netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n",
400 			    __func__, param->rx_pending,
401 			    1 << mlx5_max_log_rq_size(rq_wq_type));
402 		return -EINVAL;
403 	}
404 	if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
405 		netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n",
406 			    __func__, param->tx_pending,
407 			    1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
408 		return -EINVAL;
409 	}
410 	if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) {
411 		netdev_info(dev, "%s: tx_pending (%d) > max (%d)\n",
412 			    __func__, param->tx_pending,
413 			    1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE);
414 		return -EINVAL;
415 	}
416 
417 	log_rq_size = order_base_2(param->rx_pending);
418 	log_sq_size = order_base_2(param->tx_pending);
419 	min_rx_wqes = mlx5_min_rx_wqes(rq_wq_type, param->rx_pending);
420 
421 	if (log_rq_size == priv->params.log_rq_size &&
422 	    log_sq_size == priv->params.log_sq_size &&
423 	    min_rx_wqes == priv->params.min_rx_wqes)
424 		return 0;
425 
426 	mutex_lock(&priv->state_lock);
427 
428 	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
429 	if (was_opened)
430 		mlx5e_close_locked(dev);
431 
432 	priv->params.log_rq_size = log_rq_size;
433 	priv->params.log_sq_size = log_sq_size;
434 	priv->params.min_rx_wqes = min_rx_wqes;
435 
436 	if (was_opened)
437 		err = mlx5e_open_locked(dev);
438 
439 	mutex_unlock(&priv->state_lock);
440 
441 	return err;
442 }
443 
444 static void mlx5e_get_channels(struct net_device *dev,
445 			       struct ethtool_channels *ch)
446 {
447 	struct mlx5e_priv *priv = netdev_priv(dev);
448 
449 	ch->max_combined   = mlx5e_get_max_num_channels(priv->mdev);
450 	ch->combined_count = priv->params.num_channels;
451 }
452 
453 static int mlx5e_set_channels(struct net_device *dev,
454 			      struct ethtool_channels *ch)
455 {
456 	struct mlx5e_priv *priv = netdev_priv(dev);
457 	int ncv = mlx5e_get_max_num_channels(priv->mdev);
458 	unsigned int count = ch->combined_count;
459 	bool arfs_enabled;
460 	bool was_opened;
461 	int err = 0;
462 
463 	if (!count) {
464 		netdev_info(dev, "%s: combined_count=0 not supported\n",
465 			    __func__);
466 		return -EINVAL;
467 	}
468 	if (ch->rx_count || ch->tx_count) {
469 		netdev_info(dev, "%s: separate rx/tx count not supported\n",
470 			    __func__);
471 		return -EINVAL;
472 	}
473 	if (count > ncv) {
474 		netdev_info(dev, "%s: count (%d) > max (%d)\n",
475 			    __func__, count, ncv);
476 		return -EINVAL;
477 	}
478 
479 	if (priv->params.num_channels == count)
480 		return 0;
481 
482 	mutex_lock(&priv->state_lock);
483 
484 	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
485 	if (was_opened)
486 		mlx5e_close_locked(dev);
487 
488 	arfs_enabled = dev->features & NETIF_F_NTUPLE;
489 	if (arfs_enabled)
490 		mlx5e_arfs_disable(priv);
491 
492 	priv->params.num_channels = count;
493 	mlx5e_build_default_indir_rqt(priv->mdev, priv->params.indirection_rqt,
494 				      MLX5E_INDIR_RQT_SIZE, count);
495 
496 	if (was_opened)
497 		err = mlx5e_open_locked(dev);
498 	if (err)
499 		goto out;
500 
501 	if (arfs_enabled) {
502 		err = mlx5e_arfs_enable(priv);
503 		if (err)
504 			netdev_err(dev, "%s: mlx5e_arfs_enable failed: %d\n",
505 				   __func__, err);
506 	}
507 
508 out:
509 	mutex_unlock(&priv->state_lock);
510 
511 	return err;
512 }
513 
514 static int mlx5e_get_coalesce(struct net_device *netdev,
515 			      struct ethtool_coalesce *coal)
516 {
517 	struct mlx5e_priv *priv = netdev_priv(netdev);
518 
519 	if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
520 		return -ENOTSUPP;
521 
522 	coal->rx_coalesce_usecs       = priv->params.rx_cq_moderation_usec;
523 	coal->rx_max_coalesced_frames = priv->params.rx_cq_moderation_pkts;
524 	coal->tx_coalesce_usecs       = priv->params.tx_cq_moderation_usec;
525 	coal->tx_max_coalesced_frames = priv->params.tx_cq_moderation_pkts;
526 
527 	return 0;
528 }
529 
530 static int mlx5e_set_coalesce(struct net_device *netdev,
531 			      struct ethtool_coalesce *coal)
532 {
533 	struct mlx5e_priv *priv    = netdev_priv(netdev);
534 	struct mlx5_core_dev *mdev = priv->mdev;
535 	struct mlx5e_channel *c;
536 	int tc;
537 	int i;
538 
539 	if (!MLX5_CAP_GEN(mdev, cq_moderation))
540 		return -ENOTSUPP;
541 
542 	mutex_lock(&priv->state_lock);
543 	priv->params.tx_cq_moderation_usec = coal->tx_coalesce_usecs;
544 	priv->params.tx_cq_moderation_pkts = coal->tx_max_coalesced_frames;
545 	priv->params.rx_cq_moderation_usec = coal->rx_coalesce_usecs;
546 	priv->params.rx_cq_moderation_pkts = coal->rx_max_coalesced_frames;
547 
548 	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
549 		goto out;
550 
551 	for (i = 0; i < priv->params.num_channels; ++i) {
552 		c = priv->channel[i];
553 
554 		for (tc = 0; tc < c->num_tc; tc++) {
555 			mlx5_core_modify_cq_moderation(mdev,
556 						&c->sq[tc].cq.mcq,
557 						coal->tx_coalesce_usecs,
558 						coal->tx_max_coalesced_frames);
559 		}
560 
561 		mlx5_core_modify_cq_moderation(mdev, &c->rq.cq.mcq,
562 					       coal->rx_coalesce_usecs,
563 					       coal->rx_max_coalesced_frames);
564 	}
565 
566 out:
567 	mutex_unlock(&priv->state_lock);
568 	return 0;
569 }
570 
571 static u32 ptys2ethtool_supported_link(u32 eth_proto_cap)
572 {
573 	int i;
574 	u32 supported_modes = 0;
575 
576 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
577 		if (eth_proto_cap & MLX5E_PROT_MASK(i))
578 			supported_modes |= ptys2ethtool_table[i].supported;
579 	}
580 	return supported_modes;
581 }
582 
583 static u32 ptys2ethtool_adver_link(u32 eth_proto_cap)
584 {
585 	int i;
586 	u32 advertising_modes = 0;
587 
588 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
589 		if (eth_proto_cap & MLX5E_PROT_MASK(i))
590 			advertising_modes |= ptys2ethtool_table[i].advertised;
591 	}
592 	return advertising_modes;
593 }
594 
595 static u32 ptys2ethtool_supported_port(u32 eth_proto_cap)
596 {
597 	if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
598 			   | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
599 			   | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
600 			   | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
601 			   | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
602 			   | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
603 		return SUPPORTED_FIBRE;
604 	}
605 
606 	if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
607 			   | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
608 			   | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
609 			   | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
610 			   | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
611 		return SUPPORTED_Backplane;
612 	}
613 	return 0;
614 }
615 
616 int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
617 {
618 	u32 max_speed = 0;
619 	u32 proto_cap;
620 	int err;
621 	int i;
622 
623 	err = mlx5_query_port_proto_cap(mdev, &proto_cap, MLX5_PTYS_EN);
624 	if (err)
625 		return err;
626 
627 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i)
628 		if (proto_cap & MLX5E_PROT_MASK(i))
629 			max_speed = max(max_speed, ptys2ethtool_table[i].speed);
630 
631 	*speed = max_speed;
632 	return 0;
633 }
634 
635 static void get_speed_duplex(struct net_device *netdev,
636 			     u32 eth_proto_oper,
637 			     struct ethtool_cmd *cmd)
638 {
639 	int i;
640 	u32 speed = SPEED_UNKNOWN;
641 	u8 duplex = DUPLEX_UNKNOWN;
642 
643 	if (!netif_carrier_ok(netdev))
644 		goto out;
645 
646 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
647 		if (eth_proto_oper & MLX5E_PROT_MASK(i)) {
648 			speed = ptys2ethtool_table[i].speed;
649 			duplex = DUPLEX_FULL;
650 			break;
651 		}
652 	}
653 out:
654 	ethtool_cmd_speed_set(cmd, speed);
655 	cmd->duplex = duplex;
656 }
657 
658 static void get_supported(u32 eth_proto_cap, u32 *supported)
659 {
660 	*supported |= ptys2ethtool_supported_port(eth_proto_cap);
661 	*supported |= ptys2ethtool_supported_link(eth_proto_cap);
662 	*supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
663 }
664 
665 static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
666 			    u8 rx_pause, u32 *advertising)
667 {
668 	*advertising |= ptys2ethtool_adver_link(eth_proto_cap);
669 	*advertising |= tx_pause ? ADVERTISED_Pause : 0;
670 	*advertising |= (tx_pause ^ rx_pause) ? ADVERTISED_Asym_Pause : 0;
671 }
672 
673 static u8 get_connector_port(u32 eth_proto)
674 {
675 	if (eth_proto & (MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
676 			 | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
677 			 | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
678 			 | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
679 			return PORT_FIBRE;
680 	}
681 
682 	if (eth_proto & (MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
683 			 | MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
684 			 | MLX5E_PROT_MASK(MLX5E_100GBASE_CR4))) {
685 			return PORT_DA;
686 	}
687 
688 	if (eth_proto & (MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
689 			 | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
690 			 | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
691 			 | MLX5E_PROT_MASK(MLX5E_100GBASE_KR4))) {
692 			return PORT_NONE;
693 	}
694 
695 	return PORT_OTHER;
696 }
697 
698 static void get_lp_advertising(u32 eth_proto_lp, u32 *lp_advertising)
699 {
700 	*lp_advertising = ptys2ethtool_adver_link(eth_proto_lp);
701 }
702 
703 static int mlx5e_get_settings(struct net_device *netdev,
704 			      struct ethtool_cmd *cmd)
705 {
706 	struct mlx5e_priv *priv    = netdev_priv(netdev);
707 	struct mlx5_core_dev *mdev = priv->mdev;
708 	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
709 	u32 eth_proto_cap;
710 	u32 eth_proto_admin;
711 	u32 eth_proto_lp;
712 	u32 eth_proto_oper;
713 	int err;
714 
715 	err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
716 
717 	if (err) {
718 		netdev_err(netdev, "%s: query port ptys failed: %d\n",
719 			   __func__, err);
720 		goto err_query_ptys;
721 	}
722 
723 	eth_proto_cap   = MLX5_GET(ptys_reg, out, eth_proto_capability);
724 	eth_proto_admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
725 	eth_proto_oper  = MLX5_GET(ptys_reg, out, eth_proto_oper);
726 	eth_proto_lp    = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
727 
728 	cmd->supported   = 0;
729 	cmd->advertising = 0;
730 
731 	get_supported(eth_proto_cap, &cmd->supported);
732 	get_advertising(eth_proto_admin, 0, 0, &cmd->advertising);
733 	get_speed_duplex(netdev, eth_proto_oper, cmd);
734 
735 	eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
736 
737 	cmd->port = get_connector_port(eth_proto_oper);
738 	get_lp_advertising(eth_proto_lp, &cmd->lp_advertising);
739 
740 	cmd->transceiver = XCVR_INTERNAL;
741 
742 err_query_ptys:
743 	return err;
744 }
745 
746 static u32 mlx5e_ethtool2ptys_adver_link(u32 link_modes)
747 {
748 	u32 i, ptys_modes = 0;
749 
750 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
751 		if (ptys2ethtool_table[i].advertised & link_modes)
752 			ptys_modes |= MLX5E_PROT_MASK(i);
753 	}
754 
755 	return ptys_modes;
756 }
757 
758 static u32 mlx5e_ethtool2ptys_speed_link(u32 speed)
759 {
760 	u32 i, speed_links = 0;
761 
762 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
763 		if (ptys2ethtool_table[i].speed == speed)
764 			speed_links |= MLX5E_PROT_MASK(i);
765 	}
766 
767 	return speed_links;
768 }
769 
770 static int mlx5e_set_settings(struct net_device *netdev,
771 			      struct ethtool_cmd *cmd)
772 {
773 	struct mlx5e_priv *priv    = netdev_priv(netdev);
774 	struct mlx5_core_dev *mdev = priv->mdev;
775 	u32 link_modes;
776 	u32 speed;
777 	u32 eth_proto_cap, eth_proto_admin;
778 	enum mlx5_port_status ps;
779 	int err;
780 
781 	speed = ethtool_cmd_speed(cmd);
782 
783 	link_modes = cmd->autoneg == AUTONEG_ENABLE ?
784 		mlx5e_ethtool2ptys_adver_link(cmd->advertising) :
785 		mlx5e_ethtool2ptys_speed_link(speed);
786 
787 	err = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
788 	if (err) {
789 		netdev_err(netdev, "%s: query port eth proto cap failed: %d\n",
790 			   __func__, err);
791 		goto out;
792 	}
793 
794 	link_modes = link_modes & eth_proto_cap;
795 	if (!link_modes) {
796 		netdev_err(netdev, "%s: Not supported link mode(s) requested",
797 			   __func__);
798 		err = -EINVAL;
799 		goto out;
800 	}
801 
802 	err = mlx5_query_port_proto_admin(mdev, &eth_proto_admin, MLX5_PTYS_EN);
803 	if (err) {
804 		netdev_err(netdev, "%s: query port eth proto admin failed: %d\n",
805 			   __func__, err);
806 		goto out;
807 	}
808 
809 	if (link_modes == eth_proto_admin)
810 		goto out;
811 
812 	mlx5_query_port_admin_status(mdev, &ps);
813 	if (ps == MLX5_PORT_UP)
814 		mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
815 	mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
816 	if (ps == MLX5_PORT_UP)
817 		mlx5_set_port_admin_status(mdev, MLX5_PORT_UP);
818 
819 out:
820 	return err;
821 }
822 
823 static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
824 {
825 	struct mlx5e_priv *priv = netdev_priv(netdev);
826 
827 	return sizeof(priv->params.toeplitz_hash_key);
828 }
829 
830 static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
831 {
832 	return MLX5E_INDIR_RQT_SIZE;
833 }
834 
835 static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
836 			  u8 *hfunc)
837 {
838 	struct mlx5e_priv *priv = netdev_priv(netdev);
839 
840 	if (indir)
841 		memcpy(indir, priv->params.indirection_rqt,
842 		       sizeof(priv->params.indirection_rqt));
843 
844 	if (key)
845 		memcpy(key, priv->params.toeplitz_hash_key,
846 		       sizeof(priv->params.toeplitz_hash_key));
847 
848 	if (hfunc)
849 		*hfunc = priv->params.rss_hfunc;
850 
851 	return 0;
852 }
853 
854 static void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
855 {
856 	struct mlx5_core_dev *mdev = priv->mdev;
857 	void *tirc = MLX5_ADDR_OF(modify_tir_in, in, ctx);
858 	int i;
859 
860 	MLX5_SET(modify_tir_in, in, bitmask.hash, 1);
861 	mlx5e_build_tir_ctx_hash(tirc, priv);
862 
863 	for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
864 		mlx5_core_modify_tir(mdev, priv->indir_tirn[i], in, inlen);
865 }
866 
867 static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
868 			  const u8 *key, const u8 hfunc)
869 {
870 	struct mlx5e_priv *priv = netdev_priv(dev);
871 	int inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
872 	void *in;
873 
874 	if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
875 	    (hfunc != ETH_RSS_HASH_XOR) &&
876 	    (hfunc != ETH_RSS_HASH_TOP))
877 		return -EINVAL;
878 
879 	in = mlx5_vzalloc(inlen);
880 	if (!in)
881 		return -ENOMEM;
882 
883 	mutex_lock(&priv->state_lock);
884 
885 	if (indir) {
886 		u32 rqtn = priv->indir_rqtn;
887 
888 		memcpy(priv->params.indirection_rqt, indir,
889 		       sizeof(priv->params.indirection_rqt));
890 		mlx5e_redirect_rqt(priv, rqtn, MLX5E_INDIR_RQT_SIZE, 0);
891 	}
892 
893 	if (key)
894 		memcpy(priv->params.toeplitz_hash_key, key,
895 		       sizeof(priv->params.toeplitz_hash_key));
896 
897 	if (hfunc != ETH_RSS_HASH_NO_CHANGE)
898 		priv->params.rss_hfunc = hfunc;
899 
900 	mlx5e_modify_tirs_hash(priv, in, inlen);
901 
902 	mutex_unlock(&priv->state_lock);
903 
904 	kvfree(in);
905 
906 	return 0;
907 }
908 
909 static int mlx5e_get_rxnfc(struct net_device *netdev,
910 			   struct ethtool_rxnfc *info, u32 *rule_locs)
911 {
912 	struct mlx5e_priv *priv = netdev_priv(netdev);
913 	int err = 0;
914 
915 	switch (info->cmd) {
916 	case ETHTOOL_GRXRINGS:
917 		info->data = priv->params.num_channels;
918 		break;
919 	default:
920 		err = -EOPNOTSUPP;
921 		break;
922 	}
923 
924 	return err;
925 }
926 
927 static int mlx5e_get_tunable(struct net_device *dev,
928 			     const struct ethtool_tunable *tuna,
929 			     void *data)
930 {
931 	const struct mlx5e_priv *priv = netdev_priv(dev);
932 	int err = 0;
933 
934 	switch (tuna->id) {
935 	case ETHTOOL_TX_COPYBREAK:
936 		*(u32 *)data = priv->params.tx_max_inline;
937 		break;
938 	default:
939 		err = -EINVAL;
940 		break;
941 	}
942 
943 	return err;
944 }
945 
946 static int mlx5e_set_tunable(struct net_device *dev,
947 			     const struct ethtool_tunable *tuna,
948 			     const void *data)
949 {
950 	struct mlx5e_priv *priv = netdev_priv(dev);
951 	struct mlx5_core_dev *mdev = priv->mdev;
952 	bool was_opened;
953 	u32 val;
954 	int err = 0;
955 
956 	switch (tuna->id) {
957 	case ETHTOOL_TX_COPYBREAK:
958 		val = *(u32 *)data;
959 		if (val > mlx5e_get_max_inline_cap(mdev)) {
960 			err = -EINVAL;
961 			break;
962 		}
963 
964 		mutex_lock(&priv->state_lock);
965 
966 		was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
967 		if (was_opened)
968 			mlx5e_close_locked(dev);
969 
970 		priv->params.tx_max_inline = val;
971 
972 		if (was_opened)
973 			err = mlx5e_open_locked(dev);
974 
975 		mutex_unlock(&priv->state_lock);
976 		break;
977 	default:
978 		err = -EINVAL;
979 		break;
980 	}
981 
982 	return err;
983 }
984 
985 static void mlx5e_get_pauseparam(struct net_device *netdev,
986 				 struct ethtool_pauseparam *pauseparam)
987 {
988 	struct mlx5e_priv *priv    = netdev_priv(netdev);
989 	struct mlx5_core_dev *mdev = priv->mdev;
990 	int err;
991 
992 	err = mlx5_query_port_pause(mdev, &pauseparam->rx_pause,
993 				    &pauseparam->tx_pause);
994 	if (err) {
995 		netdev_err(netdev, "%s: mlx5_query_port_pause failed:0x%x\n",
996 			   __func__, err);
997 	}
998 }
999 
1000 static int mlx5e_set_pauseparam(struct net_device *netdev,
1001 				struct ethtool_pauseparam *pauseparam)
1002 {
1003 	struct mlx5e_priv *priv    = netdev_priv(netdev);
1004 	struct mlx5_core_dev *mdev = priv->mdev;
1005 	int err;
1006 
1007 	if (pauseparam->autoneg)
1008 		return -EINVAL;
1009 
1010 	err = mlx5_set_port_pause(mdev,
1011 				  pauseparam->rx_pause ? 1 : 0,
1012 				  pauseparam->tx_pause ? 1 : 0);
1013 	if (err) {
1014 		netdev_err(netdev, "%s: mlx5_set_port_pause failed:0x%x\n",
1015 			   __func__, err);
1016 	}
1017 
1018 	return err;
1019 }
1020 
1021 static int mlx5e_get_ts_info(struct net_device *dev,
1022 			     struct ethtool_ts_info *info)
1023 {
1024 	struct mlx5e_priv *priv = netdev_priv(dev);
1025 	int ret;
1026 
1027 	ret = ethtool_op_get_ts_info(dev, info);
1028 	if (ret)
1029 		return ret;
1030 
1031 	info->phc_index = priv->tstamp.ptp ?
1032 			  ptp_clock_index(priv->tstamp.ptp) : -1;
1033 
1034 	if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz))
1035 		return 0;
1036 
1037 	info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
1038 				 SOF_TIMESTAMPING_RX_HARDWARE |
1039 				 SOF_TIMESTAMPING_RAW_HARDWARE;
1040 
1041 	info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) |
1042 			 (BIT(1) << HWTSTAMP_TX_ON);
1043 
1044 	info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) |
1045 			   (BIT(1) << HWTSTAMP_FILTER_ALL);
1046 
1047 	return 0;
1048 }
1049 
1050 static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
1051 {
1052 	__u32 ret = 0;
1053 
1054 	if (MLX5_CAP_GEN(mdev, wol_g))
1055 		ret |= WAKE_MAGIC;
1056 
1057 	if (MLX5_CAP_GEN(mdev, wol_s))
1058 		ret |= WAKE_MAGICSECURE;
1059 
1060 	if (MLX5_CAP_GEN(mdev, wol_a))
1061 		ret |= WAKE_ARP;
1062 
1063 	if (MLX5_CAP_GEN(mdev, wol_b))
1064 		ret |= WAKE_BCAST;
1065 
1066 	if (MLX5_CAP_GEN(mdev, wol_m))
1067 		ret |= WAKE_MCAST;
1068 
1069 	if (MLX5_CAP_GEN(mdev, wol_u))
1070 		ret |= WAKE_UCAST;
1071 
1072 	if (MLX5_CAP_GEN(mdev, wol_p))
1073 		ret |= WAKE_PHY;
1074 
1075 	return ret;
1076 }
1077 
1078 static __u32 mlx5e_refomrat_wol_mode_mlx5_to_linux(u8 mode)
1079 {
1080 	__u32 ret = 0;
1081 
1082 	if (mode & MLX5_WOL_MAGIC)
1083 		ret |= WAKE_MAGIC;
1084 
1085 	if (mode & MLX5_WOL_SECURED_MAGIC)
1086 		ret |= WAKE_MAGICSECURE;
1087 
1088 	if (mode & MLX5_WOL_ARP)
1089 		ret |= WAKE_ARP;
1090 
1091 	if (mode & MLX5_WOL_BROADCAST)
1092 		ret |= WAKE_BCAST;
1093 
1094 	if (mode & MLX5_WOL_MULTICAST)
1095 		ret |= WAKE_MCAST;
1096 
1097 	if (mode & MLX5_WOL_UNICAST)
1098 		ret |= WAKE_UCAST;
1099 
1100 	if (mode & MLX5_WOL_PHY_ACTIVITY)
1101 		ret |= WAKE_PHY;
1102 
1103 	return ret;
1104 }
1105 
1106 static u8 mlx5e_refomrat_wol_mode_linux_to_mlx5(__u32 mode)
1107 {
1108 	u8 ret = 0;
1109 
1110 	if (mode & WAKE_MAGIC)
1111 		ret |= MLX5_WOL_MAGIC;
1112 
1113 	if (mode & WAKE_MAGICSECURE)
1114 		ret |= MLX5_WOL_SECURED_MAGIC;
1115 
1116 	if (mode & WAKE_ARP)
1117 		ret |= MLX5_WOL_ARP;
1118 
1119 	if (mode & WAKE_BCAST)
1120 		ret |= MLX5_WOL_BROADCAST;
1121 
1122 	if (mode & WAKE_MCAST)
1123 		ret |= MLX5_WOL_MULTICAST;
1124 
1125 	if (mode & WAKE_UCAST)
1126 		ret |= MLX5_WOL_UNICAST;
1127 
1128 	if (mode & WAKE_PHY)
1129 		ret |= MLX5_WOL_PHY_ACTIVITY;
1130 
1131 	return ret;
1132 }
1133 
1134 static void mlx5e_get_wol(struct net_device *netdev,
1135 			  struct ethtool_wolinfo *wol)
1136 {
1137 	struct mlx5e_priv *priv = netdev_priv(netdev);
1138 	struct mlx5_core_dev *mdev = priv->mdev;
1139 	u8 mlx5_wol_mode;
1140 	int err;
1141 
1142 	memset(wol, 0, sizeof(*wol));
1143 
1144 	wol->supported = mlx5e_get_wol_supported(mdev);
1145 	if (!wol->supported)
1146 		return;
1147 
1148 	err = mlx5_query_port_wol(mdev, &mlx5_wol_mode);
1149 	if (err)
1150 		return;
1151 
1152 	wol->wolopts = mlx5e_refomrat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
1153 }
1154 
1155 static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
1156 {
1157 	struct mlx5e_priv *priv = netdev_priv(netdev);
1158 	struct mlx5_core_dev *mdev = priv->mdev;
1159 	__u32 wol_supported = mlx5e_get_wol_supported(mdev);
1160 	u32 mlx5_wol_mode;
1161 
1162 	if (!wol_supported)
1163 		return -ENOTSUPP;
1164 
1165 	if (wol->wolopts & ~wol_supported)
1166 		return -EINVAL;
1167 
1168 	mlx5_wol_mode = mlx5e_refomrat_wol_mode_linux_to_mlx5(wol->wolopts);
1169 
1170 	return mlx5_set_port_wol(mdev, mlx5_wol_mode);
1171 }
1172 
1173 static int mlx5e_set_phys_id(struct net_device *dev,
1174 			     enum ethtool_phys_id_state state)
1175 {
1176 	struct mlx5e_priv *priv = netdev_priv(dev);
1177 	struct mlx5_core_dev *mdev = priv->mdev;
1178 	u16 beacon_duration;
1179 
1180 	if (!MLX5_CAP_GEN(mdev, beacon_led))
1181 		return -EOPNOTSUPP;
1182 
1183 	switch (state) {
1184 	case ETHTOOL_ID_ACTIVE:
1185 		beacon_duration = MLX5_BEACON_DURATION_INF;
1186 		break;
1187 	case ETHTOOL_ID_INACTIVE:
1188 		beacon_duration = MLX5_BEACON_DURATION_OFF;
1189 		break;
1190 	default:
1191 		return -EOPNOTSUPP;
1192 	}
1193 
1194 	return mlx5_set_port_beacon(mdev, beacon_duration);
1195 }
1196 
1197 static int mlx5e_get_module_info(struct net_device *netdev,
1198 				 struct ethtool_modinfo *modinfo)
1199 {
1200 	struct mlx5e_priv *priv = netdev_priv(netdev);
1201 	struct mlx5_core_dev *dev = priv->mdev;
1202 	int size_read = 0;
1203 	u8 data[4];
1204 
1205 	size_read = mlx5_query_module_eeprom(dev, 0, 2, data);
1206 	if (size_read < 2)
1207 		return -EIO;
1208 
1209 	/* data[0] = identifier byte */
1210 	switch (data[0]) {
1211 	case MLX5_MODULE_ID_QSFP:
1212 		modinfo->type       = ETH_MODULE_SFF_8436;
1213 		modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1214 		break;
1215 	case MLX5_MODULE_ID_QSFP_PLUS:
1216 	case MLX5_MODULE_ID_QSFP28:
1217 		/* data[1] = revision id */
1218 		if (data[0] == MLX5_MODULE_ID_QSFP28 || data[1] >= 0x3) {
1219 			modinfo->type       = ETH_MODULE_SFF_8636;
1220 			modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
1221 		} else {
1222 			modinfo->type       = ETH_MODULE_SFF_8436;
1223 			modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1224 		}
1225 		break;
1226 	case MLX5_MODULE_ID_SFP:
1227 		modinfo->type       = ETH_MODULE_SFF_8472;
1228 		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1229 		break;
1230 	default:
1231 		netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
1232 			   __func__, data[0]);
1233 		return -EINVAL;
1234 	}
1235 
1236 	return 0;
1237 }
1238 
1239 static int mlx5e_get_module_eeprom(struct net_device *netdev,
1240 				   struct ethtool_eeprom *ee,
1241 				   u8 *data)
1242 {
1243 	struct mlx5e_priv *priv = netdev_priv(netdev);
1244 	struct mlx5_core_dev *mdev = priv->mdev;
1245 	int offset = ee->offset;
1246 	int size_read;
1247 	int i = 0;
1248 
1249 	if (!ee->len)
1250 		return -EINVAL;
1251 
1252 	memset(data, 0, ee->len);
1253 
1254 	while (i < ee->len) {
1255 		size_read = mlx5_query_module_eeprom(mdev, offset, ee->len - i,
1256 						     data + i);
1257 
1258 		if (!size_read)
1259 			/* Done reading */
1260 			return 0;
1261 
1262 		if (size_read < 0) {
1263 			netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n",
1264 				   __func__, size_read);
1265 			return 0;
1266 		}
1267 
1268 		i += size_read;
1269 		offset += size_read;
1270 	}
1271 
1272 	return 0;
1273 }
1274 
1275 const struct ethtool_ops mlx5e_ethtool_ops = {
1276 	.get_drvinfo       = mlx5e_get_drvinfo,
1277 	.get_link          = ethtool_op_get_link,
1278 	.get_strings       = mlx5e_get_strings,
1279 	.get_sset_count    = mlx5e_get_sset_count,
1280 	.get_ethtool_stats = mlx5e_get_ethtool_stats,
1281 	.get_ringparam     = mlx5e_get_ringparam,
1282 	.set_ringparam     = mlx5e_set_ringparam,
1283 	.get_channels      = mlx5e_get_channels,
1284 	.set_channels      = mlx5e_set_channels,
1285 	.get_coalesce      = mlx5e_get_coalesce,
1286 	.set_coalesce      = mlx5e_set_coalesce,
1287 	.get_settings      = mlx5e_get_settings,
1288 	.set_settings      = mlx5e_set_settings,
1289 	.get_rxfh_key_size   = mlx5e_get_rxfh_key_size,
1290 	.get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
1291 	.get_rxfh          = mlx5e_get_rxfh,
1292 	.set_rxfh          = mlx5e_set_rxfh,
1293 	.get_rxnfc         = mlx5e_get_rxnfc,
1294 	.get_tunable       = mlx5e_get_tunable,
1295 	.set_tunable       = mlx5e_set_tunable,
1296 	.get_pauseparam    = mlx5e_get_pauseparam,
1297 	.set_pauseparam    = mlx5e_set_pauseparam,
1298 	.get_ts_info       = mlx5e_get_ts_info,
1299 	.set_phys_id       = mlx5e_set_phys_id,
1300 	.get_wol	   = mlx5e_get_wol,
1301 	.set_wol	   = mlx5e_set_wol,
1302 	.get_module_info   = mlx5e_get_module_info,
1303 	.get_module_eeprom = mlx5e_get_module_eeprom,
1304 };
1305