2 * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
34 #include <linux/kernel.h>
35 #include <linux/ethtool.h>
36 #include <linux/netdevice.h>
41 #define EN_ETHTOOL_QP_ATTACH (1ull << 63)
42 #define EN_ETHTOOL_MAC_MASK 0xffffffffffffULL
43 #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff)
44 #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff)
47 mlx4_en_get_drvinfo(struct net_device
*dev
, struct ethtool_drvinfo
*drvinfo
)
49 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
50 struct mlx4_en_dev
*mdev
= priv
->mdev
;
52 strlcpy(drvinfo
->driver
, DRV_NAME
, sizeof(drvinfo
->driver
));
53 strlcpy(drvinfo
->version
, DRV_VERSION
" (" DRV_RELDATE
")",
54 sizeof(drvinfo
->version
));
55 snprintf(drvinfo
->fw_version
, sizeof(drvinfo
->fw_version
),
57 (u16
) (mdev
->dev
->caps
.fw_ver
>> 32),
58 (u16
) ((mdev
->dev
->caps
.fw_ver
>> 16) & 0xffff),
59 (u16
) (mdev
->dev
->caps
.fw_ver
& 0xffff));
60 strlcpy(drvinfo
->bus_info
, pci_name(mdev
->dev
->pdev
),
61 sizeof(drvinfo
->bus_info
));
63 drvinfo
->regdump_len
= 0;
64 drvinfo
->eedump_len
= 0;
67 static const char main_strings
[][ETH_GSTRING_LEN
] = {
68 "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
69 "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
70 "rx_length_errors", "rx_over_errors", "rx_crc_errors",
71 "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
72 "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
73 "tx_heartbeat_errors", "tx_window_errors",
77 "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
78 "rx_csum_good", "rx_csum_none", "tx_chksum_offload",
80 /* packet statistics */
81 "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
82 "rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
83 "tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
84 "tx_prio_6", "tx_prio_7",
86 #define NUM_MAIN_STATS 21
87 #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
89 static const char mlx4_en_test_names
[][ETH_GSTRING_LEN
]= {
97 static u32
mlx4_en_get_msglevel(struct net_device
*dev
)
99 return ((struct mlx4_en_priv
*) netdev_priv(dev
))->msg_enable
;
102 static void mlx4_en_set_msglevel(struct net_device
*dev
, u32 val
)
104 ((struct mlx4_en_priv
*) netdev_priv(dev
))->msg_enable
= val
;
107 static void mlx4_en_get_wol(struct net_device
*netdev
,
108 struct ethtool_wolinfo
*wol
)
110 struct mlx4_en_priv
*priv
= netdev_priv(netdev
);
115 if ((priv
->port
< 1) || (priv
->port
> 2)) {
116 en_err(priv
, "Failed to get WoL information\n");
120 mask
= (priv
->port
== 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1
:
121 MLX4_DEV_CAP_FLAG_WOL_PORT2
;
123 if (!(priv
->mdev
->dev
->caps
.flags
& mask
)) {
129 err
= mlx4_wol_read(priv
->mdev
->dev
, &config
, priv
->port
);
131 en_err(priv
, "Failed to get WoL information\n");
135 if (config
& MLX4_EN_WOL_MAGIC
)
136 wol
->supported
= WAKE_MAGIC
;
140 if (config
& MLX4_EN_WOL_ENABLED
)
141 wol
->wolopts
= WAKE_MAGIC
;
146 static int mlx4_en_set_wol(struct net_device
*netdev
,
147 struct ethtool_wolinfo
*wol
)
149 struct mlx4_en_priv
*priv
= netdev_priv(netdev
);
154 if ((priv
->port
< 1) || (priv
->port
> 2))
157 mask
= (priv
->port
== 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1
:
158 MLX4_DEV_CAP_FLAG_WOL_PORT2
;
160 if (!(priv
->mdev
->dev
->caps
.flags
& mask
))
163 if (wol
->supported
& ~WAKE_MAGIC
)
166 err
= mlx4_wol_read(priv
->mdev
->dev
, &config
, priv
->port
);
168 en_err(priv
, "Failed to get WoL info, unable to modify\n");
172 if (wol
->wolopts
& WAKE_MAGIC
) {
173 config
|= MLX4_EN_WOL_DO_MODIFY
| MLX4_EN_WOL_ENABLED
|
176 config
&= ~(MLX4_EN_WOL_ENABLED
| MLX4_EN_WOL_MAGIC
);
177 config
|= MLX4_EN_WOL_DO_MODIFY
;
180 err
= mlx4_wol_write(priv
->mdev
->dev
, config
, priv
->port
);
182 en_err(priv
, "Failed to set WoL information\n");
187 static int mlx4_en_get_sset_count(struct net_device
*dev
, int sset
)
189 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
190 int bit_count
= hweight64(priv
->stats_bitmap
);
194 return (priv
->stats_bitmap
? bit_count
: NUM_ALL_STATS
) +
195 (priv
->tx_ring_num
+ priv
->rx_ring_num
) * 2;
197 return MLX4_EN_NUM_SELF_TEST
- !(priv
->mdev
->dev
->caps
.flags
198 & MLX4_DEV_CAP_FLAG_UC_LOOPBACK
) * 2;
204 static void mlx4_en_get_ethtool_stats(struct net_device
*dev
,
205 struct ethtool_stats
*stats
, uint64_t *data
)
207 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
211 spin_lock_bh(&priv
->stats_lock
);
213 if (!(priv
->stats_bitmap
)) {
214 for (i
= 0; i
< NUM_MAIN_STATS
; i
++)
216 ((unsigned long *) &priv
->stats
)[i
];
217 for (i
= 0; i
< NUM_PORT_STATS
; i
++)
219 ((unsigned long *) &priv
->port_stats
)[i
];
220 for (i
= 0; i
< NUM_PKT_STATS
; i
++)
222 ((unsigned long *) &priv
->pkstats
)[i
];
224 for (i
= 0; i
< NUM_MAIN_STATS
; i
++) {
225 if ((priv
->stats_bitmap
>> j
) & 1)
227 ((unsigned long *) &priv
->stats
)[i
];
230 for (i
= 0; i
< NUM_PORT_STATS
; i
++) {
231 if ((priv
->stats_bitmap
>> j
) & 1)
233 ((unsigned long *) &priv
->port_stats
)[i
];
237 for (i
= 0; i
< priv
->tx_ring_num
; i
++) {
238 data
[index
++] = priv
->tx_ring
[i
].packets
;
239 data
[index
++] = priv
->tx_ring
[i
].bytes
;
241 for (i
= 0; i
< priv
->rx_ring_num
; i
++) {
242 data
[index
++] = priv
->rx_ring
[i
].packets
;
243 data
[index
++] = priv
->rx_ring
[i
].bytes
;
245 spin_unlock_bh(&priv
->stats_lock
);
249 static void mlx4_en_self_test(struct net_device
*dev
,
250 struct ethtool_test
*etest
, u64
*buf
)
252 mlx4_en_ex_selftest(dev
, &etest
->flags
, buf
);
255 static void mlx4_en_get_strings(struct net_device
*dev
,
256 uint32_t stringset
, uint8_t *data
)
258 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
264 for (i
= 0; i
< MLX4_EN_NUM_SELF_TEST
- 2; i
++)
265 strcpy(data
+ i
* ETH_GSTRING_LEN
, mlx4_en_test_names
[i
]);
266 if (priv
->mdev
->dev
->caps
.flags
& MLX4_DEV_CAP_FLAG_UC_LOOPBACK
)
267 for (; i
< MLX4_EN_NUM_SELF_TEST
; i
++)
268 strcpy(data
+ i
* ETH_GSTRING_LEN
, mlx4_en_test_names
[i
]);
272 /* Add main counters */
273 if (!priv
->stats_bitmap
) {
274 for (i
= 0; i
< NUM_MAIN_STATS
; i
++)
275 strcpy(data
+ (index
++) * ETH_GSTRING_LEN
,
277 for (i
= 0; i
< NUM_PORT_STATS
; i
++)
278 strcpy(data
+ (index
++) * ETH_GSTRING_LEN
,
281 for (i
= 0; i
< NUM_PKT_STATS
; i
++)
282 strcpy(data
+ (index
++) * ETH_GSTRING_LEN
,
287 for (i
= 0; i
< NUM_MAIN_STATS
+ NUM_PORT_STATS
; i
++) {
288 if ((priv
->stats_bitmap
>> i
) & 1) {
290 (index
++) * ETH_GSTRING_LEN
,
293 if (!(priv
->stats_bitmap
>> i
))
296 for (i
= 0; i
< priv
->tx_ring_num
; i
++) {
297 sprintf(data
+ (index
++) * ETH_GSTRING_LEN
,
299 sprintf(data
+ (index
++) * ETH_GSTRING_LEN
,
302 for (i
= 0; i
< priv
->rx_ring_num
; i
++) {
303 sprintf(data
+ (index
++) * ETH_GSTRING_LEN
,
305 sprintf(data
+ (index
++) * ETH_GSTRING_LEN
,
312 static int mlx4_en_get_settings(struct net_device
*dev
, struct ethtool_cmd
*cmd
)
314 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
317 cmd
->autoneg
= AUTONEG_DISABLE
;
318 cmd
->supported
= SUPPORTED_10000baseT_Full
;
319 cmd
->advertising
= ADVERTISED_10000baseT_Full
;
321 if (mlx4_en_QUERY_PORT(priv
->mdev
, priv
->port
))
324 trans_type
= priv
->port_state
.transciver
;
325 if (netif_carrier_ok(dev
)) {
326 ethtool_cmd_speed_set(cmd
, priv
->port_state
.link_speed
);
327 cmd
->duplex
= DUPLEX_FULL
;
329 ethtool_cmd_speed_set(cmd
, -1);
333 if (trans_type
> 0 && trans_type
<= 0xC) {
334 cmd
->port
= PORT_FIBRE
;
335 cmd
->transceiver
= XCVR_EXTERNAL
;
336 cmd
->supported
|= SUPPORTED_FIBRE
;
337 cmd
->advertising
|= ADVERTISED_FIBRE
;
338 } else if (trans_type
== 0x80 || trans_type
== 0) {
340 cmd
->transceiver
= XCVR_INTERNAL
;
341 cmd
->supported
|= SUPPORTED_TP
;
342 cmd
->advertising
|= ADVERTISED_TP
;
345 cmd
->transceiver
= -1;
350 static int mlx4_en_set_settings(struct net_device
*dev
, struct ethtool_cmd
*cmd
)
352 if ((cmd
->autoneg
== AUTONEG_ENABLE
) ||
353 (ethtool_cmd_speed(cmd
) != SPEED_10000
) ||
354 (cmd
->duplex
!= DUPLEX_FULL
))
357 /* Nothing to change */
361 static int mlx4_en_get_coalesce(struct net_device
*dev
,
362 struct ethtool_coalesce
*coal
)
364 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
366 coal
->tx_coalesce_usecs
= priv
->tx_usecs
;
367 coal
->tx_max_coalesced_frames
= priv
->tx_frames
;
368 coal
->rx_coalesce_usecs
= priv
->rx_usecs
;
369 coal
->rx_max_coalesced_frames
= priv
->rx_frames
;
371 coal
->pkt_rate_low
= priv
->pkt_rate_low
;
372 coal
->rx_coalesce_usecs_low
= priv
->rx_usecs_low
;
373 coal
->pkt_rate_high
= priv
->pkt_rate_high
;
374 coal
->rx_coalesce_usecs_high
= priv
->rx_usecs_high
;
375 coal
->rate_sample_interval
= priv
->sample_interval
;
376 coal
->use_adaptive_rx_coalesce
= priv
->adaptive_rx_coal
;
380 static int mlx4_en_set_coalesce(struct net_device
*dev
,
381 struct ethtool_coalesce
*coal
)
383 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
386 priv
->rx_frames
= (coal
->rx_max_coalesced_frames
==
388 MLX4_EN_RX_COAL_TARGET
:
389 coal
->rx_max_coalesced_frames
;
390 priv
->rx_usecs
= (coal
->rx_coalesce_usecs
==
392 MLX4_EN_RX_COAL_TIME
:
393 coal
->rx_coalesce_usecs
;
395 /* Setting TX coalescing parameters */
396 if (coal
->tx_coalesce_usecs
!= priv
->tx_usecs
||
397 coal
->tx_max_coalesced_frames
!= priv
->tx_frames
) {
398 priv
->tx_usecs
= coal
->tx_coalesce_usecs
;
399 priv
->tx_frames
= coal
->tx_max_coalesced_frames
;
400 for (i
= 0; i
< priv
->tx_ring_num
; i
++) {
401 priv
->tx_cq
[i
].moder_cnt
= priv
->tx_frames
;
402 priv
->tx_cq
[i
].moder_time
= priv
->tx_usecs
;
403 if (mlx4_en_set_cq_moder(priv
, &priv
->tx_cq
[i
])) {
404 en_warn(priv
, "Failed changing moderation "
405 "for TX cq %d\n", i
);
410 /* Set adaptive coalescing params */
411 priv
->pkt_rate_low
= coal
->pkt_rate_low
;
412 priv
->rx_usecs_low
= coal
->rx_coalesce_usecs_low
;
413 priv
->pkt_rate_high
= coal
->pkt_rate_high
;
414 priv
->rx_usecs_high
= coal
->rx_coalesce_usecs_high
;
415 priv
->sample_interval
= coal
->rate_sample_interval
;
416 priv
->adaptive_rx_coal
= coal
->use_adaptive_rx_coalesce
;
417 if (priv
->adaptive_rx_coal
)
420 for (i
= 0; i
< priv
->rx_ring_num
; i
++) {
421 priv
->rx_cq
[i
].moder_cnt
= priv
->rx_frames
;
422 priv
->rx_cq
[i
].moder_time
= priv
->rx_usecs
;
423 priv
->last_moder_time
[i
] = MLX4_EN_AUTO_CONF
;
424 err
= mlx4_en_set_cq_moder(priv
, &priv
->rx_cq
[i
]);
431 static int mlx4_en_set_pauseparam(struct net_device
*dev
,
432 struct ethtool_pauseparam
*pause
)
434 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
435 struct mlx4_en_dev
*mdev
= priv
->mdev
;
438 priv
->prof
->tx_pause
= pause
->tx_pause
!= 0;
439 priv
->prof
->rx_pause
= pause
->rx_pause
!= 0;
440 err
= mlx4_SET_PORT_general(mdev
->dev
, priv
->port
,
441 priv
->rx_skb_size
+ ETH_FCS_LEN
,
442 priv
->prof
->tx_pause
,
444 priv
->prof
->rx_pause
,
447 en_err(priv
, "Failed setting pause params\n");
452 static void mlx4_en_get_pauseparam(struct net_device
*dev
,
453 struct ethtool_pauseparam
*pause
)
455 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
457 pause
->tx_pause
= priv
->prof
->tx_pause
;
458 pause
->rx_pause
= priv
->prof
->rx_pause
;
461 static int mlx4_en_set_ringparam(struct net_device
*dev
,
462 struct ethtool_ringparam
*param
)
464 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
465 struct mlx4_en_dev
*mdev
= priv
->mdev
;
466 u32 rx_size
, tx_size
;
471 if (param
->rx_jumbo_pending
|| param
->rx_mini_pending
)
474 rx_size
= roundup_pow_of_two(param
->rx_pending
);
475 rx_size
= max_t(u32
, rx_size
, MLX4_EN_MIN_RX_SIZE
);
476 rx_size
= min_t(u32
, rx_size
, MLX4_EN_MAX_RX_SIZE
);
477 tx_size
= roundup_pow_of_two(param
->tx_pending
);
478 tx_size
= max_t(u32
, tx_size
, MLX4_EN_MIN_TX_SIZE
);
479 tx_size
= min_t(u32
, tx_size
, MLX4_EN_MAX_TX_SIZE
);
481 if (rx_size
== (priv
->port_up
? priv
->rx_ring
[0].actual_size
:
482 priv
->rx_ring
[0].size
) &&
483 tx_size
== priv
->tx_ring
[0].size
)
486 mutex_lock(&mdev
->state_lock
);
489 mlx4_en_stop_port(dev
);
492 mlx4_en_free_resources(priv
);
494 priv
->prof
->tx_ring_size
= tx_size
;
495 priv
->prof
->rx_ring_size
= rx_size
;
497 err
= mlx4_en_alloc_resources(priv
);
499 en_err(priv
, "Failed reallocating port resources\n");
503 err
= mlx4_en_start_port(dev
);
505 en_err(priv
, "Failed starting port\n");
508 for (i
= 0; i
< priv
->rx_ring_num
; i
++) {
509 priv
->rx_cq
[i
].moder_cnt
= priv
->rx_frames
;
510 priv
->rx_cq
[i
].moder_time
= priv
->rx_usecs
;
511 priv
->last_moder_time
[i
] = MLX4_EN_AUTO_CONF
;
512 err
= mlx4_en_set_cq_moder(priv
, &priv
->rx_cq
[i
]);
518 mutex_unlock(&mdev
->state_lock
);
522 static void mlx4_en_get_ringparam(struct net_device
*dev
,
523 struct ethtool_ringparam
*param
)
525 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
527 memset(param
, 0, sizeof(*param
));
528 param
->rx_max_pending
= MLX4_EN_MAX_RX_SIZE
;
529 param
->tx_max_pending
= MLX4_EN_MAX_TX_SIZE
;
530 param
->rx_pending
= priv
->port_up
?
531 priv
->rx_ring
[0].actual_size
: priv
->rx_ring
[0].size
;
532 param
->tx_pending
= priv
->tx_ring
[0].size
;
535 static u32
mlx4_en_get_rxfh_indir_size(struct net_device
*dev
)
537 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
539 return priv
->rx_ring_num
;
542 static int mlx4_en_get_rxfh_indir(struct net_device
*dev
, u32
*ring_index
)
544 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
545 struct mlx4_en_rss_map
*rss_map
= &priv
->rss_map
;
547 size_t n
= priv
->rx_ring_num
;
550 rss_rings
= priv
->prof
->rss_rings
?: priv
->rx_ring_num
;
553 ring_index
[n
] = rss_map
->qps
[n
% rss_rings
].qpn
-
560 static int mlx4_en_set_rxfh_indir(struct net_device
*dev
,
561 const u32
*ring_index
)
563 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
564 struct mlx4_en_dev
*mdev
= priv
->mdev
;
570 /* Calculate RSS table size and make sure flows are spread evenly
573 for (i
= 0; i
< priv
->rx_ring_num
; i
++) {
574 if (i
> 0 && !ring_index
[i
] && !rss_rings
)
577 if (ring_index
[i
] != (i
% (rss_rings
?: priv
->rx_ring_num
)))
582 rss_rings
= priv
->rx_ring_num
;
584 /* RSS table size must be an order of 2 */
585 if (!is_power_of_2(rss_rings
))
588 mutex_lock(&mdev
->state_lock
);
591 mlx4_en_stop_port(dev
);
594 priv
->prof
->rss_rings
= rss_rings
;
597 err
= mlx4_en_start_port(dev
);
599 en_err(priv
, "Failed starting port\n");
602 mutex_unlock(&mdev
->state_lock
);
606 #define all_zeros_or_all_ones(field) \
607 ((field) == 0 || (field) == (__force typeof(field))-1)
609 static int mlx4_en_validate_flow(struct net_device
*dev
,
610 struct ethtool_rxnfc
*cmd
)
612 struct ethtool_usrip4_spec
*l3_mask
;
613 struct ethtool_tcpip4_spec
*l4_mask
;
614 struct ethhdr
*eth_mask
;
615 u64 full_mac
= ~0ull;
618 if (cmd
->fs
.location
>= MAX_NUM_OF_FS_RULES
)
621 switch (cmd
->fs
.flow_type
& ~FLOW_EXT
) {
624 if (cmd
->fs
.m_u
.tcp_ip4_spec
.tos
)
626 l4_mask
= &cmd
->fs
.m_u
.tcp_ip4_spec
;
627 /* don't allow mask which isn't all 0 or 1 */
628 if (!all_zeros_or_all_ones(l4_mask
->ip4src
) ||
629 !all_zeros_or_all_ones(l4_mask
->ip4dst
) ||
630 !all_zeros_or_all_ones(l4_mask
->psrc
) ||
631 !all_zeros_or_all_ones(l4_mask
->pdst
))
635 l3_mask
= &cmd
->fs
.m_u
.usr_ip4_spec
;
636 if (l3_mask
->l4_4_bytes
|| l3_mask
->tos
|| l3_mask
->proto
||
637 cmd
->fs
.h_u
.usr_ip4_spec
.ip_ver
!= ETH_RX_NFC_IP4
||
638 (!l3_mask
->ip4src
&& !l3_mask
->ip4dst
) ||
639 !all_zeros_or_all_ones(l3_mask
->ip4src
) ||
640 !all_zeros_or_all_ones(l3_mask
->ip4dst
))
644 eth_mask
= &cmd
->fs
.m_u
.ether_spec
;
645 /* source mac mask must not be set */
646 if (memcmp(eth_mask
->h_source
, &zero_mac
, ETH_ALEN
))
649 /* dest mac mask must be ff:ff:ff:ff:ff:ff */
650 if (memcmp(eth_mask
->h_dest
, &full_mac
, ETH_ALEN
))
653 if (!all_zeros_or_all_ones(eth_mask
->h_proto
))
660 if ((cmd
->fs
.flow_type
& FLOW_EXT
)) {
661 if (cmd
->fs
.m_ext
.vlan_etype
||
662 !(cmd
->fs
.m_ext
.vlan_tci
== 0 ||
663 cmd
->fs
.m_ext
.vlan_tci
== cpu_to_be16(0xfff)))
670 static int add_ip_rule(struct mlx4_en_priv
*priv
,
671 struct ethtool_rxnfc
*cmd
,
672 struct list_head
*list_h
)
674 struct mlx4_spec_list
*spec_l3
;
675 struct ethtool_usrip4_spec
*l3_mask
= &cmd
->fs
.m_u
.usr_ip4_spec
;
677 spec_l3
= kzalloc(sizeof *spec_l3
, GFP_KERNEL
);
679 en_err(priv
, "Fail to alloc ethtool rule.\n");
683 spec_l3
->id
= MLX4_NET_TRANS_RULE_ID_IPV4
;
684 spec_l3
->ipv4
.src_ip
= cmd
->fs
.h_u
.usr_ip4_spec
.ip4src
;
686 spec_l3
->ipv4
.src_ip_msk
= EN_ETHTOOL_WORD_MASK
;
687 spec_l3
->ipv4
.dst_ip
= cmd
->fs
.h_u
.usr_ip4_spec
.ip4dst
;
689 spec_l3
->ipv4
.dst_ip_msk
= EN_ETHTOOL_WORD_MASK
;
690 list_add_tail(&spec_l3
->list
, list_h
);
695 static int add_tcp_udp_rule(struct mlx4_en_priv
*priv
,
696 struct ethtool_rxnfc
*cmd
,
697 struct list_head
*list_h
, int proto
)
699 struct mlx4_spec_list
*spec_l3
;
700 struct mlx4_spec_list
*spec_l4
;
701 struct ethtool_tcpip4_spec
*l4_mask
= &cmd
->fs
.m_u
.tcp_ip4_spec
;
703 spec_l3
= kzalloc(sizeof *spec_l3
, GFP_KERNEL
);
704 spec_l4
= kzalloc(sizeof *spec_l4
, GFP_KERNEL
);
705 if (!spec_l4
|| !spec_l3
) {
706 en_err(priv
, "Fail to alloc ethtool rule.\n");
712 spec_l3
->id
= MLX4_NET_TRANS_RULE_ID_IPV4
;
714 if (proto
== TCP_V4_FLOW
) {
715 spec_l4
->id
= MLX4_NET_TRANS_RULE_ID_TCP
;
716 spec_l3
->ipv4
.src_ip
= cmd
->fs
.h_u
.tcp_ip4_spec
.ip4src
;
717 spec_l3
->ipv4
.dst_ip
= cmd
->fs
.h_u
.tcp_ip4_spec
.ip4dst
;
718 spec_l4
->tcp_udp
.src_port
= cmd
->fs
.h_u
.tcp_ip4_spec
.psrc
;
719 spec_l4
->tcp_udp
.dst_port
= cmd
->fs
.h_u
.tcp_ip4_spec
.pdst
;
721 spec_l4
->id
= MLX4_NET_TRANS_RULE_ID_UDP
;
722 spec_l3
->ipv4
.src_ip
= cmd
->fs
.h_u
.udp_ip4_spec
.ip4src
;
723 spec_l3
->ipv4
.dst_ip
= cmd
->fs
.h_u
.udp_ip4_spec
.ip4dst
;
724 spec_l4
->tcp_udp
.src_port
= cmd
->fs
.h_u
.udp_ip4_spec
.psrc
;
725 spec_l4
->tcp_udp
.dst_port
= cmd
->fs
.h_u
.udp_ip4_spec
.pdst
;
729 spec_l3
->ipv4
.src_ip_msk
= EN_ETHTOOL_WORD_MASK
;
731 spec_l3
->ipv4
.dst_ip_msk
= EN_ETHTOOL_WORD_MASK
;
734 spec_l4
->tcp_udp
.src_port_msk
= EN_ETHTOOL_SHORT_MASK
;
736 spec_l4
->tcp_udp
.dst_port_msk
= EN_ETHTOOL_SHORT_MASK
;
738 list_add_tail(&spec_l3
->list
, list_h
);
739 list_add_tail(&spec_l4
->list
, list_h
);
744 static int mlx4_en_ethtool_to_net_trans_rule(struct net_device
*dev
,
745 struct ethtool_rxnfc
*cmd
,
746 struct list_head
*rule_list_h
)
751 struct ethhdr
*eth_spec
;
752 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
753 struct mlx4_spec_list
*spec_l2
;
754 __be64 mac_msk
= cpu_to_be64(EN_ETHTOOL_MAC_MASK
<< 16);
756 err
= mlx4_en_validate_flow(dev
, cmd
);
760 spec_l2
= kzalloc(sizeof *spec_l2
, GFP_KERNEL
);
764 mac
= priv
->mac
& EN_ETHTOOL_MAC_MASK
;
765 be_mac
= cpu_to_be64(mac
<< 16);
767 spec_l2
->id
= MLX4_NET_TRANS_RULE_ID_ETH
;
768 memcpy(spec_l2
->eth
.dst_mac_msk
, &mac_msk
, ETH_ALEN
);
769 if ((cmd
->fs
.flow_type
& ~FLOW_EXT
) != ETHER_FLOW
)
770 memcpy(spec_l2
->eth
.dst_mac
, &be_mac
, ETH_ALEN
);
772 if ((cmd
->fs
.flow_type
& FLOW_EXT
) && cmd
->fs
.m_ext
.vlan_tci
) {
773 spec_l2
->eth
.vlan_id
= cmd
->fs
.h_ext
.vlan_tci
;
774 spec_l2
->eth
.vlan_id_msk
= cpu_to_be16(0xfff);
777 list_add_tail(&spec_l2
->list
, rule_list_h
);
779 switch (cmd
->fs
.flow_type
& ~FLOW_EXT
) {
781 eth_spec
= &cmd
->fs
.h_u
.ether_spec
;
782 memcpy(&spec_l2
->eth
.dst_mac
, eth_spec
->h_dest
, ETH_ALEN
);
783 spec_l2
->eth
.ether_type
= eth_spec
->h_proto
;
784 if (eth_spec
->h_proto
)
785 spec_l2
->eth
.ether_type_enable
= 1;
788 err
= add_ip_rule(priv
, cmd
, rule_list_h
);
791 err
= add_tcp_udp_rule(priv
, cmd
, rule_list_h
, TCP_V4_FLOW
);
794 err
= add_tcp_udp_rule(priv
, cmd
, rule_list_h
, UDP_V4_FLOW
);
801 static int mlx4_en_flow_replace(struct net_device
*dev
,
802 struct ethtool_rxnfc
*cmd
)
805 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
806 struct ethtool_flow_id
*loc_rule
;
807 struct mlx4_spec_list
*spec
, *tmp_spec
;
811 struct mlx4_net_trans_rule rule
= {
812 .queue_mode
= MLX4_NET_TRANS_Q_FIFO
,
815 .promisc_mode
= MLX4_FS_PROMISC_NONE
,
818 rule
.port
= priv
->port
;
819 rule
.priority
= MLX4_DOMAIN_ETHTOOL
| cmd
->fs
.location
;
820 INIT_LIST_HEAD(&rule
.list
);
822 /* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */
823 if (cmd
->fs
.ring_cookie
== RX_CLS_FLOW_DISC
)
825 else if (cmd
->fs
.ring_cookie
& EN_ETHTOOL_QP_ATTACH
) {
826 qpn
= cmd
->fs
.ring_cookie
& (EN_ETHTOOL_QP_ATTACH
- 1);
828 if (cmd
->fs
.ring_cookie
>= priv
->rx_ring_num
) {
829 en_warn(priv
, "rxnfc: RX ring (%llu) doesn't exist.\n",
830 cmd
->fs
.ring_cookie
);
833 qpn
= priv
->rss_map
.qps
[cmd
->fs
.ring_cookie
].qpn
;
835 en_warn(priv
, "rxnfc: RX ring (%llu) is inactive.\n",
836 cmd
->fs
.ring_cookie
);
841 err
= mlx4_en_ethtool_to_net_trans_rule(dev
, cmd
, &rule
.list
);
845 loc_rule
= &priv
->ethtool_rules
[cmd
->fs
.location
];
847 err
= mlx4_flow_detach(priv
->mdev
->dev
, loc_rule
->id
);
849 en_err(priv
, "Fail to detach network rule at location %d. registration id = %llx\n",
850 cmd
->fs
.location
, loc_rule
->id
);
854 memset(&loc_rule
->flow_spec
, 0,
855 sizeof(struct ethtool_rx_flow_spec
));
857 err
= mlx4_flow_attach(priv
->mdev
->dev
, &rule
, ®_id
);
859 en_err(priv
, "Fail to attach network rule at location %d.\n",
863 loc_rule
->id
= reg_id
;
864 memcpy(&loc_rule
->flow_spec
, &cmd
->fs
,
865 sizeof(struct ethtool_rx_flow_spec
));
868 list_for_each_entry_safe(spec
, tmp_spec
, &rule
.list
, list
) {
869 list_del(&spec
->list
);
875 static int mlx4_en_flow_detach(struct net_device
*dev
,
876 struct ethtool_rxnfc
*cmd
)
879 struct ethtool_flow_id
*rule
;
880 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
882 if (cmd
->fs
.location
>= MAX_NUM_OF_FS_RULES
)
885 rule
= &priv
->ethtool_rules
[cmd
->fs
.location
];
891 err
= mlx4_flow_detach(priv
->mdev
->dev
, rule
->id
);
893 en_err(priv
, "Fail to detach network rule at location %d. registration id = 0x%llx\n",
894 cmd
->fs
.location
, rule
->id
);
898 memset(&rule
->flow_spec
, 0, sizeof(struct ethtool_rx_flow_spec
));
904 static int mlx4_en_get_flow(struct net_device
*dev
, struct ethtool_rxnfc
*cmd
,
908 struct ethtool_flow_id
*rule
;
909 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
911 if (loc
< 0 || loc
>= MAX_NUM_OF_FS_RULES
)
914 rule
= &priv
->ethtool_rules
[loc
];
916 memcpy(&cmd
->fs
, &rule
->flow_spec
,
917 sizeof(struct ethtool_rx_flow_spec
));
924 static int mlx4_en_get_num_flows(struct mlx4_en_priv
*priv
)
928 for (i
= 0; i
< MAX_NUM_OF_FS_RULES
; i
++) {
929 if (priv
->ethtool_rules
[i
].id
)
936 static int mlx4_en_get_rxnfc(struct net_device
*dev
, struct ethtool_rxnfc
*cmd
,
939 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
940 struct mlx4_en_dev
*mdev
= priv
->mdev
;
942 int i
= 0, priority
= 0;
944 if ((cmd
->cmd
== ETHTOOL_GRXCLSRLCNT
||
945 cmd
->cmd
== ETHTOOL_GRXCLSRULE
||
946 cmd
->cmd
== ETHTOOL_GRXCLSRLALL
) &&
947 mdev
->dev
->caps
.steering_mode
!= MLX4_STEERING_MODE_DEVICE_MANAGED
)
951 case ETHTOOL_GRXRINGS
:
952 cmd
->data
= priv
->rx_ring_num
;
954 case ETHTOOL_GRXCLSRLCNT
:
955 cmd
->rule_cnt
= mlx4_en_get_num_flows(priv
);
957 case ETHTOOL_GRXCLSRULE
:
958 err
= mlx4_en_get_flow(dev
, cmd
, cmd
->fs
.location
);
960 case ETHTOOL_GRXCLSRLALL
:
961 while ((!err
|| err
== -ENOENT
) && priority
< cmd
->rule_cnt
) {
962 err
= mlx4_en_get_flow(dev
, cmd
, i
);
964 rule_locs
[priority
++] = i
;
977 static int mlx4_en_set_rxnfc(struct net_device
*dev
, struct ethtool_rxnfc
*cmd
)
980 struct mlx4_en_priv
*priv
= netdev_priv(dev
);
981 struct mlx4_en_dev
*mdev
= priv
->mdev
;
983 if (mdev
->dev
->caps
.steering_mode
!= MLX4_STEERING_MODE_DEVICE_MANAGED
)
987 case ETHTOOL_SRXCLSRLINS
:
988 err
= mlx4_en_flow_replace(dev
, cmd
);
990 case ETHTOOL_SRXCLSRLDEL
:
991 err
= mlx4_en_flow_detach(dev
, cmd
);
994 en_warn(priv
, "Unsupported ethtool command. (%d)\n", cmd
->cmd
);
1001 const struct ethtool_ops mlx4_en_ethtool_ops
= {
1002 .get_drvinfo
= mlx4_en_get_drvinfo
,
1003 .get_settings
= mlx4_en_get_settings
,
1004 .set_settings
= mlx4_en_set_settings
,
1005 .get_link
= ethtool_op_get_link
,
1006 .get_strings
= mlx4_en_get_strings
,
1007 .get_sset_count
= mlx4_en_get_sset_count
,
1008 .get_ethtool_stats
= mlx4_en_get_ethtool_stats
,
1009 .self_test
= mlx4_en_self_test
,
1010 .get_wol
= mlx4_en_get_wol
,
1011 .set_wol
= mlx4_en_set_wol
,
1012 .get_msglevel
= mlx4_en_get_msglevel
,
1013 .set_msglevel
= mlx4_en_set_msglevel
,
1014 .get_coalesce
= mlx4_en_get_coalesce
,
1015 .set_coalesce
= mlx4_en_set_coalesce
,
1016 .get_pauseparam
= mlx4_en_get_pauseparam
,
1017 .set_pauseparam
= mlx4_en_set_pauseparam
,
1018 .get_ringparam
= mlx4_en_get_ringparam
,
1019 .set_ringparam
= mlx4_en_set_ringparam
,
1020 .get_rxnfc
= mlx4_en_get_rxnfc
,
1021 .set_rxnfc
= mlx4_en_set_rxnfc
,
1022 .get_rxfh_indir_size
= mlx4_en_get_rxfh_indir_size
,
1023 .get_rxfh_indir
= mlx4_en_get_rxfh_indir
,
1024 .set_rxfh_indir
= mlx4_en_set_rxfh_indir
,