1 // SPDX-License-Identifier: GPL-2.0
2 /* Huawei HiNIC PCI Express Linux driver
3 * Copyright(c) 2017 Huawei Technologies Co., Ltd
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include <linux/kernel.h>
17 #include <linux/pci.h>
18 #include <linux/device.h>
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/errno.h>
22 #include <linux/interrupt.h>
23 #include <linux/etherdevice.h>
24 #include <linux/netdevice.h>
25 #include <linux/if_vlan.h>
26 #include <linux/ethtool.h>
27 #include <linux/vmalloc.h>
29 #include "hinic_hw_qp.h"
30 #include "hinic_hw_dev.h"
31 #include "hinic_port.h"
34 #include "hinic_dev.h"
36 #define SET_LINK_STR_MAX_LEN 128
38 #define GET_SUPPORTED_MODE 0
39 #define GET_ADVERTISED_MODE 1
41 #define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \
42 ((ecmd)->supported |= \
43 (1UL << hw_to_ethtool_link_mode_table[mode].link_mode_bit))
44 #define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \
45 ((ecmd)->advertising |= \
46 (1UL << hw_to_ethtool_link_mode_table[mode].link_mode_bit))
47 #define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
48 ((ecmd)->supported |= SUPPORTED_##mode)
49 #define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
50 ((ecmd)->advertising |= ADVERTISED_##mode)
52 struct hw2ethtool_link_mode
{
53 enum ethtool_link_mode_bit_indices link_mode_bit
;
55 enum hinic_link_mode hw_link_mode
;
58 struct cmd_link_settings
{
68 static u32 hw_to_ethtool_speed
[LINK_SPEED_LEVELS
] = {
70 SPEED_1000
, SPEED_10000
,
71 SPEED_25000
, SPEED_40000
,
75 static struct hw2ethtool_link_mode
76 hw_to_ethtool_link_mode_table
[HINIC_LINK_MODE_NUMBERS
] = {
78 .link_mode_bit
= ETHTOOL_LINK_MODE_10000baseKR_Full_BIT
,
80 .hw_link_mode
= HINIC_10GE_BASE_KR
,
83 .link_mode_bit
= ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT
,
85 .hw_link_mode
= HINIC_40GE_BASE_KR4
,
88 .link_mode_bit
= ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT
,
90 .hw_link_mode
= HINIC_40GE_BASE_CR4
,
93 .link_mode_bit
= ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT
,
94 .speed
= SPEED_100000
,
95 .hw_link_mode
= HINIC_100GE_BASE_KR4
,
98 .link_mode_bit
= ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT
,
99 .speed
= SPEED_100000
,
100 .hw_link_mode
= HINIC_100GE_BASE_CR4
,
103 .link_mode_bit
= ETHTOOL_LINK_MODE_25000baseKR_Full_BIT
,
104 .speed
= SPEED_25000
,
105 .hw_link_mode
= HINIC_25GE_BASE_KR_S
,
108 .link_mode_bit
= ETHTOOL_LINK_MODE_25000baseCR_Full_BIT
,
109 .speed
= SPEED_25000
,
110 .hw_link_mode
= HINIC_25GE_BASE_CR_S
,
113 .link_mode_bit
= ETHTOOL_LINK_MODE_25000baseKR_Full_BIT
,
114 .speed
= SPEED_25000
,
115 .hw_link_mode
= HINIC_25GE_BASE_KR
,
118 .link_mode_bit
= ETHTOOL_LINK_MODE_25000baseCR_Full_BIT
,
119 .speed
= SPEED_25000
,
120 .hw_link_mode
= HINIC_25GE_BASE_CR
,
123 .link_mode_bit
= ETHTOOL_LINK_MODE_1000baseKX_Full_BIT
,
125 .hw_link_mode
= HINIC_GE_BASE_KX
,
129 static void set_link_speed(struct ethtool_link_ksettings
*link_ksettings
,
130 enum hinic_speed speed
)
133 case HINIC_SPEED_10MB_LINK
:
134 link_ksettings
->base
.speed
= SPEED_10
;
137 case HINIC_SPEED_100MB_LINK
:
138 link_ksettings
->base
.speed
= SPEED_100
;
141 case HINIC_SPEED_1000MB_LINK
:
142 link_ksettings
->base
.speed
= SPEED_1000
;
145 case HINIC_SPEED_10GB_LINK
:
146 link_ksettings
->base
.speed
= SPEED_10000
;
149 case HINIC_SPEED_25GB_LINK
:
150 link_ksettings
->base
.speed
= SPEED_25000
;
153 case HINIC_SPEED_40GB_LINK
:
154 link_ksettings
->base
.speed
= SPEED_40000
;
157 case HINIC_SPEED_100GB_LINK
:
158 link_ksettings
->base
.speed
= SPEED_100000
;
162 link_ksettings
->base
.speed
= SPEED_UNKNOWN
;
167 static int hinic_get_link_mode_index(enum hinic_link_mode link_mode
)
171 for (i
= 0; i
< HINIC_LINK_MODE_NUMBERS
; i
++) {
172 if (link_mode
== hw_to_ethtool_link_mode_table
[i
].hw_link_mode
)
179 static void hinic_add_ethtool_link_mode(struct cmd_link_settings
*link_settings
,
180 enum hinic_link_mode hw_link_mode
,
183 enum hinic_link_mode link_mode
;
186 for (link_mode
= 0; link_mode
< HINIC_LINK_MODE_NUMBERS
; link_mode
++) {
187 if (hw_link_mode
& ((u32
)1 << link_mode
)) {
188 idx
= hinic_get_link_mode_index(link_mode
);
189 if (idx
>= HINIC_LINK_MODE_NUMBERS
)
192 if (name
== GET_SUPPORTED_MODE
)
193 ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
194 (link_settings
, idx
);
196 ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
197 (link_settings
, idx
);
202 static void hinic_link_port_type(struct cmd_link_settings
*link_settings
,
203 enum hinic_port_type port_type
)
206 case HINIC_PORT_ELEC
:
208 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings
, TP
);
209 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings
, TP
);
210 link_settings
->port
= PORT_TP
;
214 case HINIC_PORT_FIBRE
:
215 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings
, FIBRE
);
216 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings
, FIBRE
);
217 link_settings
->port
= PORT_FIBRE
;
220 case HINIC_PORT_COPPER
:
221 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings
, FIBRE
);
222 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings
, FIBRE
);
223 link_settings
->port
= PORT_DA
;
226 case HINIC_PORT_BACKPLANE
:
227 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings
, Backplane
);
228 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings
, Backplane
);
229 link_settings
->port
= PORT_NONE
;
233 link_settings
->port
= PORT_OTHER
;
238 static int hinic_get_link_ksettings(struct net_device
*netdev
,
239 struct ethtool_link_ksettings
242 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
243 struct hinic_link_mode_cmd link_mode
= { 0 };
244 struct hinic_pause_config pause_info
= { 0 };
245 struct cmd_link_settings settings
= { 0 };
246 enum hinic_port_link_state link_state
;
247 struct hinic_port_cap port_cap
;
250 ethtool_link_ksettings_zero_link_mode(link_ksettings
, supported
);
251 ethtool_link_ksettings_zero_link_mode(link_ksettings
, advertising
);
253 link_ksettings
->base
.speed
= SPEED_UNKNOWN
;
254 link_ksettings
->base
.autoneg
= AUTONEG_DISABLE
;
255 link_ksettings
->base
.duplex
= DUPLEX_UNKNOWN
;
257 err
= hinic_port_get_cap(nic_dev
, &port_cap
);
261 hinic_link_port_type(&settings
, port_cap
.port_type
);
262 link_ksettings
->base
.port
= settings
.port
;
264 err
= hinic_port_link_state(nic_dev
, &link_state
);
268 if (link_state
== HINIC_LINK_STATE_UP
) {
269 set_link_speed(link_ksettings
, port_cap
.speed
);
270 link_ksettings
->base
.duplex
=
271 (port_cap
.duplex
== HINIC_DUPLEX_FULL
) ?
272 DUPLEX_FULL
: DUPLEX_HALF
;
275 if (!!(port_cap
.autoneg_cap
& HINIC_AUTONEG_SUPPORTED
))
276 ethtool_link_ksettings_add_link_mode(link_ksettings
,
277 advertising
, Autoneg
);
279 if (port_cap
.autoneg_state
== HINIC_AUTONEG_ACTIVE
)
280 link_ksettings
->base
.autoneg
= AUTONEG_ENABLE
;
282 err
= hinic_get_link_mode(nic_dev
->hwdev
, &link_mode
);
283 if (err
|| link_mode
.supported
== HINIC_SUPPORTED_UNKNOWN
||
284 link_mode
.advertised
== HINIC_SUPPORTED_UNKNOWN
)
287 hinic_add_ethtool_link_mode(&settings
, link_mode
.supported
,
289 hinic_add_ethtool_link_mode(&settings
, link_mode
.advertised
,
290 GET_ADVERTISED_MODE
);
292 if (!HINIC_IS_VF(nic_dev
->hwdev
->hwif
)) {
293 err
= hinic_get_hw_pause_info(nic_dev
->hwdev
, &pause_info
);
296 ETHTOOL_ADD_SUPPORTED_LINK_MODE(&settings
, Pause
);
297 if (pause_info
.rx_pause
&& pause_info
.tx_pause
) {
298 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings
, Pause
);
299 } else if (pause_info
.tx_pause
) {
300 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings
, Asym_Pause
);
301 } else if (pause_info
.rx_pause
) {
302 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings
, Pause
);
303 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings
, Asym_Pause
);
307 bitmap_copy(link_ksettings
->link_modes
.supported
,
308 (unsigned long *)&settings
.supported
,
309 __ETHTOOL_LINK_MODE_MASK_NBITS
);
310 bitmap_copy(link_ksettings
->link_modes
.advertising
,
311 (unsigned long *)&settings
.advertising
,
312 __ETHTOOL_LINK_MODE_MASK_NBITS
);
317 static int hinic_ethtool_to_hw_speed_level(u32 speed
)
321 for (i
= 0; i
< LINK_SPEED_LEVELS
; i
++) {
322 if (hw_to_ethtool_speed
[i
] == speed
)
329 static bool hinic_is_support_speed(enum hinic_link_mode supported_link
,
332 enum hinic_link_mode link_mode
;
335 for (link_mode
= 0; link_mode
< HINIC_LINK_MODE_NUMBERS
; link_mode
++) {
336 if (!(supported_link
& ((u32
)1 << link_mode
)))
339 idx
= hinic_get_link_mode_index(link_mode
);
340 if (idx
>= HINIC_LINK_MODE_NUMBERS
)
343 if (hw_to_ethtool_link_mode_table
[idx
].speed
== speed
)
350 static bool hinic_is_speed_legal(struct hinic_dev
*nic_dev
, u32 speed
)
352 struct hinic_link_mode_cmd link_mode
= { 0 };
353 struct net_device
*netdev
= nic_dev
->netdev
;
354 enum nic_speed_level speed_level
= 0;
357 err
= hinic_get_link_mode(nic_dev
->hwdev
, &link_mode
);
361 if (link_mode
.supported
== HINIC_SUPPORTED_UNKNOWN
||
362 link_mode
.advertised
== HINIC_SUPPORTED_UNKNOWN
)
365 speed_level
= hinic_ethtool_to_hw_speed_level(speed
);
366 if (speed_level
>= LINK_SPEED_LEVELS
||
367 !hinic_is_support_speed(link_mode
.supported
, speed
)) {
368 netif_err(nic_dev
, drv
, netdev
,
369 "Unsupported speed: %d\n", speed
);
376 static int get_link_settings_type(struct hinic_dev
*nic_dev
,
377 u8 autoneg
, u32 speed
, u32
*set_settings
)
379 struct hinic_port_cap port_cap
= { 0 };
382 err
= hinic_port_get_cap(nic_dev
, &port_cap
);
386 /* always set autonegotiation */
387 if (port_cap
.autoneg_cap
)
388 *set_settings
|= HILINK_LINK_SET_AUTONEG
;
390 if (autoneg
== AUTONEG_ENABLE
) {
391 if (!port_cap
.autoneg_cap
) {
392 netif_err(nic_dev
, drv
, nic_dev
->netdev
, "Not support autoneg\n");
395 } else if (speed
!= (u32
)SPEED_UNKNOWN
) {
396 /* set speed only when autoneg is disabled */
397 if (!hinic_is_speed_legal(nic_dev
, speed
))
399 *set_settings
|= HILINK_LINK_SET_SPEED
;
401 netif_err(nic_dev
, drv
, nic_dev
->netdev
, "Need to set speed when autoneg is off\n");
408 static int set_link_settings_separate_cmd(struct hinic_dev
*nic_dev
,
409 u32 set_settings
, u8 autoneg
,
412 enum nic_speed_level speed_level
= 0;
415 if (set_settings
& HILINK_LINK_SET_AUTONEG
) {
416 err
= hinic_set_autoneg(nic_dev
->hwdev
,
417 (autoneg
== AUTONEG_ENABLE
));
419 netif_err(nic_dev
, drv
, nic_dev
->netdev
, "%s autoneg failed\n",
420 (autoneg
== AUTONEG_ENABLE
) ?
421 "Enable" : "Disable");
423 netif_info(nic_dev
, drv
, nic_dev
->netdev
, "%s autoneg successfully\n",
424 (autoneg
== AUTONEG_ENABLE
) ?
425 "Enable" : "Disable");
428 if (!err
&& (set_settings
& HILINK_LINK_SET_SPEED
)) {
429 speed_level
= hinic_ethtool_to_hw_speed_level(speed
);
430 err
= hinic_set_speed(nic_dev
->hwdev
, speed_level
);
432 netif_err(nic_dev
, drv
, nic_dev
->netdev
, "Set speed %d failed\n",
435 netif_info(nic_dev
, drv
, nic_dev
->netdev
, "Set speed %d successfully\n",
442 static int hinic_set_settings_to_hw(struct hinic_dev
*nic_dev
,
443 u32 set_settings
, u8 autoneg
, u32 speed
)
445 struct hinic_link_ksettings_info settings
= {0};
446 char set_link_str
[SET_LINK_STR_MAX_LEN
] = {0};
447 struct net_device
*netdev
= nic_dev
->netdev
;
448 enum nic_speed_level speed_level
= 0;
451 err
= snprintf(set_link_str
, SET_LINK_STR_MAX_LEN
, "%s",
452 (set_settings
& HILINK_LINK_SET_AUTONEG
) ?
453 (autoneg
? "autong enable " : "autong disable ") : "");
454 if (err
< 0 || err
>= SET_LINK_STR_MAX_LEN
) {
455 netif_err(nic_dev
, drv
, netdev
, "Failed to snprintf link state, function return(%d) and dest_len(%d)\n",
456 err
, SET_LINK_STR_MAX_LEN
);
460 if (set_settings
& HILINK_LINK_SET_SPEED
) {
461 speed_level
= hinic_ethtool_to_hw_speed_level(speed
);
462 err
= snprintf(set_link_str
, SET_LINK_STR_MAX_LEN
,
463 "%sspeed %d ", set_link_str
, speed
);
464 if (err
<= 0 || err
>= SET_LINK_STR_MAX_LEN
) {
465 netif_err(nic_dev
, drv
, netdev
, "Failed to snprintf link speed, function return(%d) and dest_len(%d)\n",
466 err
, SET_LINK_STR_MAX_LEN
);
471 settings
.func_id
= HINIC_HWIF_FUNC_IDX(nic_dev
->hwdev
->hwif
);
472 settings
.valid_bitmap
= set_settings
;
473 settings
.autoneg
= autoneg
;
474 settings
.speed
= speed_level
;
476 err
= hinic_set_link_settings(nic_dev
->hwdev
, &settings
);
477 if (err
!= HINIC_MGMT_CMD_UNSUPPORTED
) {
479 netif_err(nic_dev
, drv
, netdev
, "Set %s failed\n",
482 netif_info(nic_dev
, drv
, netdev
, "Set %s successfully\n",
488 return set_link_settings_separate_cmd(nic_dev
, set_settings
, autoneg
,
492 static int set_link_settings(struct net_device
*netdev
, u8 autoneg
, u32 speed
)
494 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
495 u32 set_settings
= 0;
498 err
= get_link_settings_type(nic_dev
, autoneg
, speed
, &set_settings
);
503 err
= hinic_set_settings_to_hw(nic_dev
, set_settings
,
506 netif_info(nic_dev
, drv
, netdev
, "Nothing changed, exit without setting anything\n");
511 static int hinic_set_link_ksettings(struct net_device
*netdev
, const struct
512 ethtool_link_ksettings
*link_settings
)
514 /* only support to set autoneg and speed */
515 return set_link_settings(netdev
, link_settings
->base
.autoneg
,
516 link_settings
->base
.speed
);
519 static void hinic_get_drvinfo(struct net_device
*netdev
,
520 struct ethtool_drvinfo
*info
)
522 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
523 u8 mgmt_ver
[HINIC_MGMT_VERSION_MAX_LEN
] = {0};
524 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
525 struct hinic_hwif
*hwif
= hwdev
->hwif
;
528 strlcpy(info
->driver
, HINIC_DRV_NAME
, sizeof(info
->driver
));
529 strlcpy(info
->bus_info
, pci_name(hwif
->pdev
), sizeof(info
->bus_info
));
531 err
= hinic_get_mgmt_version(nic_dev
, mgmt_ver
);
535 snprintf(info
->fw_version
, sizeof(info
->fw_version
), "%s", mgmt_ver
);
538 static void hinic_get_ringparam(struct net_device
*netdev
,
539 struct ethtool_ringparam
*ring
)
541 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
543 ring
->rx_max_pending
= HINIC_MAX_QUEUE_DEPTH
;
544 ring
->tx_max_pending
= HINIC_MAX_QUEUE_DEPTH
;
545 ring
->rx_pending
= nic_dev
->rq_depth
;
546 ring
->tx_pending
= nic_dev
->sq_depth
;
549 static int check_ringparam_valid(struct hinic_dev
*nic_dev
,
550 struct ethtool_ringparam
*ring
)
552 if (ring
->rx_jumbo_pending
|| ring
->rx_mini_pending
) {
553 netif_err(nic_dev
, drv
, nic_dev
->netdev
,
554 "Unsupported rx_jumbo_pending/rx_mini_pending\n");
558 if (ring
->tx_pending
> HINIC_MAX_QUEUE_DEPTH
||
559 ring
->tx_pending
< HINIC_MIN_QUEUE_DEPTH
||
560 ring
->rx_pending
> HINIC_MAX_QUEUE_DEPTH
||
561 ring
->rx_pending
< HINIC_MIN_QUEUE_DEPTH
) {
562 netif_err(nic_dev
, drv
, nic_dev
->netdev
,
563 "Queue depth out of range [%d-%d]\n",
564 HINIC_MIN_QUEUE_DEPTH
, HINIC_MAX_QUEUE_DEPTH
);
571 static int hinic_set_ringparam(struct net_device
*netdev
,
572 struct ethtool_ringparam
*ring
)
574 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
575 u16 new_sq_depth
, new_rq_depth
;
578 err
= check_ringparam_valid(nic_dev
, ring
);
582 new_sq_depth
= (u16
)(1U << (u16
)ilog2(ring
->tx_pending
));
583 new_rq_depth
= (u16
)(1U << (u16
)ilog2(ring
->rx_pending
));
585 if (new_sq_depth
== nic_dev
->sq_depth
&&
586 new_rq_depth
== nic_dev
->rq_depth
)
589 netif_info(nic_dev
, drv
, netdev
,
590 "Change Tx/Rx ring depth from %d/%d to %d/%d\n",
591 nic_dev
->sq_depth
, nic_dev
->rq_depth
,
592 new_sq_depth
, new_rq_depth
);
594 nic_dev
->sq_depth
= new_sq_depth
;
595 nic_dev
->rq_depth
= new_rq_depth
;
597 if (netif_running(netdev
)) {
598 netif_info(nic_dev
, drv
, netdev
, "Restarting netdev\n");
599 err
= hinic_close(netdev
);
601 netif_err(nic_dev
, drv
, netdev
,
602 "Failed to close netdev\n");
606 err
= hinic_open(netdev
);
608 netif_err(nic_dev
, drv
, netdev
,
609 "Failed to open netdev\n");
616 static void hinic_get_channels(struct net_device
*netdev
,
617 struct ethtool_channels
*channels
)
619 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
620 struct hinic_hwdev
*hwdev
= nic_dev
->hwdev
;
622 channels
->max_rx
= hwdev
->nic_cap
.max_qps
;
623 channels
->max_tx
= hwdev
->nic_cap
.max_qps
;
624 channels
->max_other
= 0;
625 channels
->max_combined
= 0;
626 channels
->rx_count
= hinic_hwdev_num_qps(hwdev
);
627 channels
->tx_count
= hinic_hwdev_num_qps(hwdev
);
628 channels
->other_count
= 0;
629 channels
->combined_count
= 0;
632 static int hinic_get_rss_hash_opts(struct hinic_dev
*nic_dev
,
633 struct ethtool_rxnfc
*cmd
)
635 struct hinic_rss_type rss_type
= { 0 };
640 if (!(nic_dev
->flags
& HINIC_RSS_ENABLE
))
643 err
= hinic_get_rss_type(nic_dev
, nic_dev
->rss_tmpl_idx
,
648 cmd
->data
= RXH_IP_SRC
| RXH_IP_DST
;
649 switch (cmd
->flow_type
) {
651 if (rss_type
.tcp_ipv4
)
652 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
655 if (rss_type
.tcp_ipv6
)
656 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
659 if (rss_type
.udp_ipv4
)
660 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
663 if (rss_type
.udp_ipv6
)
664 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
677 static int set_l4_rss_hash_ops(struct ethtool_rxnfc
*cmd
,
678 struct hinic_rss_type
*rss_type
)
682 switch (cmd
->data
& (RXH_L4_B_0_1
| RXH_L4_B_2_3
)) {
686 case (RXH_L4_B_0_1
| RXH_L4_B_2_3
):
693 switch (cmd
->flow_type
) {
695 rss_type
->tcp_ipv4
= rss_l4_en
;
698 rss_type
->tcp_ipv6
= rss_l4_en
;
701 rss_type
->udp_ipv4
= rss_l4_en
;
704 rss_type
->udp_ipv6
= rss_l4_en
;
713 static int hinic_set_rss_hash_opts(struct hinic_dev
*nic_dev
,
714 struct ethtool_rxnfc
*cmd
)
716 struct hinic_rss_type
*rss_type
= &nic_dev
->rss_type
;
719 if (!(nic_dev
->flags
& HINIC_RSS_ENABLE
)) {
724 /* RSS does not support anything other than hashing
725 * to queues on src and dst IPs and ports
727 if (cmd
->data
& ~(RXH_IP_SRC
| RXH_IP_DST
| RXH_L4_B_0_1
|
731 /* We need at least the IP SRC and DEST fields for hashing */
732 if (!(cmd
->data
& RXH_IP_SRC
) || !(cmd
->data
& RXH_IP_DST
))
735 err
= hinic_get_rss_type(nic_dev
,
736 nic_dev
->rss_tmpl_idx
, rss_type
);
740 switch (cmd
->flow_type
) {
745 err
= set_l4_rss_hash_ops(cmd
, rss_type
);
759 err
= hinic_set_rss_type(nic_dev
, nic_dev
->rss_tmpl_idx
,
767 static int __set_rss_rxfh(struct net_device
*netdev
,
768 const u32
*indir
, const u8
*key
)
770 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
774 if (!nic_dev
->rss_indir_user
) {
775 nic_dev
->rss_indir_user
=
776 kzalloc(sizeof(u32
) * HINIC_RSS_INDIR_SIZE
,
778 if (!nic_dev
->rss_indir_user
)
782 memcpy(nic_dev
->rss_indir_user
, indir
,
783 sizeof(u32
) * HINIC_RSS_INDIR_SIZE
);
785 err
= hinic_rss_set_indir_tbl(nic_dev
,
786 nic_dev
->rss_tmpl_idx
, indir
);
792 if (!nic_dev
->rss_hkey_user
) {
793 nic_dev
->rss_hkey_user
=
794 kzalloc(HINIC_RSS_KEY_SIZE
* 2, GFP_KERNEL
);
796 if (!nic_dev
->rss_hkey_user
)
800 memcpy(nic_dev
->rss_hkey_user
, key
, HINIC_RSS_KEY_SIZE
);
802 err
= hinic_rss_set_template_tbl(nic_dev
,
803 nic_dev
->rss_tmpl_idx
, key
);
811 static int hinic_get_rxnfc(struct net_device
*netdev
,
812 struct ethtool_rxnfc
*cmd
, u32
*rule_locs
)
814 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
818 case ETHTOOL_GRXRINGS
:
819 cmd
->data
= nic_dev
->num_qps
;
822 err
= hinic_get_rss_hash_opts(nic_dev
, cmd
);
832 static int hinic_set_rxnfc(struct net_device
*netdev
, struct ethtool_rxnfc
*cmd
)
834 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
839 err
= hinic_set_rss_hash_opts(nic_dev
, cmd
);
849 static int hinic_get_rxfh(struct net_device
*netdev
,
850 u32
*indir
, u8
*key
, u8
*hfunc
)
852 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
853 u8 hash_engine_type
= 0;
856 if (!(nic_dev
->flags
& HINIC_RSS_ENABLE
))
860 err
= hinic_rss_get_hash_engine(nic_dev
,
861 nic_dev
->rss_tmpl_idx
,
866 *hfunc
= hash_engine_type
? ETH_RSS_HASH_TOP
: ETH_RSS_HASH_XOR
;
870 err
= hinic_rss_get_indir_tbl(nic_dev
,
871 nic_dev
->rss_tmpl_idx
, indir
);
877 err
= hinic_rss_get_template_tbl(nic_dev
,
878 nic_dev
->rss_tmpl_idx
, key
);
883 static int hinic_set_rxfh(struct net_device
*netdev
, const u32
*indir
,
884 const u8
*key
, const u8 hfunc
)
886 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
889 if (!(nic_dev
->flags
& HINIC_RSS_ENABLE
))
892 if (hfunc
!= ETH_RSS_HASH_NO_CHANGE
) {
893 if (hfunc
!= ETH_RSS_HASH_TOP
&& hfunc
!= ETH_RSS_HASH_XOR
)
896 nic_dev
->rss_hash_engine
= (hfunc
== ETH_RSS_HASH_XOR
) ?
897 HINIC_RSS_HASH_ENGINE_TYPE_XOR
:
898 HINIC_RSS_HASH_ENGINE_TYPE_TOEP
;
899 err
= hinic_rss_set_hash_engine
900 (nic_dev
, nic_dev
->rss_tmpl_idx
,
901 nic_dev
->rss_hash_engine
);
906 err
= __set_rss_rxfh(netdev
, indir
, key
);
911 static u32
hinic_get_rxfh_key_size(struct net_device
*netdev
)
913 return HINIC_RSS_KEY_SIZE
;
916 static u32
hinic_get_rxfh_indir_size(struct net_device
*netdev
)
918 return HINIC_RSS_INDIR_SIZE
;
921 #define ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof(arr[0])))
923 #define HINIC_FUNC_STAT(_stat_item) { \
924 .name = #_stat_item, \
925 .size = sizeof_field(struct hinic_vport_stats, _stat_item), \
926 .offset = offsetof(struct hinic_vport_stats, _stat_item) \
929 static struct hinic_stats hinic_function_stats
[] = {
930 HINIC_FUNC_STAT(tx_unicast_pkts_vport
),
931 HINIC_FUNC_STAT(tx_unicast_bytes_vport
),
932 HINIC_FUNC_STAT(tx_multicast_pkts_vport
),
933 HINIC_FUNC_STAT(tx_multicast_bytes_vport
),
934 HINIC_FUNC_STAT(tx_broadcast_pkts_vport
),
935 HINIC_FUNC_STAT(tx_broadcast_bytes_vport
),
937 HINIC_FUNC_STAT(rx_unicast_pkts_vport
),
938 HINIC_FUNC_STAT(rx_unicast_bytes_vport
),
939 HINIC_FUNC_STAT(rx_multicast_pkts_vport
),
940 HINIC_FUNC_STAT(rx_multicast_bytes_vport
),
941 HINIC_FUNC_STAT(rx_broadcast_pkts_vport
),
942 HINIC_FUNC_STAT(rx_broadcast_bytes_vport
),
944 HINIC_FUNC_STAT(tx_discard_vport
),
945 HINIC_FUNC_STAT(rx_discard_vport
),
946 HINIC_FUNC_STAT(tx_err_vport
),
947 HINIC_FUNC_STAT(rx_err_vport
),
950 #define HINIC_PORT_STAT(_stat_item) { \
951 .name = #_stat_item, \
952 .size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \
953 .offset = offsetof(struct hinic_phy_port_stats, _stat_item) \
956 static struct hinic_stats hinic_port_stats
[] = {
957 HINIC_PORT_STAT(mac_rx_total_pkt_num
),
958 HINIC_PORT_STAT(mac_rx_total_oct_num
),
959 HINIC_PORT_STAT(mac_rx_bad_pkt_num
),
960 HINIC_PORT_STAT(mac_rx_bad_oct_num
),
961 HINIC_PORT_STAT(mac_rx_good_pkt_num
),
962 HINIC_PORT_STAT(mac_rx_good_oct_num
),
963 HINIC_PORT_STAT(mac_rx_uni_pkt_num
),
964 HINIC_PORT_STAT(mac_rx_multi_pkt_num
),
965 HINIC_PORT_STAT(mac_rx_broad_pkt_num
),
966 HINIC_PORT_STAT(mac_tx_total_pkt_num
),
967 HINIC_PORT_STAT(mac_tx_total_oct_num
),
968 HINIC_PORT_STAT(mac_tx_bad_pkt_num
),
969 HINIC_PORT_STAT(mac_tx_bad_oct_num
),
970 HINIC_PORT_STAT(mac_tx_good_pkt_num
),
971 HINIC_PORT_STAT(mac_tx_good_oct_num
),
972 HINIC_PORT_STAT(mac_tx_uni_pkt_num
),
973 HINIC_PORT_STAT(mac_tx_multi_pkt_num
),
974 HINIC_PORT_STAT(mac_tx_broad_pkt_num
),
975 HINIC_PORT_STAT(mac_rx_fragment_pkt_num
),
976 HINIC_PORT_STAT(mac_rx_undersize_pkt_num
),
977 HINIC_PORT_STAT(mac_rx_undermin_pkt_num
),
978 HINIC_PORT_STAT(mac_rx_64_oct_pkt_num
),
979 HINIC_PORT_STAT(mac_rx_65_127_oct_pkt_num
),
980 HINIC_PORT_STAT(mac_rx_128_255_oct_pkt_num
),
981 HINIC_PORT_STAT(mac_rx_256_511_oct_pkt_num
),
982 HINIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num
),
983 HINIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num
),
984 HINIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num
),
985 HINIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num
),
986 HINIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num
),
987 HINIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num
),
988 HINIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num
),
989 HINIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num
),
990 HINIC_PORT_STAT(mac_rx_1519_max_good_pkt_num
),
991 HINIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num
),
992 HINIC_PORT_STAT(mac_rx_oversize_pkt_num
),
993 HINIC_PORT_STAT(mac_rx_jabber_pkt_num
),
994 HINIC_PORT_STAT(mac_rx_pause_num
),
995 HINIC_PORT_STAT(mac_rx_pfc_pkt_num
),
996 HINIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num
),
997 HINIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num
),
998 HINIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num
),
999 HINIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num
),
1000 HINIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num
),
1001 HINIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num
),
1002 HINIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num
),
1003 HINIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num
),
1004 HINIC_PORT_STAT(mac_rx_control_pkt_num
),
1005 HINIC_PORT_STAT(mac_rx_sym_err_pkt_num
),
1006 HINIC_PORT_STAT(mac_rx_fcs_err_pkt_num
),
1007 HINIC_PORT_STAT(mac_rx_send_app_good_pkt_num
),
1008 HINIC_PORT_STAT(mac_rx_send_app_bad_pkt_num
),
1009 HINIC_PORT_STAT(mac_tx_fragment_pkt_num
),
1010 HINIC_PORT_STAT(mac_tx_undersize_pkt_num
),
1011 HINIC_PORT_STAT(mac_tx_undermin_pkt_num
),
1012 HINIC_PORT_STAT(mac_tx_64_oct_pkt_num
),
1013 HINIC_PORT_STAT(mac_tx_65_127_oct_pkt_num
),
1014 HINIC_PORT_STAT(mac_tx_128_255_oct_pkt_num
),
1015 HINIC_PORT_STAT(mac_tx_256_511_oct_pkt_num
),
1016 HINIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num
),
1017 HINIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num
),
1018 HINIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num
),
1019 HINIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num
),
1020 HINIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num
),
1021 HINIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num
),
1022 HINIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num
),
1023 HINIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num
),
1024 HINIC_PORT_STAT(mac_tx_1519_max_good_pkt_num
),
1025 HINIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num
),
1026 HINIC_PORT_STAT(mac_tx_oversize_pkt_num
),
1027 HINIC_PORT_STAT(mac_tx_jabber_pkt_num
),
1028 HINIC_PORT_STAT(mac_tx_pause_num
),
1029 HINIC_PORT_STAT(mac_tx_pfc_pkt_num
),
1030 HINIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num
),
1031 HINIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num
),
1032 HINIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num
),
1033 HINIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num
),
1034 HINIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num
),
1035 HINIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num
),
1036 HINIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num
),
1037 HINIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num
),
1038 HINIC_PORT_STAT(mac_tx_control_pkt_num
),
1039 HINIC_PORT_STAT(mac_tx_err_all_pkt_num
),
1040 HINIC_PORT_STAT(mac_tx_from_app_good_pkt_num
),
1041 HINIC_PORT_STAT(mac_tx_from_app_bad_pkt_num
),
1044 #define HINIC_TXQ_STAT(_stat_item) { \
1045 .name = "txq%d_"#_stat_item, \
1046 .size = sizeof_field(struct hinic_txq_stats, _stat_item), \
1047 .offset = offsetof(struct hinic_txq_stats, _stat_item) \
1050 static struct hinic_stats hinic_tx_queue_stats
[] = {
1051 HINIC_TXQ_STAT(pkts
),
1052 HINIC_TXQ_STAT(bytes
),
1053 HINIC_TXQ_STAT(tx_busy
),
1054 HINIC_TXQ_STAT(tx_wake
),
1055 HINIC_TXQ_STAT(tx_dropped
),
1056 HINIC_TXQ_STAT(big_frags_pkts
),
1059 #define HINIC_RXQ_STAT(_stat_item) { \
1060 .name = "rxq%d_"#_stat_item, \
1061 .size = sizeof_field(struct hinic_rxq_stats, _stat_item), \
1062 .offset = offsetof(struct hinic_rxq_stats, _stat_item) \
1065 static struct hinic_stats hinic_rx_queue_stats
[] = {
1066 HINIC_RXQ_STAT(pkts
),
1067 HINIC_RXQ_STAT(bytes
),
1068 HINIC_RXQ_STAT(errors
),
1069 HINIC_RXQ_STAT(csum_errors
),
1070 HINIC_RXQ_STAT(other_errors
),
1073 static void get_drv_queue_stats(struct hinic_dev
*nic_dev
, u64
*data
)
1075 struct hinic_txq_stats txq_stats
;
1076 struct hinic_rxq_stats rxq_stats
;
1077 u16 i
= 0, j
= 0, qid
= 0;
1080 for (qid
= 0; qid
< nic_dev
->num_qps
; qid
++) {
1084 hinic_txq_get_stats(&nic_dev
->txqs
[qid
], &txq_stats
);
1085 for (j
= 0; j
< ARRAY_LEN(hinic_tx_queue_stats
); j
++, i
++) {
1086 p
= (char *)&txq_stats
+
1087 hinic_tx_queue_stats
[j
].offset
;
1088 data
[i
] = (hinic_tx_queue_stats
[j
].size
==
1089 sizeof(u64
)) ? *(u64
*)p
: *(u32
*)p
;
1093 for (qid
= 0; qid
< nic_dev
->num_qps
; qid
++) {
1097 hinic_rxq_get_stats(&nic_dev
->rxqs
[qid
], &rxq_stats
);
1098 for (j
= 0; j
< ARRAY_LEN(hinic_rx_queue_stats
); j
++, i
++) {
1099 p
= (char *)&rxq_stats
+
1100 hinic_rx_queue_stats
[j
].offset
;
1101 data
[i
] = (hinic_rx_queue_stats
[j
].size
==
1102 sizeof(u64
)) ? *(u64
*)p
: *(u32
*)p
;
1107 static void hinic_get_ethtool_stats(struct net_device
*netdev
,
1108 struct ethtool_stats
*stats
, u64
*data
)
1110 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
1111 struct hinic_vport_stats vport_stats
= {0};
1112 struct hinic_phy_port_stats
*port_stats
;
1117 err
= hinic_get_vport_stats(nic_dev
, &vport_stats
);
1119 netif_err(nic_dev
, drv
, netdev
,
1120 "Failed to get vport stats from firmware\n");
1122 for (j
= 0; j
< ARRAY_LEN(hinic_function_stats
); j
++, i
++) {
1123 p
= (char *)&vport_stats
+ hinic_function_stats
[j
].offset
;
1124 data
[i
] = (hinic_function_stats
[j
].size
==
1125 sizeof(u64
)) ? *(u64
*)p
: *(u32
*)p
;
1128 port_stats
= kzalloc(sizeof(*port_stats
), GFP_KERNEL
);
1131 ARRAY_LEN(hinic_port_stats
) * sizeof(*data
));
1132 i
+= ARRAY_LEN(hinic_port_stats
);
1136 err
= hinic_get_phy_port_stats(nic_dev
, port_stats
);
1138 netif_err(nic_dev
, drv
, netdev
,
1139 "Failed to get port stats from firmware\n");
1141 for (j
= 0; j
< ARRAY_LEN(hinic_port_stats
); j
++, i
++) {
1142 p
= (char *)port_stats
+ hinic_port_stats
[j
].offset
;
1143 data
[i
] = (hinic_port_stats
[j
].size
==
1144 sizeof(u64
)) ? *(u64
*)p
: *(u32
*)p
;
1150 get_drv_queue_stats(nic_dev
, data
+ i
);
1153 static int hinic_get_sset_count(struct net_device
*netdev
, int sset
)
1155 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
1160 q_num
= nic_dev
->num_qps
;
1161 count
= ARRAY_LEN(hinic_function_stats
) +
1162 (ARRAY_LEN(hinic_tx_queue_stats
) +
1163 ARRAY_LEN(hinic_rx_queue_stats
)) * q_num
;
1165 count
+= ARRAY_LEN(hinic_port_stats
);
1173 static void hinic_get_strings(struct net_device
*netdev
,
1174 u32 stringset
, u8
*data
)
1176 struct hinic_dev
*nic_dev
= netdev_priv(netdev
);
1177 char *p
= (char *)data
;
1180 switch (stringset
) {
1182 for (i
= 0; i
< ARRAY_LEN(hinic_function_stats
); i
++) {
1183 memcpy(p
, hinic_function_stats
[i
].name
,
1185 p
+= ETH_GSTRING_LEN
;
1188 for (i
= 0; i
< ARRAY_LEN(hinic_port_stats
); i
++) {
1189 memcpy(p
, hinic_port_stats
[i
].name
,
1191 p
+= ETH_GSTRING_LEN
;
1194 for (i
= 0; i
< nic_dev
->num_qps
; i
++) {
1195 for (j
= 0; j
< ARRAY_LEN(hinic_tx_queue_stats
); j
++) {
1196 sprintf(p
, hinic_tx_queue_stats
[j
].name
, i
);
1197 p
+= ETH_GSTRING_LEN
;
1201 for (i
= 0; i
< nic_dev
->num_qps
; i
++) {
1202 for (j
= 0; j
< ARRAY_LEN(hinic_rx_queue_stats
); j
++) {
1203 sprintf(p
, hinic_rx_queue_stats
[j
].name
, i
);
1204 p
+= ETH_GSTRING_LEN
;
1214 static const struct ethtool_ops hinic_ethtool_ops
= {
1215 .get_link_ksettings
= hinic_get_link_ksettings
,
1216 .set_link_ksettings
= hinic_set_link_ksettings
,
1217 .get_drvinfo
= hinic_get_drvinfo
,
1218 .get_link
= ethtool_op_get_link
,
1219 .get_ringparam
= hinic_get_ringparam
,
1220 .set_ringparam
= hinic_set_ringparam
,
1221 .get_channels
= hinic_get_channels
,
1222 .get_rxnfc
= hinic_get_rxnfc
,
1223 .set_rxnfc
= hinic_set_rxnfc
,
1224 .get_rxfh_key_size
= hinic_get_rxfh_key_size
,
1225 .get_rxfh_indir_size
= hinic_get_rxfh_indir_size
,
1226 .get_rxfh
= hinic_get_rxfh
,
1227 .set_rxfh
= hinic_set_rxfh
,
1228 .get_sset_count
= hinic_get_sset_count
,
1229 .get_ethtool_stats
= hinic_get_ethtool_stats
,
1230 .get_strings
= hinic_get_strings
,
1233 void hinic_set_ethtool_ops(struct net_device
*netdev
)
1235 netdev
->ethtool_ops
= &hinic_ethtool_ops
;