2 * Copyright (c) 2016~2017 Hisilicon Limited.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
10 #include <linux/etherdevice.h>
11 #include <linux/string.h>
13 #include "hns3_enet.h"
16 char stats_string
[ETH_GSTRING_LEN
];
21 /* tqp related stats */
22 #define HNS3_TQP_STAT(_string, _member) { \
23 .stats_string = _string, \
24 .stats_size = FIELD_SIZEOF(struct ring_stats, _member), \
25 .stats_offset = offsetof(struct hns3_enet_ring, stats), \
28 static const struct hns3_stats hns3_txq_stats[] = {
29 /* Tx per-queue statistics */
30 HNS3_TQP_STAT("tx_io_err_cnt", io_err_cnt
),
31 HNS3_TQP_STAT("tx_sw_err_cnt", sw_err_cnt
),
32 HNS3_TQP_STAT("tx_seg_pkt_cnt", seg_pkt_cnt
),
33 HNS3_TQP_STAT("tx_pkts", tx_pkts
),
34 HNS3_TQP_STAT("tx_bytes", tx_bytes
),
35 HNS3_TQP_STAT("tx_err_cnt", tx_err_cnt
),
36 HNS3_TQP_STAT("tx_restart_queue", restart_queue
),
37 HNS3_TQP_STAT("tx_busy", tx_busy
),
40 #define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats)
42 static const struct hns3_stats hns3_rxq_stats
[] = {
43 /* Rx per-queue statistics */
44 HNS3_TQP_STAT("rx_io_err_cnt", io_err_cnt
),
45 HNS3_TQP_STAT("rx_sw_err_cnt", sw_err_cnt
),
46 HNS3_TQP_STAT("rx_seg_pkt_cnt", seg_pkt_cnt
),
47 HNS3_TQP_STAT("rx_pkts", rx_pkts
),
48 HNS3_TQP_STAT("rx_bytes", rx_bytes
),
49 HNS3_TQP_STAT("rx_err_cnt", rx_err_cnt
),
50 HNS3_TQP_STAT("rx_reuse_pg_cnt", reuse_pg_cnt
),
51 HNS3_TQP_STAT("rx_err_pkt_len", err_pkt_len
),
52 HNS3_TQP_STAT("rx_non_vld_descs", non_vld_descs
),
53 HNS3_TQP_STAT("rx_err_bd_num", err_bd_num
),
54 HNS3_TQP_STAT("rx_l2_err", l2_err
),
55 HNS3_TQP_STAT("rx_l3l4_csum_err", l3l4_csum_err
),
58 #define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
60 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
62 struct hns3_link_mode_mapping
{
64 u32 ethtool_link_mode
;
67 static const struct hns3_link_mode_mapping hns3_lm_map
[] = {
68 {HNS3_LM_FIBRE_BIT
, ETHTOOL_LINK_MODE_FIBRE_BIT
},
69 {HNS3_LM_AUTONEG_BIT
, ETHTOOL_LINK_MODE_Autoneg_BIT
},
70 {HNS3_LM_TP_BIT
, ETHTOOL_LINK_MODE_TP_BIT
},
71 {HNS3_LM_PAUSE_BIT
, ETHTOOL_LINK_MODE_Pause_BIT
},
72 {HNS3_LM_BACKPLANE_BIT
, ETHTOOL_LINK_MODE_Backplane_BIT
},
73 {HNS3_LM_10BASET_HALF_BIT
, ETHTOOL_LINK_MODE_10baseT_Half_BIT
},
74 {HNS3_LM_10BASET_FULL_BIT
, ETHTOOL_LINK_MODE_10baseT_Full_BIT
},
75 {HNS3_LM_100BASET_HALF_BIT
, ETHTOOL_LINK_MODE_100baseT_Half_BIT
},
76 {HNS3_LM_100BASET_FULL_BIT
, ETHTOOL_LINK_MODE_100baseT_Full_BIT
},
77 {HNS3_LM_1000BASET_FULL_BIT
, ETHTOOL_LINK_MODE_1000baseT_Full_BIT
},
80 static void hns3_driv_to_eth_caps(u32 caps
, struct ethtool_link_ksettings
*cmd
,
85 for (i
= 0; i
< ARRAY_SIZE(hns3_lm_map
); i
++) {
86 if (!(caps
& hns3_lm_map
[i
].hns3_link_mode
))
90 ethtool_link_ksettings_zero_link_mode(cmd
,
92 __set_bit(hns3_lm_map
[i
].ethtool_link_mode
,
93 cmd
->link_modes
.advertising
);
95 ethtool_link_ksettings_zero_link_mode(cmd
,
97 __set_bit(hns3_lm_map
[i
].ethtool_link_mode
,
98 cmd
->link_modes
.supported
);
103 static int hns3_get_sset_count(struct net_device
*netdev
, int stringset
)
105 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
106 struct hnae3_handle
*h
= priv
->ae_handle
;
107 const struct hnae3_ae_ops
*ops
= h
->ae_algo
->ops
;
109 if (!ops
->get_sset_count
)
114 return ((HNS3_TQP_STATS_COUNT
* h
->kinfo
.num_tqps
) +
115 ops
->get_sset_count(h
, stringset
));
118 return ops
->get_sset_count(h
, stringset
);
124 static void *hns3_update_strings(u8
*data
, const struct hns3_stats
*stats
,
125 u32 stat_count
, u32 num_tqps
)
127 #define MAX_PREFIX_SIZE (8 + 4)
132 for (i
= 0; i
< num_tqps
; i
++) {
133 for (j
= 0; j
< stat_count
; j
++) {
134 data
[ETH_GSTRING_LEN
- 1] = '\0';
136 /* first, prepend the prefix string */
137 n1
= snprintf(data
, MAX_PREFIX_SIZE
, "rcb_q%d_", i
);
138 n1
= min_t(uint
, n1
, MAX_PREFIX_SIZE
- 1);
139 size_left
= (ETH_GSTRING_LEN
- 1) - n1
;
141 /* now, concatenate the stats string to it */
142 strncat(data
, stats
[j
].stats_string
, size_left
);
143 data
+= ETH_GSTRING_LEN
;
150 static u8
*hns3_get_strings_tqps(struct hnae3_handle
*handle
, u8
*data
)
152 struct hnae3_knic_private_info
*kinfo
= &handle
->kinfo
;
154 /* get strings for Tx */
155 data
= hns3_update_strings(data
, hns3_txq_stats
, HNS3_TXQ_STATS_COUNT
,
158 /* get strings for Rx */
159 data
= hns3_update_strings(data
, hns3_rxq_stats
, HNS3_RXQ_STATS_COUNT
,
165 static void hns3_get_strings(struct net_device
*netdev
, u32 stringset
, u8
*data
)
167 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
168 struct hnae3_handle
*h
= priv
->ae_handle
;
169 const struct hnae3_ae_ops
*ops
= h
->ae_algo
->ops
;
170 char *buff
= (char *)data
;
172 if (!ops
->get_strings
)
177 buff
= hns3_get_strings_tqps(h
, buff
);
178 h
->ae_algo
->ops
->get_strings(h
, stringset
, (u8
*)buff
);
181 ops
->get_strings(h
, stringset
, data
);
186 static u64
*hns3_get_stats_tqps(struct hnae3_handle
*handle
, u64
*data
)
188 struct hns3_nic_priv
*nic_priv
= (struct hns3_nic_priv
*)handle
->priv
;
189 struct hnae3_knic_private_info
*kinfo
= &handle
->kinfo
;
190 struct hns3_enet_ring
*ring
;
194 /* get stats for Tx */
195 for (i
= 0; i
< kinfo
->num_tqps
; i
++) {
196 ring
= nic_priv
->ring_data
[i
].ring
;
197 for (i
= 0; i
< HNS3_TXQ_STATS_COUNT
; i
++) {
198 stat
= (u8
*)ring
+ hns3_txq_stats
[i
].stats_offset
;
199 *data
++ = *(u64
*)stat
;
203 /* get stats for Rx */
204 for (i
= 0; i
< kinfo
->num_tqps
; i
++) {
205 ring
= nic_priv
->ring_data
[i
+ kinfo
->num_tqps
].ring
;
206 for (i
= 0; i
< HNS3_RXQ_STATS_COUNT
; i
++) {
207 stat
= (u8
*)ring
+ hns3_rxq_stats
[i
].stats_offset
;
208 *data
++ = *(u64
*)stat
;
215 /* hns3_get_stats - get detail statistics.
216 * @netdev: net device
217 * @stats: statistics info.
218 * @data: statistics data.
220 void hns3_get_stats(struct net_device
*netdev
, struct ethtool_stats
*stats
,
223 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
224 struct hnae3_handle
*h
= priv
->ae_handle
;
227 if (!h
->ae_algo
->ops
->get_stats
|| !h
->ae_algo
->ops
->update_stats
) {
228 netdev_err(netdev
, "could not get any statistics\n");
232 h
->ae_algo
->ops
->update_stats(h
, &netdev
->stats
);
234 /* get per-queue stats */
235 p
= hns3_get_stats_tqps(h
, p
);
237 /* get MAC & other misc hardware stats */
238 h
->ae_algo
->ops
->get_stats(h
, p
);
241 static void hns3_get_drvinfo(struct net_device
*netdev
,
242 struct ethtool_drvinfo
*drvinfo
)
244 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
245 struct hnae3_handle
*h
= priv
->ae_handle
;
247 strncpy(drvinfo
->version
, hns3_driver_version
,
248 sizeof(drvinfo
->version
));
249 drvinfo
->version
[sizeof(drvinfo
->version
) - 1] = '\0';
251 strncpy(drvinfo
->driver
, h
->pdev
->driver
->name
,
252 sizeof(drvinfo
->driver
));
253 drvinfo
->driver
[sizeof(drvinfo
->driver
) - 1] = '\0';
255 strncpy(drvinfo
->bus_info
, pci_name(h
->pdev
),
256 sizeof(drvinfo
->bus_info
));
257 drvinfo
->bus_info
[ETHTOOL_BUSINFO_LEN
- 1] = '\0';
259 snprintf(drvinfo
->fw_version
, sizeof(drvinfo
->fw_version
), "0x%08x",
260 priv
->ae_handle
->ae_algo
->ops
->get_fw_version(h
));
263 static u32
hns3_get_link(struct net_device
*netdev
)
265 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
266 struct hnae3_handle
*h
;
270 if (h
->ae_algo
&& h
->ae_algo
->ops
&& h
->ae_algo
->ops
->get_status
)
271 return h
->ae_algo
->ops
->get_status(h
);
276 static void hns3_get_ringparam(struct net_device
*netdev
,
277 struct ethtool_ringparam
*param
)
279 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
280 int queue_num
= priv
->ae_handle
->kinfo
.num_tqps
;
282 param
->tx_max_pending
= HNS3_RING_MAX_PENDING
;
283 param
->rx_max_pending
= HNS3_RING_MAX_PENDING
;
285 param
->tx_pending
= priv
->ring_data
[0].ring
->desc_num
;
286 param
->rx_pending
= priv
->ring_data
[queue_num
].ring
->desc_num
;
289 static void hns3_get_pauseparam(struct net_device
*netdev
,
290 struct ethtool_pauseparam
*param
)
292 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
293 struct hnae3_handle
*h
= priv
->ae_handle
;
295 if (h
->ae_algo
&& h
->ae_algo
->ops
&& h
->ae_algo
->ops
->get_pauseparam
)
296 h
->ae_algo
->ops
->get_pauseparam(h
, ¶m
->autoneg
,
297 ¶m
->rx_pause
, ¶m
->tx_pause
);
300 static int hns3_get_link_ksettings(struct net_device
*netdev
,
301 struct ethtool_link_ksettings
*cmd
)
303 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
304 struct hnae3_handle
*h
= priv
->ae_handle
;
307 u8 media_type
= HNAE3_MEDIA_TYPE_UNKNOWN
;
313 if (!h
->ae_algo
|| !h
->ae_algo
->ops
)
316 /* 1.auto_neg & speed & duplex from cmd */
317 if (h
->ae_algo
->ops
->get_ksettings_an_result
) {
318 h
->ae_algo
->ops
->get_ksettings_an_result(h
, &auto_neg
,
320 cmd
->base
.autoneg
= auto_neg
;
321 cmd
->base
.speed
= speed
;
322 cmd
->base
.duplex
= duplex
;
324 link_stat
= hns3_get_link(netdev
);
326 cmd
->base
.speed
= (u32
)SPEED_UNKNOWN
;
327 cmd
->base
.duplex
= DUPLEX_UNKNOWN
;
331 /* 2.media_type get from bios parameter block */
332 if (h
->ae_algo
->ops
->get_media_type
) {
333 h
->ae_algo
->ops
->get_media_type(h
, &media_type
);
335 switch (media_type
) {
336 case HNAE3_MEDIA_TYPE_FIBER
:
337 cmd
->base
.port
= PORT_FIBRE
;
338 supported_caps
= HNS3_LM_FIBRE_BIT
|
339 HNS3_LM_AUTONEG_BIT
|
341 HNS3_LM_1000BASET_FULL_BIT
;
343 advertised_caps
= supported_caps
;
345 case HNAE3_MEDIA_TYPE_COPPER
:
346 cmd
->base
.port
= PORT_TP
;
347 supported_caps
= HNS3_LM_TP_BIT
|
348 HNS3_LM_AUTONEG_BIT
|
350 HNS3_LM_1000BASET_FULL_BIT
|
351 HNS3_LM_100BASET_FULL_BIT
|
352 HNS3_LM_100BASET_HALF_BIT
|
353 HNS3_LM_10BASET_FULL_BIT
|
354 HNS3_LM_10BASET_HALF_BIT
;
355 advertised_caps
= supported_caps
;
357 case HNAE3_MEDIA_TYPE_BACKPLANE
:
358 cmd
->base
.port
= PORT_NONE
;
359 supported_caps
= HNS3_LM_BACKPLANE_BIT
|
361 HNS3_LM_AUTONEG_BIT
|
362 HNS3_LM_1000BASET_FULL_BIT
|
363 HNS3_LM_100BASET_FULL_BIT
|
364 HNS3_LM_100BASET_HALF_BIT
|
365 HNS3_LM_10BASET_FULL_BIT
|
366 HNS3_LM_10BASET_HALF_BIT
;
368 advertised_caps
= supported_caps
;
370 case HNAE3_MEDIA_TYPE_UNKNOWN
:
372 cmd
->base
.port
= PORT_OTHER
;
378 /* now, map driver link modes to ethtool link modes */
379 hns3_driv_to_eth_caps(supported_caps
, cmd
, false);
380 hns3_driv_to_eth_caps(advertised_caps
, cmd
, true);
383 /* 3.mdix_ctrl&mdix get from phy reg */
384 if (h
->ae_algo
->ops
->get_mdix_mode
)
385 h
->ae_algo
->ops
->get_mdix_mode(h
, &cmd
->base
.eth_tp_mdix_ctrl
,
386 &cmd
->base
.eth_tp_mdix
);
388 cmd
->base
.mdio_support
= ETH_MDIO_SUPPORTS_C22
;
393 static u32
hns3_get_rss_key_size(struct net_device
*netdev
)
395 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
396 struct hnae3_handle
*h
= priv
->ae_handle
;
398 if (!h
->ae_algo
|| !h
->ae_algo
->ops
||
399 !h
->ae_algo
->ops
->get_rss_key_size
)
402 return h
->ae_algo
->ops
->get_rss_key_size(h
);
405 static u32
hns3_get_rss_indir_size(struct net_device
*netdev
)
407 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
408 struct hnae3_handle
*h
= priv
->ae_handle
;
410 if (!h
->ae_algo
|| !h
->ae_algo
->ops
||
411 !h
->ae_algo
->ops
->get_rss_indir_size
)
414 return h
->ae_algo
->ops
->get_rss_indir_size(h
);
417 static int hns3_get_rss(struct net_device
*netdev
, u32
*indir
, u8
*key
,
420 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
421 struct hnae3_handle
*h
= priv
->ae_handle
;
423 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->get_rss
)
426 return h
->ae_algo
->ops
->get_rss(h
, indir
, key
, hfunc
);
429 static int hns3_set_rss(struct net_device
*netdev
, const u32
*indir
,
430 const u8
*key
, const u8 hfunc
)
432 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
433 struct hnae3_handle
*h
= priv
->ae_handle
;
435 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->set_rss
)
438 /* currently we only support Toeplitz hash */
439 if ((hfunc
!= ETH_RSS_HASH_NO_CHANGE
) && (hfunc
!= ETH_RSS_HASH_TOP
)) {
441 "hash func not supported (only Toeplitz hash)\n");
446 "set rss failed for indir is empty\n");
450 return h
->ae_algo
->ops
->set_rss(h
, indir
, key
, hfunc
);
453 static int hns3_get_rxnfc(struct net_device
*netdev
,
454 struct ethtool_rxnfc
*cmd
,
457 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
458 struct hnae3_handle
*h
= priv
->ae_handle
;
460 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->get_tc_size
)
464 case ETHTOOL_GRXRINGS
:
465 cmd
->data
= h
->ae_algo
->ops
->get_tc_size(h
);
474 static const struct ethtool_ops hns3_ethtool_ops
= {
475 .get_drvinfo
= hns3_get_drvinfo
,
476 .get_link
= hns3_get_link
,
477 .get_ringparam
= hns3_get_ringparam
,
478 .get_pauseparam
= hns3_get_pauseparam
,
479 .get_strings
= hns3_get_strings
,
480 .get_ethtool_stats
= hns3_get_stats
,
481 .get_sset_count
= hns3_get_sset_count
,
482 .get_rxnfc
= hns3_get_rxnfc
,
483 .get_rxfh_key_size
= hns3_get_rss_key_size
,
484 .get_rxfh_indir_size
= hns3_get_rss_indir_size
,
485 .get_rxfh
= hns3_get_rss
,
486 .set_rxfh
= hns3_set_rss
,
487 .get_link_ksettings
= hns3_get_link_ksettings
,
490 void hns3_ethtool_set_ops(struct net_device
*netdev
)
492 netdev
->ethtool_ops
= &hns3_ethtool_ops
;