en_ethtool.c revision 377d97393d93cca146937058986050a30857eec7
1/*
2 * Copyright (c) 2007 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
34#include <linux/kernel.h>
35#include <linux/ethtool.h>
36#include <linux/netdevice.h>
37#include <linux/mlx4/driver.h>
38#include <linux/in.h>
39#include <net/ip.h>
40
41#include "mlx4_en.h"
42#include "en_port.h"
43
44#define EN_ETHTOOL_QP_ATTACH (1ull << 63)
45#define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff)
46#define EN_ETHTOOL_WORD_MASK  cpu_to_be32(0xffffffff)
47
48static int mlx4_en_moderation_update(struct mlx4_en_priv *priv)
49{
50	int i;
51	int err = 0;
52
53	for (i = 0; i < priv->tx_ring_num; i++) {
54		priv->tx_cq[i].moder_cnt = priv->tx_frames;
55		priv->tx_cq[i].moder_time = priv->tx_usecs;
56		err = mlx4_en_set_cq_moder(priv, &priv->tx_cq[i]);
57		if (err)
58			return err;
59	}
60
61	if (priv->adaptive_rx_coal)
62		return 0;
63
64	for (i = 0; i < priv->rx_ring_num; i++) {
65		priv->rx_cq[i].moder_cnt = priv->rx_frames;
66		priv->rx_cq[i].moder_time = priv->rx_usecs;
67		priv->last_moder_time[i] = MLX4_EN_AUTO_CONF;
68		err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]);
69		if (err)
70			return err;
71	}
72
73	return err;
74}
75
76static void
77mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
78{
79	struct mlx4_en_priv *priv = netdev_priv(dev);
80	struct mlx4_en_dev *mdev = priv->mdev;
81
82	strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
83	strlcpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")",
84		sizeof(drvinfo->version));
85	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
86		"%d.%d.%d",
87		(u16) (mdev->dev->caps.fw_ver >> 32),
88		(u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff),
89		(u16) (mdev->dev->caps.fw_ver & 0xffff));
90	strlcpy(drvinfo->bus_info, pci_name(mdev->dev->pdev),
91		sizeof(drvinfo->bus_info));
92	drvinfo->n_stats = 0;
93	drvinfo->regdump_len = 0;
94	drvinfo->eedump_len = 0;
95}
96
97static const char main_strings[][ETH_GSTRING_LEN] = {
98	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
99	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
100	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
101	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
102	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
103	"tx_heartbeat_errors", "tx_window_errors",
104
105	/* port statistics */
106	"tso_packets",
107	"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
108	"rx_csum_good", "rx_csum_none", "tx_chksum_offload",
109
110	/* packet statistics */
111	"broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
112	"rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
113	"tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
114	"tx_prio_6", "tx_prio_7",
115};
116#define NUM_MAIN_STATS	21
117#define NUM_ALL_STATS	(NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
118
119static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
120	"Interrupt Test",
121	"Link Test",
122	"Speed Test",
123	"Register Test",
124	"Loopback Test",
125};
126
127static u32 mlx4_en_get_msglevel(struct net_device *dev)
128{
129	return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
130}
131
132static void mlx4_en_set_msglevel(struct net_device *dev, u32 val)
133{
134	((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable = val;
135}
136
137static void mlx4_en_get_wol(struct net_device *netdev,
138			    struct ethtool_wolinfo *wol)
139{
140	struct mlx4_en_priv *priv = netdev_priv(netdev);
141	int err = 0;
142	u64 config = 0;
143	u64 mask;
144
145	if ((priv->port < 1) || (priv->port > 2)) {
146		en_err(priv, "Failed to get WoL information\n");
147		return;
148	}
149
150	mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
151		MLX4_DEV_CAP_FLAG_WOL_PORT2;
152
153	if (!(priv->mdev->dev->caps.flags & mask)) {
154		wol->supported = 0;
155		wol->wolopts = 0;
156		return;
157	}
158
159	err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
160	if (err) {
161		en_err(priv, "Failed to get WoL information\n");
162		return;
163	}
164
165	if (config & MLX4_EN_WOL_MAGIC)
166		wol->supported = WAKE_MAGIC;
167	else
168		wol->supported = 0;
169
170	if (config & MLX4_EN_WOL_ENABLED)
171		wol->wolopts = WAKE_MAGIC;
172	else
173		wol->wolopts = 0;
174}
175
176static int mlx4_en_set_wol(struct net_device *netdev,
177			    struct ethtool_wolinfo *wol)
178{
179	struct mlx4_en_priv *priv = netdev_priv(netdev);
180	u64 config = 0;
181	int err = 0;
182	u64 mask;
183
184	if ((priv->port < 1) || (priv->port > 2))
185		return -EOPNOTSUPP;
186
187	mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
188		MLX4_DEV_CAP_FLAG_WOL_PORT2;
189
190	if (!(priv->mdev->dev->caps.flags & mask))
191		return -EOPNOTSUPP;
192
193	if (wol->supported & ~WAKE_MAGIC)
194		return -EINVAL;
195
196	err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
197	if (err) {
198		en_err(priv, "Failed to get WoL info, unable to modify\n");
199		return err;
200	}
201
202	if (wol->wolopts & WAKE_MAGIC) {
203		config |= MLX4_EN_WOL_DO_MODIFY | MLX4_EN_WOL_ENABLED |
204				MLX4_EN_WOL_MAGIC;
205	} else {
206		config &= ~(MLX4_EN_WOL_ENABLED | MLX4_EN_WOL_MAGIC);
207		config |= MLX4_EN_WOL_DO_MODIFY;
208	}
209
210	err = mlx4_wol_write(priv->mdev->dev, config, priv->port);
211	if (err)
212		en_err(priv, "Failed to set WoL information\n");
213
214	return err;
215}
216
217static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
218{
219	struct mlx4_en_priv *priv = netdev_priv(dev);
220	int bit_count = hweight64(priv->stats_bitmap);
221
222	switch (sset) {
223	case ETH_SS_STATS:
224		return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) +
225			(priv->tx_ring_num + priv->rx_ring_num) * 2;
226	case ETH_SS_TEST:
227		return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
228					& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
229	default:
230		return -EOPNOTSUPP;
231	}
232}
233
234static void mlx4_en_get_ethtool_stats(struct net_device *dev,
235		struct ethtool_stats *stats, uint64_t *data)
236{
237	struct mlx4_en_priv *priv = netdev_priv(dev);
238	int index = 0;
239	int i, j = 0;
240
241	spin_lock_bh(&priv->stats_lock);
242
243	if (!(priv->stats_bitmap)) {
244		for (i = 0; i < NUM_MAIN_STATS; i++)
245			data[index++] =
246				((unsigned long *) &priv->stats)[i];
247		for (i = 0; i < NUM_PORT_STATS; i++)
248			data[index++] =
249				((unsigned long *) &priv->port_stats)[i];
250		for (i = 0; i < NUM_PKT_STATS; i++)
251			data[index++] =
252				((unsigned long *) &priv->pkstats)[i];
253	} else {
254		for (i = 0; i < NUM_MAIN_STATS; i++) {
255			if ((priv->stats_bitmap >> j) & 1)
256				data[index++] =
257				((unsigned long *) &priv->stats)[i];
258			j++;
259		}
260		for (i = 0; i < NUM_PORT_STATS; i++) {
261			if ((priv->stats_bitmap >> j) & 1)
262				data[index++] =
263				((unsigned long *) &priv->port_stats)[i];
264			j++;
265		}
266	}
267	for (i = 0; i < priv->tx_ring_num; i++) {
268		data[index++] = priv->tx_ring[i].packets;
269		data[index++] = priv->tx_ring[i].bytes;
270	}
271	for (i = 0; i < priv->rx_ring_num; i++) {
272		data[index++] = priv->rx_ring[i].packets;
273		data[index++] = priv->rx_ring[i].bytes;
274	}
275	spin_unlock_bh(&priv->stats_lock);
276
277}
278
279static void mlx4_en_self_test(struct net_device *dev,
280			      struct ethtool_test *etest, u64 *buf)
281{
282	mlx4_en_ex_selftest(dev, &etest->flags, buf);
283}
284
285static void mlx4_en_get_strings(struct net_device *dev,
286				uint32_t stringset, uint8_t *data)
287{
288	struct mlx4_en_priv *priv = netdev_priv(dev);
289	int index = 0;
290	int i;
291
292	switch (stringset) {
293	case ETH_SS_TEST:
294		for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++)
295			strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
296		if (priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UC_LOOPBACK)
297			for (; i < MLX4_EN_NUM_SELF_TEST; i++)
298				strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
299		break;
300
301	case ETH_SS_STATS:
302		/* Add main counters */
303		if (!priv->stats_bitmap) {
304			for (i = 0; i < NUM_MAIN_STATS; i++)
305				strcpy(data + (index++) * ETH_GSTRING_LEN,
306					main_strings[i]);
307			for (i = 0; i < NUM_PORT_STATS; i++)
308				strcpy(data + (index++) * ETH_GSTRING_LEN,
309					main_strings[i +
310					NUM_MAIN_STATS]);
311			for (i = 0; i < NUM_PKT_STATS; i++)
312				strcpy(data + (index++) * ETH_GSTRING_LEN,
313					main_strings[i +
314					NUM_MAIN_STATS +
315					NUM_PORT_STATS]);
316		} else
317			for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) {
318				if ((priv->stats_bitmap >> i) & 1) {
319					strcpy(data +
320					       (index++) * ETH_GSTRING_LEN,
321					       main_strings[i]);
322				}
323				if (!(priv->stats_bitmap >> i))
324					break;
325			}
326		for (i = 0; i < priv->tx_ring_num; i++) {
327			sprintf(data + (index++) * ETH_GSTRING_LEN,
328				"tx%d_packets", i);
329			sprintf(data + (index++) * ETH_GSTRING_LEN,
330				"tx%d_bytes", i);
331		}
332		for (i = 0; i < priv->rx_ring_num; i++) {
333			sprintf(data + (index++) * ETH_GSTRING_LEN,
334				"rx%d_packets", i);
335			sprintf(data + (index++) * ETH_GSTRING_LEN,
336				"rx%d_bytes", i);
337		}
338		break;
339	}
340}
341
342static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
343{
344	struct mlx4_en_priv *priv = netdev_priv(dev);
345	int trans_type;
346
347	cmd->autoneg = AUTONEG_DISABLE;
348	cmd->supported = SUPPORTED_10000baseT_Full;
349	cmd->advertising = ADVERTISED_10000baseT_Full;
350
351	if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
352		return -ENOMEM;
353
354	trans_type = priv->port_state.transciver;
355	if (netif_carrier_ok(dev)) {
356		ethtool_cmd_speed_set(cmd, priv->port_state.link_speed);
357		cmd->duplex = DUPLEX_FULL;
358	} else {
359		ethtool_cmd_speed_set(cmd, -1);
360		cmd->duplex = -1;
361	}
362
363	if (trans_type > 0 && trans_type <= 0xC) {
364		cmd->port = PORT_FIBRE;
365		cmd->transceiver = XCVR_EXTERNAL;
366		cmd->supported |= SUPPORTED_FIBRE;
367		cmd->advertising |= ADVERTISED_FIBRE;
368	} else if (trans_type == 0x80 || trans_type == 0) {
369		cmd->port = PORT_TP;
370		cmd->transceiver = XCVR_INTERNAL;
371		cmd->supported |= SUPPORTED_TP;
372		cmd->advertising |= ADVERTISED_TP;
373	} else  {
374		cmd->port = -1;
375		cmd->transceiver = -1;
376	}
377	return 0;
378}
379
380static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
381{
382	if ((cmd->autoneg == AUTONEG_ENABLE) ||
383	    (ethtool_cmd_speed(cmd) != SPEED_10000) ||
384	    (cmd->duplex != DUPLEX_FULL))
385		return -EINVAL;
386
387	/* Nothing to change */
388	return 0;
389}
390
391static int mlx4_en_get_coalesce(struct net_device *dev,
392			      struct ethtool_coalesce *coal)
393{
394	struct mlx4_en_priv *priv = netdev_priv(dev);
395
396	coal->tx_coalesce_usecs = priv->tx_usecs;
397	coal->tx_max_coalesced_frames = priv->tx_frames;
398	coal->rx_coalesce_usecs = priv->rx_usecs;
399	coal->rx_max_coalesced_frames = priv->rx_frames;
400
401	coal->pkt_rate_low = priv->pkt_rate_low;
402	coal->rx_coalesce_usecs_low = priv->rx_usecs_low;
403	coal->pkt_rate_high = priv->pkt_rate_high;
404	coal->rx_coalesce_usecs_high = priv->rx_usecs_high;
405	coal->rate_sample_interval = priv->sample_interval;
406	coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;
407	return 0;
408}
409
410static int mlx4_en_set_coalesce(struct net_device *dev,
411			      struct ethtool_coalesce *coal)
412{
413	struct mlx4_en_priv *priv = netdev_priv(dev);
414
415	priv->rx_frames = (coal->rx_max_coalesced_frames ==
416			   MLX4_EN_AUTO_CONF) ?
417				MLX4_EN_RX_COAL_TARGET :
418				coal->rx_max_coalesced_frames;
419	priv->rx_usecs = (coal->rx_coalesce_usecs ==
420			  MLX4_EN_AUTO_CONF) ?
421				MLX4_EN_RX_COAL_TIME :
422				coal->rx_coalesce_usecs;
423
424	/* Setting TX coalescing parameters */
425	if (coal->tx_coalesce_usecs != priv->tx_usecs ||
426	    coal->tx_max_coalesced_frames != priv->tx_frames) {
427		priv->tx_usecs = coal->tx_coalesce_usecs;
428		priv->tx_frames = coal->tx_max_coalesced_frames;
429	}
430
431	/* Set adaptive coalescing params */
432	priv->pkt_rate_low = coal->pkt_rate_low;
433	priv->rx_usecs_low = coal->rx_coalesce_usecs_low;
434	priv->pkt_rate_high = coal->pkt_rate_high;
435	priv->rx_usecs_high = coal->rx_coalesce_usecs_high;
436	priv->sample_interval = coal->rate_sample_interval;
437	priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
438
439	return mlx4_en_moderation_update(priv);
440}
441
442static int mlx4_en_set_pauseparam(struct net_device *dev,
443				struct ethtool_pauseparam *pause)
444{
445	struct mlx4_en_priv *priv = netdev_priv(dev);
446	struct mlx4_en_dev *mdev = priv->mdev;
447	int err;
448
449	priv->prof->tx_pause = pause->tx_pause != 0;
450	priv->prof->rx_pause = pause->rx_pause != 0;
451	err = mlx4_SET_PORT_general(mdev->dev, priv->port,
452				    priv->rx_skb_size + ETH_FCS_LEN,
453				    priv->prof->tx_pause,
454				    priv->prof->tx_ppp,
455				    priv->prof->rx_pause,
456				    priv->prof->rx_ppp);
457	if (err)
458		en_err(priv, "Failed setting pause params\n");
459
460	return err;
461}
462
463static void mlx4_en_get_pauseparam(struct net_device *dev,
464				 struct ethtool_pauseparam *pause)
465{
466	struct mlx4_en_priv *priv = netdev_priv(dev);
467
468	pause->tx_pause = priv->prof->tx_pause;
469	pause->rx_pause = priv->prof->rx_pause;
470}
471
472static int mlx4_en_set_ringparam(struct net_device *dev,
473				 struct ethtool_ringparam *param)
474{
475	struct mlx4_en_priv *priv = netdev_priv(dev);
476	struct mlx4_en_dev *mdev = priv->mdev;
477	u32 rx_size, tx_size;
478	int port_up = 0;
479	int err = 0;
480
481	if (param->rx_jumbo_pending || param->rx_mini_pending)
482		return -EINVAL;
483
484	rx_size = roundup_pow_of_two(param->rx_pending);
485	rx_size = max_t(u32, rx_size, MLX4_EN_MIN_RX_SIZE);
486	rx_size = min_t(u32, rx_size, MLX4_EN_MAX_RX_SIZE);
487	tx_size = roundup_pow_of_two(param->tx_pending);
488	tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
489	tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
490
491	if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size :
492					priv->rx_ring[0].size) &&
493	    tx_size == priv->tx_ring[0].size)
494		return 0;
495
496	mutex_lock(&mdev->state_lock);
497	if (priv->port_up) {
498		port_up = 1;
499		mlx4_en_stop_port(dev, 1);
500	}
501
502	mlx4_en_free_resources(priv);
503
504	priv->prof->tx_ring_size = tx_size;
505	priv->prof->rx_ring_size = rx_size;
506
507	err = mlx4_en_alloc_resources(priv);
508	if (err) {
509		en_err(priv, "Failed reallocating port resources\n");
510		goto out;
511	}
512	if (port_up) {
513		err = mlx4_en_start_port(dev);
514		if (err)
515			en_err(priv, "Failed starting port\n");
516	}
517
518	err = mlx4_en_moderation_update(priv);
519
520out:
521	mutex_unlock(&mdev->state_lock);
522	return err;
523}
524
525static void mlx4_en_get_ringparam(struct net_device *dev,
526				  struct ethtool_ringparam *param)
527{
528	struct mlx4_en_priv *priv = netdev_priv(dev);
529
530	memset(param, 0, sizeof(*param));
531	param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
532	param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
533	param->rx_pending = priv->port_up ?
534		priv->rx_ring[0].actual_size : priv->rx_ring[0].size;
535	param->tx_pending = priv->tx_ring[0].size;
536}
537
538static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
539{
540	struct mlx4_en_priv *priv = netdev_priv(dev);
541
542	return priv->rx_ring_num;
543}
544
545static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
546{
547	struct mlx4_en_priv *priv = netdev_priv(dev);
548	struct mlx4_en_rss_map *rss_map = &priv->rss_map;
549	int rss_rings;
550	size_t n = priv->rx_ring_num;
551	int err = 0;
552
553	rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num;
554
555	while (n--) {
556		ring_index[n] = rss_map->qps[n % rss_rings].qpn -
557			rss_map->base_qpn;
558	}
559
560	return err;
561}
562
563static int mlx4_en_set_rxfh_indir(struct net_device *dev,
564		const u32 *ring_index)
565{
566	struct mlx4_en_priv *priv = netdev_priv(dev);
567	struct mlx4_en_dev *mdev = priv->mdev;
568	int port_up = 0;
569	int err = 0;
570	int i;
571	int rss_rings = 0;
572
573	/* Calculate RSS table size and make sure flows are spread evenly
574	 * between rings
575	 */
576	for (i = 0; i < priv->rx_ring_num; i++) {
577		if (i > 0 && !ring_index[i] && !rss_rings)
578			rss_rings = i;
579
580		if (ring_index[i] != (i % (rss_rings ?: priv->rx_ring_num)))
581			return -EINVAL;
582	}
583
584	if (!rss_rings)
585		rss_rings = priv->rx_ring_num;
586
587	/* RSS table size must be an order of 2 */
588	if (!is_power_of_2(rss_rings))
589		return -EINVAL;
590
591	mutex_lock(&mdev->state_lock);
592	if (priv->port_up) {
593		port_up = 1;
594		mlx4_en_stop_port(dev, 1);
595	}
596
597	priv->prof->rss_rings = rss_rings;
598
599	if (port_up) {
600		err = mlx4_en_start_port(dev);
601		if (err)
602			en_err(priv, "Failed starting port\n");
603	}
604
605	mutex_unlock(&mdev->state_lock);
606	return err;
607}
608
609#define all_zeros_or_all_ones(field)		\
610	((field) == 0 || (field) == (__force typeof(field))-1)
611
612static int mlx4_en_validate_flow(struct net_device *dev,
613				 struct ethtool_rxnfc *cmd)
614{
615	struct ethtool_usrip4_spec *l3_mask;
616	struct ethtool_tcpip4_spec *l4_mask;
617	struct ethhdr *eth_mask;
618
619	if (cmd->fs.location >= MAX_NUM_OF_FS_RULES)
620		return -EINVAL;
621
622	if (cmd->fs.flow_type & FLOW_MAC_EXT) {
623		/* dest mac mask must be ff:ff:ff:ff:ff:ff */
624		if (!is_broadcast_ether_addr(cmd->fs.m_ext.h_dest))
625			return -EINVAL;
626	}
627
628	switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
629	case TCP_V4_FLOW:
630	case UDP_V4_FLOW:
631		if (cmd->fs.m_u.tcp_ip4_spec.tos)
632			return -EINVAL;
633		l4_mask = &cmd->fs.m_u.tcp_ip4_spec;
634		/* don't allow mask which isn't all 0 or 1 */
635		if (!all_zeros_or_all_ones(l4_mask->ip4src) ||
636		    !all_zeros_or_all_ones(l4_mask->ip4dst) ||
637		    !all_zeros_or_all_ones(l4_mask->psrc) ||
638		    !all_zeros_or_all_ones(l4_mask->pdst))
639			return -EINVAL;
640		break;
641	case IP_USER_FLOW:
642		l3_mask = &cmd->fs.m_u.usr_ip4_spec;
643		if (l3_mask->l4_4_bytes || l3_mask->tos || l3_mask->proto ||
644		    cmd->fs.h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4 ||
645		    (!l3_mask->ip4src && !l3_mask->ip4dst) ||
646		    !all_zeros_or_all_ones(l3_mask->ip4src) ||
647		    !all_zeros_or_all_ones(l3_mask->ip4dst))
648			return -EINVAL;
649		break;
650	case ETHER_FLOW:
651		eth_mask = &cmd->fs.m_u.ether_spec;
652		/* source mac mask must not be set */
653		if (!is_zero_ether_addr(eth_mask->h_source))
654			return -EINVAL;
655
656		/* dest mac mask must be ff:ff:ff:ff:ff:ff */
657		if (!is_broadcast_ether_addr(eth_mask->h_dest))
658			return -EINVAL;
659
660		if (!all_zeros_or_all_ones(eth_mask->h_proto))
661			return -EINVAL;
662		break;
663	default:
664		return -EINVAL;
665	}
666
667	if ((cmd->fs.flow_type & FLOW_EXT)) {
668		if (cmd->fs.m_ext.vlan_etype ||
669		    !((cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK)) ==
670		      0 ||
671		      (cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK)) ==
672		      cpu_to_be16(VLAN_VID_MASK)))
673			return -EINVAL;
674
675		if (cmd->fs.m_ext.vlan_tci) {
676			if (be16_to_cpu(cmd->fs.h_ext.vlan_tci) >= VLAN_N_VID)
677				return -EINVAL;
678
679		}
680	}
681
682	return 0;
683}
684
685static int mlx4_en_ethtool_add_mac_rule(struct ethtool_rxnfc *cmd,
686					struct list_head *rule_list_h,
687					struct mlx4_spec_list *spec_l2,
688					unsigned char *mac)
689{
690	int err = 0;
691	__be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16);
692
693	spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH;
694	memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN);
695	memcpy(spec_l2->eth.dst_mac, mac, ETH_ALEN);
696
697	if ((cmd->fs.flow_type & FLOW_EXT) &&
698	    (cmd->fs.m_ext.vlan_tci & cpu_to_be16(VLAN_VID_MASK))) {
699		spec_l2->eth.vlan_id = cmd->fs.h_ext.vlan_tci;
700		spec_l2->eth.vlan_id_msk = cpu_to_be16(VLAN_VID_MASK);
701	}
702
703	list_add_tail(&spec_l2->list, rule_list_h);
704
705	return err;
706}
707
708static int mlx4_en_ethtool_add_mac_rule_by_ipv4(struct mlx4_en_priv *priv,
709						struct ethtool_rxnfc *cmd,
710						struct list_head *rule_list_h,
711						struct mlx4_spec_list *spec_l2,
712						__be32 ipv4_dst)
713{
714	__be64 be_mac = 0;
715	unsigned char mac[ETH_ALEN];
716
717	if (!ipv4_is_multicast(ipv4_dst)) {
718		if (cmd->fs.flow_type & FLOW_MAC_EXT) {
719			memcpy(&mac, cmd->fs.h_ext.h_dest, ETH_ALEN);
720		} else {
721			be_mac = cpu_to_be64((priv->mac & MLX4_MAC_MASK) << 16);
722			memcpy(&mac, &be_mac, ETH_ALEN);
723		}
724	} else {
725		ip_eth_mc_map(ipv4_dst, mac);
726	}
727
728	return mlx4_en_ethtool_add_mac_rule(cmd, rule_list_h, spec_l2, &mac[0]);
729}
730
731static int add_ip_rule(struct mlx4_en_priv *priv,
732		       struct ethtool_rxnfc *cmd,
733		       struct list_head *list_h)
734{
735	int err;
736	struct mlx4_spec_list *spec_l2 = NULL;
737	struct mlx4_spec_list *spec_l3 = NULL;
738	struct ethtool_usrip4_spec *l3_mask = &cmd->fs.m_u.usr_ip4_spec;
739
740	spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL);
741	spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL);
742	if (!spec_l2 || !spec_l3) {
743		en_err(priv, "Fail to alloc ethtool rule.\n");
744		err = -ENOMEM;
745		goto free_spec;
746	}
747
748	err = mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h, spec_l2,
749						   cmd->fs.h_u.
750						   usr_ip4_spec.ip4dst);
751	if (err)
752		goto free_spec;
753	spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4;
754	spec_l3->ipv4.src_ip = cmd->fs.h_u.usr_ip4_spec.ip4src;
755	if (l3_mask->ip4src)
756		spec_l3->ipv4.src_ip_msk = EN_ETHTOOL_WORD_MASK;
757	spec_l3->ipv4.dst_ip = cmd->fs.h_u.usr_ip4_spec.ip4dst;
758	if (l3_mask->ip4dst)
759		spec_l3->ipv4.dst_ip_msk = EN_ETHTOOL_WORD_MASK;
760	list_add_tail(&spec_l3->list, list_h);
761
762	return 0;
763
764free_spec:
765	kfree(spec_l2);
766	kfree(spec_l3);
767	return err;
768}
769
770static int add_tcp_udp_rule(struct mlx4_en_priv *priv,
771			     struct ethtool_rxnfc *cmd,
772			     struct list_head *list_h, int proto)
773{
774	int err;
775	struct mlx4_spec_list *spec_l2 = NULL;
776	struct mlx4_spec_list *spec_l3 = NULL;
777	struct mlx4_spec_list *spec_l4 = NULL;
778	struct ethtool_tcpip4_spec *l4_mask = &cmd->fs.m_u.tcp_ip4_spec;
779
780	spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL);
781	spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL);
782	spec_l4 = kzalloc(sizeof(*spec_l4), GFP_KERNEL);
783	if (!spec_l2 || !spec_l3 || !spec_l4) {
784		en_err(priv, "Fail to alloc ethtool rule.\n");
785		err = -ENOMEM;
786		goto free_spec;
787	}
788
789	spec_l3->id = MLX4_NET_TRANS_RULE_ID_IPV4;
790
791	if (proto == TCP_V4_FLOW) {
792		err = mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h,
793							   spec_l2,
794							   cmd->fs.h_u.
795							   tcp_ip4_spec.ip4dst);
796		if (err)
797			goto free_spec;
798		spec_l4->id = MLX4_NET_TRANS_RULE_ID_TCP;
799		spec_l3->ipv4.src_ip = cmd->fs.h_u.tcp_ip4_spec.ip4src;
800		spec_l3->ipv4.dst_ip = cmd->fs.h_u.tcp_ip4_spec.ip4dst;
801		spec_l4->tcp_udp.src_port = cmd->fs.h_u.tcp_ip4_spec.psrc;
802		spec_l4->tcp_udp.dst_port = cmd->fs.h_u.tcp_ip4_spec.pdst;
803	} else {
804		err = mlx4_en_ethtool_add_mac_rule_by_ipv4(priv, cmd, list_h,
805							   spec_l2,
806							   cmd->fs.h_u.
807							   udp_ip4_spec.ip4dst);
808		if (err)
809			goto free_spec;
810		spec_l4->id = MLX4_NET_TRANS_RULE_ID_UDP;
811		spec_l3->ipv4.src_ip = cmd->fs.h_u.udp_ip4_spec.ip4src;
812		spec_l3->ipv4.dst_ip = cmd->fs.h_u.udp_ip4_spec.ip4dst;
813		spec_l4->tcp_udp.src_port = cmd->fs.h_u.udp_ip4_spec.psrc;
814		spec_l4->tcp_udp.dst_port = cmd->fs.h_u.udp_ip4_spec.pdst;
815	}
816
817	if (l4_mask->ip4src)
818		spec_l3->ipv4.src_ip_msk = EN_ETHTOOL_WORD_MASK;
819	if (l4_mask->ip4dst)
820		spec_l3->ipv4.dst_ip_msk = EN_ETHTOOL_WORD_MASK;
821
822	if (l4_mask->psrc)
823		spec_l4->tcp_udp.src_port_msk = EN_ETHTOOL_SHORT_MASK;
824	if (l4_mask->pdst)
825		spec_l4->tcp_udp.dst_port_msk = EN_ETHTOOL_SHORT_MASK;
826
827	list_add_tail(&spec_l3->list, list_h);
828	list_add_tail(&spec_l4->list, list_h);
829
830	return 0;
831
832free_spec:
833	kfree(spec_l2);
834	kfree(spec_l3);
835	kfree(spec_l4);
836	return err;
837}
838
839static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev,
840					     struct ethtool_rxnfc *cmd,
841					     struct list_head *rule_list_h)
842{
843	int err;
844	struct ethhdr *eth_spec;
845	struct mlx4_spec_list *spec_l2;
846	struct mlx4_en_priv *priv = netdev_priv(dev);
847
848	err = mlx4_en_validate_flow(dev, cmd);
849	if (err)
850		return err;
851
852	switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
853	case ETHER_FLOW:
854		spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL);
855		if (!spec_l2)
856			return -ENOMEM;
857
858		eth_spec = &cmd->fs.h_u.ether_spec;
859		mlx4_en_ethtool_add_mac_rule(cmd, rule_list_h, spec_l2,
860					     &eth_spec->h_dest[0]);
861		spec_l2->eth.ether_type = eth_spec->h_proto;
862		if (eth_spec->h_proto)
863			spec_l2->eth.ether_type_enable = 1;
864		break;
865	case IP_USER_FLOW:
866		err = add_ip_rule(priv, cmd, rule_list_h);
867		break;
868	case TCP_V4_FLOW:
869		err = add_tcp_udp_rule(priv, cmd, rule_list_h, TCP_V4_FLOW);
870		break;
871	case UDP_V4_FLOW:
872		err = add_tcp_udp_rule(priv, cmd, rule_list_h, UDP_V4_FLOW);
873		break;
874	}
875
876	return err;
877}
878
879static int mlx4_en_flow_replace(struct net_device *dev,
880				struct ethtool_rxnfc *cmd)
881{
882	int err;
883	struct mlx4_en_priv *priv = netdev_priv(dev);
884	struct ethtool_flow_id *loc_rule;
885	struct mlx4_spec_list *spec, *tmp_spec;
886	u32 qpn;
887	u64 reg_id;
888
889	struct mlx4_net_trans_rule rule = {
890		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
891		.exclusive = 0,
892		.allow_loopback = 1,
893		.promisc_mode = MLX4_FS_PROMISC_NONE,
894	};
895
896	rule.port = priv->port;
897	rule.priority = MLX4_DOMAIN_ETHTOOL | cmd->fs.location;
898	INIT_LIST_HEAD(&rule.list);
899
900	/* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */
901	if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC)
902		qpn = priv->drop_qp.qpn;
903	else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) {
904		qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1);
905	} else {
906		if (cmd->fs.ring_cookie >= priv->rx_ring_num) {
907			en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist.\n",
908				cmd->fs.ring_cookie);
909			return -EINVAL;
910		}
911		qpn = priv->rss_map.qps[cmd->fs.ring_cookie].qpn;
912		if (!qpn) {
913			en_warn(priv, "rxnfc: RX ring (%llu) is inactive.\n",
914				cmd->fs.ring_cookie);
915			return -EINVAL;
916		}
917	}
918	rule.qpn = qpn;
919	err = mlx4_en_ethtool_to_net_trans_rule(dev, cmd, &rule.list);
920	if (err)
921		goto out_free_list;
922
923	loc_rule = &priv->ethtool_rules[cmd->fs.location];
924	if (loc_rule->id) {
925		err = mlx4_flow_detach(priv->mdev->dev, loc_rule->id);
926		if (err) {
927			en_err(priv, "Fail to detach network rule at location %d. registration id = %llx\n",
928			       cmd->fs.location, loc_rule->id);
929			goto out_free_list;
930		}
931		loc_rule->id = 0;
932		memset(&loc_rule->flow_spec, 0,
933		       sizeof(struct ethtool_rx_flow_spec));
934		list_del(&loc_rule->list);
935	}
936	err = mlx4_flow_attach(priv->mdev->dev, &rule, &reg_id);
937	if (err) {
938		en_err(priv, "Fail to attach network rule at location %d.\n",
939		       cmd->fs.location);
940		goto out_free_list;
941	}
942	loc_rule->id = reg_id;
943	memcpy(&loc_rule->flow_spec, &cmd->fs,
944	       sizeof(struct ethtool_rx_flow_spec));
945	list_add_tail(&loc_rule->list, &priv->ethtool_list);
946
947out_free_list:
948	list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) {
949		list_del(&spec->list);
950		kfree(spec);
951	}
952	return err;
953}
954
955static int mlx4_en_flow_detach(struct net_device *dev,
956			       struct ethtool_rxnfc *cmd)
957{
958	int err = 0;
959	struct ethtool_flow_id *rule;
960	struct mlx4_en_priv *priv = netdev_priv(dev);
961
962	if (cmd->fs.location >= MAX_NUM_OF_FS_RULES)
963		return -EINVAL;
964
965	rule = &priv->ethtool_rules[cmd->fs.location];
966	if (!rule->id) {
967		err =  -ENOENT;
968		goto out;
969	}
970
971	err = mlx4_flow_detach(priv->mdev->dev, rule->id);
972	if (err) {
973		en_err(priv, "Fail to detach network rule at location %d. registration id = 0x%llx\n",
974		       cmd->fs.location, rule->id);
975		goto out;
976	}
977	rule->id = 0;
978	memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec));
979	list_del(&rule->list);
980out:
981	return err;
982
983}
984
985static int mlx4_en_get_flow(struct net_device *dev, struct ethtool_rxnfc *cmd,
986			    int loc)
987{
988	int err = 0;
989	struct ethtool_flow_id *rule;
990	struct mlx4_en_priv *priv = netdev_priv(dev);
991
992	if (loc < 0 || loc >= MAX_NUM_OF_FS_RULES)
993		return -EINVAL;
994
995	rule = &priv->ethtool_rules[loc];
996	if (rule->id)
997		memcpy(&cmd->fs, &rule->flow_spec,
998		       sizeof(struct ethtool_rx_flow_spec));
999	else
1000		err = -ENOENT;
1001
1002	return err;
1003}
1004
1005static int mlx4_en_get_num_flows(struct mlx4_en_priv *priv)
1006{
1007
1008	int i, res = 0;
1009	for (i = 0; i < MAX_NUM_OF_FS_RULES; i++) {
1010		if (priv->ethtool_rules[i].id)
1011			res++;
1012	}
1013	return res;
1014
1015}
1016
1017static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
1018			     u32 *rule_locs)
1019{
1020	struct mlx4_en_priv *priv = netdev_priv(dev);
1021	struct mlx4_en_dev *mdev = priv->mdev;
1022	int err = 0;
1023	int i = 0, priority = 0;
1024
1025	if ((cmd->cmd == ETHTOOL_GRXCLSRLCNT ||
1026	     cmd->cmd == ETHTOOL_GRXCLSRULE ||
1027	     cmd->cmd == ETHTOOL_GRXCLSRLALL) &&
1028	    (mdev->dev->caps.steering_mode !=
1029	     MLX4_STEERING_MODE_DEVICE_MANAGED || !priv->port_up))
1030		return -EINVAL;
1031
1032	switch (cmd->cmd) {
1033	case ETHTOOL_GRXRINGS:
1034		cmd->data = priv->rx_ring_num;
1035		break;
1036	case ETHTOOL_GRXCLSRLCNT:
1037		cmd->rule_cnt = mlx4_en_get_num_flows(priv);
1038		break;
1039	case ETHTOOL_GRXCLSRULE:
1040		err = mlx4_en_get_flow(dev, cmd, cmd->fs.location);
1041		break;
1042	case ETHTOOL_GRXCLSRLALL:
1043		while ((!err || err == -ENOENT) && priority < cmd->rule_cnt) {
1044			err = mlx4_en_get_flow(dev, cmd, i);
1045			if (!err)
1046				rule_locs[priority++] = i;
1047			i++;
1048		}
1049		err = 0;
1050		break;
1051	default:
1052		err = -EOPNOTSUPP;
1053		break;
1054	}
1055
1056	return err;
1057}
1058
1059static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
1060{
1061	int err = 0;
1062	struct mlx4_en_priv *priv = netdev_priv(dev);
1063	struct mlx4_en_dev *mdev = priv->mdev;
1064
1065	if (mdev->dev->caps.steering_mode !=
1066	    MLX4_STEERING_MODE_DEVICE_MANAGED || !priv->port_up)
1067		return -EINVAL;
1068
1069	switch (cmd->cmd) {
1070	case ETHTOOL_SRXCLSRLINS:
1071		err = mlx4_en_flow_replace(dev, cmd);
1072		break;
1073	case ETHTOOL_SRXCLSRLDEL:
1074		err = mlx4_en_flow_detach(dev, cmd);
1075		break;
1076	default:
1077		en_warn(priv, "Unsupported ethtool command. (%d)\n", cmd->cmd);
1078		return -EINVAL;
1079	}
1080
1081	return err;
1082}
1083
1084static void mlx4_en_get_channels(struct net_device *dev,
1085				 struct ethtool_channels *channel)
1086{
1087	struct mlx4_en_priv *priv = netdev_priv(dev);
1088
1089	memset(channel, 0, sizeof(*channel));
1090
1091	channel->max_rx = MAX_RX_RINGS;
1092	channel->max_tx = MLX4_EN_MAX_TX_RING_P_UP;
1093
1094	channel->rx_count = priv->rx_ring_num;
1095	channel->tx_count = priv->tx_ring_num / MLX4_EN_NUM_UP;
1096}
1097
1098static int mlx4_en_set_channels(struct net_device *dev,
1099				struct ethtool_channels *channel)
1100{
1101	struct mlx4_en_priv *priv = netdev_priv(dev);
1102	struct mlx4_en_dev *mdev = priv->mdev;
1103	int port_up;
1104	int err = 0;
1105
1106	if (channel->other_count || channel->combined_count ||
1107	    channel->tx_count > MLX4_EN_MAX_TX_RING_P_UP ||
1108	    channel->rx_count > MAX_RX_RINGS ||
1109	    !channel->tx_count || !channel->rx_count)
1110		return -EINVAL;
1111
1112	mutex_lock(&mdev->state_lock);
1113	if (priv->port_up) {
1114		port_up = 1;
1115		mlx4_en_stop_port(dev, 1);
1116	}
1117
1118	mlx4_en_free_resources(priv);
1119
1120	priv->num_tx_rings_p_up = channel->tx_count;
1121	priv->tx_ring_num = channel->tx_count * MLX4_EN_NUM_UP;
1122	priv->rx_ring_num = channel->rx_count;
1123
1124	err = mlx4_en_alloc_resources(priv);
1125	if (err) {
1126		en_err(priv, "Failed reallocating port resources\n");
1127		goto out;
1128	}
1129
1130	netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
1131	netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
1132
1133	mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP);
1134
1135	en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num);
1136	en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);
1137
1138	if (port_up) {
1139		err = mlx4_en_start_port(dev);
1140		if (err)
1141			en_err(priv, "Failed starting port\n");
1142	}
1143
1144	err = mlx4_en_moderation_update(priv);
1145
1146out:
1147	mutex_unlock(&mdev->state_lock);
1148	return err;
1149}
1150
1151const struct ethtool_ops mlx4_en_ethtool_ops = {
1152	.get_drvinfo = mlx4_en_get_drvinfo,
1153	.get_settings = mlx4_en_get_settings,
1154	.set_settings = mlx4_en_set_settings,
1155	.get_link = ethtool_op_get_link,
1156	.get_strings = mlx4_en_get_strings,
1157	.get_sset_count = mlx4_en_get_sset_count,
1158	.get_ethtool_stats = mlx4_en_get_ethtool_stats,
1159	.self_test = mlx4_en_self_test,
1160	.get_wol = mlx4_en_get_wol,
1161	.set_wol = mlx4_en_set_wol,
1162	.get_msglevel = mlx4_en_get_msglevel,
1163	.set_msglevel = mlx4_en_set_msglevel,
1164	.get_coalesce = mlx4_en_get_coalesce,
1165	.set_coalesce = mlx4_en_set_coalesce,
1166	.get_pauseparam = mlx4_en_get_pauseparam,
1167	.set_pauseparam = mlx4_en_set_pauseparam,
1168	.get_ringparam = mlx4_en_get_ringparam,
1169	.set_ringparam = mlx4_en_set_ringparam,
1170	.get_rxnfc = mlx4_en_get_rxnfc,
1171	.set_rxnfc = mlx4_en_set_rxnfc,
1172	.get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
1173	.get_rxfh_indir = mlx4_en_get_rxfh_indir,
1174	.set_rxfh_indir = mlx4_en_set_rxfh_indir,
1175	.get_channels = mlx4_en_get_channels,
1176	.set_channels = mlx4_en_set_channels,
1177};
1178
1179
1180
1181
1182
1183