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 hnae3_handle
*h
= hns3_get_handle(netdev
);
106 const struct hnae3_ae_ops
*ops
= h
->ae_algo
->ops
;
108 if (!ops
->get_sset_count
)
113 return ((HNS3_TQP_STATS_COUNT
* h
->kinfo
.num_tqps
) +
114 ops
->get_sset_count(h
, stringset
));
117 return ops
->get_sset_count(h
, stringset
);
123 static void *hns3_update_strings(u8
*data
, const struct hns3_stats
*stats
,
124 u32 stat_count
, u32 num_tqps
)
126 #define MAX_PREFIX_SIZE (8 + 4)
131 for (i
= 0; i
< num_tqps
; i
++) {
132 for (j
= 0; j
< stat_count
; j
++) {
133 data
[ETH_GSTRING_LEN
- 1] = '\0';
135 /* first, prepend the prefix string */
136 n1
= snprintf(data
, MAX_PREFIX_SIZE
, "rcb_q%d_", i
);
137 n1
= min_t(uint
, n1
, MAX_PREFIX_SIZE
- 1);
138 size_left
= (ETH_GSTRING_LEN
- 1) - n1
;
140 /* now, concatenate the stats string to it */
141 strncat(data
, stats
[j
].stats_string
, size_left
);
142 data
+= ETH_GSTRING_LEN
;
149 static u8
*hns3_get_strings_tqps(struct hnae3_handle
*handle
, u8
*data
)
151 struct hnae3_knic_private_info
*kinfo
= &handle
->kinfo
;
153 /* get strings for Tx */
154 data
= hns3_update_strings(data
, hns3_txq_stats
, HNS3_TXQ_STATS_COUNT
,
157 /* get strings for Rx */
158 data
= hns3_update_strings(data
, hns3_rxq_stats
, HNS3_RXQ_STATS_COUNT
,
164 static void hns3_get_strings(struct net_device
*netdev
, u32 stringset
, u8
*data
)
166 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
167 const struct hnae3_ae_ops
*ops
= h
->ae_algo
->ops
;
168 char *buff
= (char *)data
;
170 if (!ops
->get_strings
)
175 buff
= hns3_get_strings_tqps(h
, buff
);
176 h
->ae_algo
->ops
->get_strings(h
, stringset
, (u8
*)buff
);
179 ops
->get_strings(h
, stringset
, data
);
184 static u64
*hns3_get_stats_tqps(struct hnae3_handle
*handle
, u64
*data
)
186 struct hns3_nic_priv
*nic_priv
= (struct hns3_nic_priv
*)handle
->priv
;
187 struct hnae3_knic_private_info
*kinfo
= &handle
->kinfo
;
188 struct hns3_enet_ring
*ring
;
192 /* get stats for Tx */
193 for (i
= 0; i
< kinfo
->num_tqps
; i
++) {
194 ring
= nic_priv
->ring_data
[i
].ring
;
195 for (i
= 0; i
< HNS3_TXQ_STATS_COUNT
; i
++) {
196 stat
= (u8
*)ring
+ hns3_txq_stats
[i
].stats_offset
;
197 *data
++ = *(u64
*)stat
;
201 /* get stats for Rx */
202 for (i
= 0; i
< kinfo
->num_tqps
; i
++) {
203 ring
= nic_priv
->ring_data
[i
+ kinfo
->num_tqps
].ring
;
204 for (i
= 0; i
< HNS3_RXQ_STATS_COUNT
; i
++) {
205 stat
= (u8
*)ring
+ hns3_rxq_stats
[i
].stats_offset
;
206 *data
++ = *(u64
*)stat
;
213 /* hns3_get_stats - get detail statistics.
214 * @netdev: net device
215 * @stats: statistics info.
216 * @data: statistics data.
218 static void hns3_get_stats(struct net_device
*netdev
,
219 struct ethtool_stats
*stats
, u64
*data
)
221 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
224 if (!h
->ae_algo
->ops
->get_stats
|| !h
->ae_algo
->ops
->update_stats
) {
225 netdev_err(netdev
, "could not get any statistics\n");
229 h
->ae_algo
->ops
->update_stats(h
, &netdev
->stats
);
231 /* get per-queue stats */
232 p
= hns3_get_stats_tqps(h
, p
);
234 /* get MAC & other misc hardware stats */
235 h
->ae_algo
->ops
->get_stats(h
, p
);
238 static void hns3_get_drvinfo(struct net_device
*netdev
,
239 struct ethtool_drvinfo
*drvinfo
)
241 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
242 struct hnae3_handle
*h
= priv
->ae_handle
;
244 strncpy(drvinfo
->version
, hns3_driver_version
,
245 sizeof(drvinfo
->version
));
246 drvinfo
->version
[sizeof(drvinfo
->version
) - 1] = '\0';
248 strncpy(drvinfo
->driver
, h
->pdev
->driver
->name
,
249 sizeof(drvinfo
->driver
));
250 drvinfo
->driver
[sizeof(drvinfo
->driver
) - 1] = '\0';
252 strncpy(drvinfo
->bus_info
, pci_name(h
->pdev
),
253 sizeof(drvinfo
->bus_info
));
254 drvinfo
->bus_info
[ETHTOOL_BUSINFO_LEN
- 1] = '\0';
256 snprintf(drvinfo
->fw_version
, sizeof(drvinfo
->fw_version
), "0x%08x",
257 priv
->ae_handle
->ae_algo
->ops
->get_fw_version(h
));
260 static u32
hns3_get_link(struct net_device
*netdev
)
262 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
264 if (h
->ae_algo
&& h
->ae_algo
->ops
&& h
->ae_algo
->ops
->get_status
)
265 return h
->ae_algo
->ops
->get_status(h
);
270 static void hns3_get_ringparam(struct net_device
*netdev
,
271 struct ethtool_ringparam
*param
)
273 struct hns3_nic_priv
*priv
= netdev_priv(netdev
);
274 struct hnae3_handle
*h
= priv
->ae_handle
;
275 int queue_num
= h
->kinfo
.num_tqps
;
277 param
->tx_max_pending
= HNS3_RING_MAX_PENDING
;
278 param
->rx_max_pending
= HNS3_RING_MAX_PENDING
;
280 param
->tx_pending
= priv
->ring_data
[0].ring
->desc_num
;
281 param
->rx_pending
= priv
->ring_data
[queue_num
].ring
->desc_num
;
284 static void hns3_get_pauseparam(struct net_device
*netdev
,
285 struct ethtool_pauseparam
*param
)
287 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
289 if (h
->ae_algo
&& h
->ae_algo
->ops
&& h
->ae_algo
->ops
->get_pauseparam
)
290 h
->ae_algo
->ops
->get_pauseparam(h
, ¶m
->autoneg
,
291 ¶m
->rx_pause
, ¶m
->tx_pause
);
294 static int hns3_get_link_ksettings(struct net_device
*netdev
,
295 struct ethtool_link_ksettings
*cmd
)
297 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
300 u8 media_type
= HNAE3_MEDIA_TYPE_UNKNOWN
;
306 if (!h
->ae_algo
|| !h
->ae_algo
->ops
)
309 /* 1.auto_neg & speed & duplex from cmd */
310 if (h
->ae_algo
->ops
->get_ksettings_an_result
) {
311 h
->ae_algo
->ops
->get_ksettings_an_result(h
, &auto_neg
,
313 cmd
->base
.autoneg
= auto_neg
;
314 cmd
->base
.speed
= speed
;
315 cmd
->base
.duplex
= duplex
;
317 link_stat
= hns3_get_link(netdev
);
319 cmd
->base
.speed
= (u32
)SPEED_UNKNOWN
;
320 cmd
->base
.duplex
= DUPLEX_UNKNOWN
;
324 /* 2.media_type get from bios parameter block */
325 if (h
->ae_algo
->ops
->get_media_type
) {
326 h
->ae_algo
->ops
->get_media_type(h
, &media_type
);
328 switch (media_type
) {
329 case HNAE3_MEDIA_TYPE_FIBER
:
330 cmd
->base
.port
= PORT_FIBRE
;
331 supported_caps
= HNS3_LM_FIBRE_BIT
|
332 HNS3_LM_AUTONEG_BIT
|
334 HNS3_LM_1000BASET_FULL_BIT
;
336 advertised_caps
= supported_caps
;
338 case HNAE3_MEDIA_TYPE_COPPER
:
339 cmd
->base
.port
= PORT_TP
;
340 supported_caps
= HNS3_LM_TP_BIT
|
341 HNS3_LM_AUTONEG_BIT
|
343 HNS3_LM_1000BASET_FULL_BIT
|
344 HNS3_LM_100BASET_FULL_BIT
|
345 HNS3_LM_100BASET_HALF_BIT
|
346 HNS3_LM_10BASET_FULL_BIT
|
347 HNS3_LM_10BASET_HALF_BIT
;
348 advertised_caps
= supported_caps
;
350 case HNAE3_MEDIA_TYPE_BACKPLANE
:
351 cmd
->base
.port
= PORT_NONE
;
352 supported_caps
= HNS3_LM_BACKPLANE_BIT
|
354 HNS3_LM_AUTONEG_BIT
|
355 HNS3_LM_1000BASET_FULL_BIT
|
356 HNS3_LM_100BASET_FULL_BIT
|
357 HNS3_LM_100BASET_HALF_BIT
|
358 HNS3_LM_10BASET_FULL_BIT
|
359 HNS3_LM_10BASET_HALF_BIT
;
361 advertised_caps
= supported_caps
;
363 case HNAE3_MEDIA_TYPE_UNKNOWN
:
365 cmd
->base
.port
= PORT_OTHER
;
371 /* now, map driver link modes to ethtool link modes */
372 hns3_driv_to_eth_caps(supported_caps
, cmd
, false);
373 hns3_driv_to_eth_caps(advertised_caps
, cmd
, true);
376 /* 3.mdix_ctrl&mdix get from phy reg */
377 if (h
->ae_algo
->ops
->get_mdix_mode
)
378 h
->ae_algo
->ops
->get_mdix_mode(h
, &cmd
->base
.eth_tp_mdix_ctrl
,
379 &cmd
->base
.eth_tp_mdix
);
381 cmd
->base
.mdio_support
= ETH_MDIO_SUPPORTS_C22
;
386 static u32
hns3_get_rss_key_size(struct net_device
*netdev
)
388 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
390 if (!h
->ae_algo
|| !h
->ae_algo
->ops
||
391 !h
->ae_algo
->ops
->get_rss_key_size
)
394 return h
->ae_algo
->ops
->get_rss_key_size(h
);
397 static u32
hns3_get_rss_indir_size(struct net_device
*netdev
)
399 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
401 if (!h
->ae_algo
|| !h
->ae_algo
->ops
||
402 !h
->ae_algo
->ops
->get_rss_indir_size
)
405 return h
->ae_algo
->ops
->get_rss_indir_size(h
);
408 static int hns3_get_rss(struct net_device
*netdev
, u32
*indir
, u8
*key
,
411 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
413 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->get_rss
)
416 return h
->ae_algo
->ops
->get_rss(h
, indir
, key
, hfunc
);
419 static int hns3_set_rss(struct net_device
*netdev
, const u32
*indir
,
420 const u8
*key
, const u8 hfunc
)
422 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
424 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->set_rss
)
427 /* currently we only support Toeplitz hash */
428 if ((hfunc
!= ETH_RSS_HASH_NO_CHANGE
) && (hfunc
!= ETH_RSS_HASH_TOP
)) {
430 "hash func not supported (only Toeplitz hash)\n");
435 "set rss failed for indir is empty\n");
439 return h
->ae_algo
->ops
->set_rss(h
, indir
, key
, hfunc
);
442 static int hns3_get_rxnfc(struct net_device
*netdev
,
443 struct ethtool_rxnfc
*cmd
,
446 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
448 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->get_tc_size
)
452 case ETHTOOL_GRXRINGS
:
453 cmd
->data
= h
->ae_algo
->ops
->get_tc_size(h
);
462 int hns3_change_all_ring_bd_num(struct hns3_nic_priv
*priv
, u32 new_desc_num
)
464 struct hnae3_handle
*h
= priv
->ae_handle
;
467 h
->kinfo
.num_desc
= new_desc_num
;
469 for (i
= 0; i
< h
->kinfo
.num_tqps
* 2; i
++)
470 priv
->ring_data
[i
].ring
->desc_num
= new_desc_num
;
472 return hns3_init_all_ring(priv
);
475 int hns3_set_ringparam(struct net_device
*ndev
, struct ethtool_ringparam
*param
)
477 struct hns3_nic_priv
*priv
= netdev_priv(ndev
);
478 struct hnae3_handle
*h
= priv
->ae_handle
;
479 bool if_running
= netif_running(ndev
);
480 u32 old_desc_num
, new_desc_num
;
483 if (param
->rx_mini_pending
|| param
->rx_jumbo_pending
)
486 if (param
->tx_pending
!= param
->rx_pending
) {
488 "Descriptors of tx and rx must be equal");
492 if (param
->tx_pending
> HNS3_RING_MAX_PENDING
||
493 param
->tx_pending
< HNS3_RING_MIN_PENDING
) {
495 "Descriptors requested (Tx/Rx: %d) out of range [%d-%d]\n",
496 param
->tx_pending
, HNS3_RING_MIN_PENDING
,
497 HNS3_RING_MAX_PENDING
);
501 new_desc_num
= param
->tx_pending
;
503 /* Hardware requires that its descriptors must be multiple of eight */
504 new_desc_num
= ALIGN(new_desc_num
, HNS3_RING_BD_MULTIPLE
);
505 old_desc_num
= h
->kinfo
.num_desc
;
506 if (old_desc_num
== new_desc_num
)
510 "Changing descriptor count from %d to %d.\n",
511 old_desc_num
, new_desc_num
);
516 ret
= hns3_uninit_all_ring(priv
);
520 ret
= hns3_change_all_ring_bd_num(priv
, new_desc_num
);
522 ret
= hns3_change_all_ring_bd_num(priv
, old_desc_num
);
525 "Revert to old bd num fail, ret=%d.\n", ret
);
531 ret
= dev_open(ndev
);
536 static int hns3_set_rxnfc(struct net_device
*netdev
, struct ethtool_rxnfc
*cmd
)
538 struct hnae3_handle
*h
= hns3_get_handle(netdev
);
540 if (!h
->ae_algo
|| !h
->ae_algo
->ops
|| !h
->ae_algo
->ops
->set_rss_tuple
)
545 return h
->ae_algo
->ops
->set_rss_tuple(h
, cmd
);
551 static const struct ethtool_ops hns3_ethtool_ops
= {
552 .get_drvinfo
= hns3_get_drvinfo
,
553 .get_link
= hns3_get_link
,
554 .get_ringparam
= hns3_get_ringparam
,
555 .set_ringparam
= hns3_set_ringparam
,
556 .get_pauseparam
= hns3_get_pauseparam
,
557 .get_strings
= hns3_get_strings
,
558 .get_ethtool_stats
= hns3_get_stats
,
559 .get_sset_count
= hns3_get_sset_count
,
560 .get_rxnfc
= hns3_get_rxnfc
,
561 .set_rxnfc
= hns3_set_rxnfc
,
562 .get_rxfh_key_size
= hns3_get_rss_key_size
,
563 .get_rxfh_indir_size
= hns3_get_rss_indir_size
,
564 .get_rxfh
= hns3_get_rss
,
565 .set_rxfh
= hns3_set_rss
,
566 .get_link_ksettings
= hns3_get_link_ksettings
,
569 void hns3_ethtool_set_ops(struct net_device
*netdev
)
571 netdev
->ethtool_ops
= &hns3_ethtool_ops
;