2 * Copyright (c) 2015, 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
35 static void mlx5e_get_drvinfo(struct net_device
*dev
,
36 struct ethtool_drvinfo
*drvinfo
)
38 struct mlx5e_priv
*priv
= netdev_priv(dev
);
39 struct mlx5_core_dev
*mdev
= priv
->mdev
;
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
),
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
));
55 } ptys2ethtool_table
[MLX5E_LINK_MODES_NUMBER
] = {
56 [MLX5E_1000BASE_CX_SGMII
] = {
57 .supported
= SUPPORTED_1000baseKX_Full
,
58 .advertised
= ADVERTISED_1000baseKX_Full
,
61 [MLX5E_1000BASE_KX
] = {
62 .supported
= SUPPORTED_1000baseKX_Full
,
63 .advertised
= ADVERTISED_1000baseKX_Full
,
66 [MLX5E_10GBASE_CX4
] = {
67 .supported
= SUPPORTED_10000baseKX4_Full
,
68 .advertised
= ADVERTISED_10000baseKX4_Full
,
71 [MLX5E_10GBASE_KX4
] = {
72 .supported
= SUPPORTED_10000baseKX4_Full
,
73 .advertised
= ADVERTISED_10000baseKX4_Full
,
76 [MLX5E_10GBASE_KR
] = {
77 .supported
= SUPPORTED_10000baseKR_Full
,
78 .advertised
= ADVERTISED_10000baseKR_Full
,
81 [MLX5E_20GBASE_KR2
] = {
82 .supported
= SUPPORTED_20000baseKR2_Full
,
83 .advertised
= ADVERTISED_20000baseKR2_Full
,
86 [MLX5E_40GBASE_CR4
] = {
87 .supported
= SUPPORTED_40000baseCR4_Full
,
88 .advertised
= ADVERTISED_40000baseCR4_Full
,
91 [MLX5E_40GBASE_KR4
] = {
92 .supported
= SUPPORTED_40000baseKR4_Full
,
93 .advertised
= ADVERTISED_40000baseKR4_Full
,
96 [MLX5E_56GBASE_R4
] = {
97 .supported
= SUPPORTED_56000baseKR4_Full
,
98 .advertised
= ADVERTISED_56000baseKR4_Full
,
101 [MLX5E_10GBASE_CR
] = {
102 .supported
= SUPPORTED_10000baseKR_Full
,
103 .advertised
= ADVERTISED_10000baseKR_Full
,
106 [MLX5E_10GBASE_SR
] = {
107 .supported
= SUPPORTED_10000baseKR_Full
,
108 .advertised
= ADVERTISED_10000baseKR_Full
,
111 [MLX5E_10GBASE_ER
] = {
112 .supported
= SUPPORTED_10000baseKR_Full
,
113 .advertised
= ADVERTISED_10000baseKR_Full
,
116 [MLX5E_40GBASE_SR4
] = {
117 .supported
= SUPPORTED_40000baseSR4_Full
,
118 .advertised
= ADVERTISED_40000baseSR4_Full
,
121 [MLX5E_40GBASE_LR4
] = {
122 .supported
= SUPPORTED_40000baseLR4_Full
,
123 .advertised
= ADVERTISED_40000baseLR4_Full
,
126 [MLX5E_100GBASE_CR4
] = {
129 [MLX5E_100GBASE_SR4
] = {
132 [MLX5E_100GBASE_KR4
] = {
135 [MLX5E_100GBASE_LR4
] = {
138 [MLX5E_100BASE_TX
] = {
141 [MLX5E_100BASE_T
] = {
142 .supported
= SUPPORTED_100baseT_Full
,
143 .advertised
= ADVERTISED_100baseT_Full
,
146 [MLX5E_10GBASE_T
] = {
147 .supported
= SUPPORTED_10000baseT_Full
,
148 .advertised
= ADVERTISED_10000baseT_Full
,
151 [MLX5E_25GBASE_CR
] = {
154 [MLX5E_25GBASE_KR
] = {
157 [MLX5E_25GBASE_SR
] = {
160 [MLX5E_50GBASE_CR2
] = {
163 [MLX5E_50GBASE_KR2
] = {
168 #define MLX5E_NUM_Q_CNTRS(priv) (NUM_Q_COUNTERS * (!!priv->q_counter))
170 static int mlx5e_get_sset_count(struct net_device
*dev
, int sset
)
172 struct mlx5e_priv
*priv
= netdev_priv(dev
);
176 return NUM_VPORT_COUNTERS
+ NUM_PPORT_COUNTERS
+
177 MLX5E_NUM_Q_CNTRS(priv
) +
178 priv
->params
.num_channels
* NUM_RQ_STATS
+
179 priv
->params
.num_channels
* priv
->params
.num_tc
*
187 static void mlx5e_get_strings(struct net_device
*dev
,
188 uint32_t stringset
, uint8_t *data
)
190 int i
, j
, tc
, idx
= 0;
191 struct mlx5e_priv
*priv
= netdev_priv(dev
);
194 case ETH_SS_PRIV_FLAGS
:
202 for (i
= 0; i
< NUM_VPORT_COUNTERS
; i
++)
203 strcpy(data
+ (idx
++) * ETH_GSTRING_LEN
,
207 for (i
= 0; i
< MLX5E_NUM_Q_CNTRS(priv
); i
++)
208 strcpy(data
+ (idx
++) * ETH_GSTRING_LEN
,
209 qcounter_stats_strings
[i
]);
212 for (i
= 0; i
< NUM_PPORT_COUNTERS
; i
++)
213 strcpy(data
+ (idx
++) * ETH_GSTRING_LEN
,
216 /* per channel counters */
217 for (i
= 0; i
< priv
->params
.num_channels
; i
++)
218 for (j
= 0; j
< NUM_RQ_STATS
; j
++)
219 sprintf(data
+ (idx
++) * ETH_GSTRING_LEN
,
220 "rx%d_%s", i
, rq_stats_strings
[j
]);
222 for (tc
= 0; tc
< priv
->params
.num_tc
; tc
++)
223 for (i
= 0; i
< priv
->params
.num_channels
; i
++)
224 for (j
= 0; j
< NUM_SQ_STATS
; j
++)
226 (idx
++) * ETH_GSTRING_LEN
,
228 priv
->channeltc_to_txq_map
[i
][tc
],
229 sq_stats_strings
[j
]);
234 static void mlx5e_get_ethtool_stats(struct net_device
*dev
,
235 struct ethtool_stats
*stats
, u64
*data
)
237 struct mlx5e_priv
*priv
= netdev_priv(dev
);
238 int i
, j
, tc
, idx
= 0;
243 mutex_lock(&priv
->state_lock
);
244 if (test_bit(MLX5E_STATE_OPENED
, &priv
->state
))
245 mlx5e_update_stats(priv
);
246 mutex_unlock(&priv
->state_lock
);
248 for (i
= 0; i
< NUM_VPORT_COUNTERS
; i
++)
249 data
[idx
++] = ((u64
*)&priv
->stats
.vport
)[i
];
251 for (i
= 0; i
< MLX5E_NUM_Q_CNTRS(priv
); i
++)
252 data
[idx
++] = ((u32
*)&priv
->stats
.qcnt
)[i
];
254 for (i
= 0; i
< NUM_PPORT_COUNTERS
; i
++)
255 data
[idx
++] = be64_to_cpu(((__be64
*)&priv
->stats
.pport
)[i
]);
257 /* per channel counters */
258 for (i
= 0; i
< priv
->params
.num_channels
; i
++)
259 for (j
= 0; j
< NUM_RQ_STATS
; j
++)
260 data
[idx
++] = !test_bit(MLX5E_STATE_OPENED
,
262 ((u64
*)&priv
->channel
[i
]->rq
.stats
)[j
];
264 for (tc
= 0; tc
< priv
->params
.num_tc
; tc
++)
265 for (i
= 0; i
< priv
->params
.num_channels
; i
++)
266 for (j
= 0; j
< NUM_SQ_STATS
; j
++)
267 data
[idx
++] = !test_bit(MLX5E_STATE_OPENED
,
269 ((u64
*)&priv
->channel
[i
]->sq
[tc
].stats
)[j
];
272 static void mlx5e_get_ringparam(struct net_device
*dev
,
273 struct ethtool_ringparam
*param
)
275 struct mlx5e_priv
*priv
= netdev_priv(dev
);
277 param
->rx_max_pending
= 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE
;
278 param
->tx_max_pending
= 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE
;
279 param
->rx_pending
= 1 << priv
->params
.log_rq_size
;
280 param
->tx_pending
= 1 << priv
->params
.log_sq_size
;
283 static int mlx5e_set_ringparam(struct net_device
*dev
,
284 struct ethtool_ringparam
*param
)
286 struct mlx5e_priv
*priv
= netdev_priv(dev
);
293 if (param
->rx_jumbo_pending
) {
294 netdev_info(dev
, "%s: rx_jumbo_pending not supported\n",
298 if (param
->rx_mini_pending
) {
299 netdev_info(dev
, "%s: rx_mini_pending not supported\n",
303 if (param
->rx_pending
< (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE
)) {
304 netdev_info(dev
, "%s: rx_pending (%d) < min (%d)\n",
305 __func__
, param
->rx_pending
,
306 1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE
);
309 if (param
->rx_pending
> (1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE
)) {
310 netdev_info(dev
, "%s: rx_pending (%d) > max (%d)\n",
311 __func__
, param
->rx_pending
,
312 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE
);
315 if (param
->tx_pending
< (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE
)) {
316 netdev_info(dev
, "%s: tx_pending (%d) < min (%d)\n",
317 __func__
, param
->tx_pending
,
318 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE
);
321 if (param
->tx_pending
> (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE
)) {
322 netdev_info(dev
, "%s: tx_pending (%d) > max (%d)\n",
323 __func__
, param
->tx_pending
,
324 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE
);
328 log_rq_size
= order_base_2(param
->rx_pending
);
329 log_sq_size
= order_base_2(param
->tx_pending
);
330 min_rx_wqes
= min_t(u16
, param
->rx_pending
- 1,
331 MLX5E_PARAMS_DEFAULT_MIN_RX_WQES
);
333 if (log_rq_size
== priv
->params
.log_rq_size
&&
334 log_sq_size
== priv
->params
.log_sq_size
&&
335 min_rx_wqes
== priv
->params
.min_rx_wqes
)
338 mutex_lock(&priv
->state_lock
);
340 was_opened
= test_bit(MLX5E_STATE_OPENED
, &priv
->state
);
342 mlx5e_close_locked(dev
);
344 priv
->params
.log_rq_size
= log_rq_size
;
345 priv
->params
.log_sq_size
= log_sq_size
;
346 priv
->params
.min_rx_wqes
= min_rx_wqes
;
349 err
= mlx5e_open_locked(dev
);
351 mutex_unlock(&priv
->state_lock
);
356 static void mlx5e_get_channels(struct net_device
*dev
,
357 struct ethtool_channels
*ch
)
359 struct mlx5e_priv
*priv
= netdev_priv(dev
);
361 ch
->max_combined
= mlx5e_get_max_num_channels(priv
->mdev
);
362 ch
->combined_count
= priv
->params
.num_channels
;
365 static int mlx5e_set_channels(struct net_device
*dev
,
366 struct ethtool_channels
*ch
)
368 struct mlx5e_priv
*priv
= netdev_priv(dev
);
369 int ncv
= mlx5e_get_max_num_channels(priv
->mdev
);
370 unsigned int count
= ch
->combined_count
;
375 netdev_info(dev
, "%s: combined_count=0 not supported\n",
379 if (ch
->rx_count
|| ch
->tx_count
) {
380 netdev_info(dev
, "%s: separate rx/tx count not supported\n",
385 netdev_info(dev
, "%s: count (%d) > max (%d)\n",
386 __func__
, count
, ncv
);
390 if (priv
->params
.num_channels
== count
)
393 mutex_lock(&priv
->state_lock
);
395 was_opened
= test_bit(MLX5E_STATE_OPENED
, &priv
->state
);
397 mlx5e_close_locked(dev
);
399 priv
->params
.num_channels
= count
;
400 mlx5e_build_default_indir_rqt(priv
->params
.indirection_rqt
,
401 MLX5E_INDIR_RQT_SIZE
, count
);
404 err
= mlx5e_open_locked(dev
);
406 mutex_unlock(&priv
->state_lock
);
411 static int mlx5e_get_coalesce(struct net_device
*netdev
,
412 struct ethtool_coalesce
*coal
)
414 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
416 if (!MLX5_CAP_GEN(priv
->mdev
, cq_moderation
))
419 coal
->rx_coalesce_usecs
= priv
->params
.rx_cq_moderation_usec
;
420 coal
->rx_max_coalesced_frames
= priv
->params
.rx_cq_moderation_pkts
;
421 coal
->tx_coalesce_usecs
= priv
->params
.tx_cq_moderation_usec
;
422 coal
->tx_max_coalesced_frames
= priv
->params
.tx_cq_moderation_pkts
;
427 static int mlx5e_set_coalesce(struct net_device
*netdev
,
428 struct ethtool_coalesce
*coal
)
430 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
431 struct mlx5_core_dev
*mdev
= priv
->mdev
;
432 struct mlx5e_channel
*c
;
436 if (!MLX5_CAP_GEN(mdev
, cq_moderation
))
439 mutex_lock(&priv
->state_lock
);
440 priv
->params
.tx_cq_moderation_usec
= coal
->tx_coalesce_usecs
;
441 priv
->params
.tx_cq_moderation_pkts
= coal
->tx_max_coalesced_frames
;
442 priv
->params
.rx_cq_moderation_usec
= coal
->rx_coalesce_usecs
;
443 priv
->params
.rx_cq_moderation_pkts
= coal
->rx_max_coalesced_frames
;
445 if (!test_bit(MLX5E_STATE_OPENED
, &priv
->state
))
448 for (i
= 0; i
< priv
->params
.num_channels
; ++i
) {
449 c
= priv
->channel
[i
];
451 for (tc
= 0; tc
< c
->num_tc
; tc
++) {
452 mlx5_core_modify_cq_moderation(mdev
,
454 coal
->tx_coalesce_usecs
,
455 coal
->tx_max_coalesced_frames
);
458 mlx5_core_modify_cq_moderation(mdev
, &c
->rq
.cq
.mcq
,
459 coal
->rx_coalesce_usecs
,
460 coal
->rx_max_coalesced_frames
);
464 mutex_unlock(&priv
->state_lock
);
468 static u32
ptys2ethtool_supported_link(u32 eth_proto_cap
)
471 u32 supported_modes
= 0;
473 for (i
= 0; i
< MLX5E_LINK_MODES_NUMBER
; ++i
) {
474 if (eth_proto_cap
& MLX5E_PROT_MASK(i
))
475 supported_modes
|= ptys2ethtool_table
[i
].supported
;
477 return supported_modes
;
480 static u32
ptys2ethtool_adver_link(u32 eth_proto_cap
)
483 u32 advertising_modes
= 0;
485 for (i
= 0; i
< MLX5E_LINK_MODES_NUMBER
; ++i
) {
486 if (eth_proto_cap
& MLX5E_PROT_MASK(i
))
487 advertising_modes
|= ptys2ethtool_table
[i
].advertised
;
489 return advertising_modes
;
492 static u32
ptys2ethtool_supported_port(u32 eth_proto_cap
)
494 if (eth_proto_cap
& (MLX5E_PROT_MASK(MLX5E_10GBASE_CR
)
495 | MLX5E_PROT_MASK(MLX5E_10GBASE_SR
)
496 | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4
)
497 | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4
)
498 | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4
)
499 | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII
))) {
500 return SUPPORTED_FIBRE
;
503 if (eth_proto_cap
& (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4
)
504 | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4
)
505 | MLX5E_PROT_MASK(MLX5E_10GBASE_KR
)
506 | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4
)
507 | MLX5E_PROT_MASK(MLX5E_1000BASE_KX
))) {
508 return SUPPORTED_Backplane
;
513 static void get_speed_duplex(struct net_device
*netdev
,
515 struct ethtool_cmd
*cmd
)
518 u32 speed
= SPEED_UNKNOWN
;
519 u8 duplex
= DUPLEX_UNKNOWN
;
521 if (!netif_carrier_ok(netdev
))
524 for (i
= 0; i
< MLX5E_LINK_MODES_NUMBER
; ++i
) {
525 if (eth_proto_oper
& MLX5E_PROT_MASK(i
)) {
526 speed
= ptys2ethtool_table
[i
].speed
;
527 duplex
= DUPLEX_FULL
;
532 ethtool_cmd_speed_set(cmd
, speed
);
533 cmd
->duplex
= duplex
;
536 static void get_supported(u32 eth_proto_cap
, u32
*supported
)
538 *supported
|= ptys2ethtool_supported_port(eth_proto_cap
);
539 *supported
|= ptys2ethtool_supported_link(eth_proto_cap
);
540 *supported
|= SUPPORTED_Pause
| SUPPORTED_Asym_Pause
;
543 static void get_advertising(u32 eth_proto_cap
, u8 tx_pause
,
544 u8 rx_pause
, u32
*advertising
)
546 *advertising
|= ptys2ethtool_adver_link(eth_proto_cap
);
547 *advertising
|= tx_pause
? ADVERTISED_Pause
: 0;
548 *advertising
|= (tx_pause
^ rx_pause
) ? ADVERTISED_Asym_Pause
: 0;
551 static u8
get_connector_port(u32 eth_proto
)
553 if (eth_proto
& (MLX5E_PROT_MASK(MLX5E_10GBASE_SR
)
554 | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4
)
555 | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4
)
556 | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII
))) {
560 if (eth_proto
& (MLX5E_PROT_MASK(MLX5E_40GBASE_CR4
)
561 | MLX5E_PROT_MASK(MLX5E_10GBASE_CR
)
562 | MLX5E_PROT_MASK(MLX5E_100GBASE_CR4
))) {
566 if (eth_proto
& (MLX5E_PROT_MASK(MLX5E_10GBASE_KX4
)
567 | MLX5E_PROT_MASK(MLX5E_10GBASE_KR
)
568 | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4
)
569 | MLX5E_PROT_MASK(MLX5E_100GBASE_KR4
))) {
576 static void get_lp_advertising(u32 eth_proto_lp
, u32
*lp_advertising
)
578 *lp_advertising
= ptys2ethtool_adver_link(eth_proto_lp
);
581 static int mlx5e_get_settings(struct net_device
*netdev
,
582 struct ethtool_cmd
*cmd
)
584 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
585 struct mlx5_core_dev
*mdev
= priv
->mdev
;
586 u32 out
[MLX5_ST_SZ_DW(ptys_reg
)];
593 err
= mlx5_query_port_ptys(mdev
, out
, sizeof(out
), MLX5_PTYS_EN
, 1);
596 netdev_err(netdev
, "%s: query port ptys failed: %d\n",
601 eth_proto_cap
= MLX5_GET(ptys_reg
, out
, eth_proto_capability
);
602 eth_proto_admin
= MLX5_GET(ptys_reg
, out
, eth_proto_admin
);
603 eth_proto_oper
= MLX5_GET(ptys_reg
, out
, eth_proto_oper
);
604 eth_proto_lp
= MLX5_GET(ptys_reg
, out
, eth_proto_lp_advertise
);
607 cmd
->advertising
= 0;
609 get_supported(eth_proto_cap
, &cmd
->supported
);
610 get_advertising(eth_proto_admin
, 0, 0, &cmd
->advertising
);
611 get_speed_duplex(netdev
, eth_proto_oper
, cmd
);
613 eth_proto_oper
= eth_proto_oper
? eth_proto_oper
: eth_proto_cap
;
615 cmd
->port
= get_connector_port(eth_proto_oper
);
616 get_lp_advertising(eth_proto_lp
, &cmd
->lp_advertising
);
618 cmd
->transceiver
= XCVR_INTERNAL
;
624 static u32
mlx5e_ethtool2ptys_adver_link(u32 link_modes
)
626 u32 i
, ptys_modes
= 0;
628 for (i
= 0; i
< MLX5E_LINK_MODES_NUMBER
; ++i
) {
629 if (ptys2ethtool_table
[i
].advertised
& link_modes
)
630 ptys_modes
|= MLX5E_PROT_MASK(i
);
636 static u32
mlx5e_ethtool2ptys_speed_link(u32 speed
)
638 u32 i
, speed_links
= 0;
640 for (i
= 0; i
< MLX5E_LINK_MODES_NUMBER
; ++i
) {
641 if (ptys2ethtool_table
[i
].speed
== speed
)
642 speed_links
|= MLX5E_PROT_MASK(i
);
648 static int mlx5e_set_settings(struct net_device
*netdev
,
649 struct ethtool_cmd
*cmd
)
651 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
652 struct mlx5_core_dev
*mdev
= priv
->mdev
;
655 u32 eth_proto_cap
, eth_proto_admin
;
656 enum mlx5_port_status ps
;
659 speed
= ethtool_cmd_speed(cmd
);
661 link_modes
= cmd
->autoneg
== AUTONEG_ENABLE
?
662 mlx5e_ethtool2ptys_adver_link(cmd
->advertising
) :
663 mlx5e_ethtool2ptys_speed_link(speed
);
665 err
= mlx5_query_port_proto_cap(mdev
, ð_proto_cap
, MLX5_PTYS_EN
);
667 netdev_err(netdev
, "%s: query port eth proto cap failed: %d\n",
672 link_modes
= link_modes
& eth_proto_cap
;
674 netdev_err(netdev
, "%s: Not supported link mode(s) requested",
680 err
= mlx5_query_port_proto_admin(mdev
, ð_proto_admin
, MLX5_PTYS_EN
);
682 netdev_err(netdev
, "%s: query port eth proto admin failed: %d\n",
687 if (link_modes
== eth_proto_admin
)
690 mlx5_query_port_admin_status(mdev
, &ps
);
691 if (ps
== MLX5_PORT_UP
)
692 mlx5_set_port_admin_status(mdev
, MLX5_PORT_DOWN
);
693 mlx5_set_port_proto(mdev
, link_modes
, MLX5_PTYS_EN
);
694 if (ps
== MLX5_PORT_UP
)
695 mlx5_set_port_admin_status(mdev
, MLX5_PORT_UP
);
701 static u32
mlx5e_get_rxfh_key_size(struct net_device
*netdev
)
703 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
705 return sizeof(priv
->params
.toeplitz_hash_key
);
708 static u32
mlx5e_get_rxfh_indir_size(struct net_device
*netdev
)
710 return MLX5E_INDIR_RQT_SIZE
;
713 static int mlx5e_get_rxfh(struct net_device
*netdev
, u32
*indir
, u8
*key
,
716 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
719 memcpy(indir
, priv
->params
.indirection_rqt
,
720 sizeof(priv
->params
.indirection_rqt
));
723 memcpy(key
, priv
->params
.toeplitz_hash_key
,
724 sizeof(priv
->params
.toeplitz_hash_key
));
727 *hfunc
= priv
->params
.rss_hfunc
;
732 static void mlx5e_modify_tirs_hash(struct mlx5e_priv
*priv
, void *in
, int inlen
)
734 struct mlx5_core_dev
*mdev
= priv
->mdev
;
735 void *tirc
= MLX5_ADDR_OF(modify_tir_in
, in
, ctx
);
738 MLX5_SET(modify_tir_in
, in
, bitmask
.hash
, 1);
739 mlx5e_build_tir_ctx_hash(tirc
, priv
);
741 for (i
= 0; i
< MLX5E_NUM_TT
; i
++)
742 if (IS_HASHING_TT(i
))
743 mlx5_core_modify_tir(mdev
, priv
->tirn
[i
], in
, inlen
);
746 static int mlx5e_set_rxfh(struct net_device
*dev
, const u32
*indir
,
747 const u8
*key
, const u8 hfunc
)
749 struct mlx5e_priv
*priv
= netdev_priv(dev
);
750 int inlen
= MLX5_ST_SZ_BYTES(modify_tir_in
);
753 if ((hfunc
!= ETH_RSS_HASH_NO_CHANGE
) &&
754 (hfunc
!= ETH_RSS_HASH_XOR
) &&
755 (hfunc
!= ETH_RSS_HASH_TOP
))
758 in
= mlx5_vzalloc(inlen
);
762 mutex_lock(&priv
->state_lock
);
765 memcpy(priv
->params
.indirection_rqt
, indir
,
766 sizeof(priv
->params
.indirection_rqt
));
767 mlx5e_redirect_rqt(priv
, MLX5E_INDIRECTION_RQT
);
771 memcpy(priv
->params
.toeplitz_hash_key
, key
,
772 sizeof(priv
->params
.toeplitz_hash_key
));
774 if (hfunc
!= ETH_RSS_HASH_NO_CHANGE
)
775 priv
->params
.rss_hfunc
= hfunc
;
777 mlx5e_modify_tirs_hash(priv
, in
, inlen
);
779 mutex_unlock(&priv
->state_lock
);
786 static int mlx5e_get_rxnfc(struct net_device
*netdev
,
787 struct ethtool_rxnfc
*info
, u32
*rule_locs
)
789 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
793 case ETHTOOL_GRXRINGS
:
794 info
->data
= priv
->params
.num_channels
;
804 static int mlx5e_get_tunable(struct net_device
*dev
,
805 const struct ethtool_tunable
*tuna
,
808 const struct mlx5e_priv
*priv
= netdev_priv(dev
);
812 case ETHTOOL_TX_COPYBREAK
:
813 *(u32
*)data
= priv
->params
.tx_max_inline
;
823 static int mlx5e_set_tunable(struct net_device
*dev
,
824 const struct ethtool_tunable
*tuna
,
827 struct mlx5e_priv
*priv
= netdev_priv(dev
);
828 struct mlx5_core_dev
*mdev
= priv
->mdev
;
834 case ETHTOOL_TX_COPYBREAK
:
836 if (val
> mlx5e_get_max_inline_cap(mdev
)) {
841 mutex_lock(&priv
->state_lock
);
843 was_opened
= test_bit(MLX5E_STATE_OPENED
, &priv
->state
);
845 mlx5e_close_locked(dev
);
847 priv
->params
.tx_max_inline
= val
;
850 err
= mlx5e_open_locked(dev
);
852 mutex_unlock(&priv
->state_lock
);
862 static void mlx5e_get_pauseparam(struct net_device
*netdev
,
863 struct ethtool_pauseparam
*pauseparam
)
865 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
866 struct mlx5_core_dev
*mdev
= priv
->mdev
;
869 err
= mlx5_query_port_pause(mdev
, &pauseparam
->rx_pause
,
870 &pauseparam
->tx_pause
);
872 netdev_err(netdev
, "%s: mlx5_query_port_pause failed:0x%x\n",
877 static int mlx5e_set_pauseparam(struct net_device
*netdev
,
878 struct ethtool_pauseparam
*pauseparam
)
880 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
881 struct mlx5_core_dev
*mdev
= priv
->mdev
;
884 if (pauseparam
->autoneg
)
887 err
= mlx5_set_port_pause(mdev
,
888 pauseparam
->rx_pause
? 1 : 0,
889 pauseparam
->tx_pause
? 1 : 0);
891 netdev_err(netdev
, "%s: mlx5_set_port_pause failed:0x%x\n",
898 static int mlx5e_get_ts_info(struct net_device
*dev
,
899 struct ethtool_ts_info
*info
)
901 struct mlx5e_priv
*priv
= netdev_priv(dev
);
904 ret
= ethtool_op_get_ts_info(dev
, info
);
908 info
->phc_index
= priv
->tstamp
.ptp
?
909 ptp_clock_index(priv
->tstamp
.ptp
) : -1;
911 if (!MLX5_CAP_GEN(priv
->mdev
, device_frequency_khz
))
914 info
->so_timestamping
|= SOF_TIMESTAMPING_TX_HARDWARE
|
915 SOF_TIMESTAMPING_RX_HARDWARE
|
916 SOF_TIMESTAMPING_RAW_HARDWARE
;
918 info
->tx_types
= (BIT(1) << HWTSTAMP_TX_OFF
) |
919 (BIT(1) << HWTSTAMP_TX_ON
);
921 info
->rx_filters
= (BIT(1) << HWTSTAMP_FILTER_NONE
) |
922 (BIT(1) << HWTSTAMP_FILTER_ALL
);
927 static __u32
mlx5e_get_wol_supported(struct mlx5_core_dev
*mdev
)
931 if (MLX5_CAP_GEN(mdev
, wol_g
))
934 if (MLX5_CAP_GEN(mdev
, wol_s
))
935 ret
|= WAKE_MAGICSECURE
;
937 if (MLX5_CAP_GEN(mdev
, wol_a
))
940 if (MLX5_CAP_GEN(mdev
, wol_b
))
943 if (MLX5_CAP_GEN(mdev
, wol_m
))
946 if (MLX5_CAP_GEN(mdev
, wol_u
))
949 if (MLX5_CAP_GEN(mdev
, wol_p
))
955 static __u32
mlx5e_refomrat_wol_mode_mlx5_to_linux(u8 mode
)
959 if (mode
& MLX5_WOL_MAGIC
)
962 if (mode
& MLX5_WOL_SECURED_MAGIC
)
963 ret
|= WAKE_MAGICSECURE
;
965 if (mode
& MLX5_WOL_ARP
)
968 if (mode
& MLX5_WOL_BROADCAST
)
971 if (mode
& MLX5_WOL_MULTICAST
)
974 if (mode
& MLX5_WOL_UNICAST
)
977 if (mode
& MLX5_WOL_PHY_ACTIVITY
)
983 static u8
mlx5e_refomrat_wol_mode_linux_to_mlx5(__u32 mode
)
987 if (mode
& WAKE_MAGIC
)
988 ret
|= MLX5_WOL_MAGIC
;
990 if (mode
& WAKE_MAGICSECURE
)
991 ret
|= MLX5_WOL_SECURED_MAGIC
;
996 if (mode
& WAKE_BCAST
)
997 ret
|= MLX5_WOL_BROADCAST
;
999 if (mode
& WAKE_MCAST
)
1000 ret
|= MLX5_WOL_MULTICAST
;
1002 if (mode
& WAKE_UCAST
)
1003 ret
|= MLX5_WOL_UNICAST
;
1005 if (mode
& WAKE_PHY
)
1006 ret
|= MLX5_WOL_PHY_ACTIVITY
;
1011 static void mlx5e_get_wol(struct net_device
*netdev
,
1012 struct ethtool_wolinfo
*wol
)
1014 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
1015 struct mlx5_core_dev
*mdev
= priv
->mdev
;
1019 memset(wol
, 0, sizeof(*wol
));
1021 wol
->supported
= mlx5e_get_wol_supported(mdev
);
1022 if (!wol
->supported
)
1025 err
= mlx5_query_port_wol(mdev
, &mlx5_wol_mode
);
1029 wol
->wolopts
= mlx5e_refomrat_wol_mode_mlx5_to_linux(mlx5_wol_mode
);
1032 static int mlx5e_set_wol(struct net_device
*netdev
, struct ethtool_wolinfo
*wol
)
1034 struct mlx5e_priv
*priv
= netdev_priv(netdev
);
1035 struct mlx5_core_dev
*mdev
= priv
->mdev
;
1036 __u32 wol_supported
= mlx5e_get_wol_supported(mdev
);
1042 if (wol
->wolopts
& ~wol_supported
)
1045 mlx5_wol_mode
= mlx5e_refomrat_wol_mode_linux_to_mlx5(wol
->wolopts
);
1047 return mlx5_set_port_wol(mdev
, mlx5_wol_mode
);
1050 const struct ethtool_ops mlx5e_ethtool_ops
= {
1051 .get_drvinfo
= mlx5e_get_drvinfo
,
1052 .get_link
= ethtool_op_get_link
,
1053 .get_strings
= mlx5e_get_strings
,
1054 .get_sset_count
= mlx5e_get_sset_count
,
1055 .get_ethtool_stats
= mlx5e_get_ethtool_stats
,
1056 .get_ringparam
= mlx5e_get_ringparam
,
1057 .set_ringparam
= mlx5e_set_ringparam
,
1058 .get_channels
= mlx5e_get_channels
,
1059 .set_channels
= mlx5e_set_channels
,
1060 .get_coalesce
= mlx5e_get_coalesce
,
1061 .set_coalesce
= mlx5e_set_coalesce
,
1062 .get_settings
= mlx5e_get_settings
,
1063 .set_settings
= mlx5e_set_settings
,
1064 .get_rxfh_key_size
= mlx5e_get_rxfh_key_size
,
1065 .get_rxfh_indir_size
= mlx5e_get_rxfh_indir_size
,
1066 .get_rxfh
= mlx5e_get_rxfh
,
1067 .set_rxfh
= mlx5e_set_rxfh
,
1068 .get_rxnfc
= mlx5e_get_rxnfc
,
1069 .get_tunable
= mlx5e_get_tunable
,
1070 .set_tunable
= mlx5e_set_tunable
,
1071 .get_pauseparam
= mlx5e_get_pauseparam
,
1072 .set_pauseparam
= mlx5e_set_pauseparam
,
1073 .get_ts_info
= mlx5e_get_ts_info
,
1074 .get_wol
= mlx5e_get_wol
,
1075 .set_wol
= mlx5e_set_wol
,