059a4d86440805745120486b4eb4b0df82569c37
[dpdk.git] / drivers / net / hns3 / hns3_ethdev_dump.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2022 HiSilicon Limited
3  */
4
5 #include "hns3_common.h"
6 #include "hns3_logs.h"
7 #include "hns3_regs.h"
8 #include "hns3_rxtx.h"
9 #include "hns3_ethdev.h"
10
11 static const char *
12 get_adapter_state_name(enum hns3_adapter_state state)
13 {
14         const struct {
15                 enum hns3_adapter_state state;
16                 const char *name;
17         } adapter_state_name[] = {
18                 {HNS3_NIC_UNINITIALIZED, "UNINITIALIZED"},
19                 {HNS3_NIC_INITIALIZED, "INITIALIZED"},
20                 {HNS3_NIC_CONFIGURING, "CONFIGURING"},
21                 {HNS3_NIC_CONFIGURED, "CONFIGURED"},
22                 {HNS3_NIC_STARTING, "STARTING"},
23                 {HNS3_NIC_STARTED, "STARTED"},
24                 {HNS3_NIC_STOPPING, "STOPPING"},
25                 {HNS3_NIC_CLOSING, "CLOSING"},
26                 {HNS3_NIC_CLOSED, "CLOSED"},
27                 {HNS3_NIC_REMOVED, "REMOVED"},
28                 {HNS3_NIC_NSTATES, "NSTATES"},
29         };
30         uint32_t i;
31
32         for (i = 0; i < RTE_DIM(adapter_state_name); i++)
33                 if (state == adapter_state_name[i].state)
34                         return adapter_state_name[i].name;
35
36         return "Unknown";
37 }
38
39 static const char *
40 get_io_func_hint_name(uint32_t hint)
41 {
42         switch (hint) {
43         case HNS3_IO_FUNC_HINT_NONE:
44                 return "none";
45         case HNS3_IO_FUNC_HINT_VEC:
46                 return "vec";
47         case HNS3_IO_FUNC_HINT_SVE:
48                 return "sve";
49         case HNS3_IO_FUNC_HINT_SIMPLE:
50                 return "simple";
51         case HNS3_IO_FUNC_HINT_COMMON:
52                 return "common";
53         default:
54                 return "unknown";
55         }
56 }
57
58 static void
59 get_dev_mac_info(FILE *file, struct hns3_adapter *hns)
60 {
61         struct hns3_hw *hw = &hns->hw;
62         struct hns3_pf *pf = &hns->pf;
63
64         fprintf(file, "  - MAC Info:\n");
65         fprintf(file,
66                 "\t  -- query_type=%u\n"
67                 "\t  -- supported_speed=0x%x\n"
68                 "\t  -- advertising=0x%x\n"
69                 "\t  -- lp_advertising=0x%x\n"
70                 "\t  -- support_autoneg=%s\n"
71                 "\t  -- support_fc_autoneg=%s\n",
72                 hw->mac.query_type,
73                 hw->mac.supported_speed,
74                 hw->mac.advertising,
75                 hw->mac.lp_advertising,
76                 hw->mac.support_autoneg != 0 ? "Yes" : "No",
77                 pf->support_fc_autoneg ? "Yes" : "No");
78 }
79
80 static void
81 get_dev_feature_capability(FILE *file, struct hns3_hw *hw)
82 {
83         const struct {
84                 enum hns3_dev_cap cap;
85                 const char *name;
86         } caps_name[] = {
87                 {HNS3_DEV_SUPPORT_DCB_B, "DCB"},
88                 {HNS3_DEV_SUPPORT_COPPER_B, "COPPER"},
89                 {HNS3_DEV_SUPPORT_FD_QUEUE_REGION_B, "FD QUEUE REGION"},
90                 {HNS3_DEV_SUPPORT_PTP_B, "PTP"},
91                 {HNS3_DEV_SUPPORT_TX_PUSH_B, "TX PUSH"},
92                 {HNS3_DEV_SUPPORT_INDEP_TXRX_B, "INDEP TXRX"},
93                 {HNS3_DEV_SUPPORT_STASH_B, "STASH"},
94                 {HNS3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, "RXD Advanced Layout"},
95                 {HNS3_DEV_SUPPORT_OUTER_UDP_CKSUM_B, "OUTER UDP CKSUM"},
96                 {HNS3_DEV_SUPPORT_RAS_IMP_B, "RAS IMP"},
97                 {HNS3_DEV_SUPPORT_TM_B, "TM"},
98         };
99         uint32_t i;
100
101         fprintf(file, "  - Dev Capability:\n");
102         for (i = 0; i < RTE_DIM(caps_name); i++)
103                 fprintf(file, "\t  -- support %s: %s\n", caps_name[i].name,
104                         hns3_get_bit(hw->capability, caps_name[i].cap) ? "Yes" :
105                                                                          "No");
106 }
107
108 static const char *
109 get_fdir_tuple_name(uint32_t index)
110 {
111         static const char * const tuple_name[] = {
112                 "outer_dst_mac",
113                 "outer_src_mac",
114                 "outer_vlan_1st_tag",
115                 "outer_vlan_2nd_tag",
116                 "outer_eth_type",
117                 "outer_l2_rsv",
118                 "outer_ip_tos",
119                 "outer_ip_proto",
120                 "outer_src_ip",
121                 "outer_dst_ip",
122                 "outer_l3_rsv",
123                 "outer_src_port",
124                 "outer_dst_port",
125                 "outer_l4_rsv",
126                 "outer_tun_vni",
127                 "outer_tun_flow_id",
128                 "inner_dst_mac",
129                 "inner_src_mac",
130                 "inner_vlan_tag1",
131                 "inner_vlan_tag2",
132                 "inner_eth_type",
133                 "inner_l2_rsv",
134                 "inner_ip_tos",
135                 "inner_ip_proto",
136                 "inner_src_ip",
137                 "inner_dst_ip",
138                 "inner_l3_rsv",
139                 "inner_src_port",
140                 "inner_dst_port",
141                 "inner_sctp_tag",
142         };
143         if (index < RTE_DIM(tuple_name))
144                 return tuple_name[index];
145         else
146                 return "unknown";
147 }
148
149 static void
150 get_fdir_basic_info(FILE *file, struct hns3_pf *pf)
151 {
152 #define TMPBUF_SIZE             2048
153 #define PERLINE_TUPLE_NAMES     4
154         struct hns3_fd_cfg *fdcfg = &pf->fdir.fd_cfg;
155         char tmpbuf[TMPBUF_SIZE] = {0};
156         uint32_t i, count = 0;
157
158         fprintf(file, "  - Fdir Info:\n");
159         fprintf(file,
160                 "\t  -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n"
161                 "\t  -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n"
162                 "\t  -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n"
163                 "\t  -- active_tuples:\n",
164                 fdcfg->fd_mode, fdcfg->max_key_length,
165                 fdcfg->rule_num[HNS3_FD_STAGE_1],
166                 fdcfg->cnt_num[HNS3_FD_STAGE_1],
167                 fdcfg->key_cfg[HNS3_FD_STAGE_1].key_sel,
168                 fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active,
169                 fdcfg->key_cfg[HNS3_FD_STAGE_1].meta_data_active,
170                 fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en,
171                 fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en,
172                 fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en,
173                 fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en);
174
175         for (i = 0; i < MAX_TUPLE; i++) {
176                 if (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i)))
177                         continue;
178                 if (count % PERLINE_TUPLE_NAMES == 0)
179                         fprintf(file, "\t      ");
180                 fprintf(file, " %s", get_fdir_tuple_name(i));
181                 count++;
182                 if (count % PERLINE_TUPLE_NAMES == 0)
183                         fprintf(file, "\n");
184         }
185         if (count % PERLINE_TUPLE_NAMES)
186                 fprintf(file, "\n");
187
188         fprintf(file, "%s", tmpbuf);
189 }
190
191 static void
192 get_device_basic_info(FILE *file, struct rte_eth_dev *dev)
193 {
194         struct hns3_adapter *hns = dev->data->dev_private;
195         struct hns3_hw *hw = &hns->hw;
196
197         fprintf(file,
198                 "  - Device Base Info:\n"
199                 "\t  -- name: %s\n"
200                 "\t  -- adapter_state=%s\n"
201                 "\t  -- nb_rx_queues=%u nb_tx_queues=%u\n"
202                 "\t  -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n"
203                 "\t  -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n"
204                 "\t  -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\n"
205                 "\t  -- tso_mode=%u max_non_tso_bd_num=%u\n"
206                 "\t  -- max_tm_rate=%u Mbps\n"
207                 "\t  -- set link down: %s\n"
208                 "\t  -- rx_func_hint=%s tx_func_hint=%s\n"
209                 "\t  -- dev_flags: lsc=%d\n"
210                 "\t  -- intr_conf: lsc=%u rxq=%u\n",
211                 dev->data->name,
212                 get_adapter_state_name(hw->adapter_state),
213                 dev->data->nb_rx_queues, dev->data->nb_tx_queues,
214                 hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num,
215                 hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc,
216                 hw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode,
217                 hw->tso_mode, hw->max_non_tso_bd_num,
218                 hw->max_tm_rate,
219                 hw->set_link_down ? "Yes" : "No",
220                 get_io_func_hint_name(hns->rx_func_hint),
221                 get_io_func_hint_name(hns->tx_func_hint),
222                 !!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC),
223                 dev->data->dev_conf.intr_conf.lsc,
224                 dev->data->dev_conf.intr_conf.rxq);
225 }
226
227 /*
228  * Note: caller must make sure queue_id < nb_queues
229  *       nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
230  *                           eth_dev->data->nb_tx_queues)
231  */
232 static struct hns3_rx_queue *
233 get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
234 {
235         struct hns3_adapter *hns = dev->data->dev_private;
236         struct hns3_hw *hw = &hns->hw;
237         unsigned int offset;
238         void **rx_queues;
239
240         if (queue_id < dev->data->nb_rx_queues) {
241                 rx_queues = dev->data->rx_queues;
242                 offset = queue_id;
243         } else {
244                 /*
245                  * For kunpeng930, fake queue is not exist. But since the queues
246                  * are usually accessd in pairs, this branch may still exist.
247                  */
248                 if (hns3_dev_get_support(hw, INDEP_TXRX))
249                         return NULL;
250
251                 rx_queues = hw->fkq_data.rx_queues;
252                 offset = queue_id - dev->data->nb_rx_queues;
253         }
254
255         if (rx_queues != NULL && rx_queues[offset] != NULL)
256                 return rx_queues[offset];
257
258         hns3_err(hw, "Detect rx_queues is NULL!\n");
259         return NULL;
260 }
261
262 /*
263  * Note: caller must make sure queue_id < nb_queues
264  *       nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
265  *                           eth_dev->data->nb_tx_queues)
266  */
267 static struct hns3_tx_queue *
268 get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
269 {
270         struct hns3_adapter *hns = dev->data->dev_private;
271         struct hns3_hw *hw = &hns->hw;
272         unsigned int offset;
273         void **tx_queues;
274
275         if (queue_id < dev->data->nb_tx_queues) {
276                 tx_queues = dev->data->tx_queues;
277                 offset = queue_id;
278         } else {
279                 /*
280                  * For kunpeng930, fake queue is not exist. But since the queues
281                  * are usually accessd in pairs, this branch may still exist.
282                  */
283                 if (hns3_dev_get_support(hw, INDEP_TXRX))
284                         return NULL;
285                 tx_queues = hw->fkq_data.tx_queues;
286                 offset = queue_id - dev->data->nb_tx_queues;
287         }
288
289         if (tx_queues != NULL && tx_queues[offset] != NULL)
290                 return tx_queues[offset];
291
292         hns3_err(hw, "Detect tx_queues is NULL!\n");
293         return NULL;
294 }
295
296 static void
297 get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev)
298 {
299         struct hns3_adapter *hns = dev->data->dev_private;
300         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
301         struct hns3_rx_queue *rxq;
302         struct hns3_tx_queue *txq;
303         unsigned int queue_id;
304
305         if (dev->data->nb_rx_queues != dev->data->nb_tx_queues &&
306             !hns3_dev_get_support(hw, INDEP_TXRX)) {
307                 queue_id = RTE_MIN(dev->data->nb_rx_queues,
308                                    dev->data->nb_tx_queues);
309                 rxq = get_rx_queue(dev, queue_id);
310                 if (rxq == NULL)
311                         return;
312                 txq = get_tx_queue(dev, queue_id);
313                 if (txq == NULL)
314                         return;
315                 fprintf(file,
316                         "\t  -- first fake_queue rxtx info:\n"
317                         "\t       rx: port=%u nb_desc=%u free_thresh=%u\n"
318                         "\t       tx: port=%u nb_desc=%u\n",
319                         rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
320                         txq->port_id, txq->nb_tx_desc);
321         }
322 }
323
324 static void
325 get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state,
326                         uint32_t nb_queues, bool is_rxq)
327 {
328 #define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT)
329         uint32_t queue_en_reg;
330         uint32_t reg_offset;
331         uint32_t state;
332         uint32_t i;
333
334         queue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG;
335         for (i = 0; i < nb_queues; i++) {
336                 reg_offset = hns3_get_tqp_reg_offset(i);
337                 state = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG);
338                 if (hns3_dev_get_support(hw, INDEP_TXRX))
339                         state = state && hns3_read_dev(hw, reg_offset +
340                                                        queue_en_reg);
341                 hns3_set_bit(queue_state[i / STATE_SIZE],
342                                 i % STATE_SIZE, state);
343         }
344 }
345
346 static void
347 print_queue_state_perline(FILE *file, const uint32_t *queue_state,
348                           uint32_t nb_queues, uint32_t line_num)
349 {
350 #define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
351         uint32_t qid = line_num * NUM_QUEUE_PER_LINE;
352         uint32_t j;
353
354         for (j = 0; j < NUM_QUEUE_PER_LINE; j++) {
355                 fprintf(file, "%1lx", hns3_get_bit(queue_state[line_num], j));
356
357                 if (qid % CHAR_BIT == CHAR_BIT - 1) {
358                         fprintf(file, "%s",
359                                 j == NUM_QUEUE_PER_LINE - 1 ? "\n" : ":");
360                 }
361                 qid++;
362                 if (qid >= nb_queues) {
363                         fprintf(file, "\n");
364                         break;
365                 }
366         }
367 }
368
369 static void
370 display_queue_enable_state(FILE *file, const uint32_t *queue_state,
371                            uint32_t nb_queues, bool is_rxq)
372 {
373 #define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
374         uint32_t i;
375
376         if (nb_queues == 0) {
377                 fprintf(file, "\t       %s queue number is 0\n",
378                                 is_rxq ? "Rx" : "Tx");
379                 return;
380         }
381
382         fprintf(file, "\t       %s queue id | enable state bitMap\n",
383                         is_rxq ? "rx" : "tx");
384
385         for (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) {
386                 uint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1;
387                 uint32_t line_start = i * NUM_QUEUE_PER_LINE;
388                 fprintf(file, "\t       %04u - %04u | ", line_start,
389                         nb_queues - 1 > line_end ? line_end : nb_queues - 1);
390
391
392                 print_queue_state_perline(file, queue_state, nb_queues, i);
393         }
394 }
395
396 static void
397 get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev)
398 {
399 #define MAX_TQP_NUM 1280
400 #define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32)
401         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
402         uint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0};
403         uint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0};
404         uint32_t nb_rx_queues;
405         uint32_t nb_tx_queues;
406
407         nb_rx_queues = dev->data->nb_rx_queues;
408         nb_tx_queues = dev->data->nb_tx_queues;
409
410         fprintf(file, "\t  -- enable state:\n");
411         get_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true);
412         display_queue_enable_state(file, rx_queue_state, nb_rx_queues,
413                                          true);
414
415         get_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false);
416         display_queue_enable_state(file, tx_queue_state, nb_tx_queues,
417                                          false);
418 }
419
420 static void
421 get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev)
422 {
423         struct hns3_rx_queue *rxq;
424         struct hns3_tx_queue *txq;
425         unsigned int queue_id = 0;
426
427         rxq = get_rx_queue(dev, queue_id);
428         if (rxq == NULL)
429                 return;
430         txq = get_tx_queue(dev, queue_id);
431         if (txq == NULL)
432                 return;
433         fprintf(file, "  - Rx/Tx Queue Info:\n");
434         fprintf(file,
435                 "\t  -- nb_rx_queues=%u nb_tx_queues=%u, "
436                 "first queue rxtx info:\n"
437                 "\t       rx: port=%u nb_desc=%u free_thresh=%u\n"
438                 "\t       tx: port=%u nb_desc=%u\n"
439                 "\t  -- tx push: %s\n",
440                 dev->data->nb_rx_queues,
441                 dev->data->nb_tx_queues,
442                 rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
443                 txq->port_id, txq->nb_tx_desc,
444                 txq->tx_push_enable ? "enabled" : "disabled");
445
446         get_rxtx_fake_queue_info(file, dev);
447         get_rxtx_queue_enable_state(file, dev);
448 }
449
450 static int
451 get_vlan_filter_cfg(FILE *file, struct hns3_hw *hw)
452 {
453 #define HNS3_FILTER_TYPE_VF             0
454 #define HNS3_FILTER_TYPE_PORT           1
455 #define HNS3_FILTER_FE_NIC_INGRESS_B    BIT(0)
456 #define HNS3_FILTER_FE_NIC_EGRESS_B     BIT(1)
457         struct hns3_vlan_filter_ctrl_cmd *req;
458         struct hns3_cmd_desc desc;
459         uint8_t i;
460         int ret;
461
462         static const uint32_t vlan_filter_type[] = {
463                 HNS3_FILTER_TYPE_PORT,
464                 HNS3_FILTER_TYPE_VF
465         };
466
467         for (i = 0; i < RTE_DIM(vlan_filter_type); i++) {
468                 hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_FILTER_CTRL,
469                                                 true);
470                 req = (struct hns3_vlan_filter_ctrl_cmd *)desc.data;
471                 req->vlan_type = vlan_filter_type[i];
472                 req->vf_id = HNS3_PF_FUNC_ID;
473                 ret = hns3_cmd_send(hw, &desc, 1);
474                 if (ret != 0) {
475                         hns3_err(hw,
476                                 "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
477                                 ret, 1, rte_le_to_cpu_16(desc.opcode));
478                         return ret;
479                 }
480                 fprintf(file,
481                         "\t  -- %s VLAN filter configuration\n"
482                         "\t       nic_ingress           :%s\n"
483                         "\t       nic_egress            :%s\n",
484                         req->vlan_type == HNS3_FILTER_TYPE_PORT ?
485                         "Port" : "VF",
486                         req->vlan_fe & HNS3_FILTER_FE_NIC_INGRESS_B ?
487                         "Enable" : "Disable",
488                         req->vlan_fe & HNS3_FILTER_FE_NIC_EGRESS_B ?
489                         "Enable" : "Disable");
490         }
491
492         return 0;
493 }
494
495 static int
496 get_vlan_rx_offload_cfg(FILE *file, struct hns3_hw *hw)
497 {
498         struct hns3_vport_vtag_rx_cfg_cmd *req;
499         struct hns3_cmd_desc desc;
500         uint16_t vport_id;
501         uint8_t bitmap;
502         int ret;
503
504         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_RX_CFG, true);
505         req = (struct hns3_vport_vtag_rx_cfg_cmd *)desc.data;
506         vport_id = HNS3_PF_FUNC_ID;
507         req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
508         bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
509         req->vf_bitmap[req->vf_offset] = bitmap;
510
511         /*
512          * current version VF is not supported when PF is driven by DPDK driver,
513          * just need to configure rx parameters for PF vport.
514          */
515         ret = hns3_cmd_send(hw, &desc, 1);
516         if (ret != 0) {
517                 hns3_err(hw,
518                         "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
519                         ret, 1, rte_le_to_cpu_16(desc.opcode));
520                 return ret;
521         }
522
523         fprintf(file,
524                 "\t  -- RX VLAN configuration\n"
525                 "\t       vlan1_strip_en        :%s\n"
526                 "\t       vlan2_strip_en        :%s\n"
527                 "\t       vlan1_vlan_prionly    :%s\n"
528                 "\t       vlan2_vlan_prionly    :%s\n"
529                 "\t       vlan1_strip_discard   :%s\n"
530                 "\t       vlan2_strip_discard   :%s\n",
531                 hns3_get_bit(req->vport_vlan_cfg,
532                         HNS3_REM_TAG1_EN_B) ? "Enable" : "Disable",
533                 hns3_get_bit(req->vport_vlan_cfg,
534                         HNS3_REM_TAG2_EN_B) ? "Enable" : "Disable",
535                 hns3_get_bit(req->vport_vlan_cfg,
536                         HNS3_SHOW_TAG1_EN_B) ? "Enable" : "Disable",
537                 hns3_get_bit(req->vport_vlan_cfg,
538                         HNS3_SHOW_TAG2_EN_B) ? "Enable" : "Disable",
539                 hns3_get_bit(req->vport_vlan_cfg,
540                         HNS3_DISCARD_TAG1_EN_B) ? "Enable" : "Disable",
541                 hns3_get_bit(req->vport_vlan_cfg,
542                         HNS3_DISCARD_TAG2_EN_B) ? "Enable" : "Disable");
543
544         return 0;
545 }
546
547 static void
548 parse_tx_vlan_cfg(FILE *file, struct hns3_vport_vtag_tx_cfg_cmd *req)
549 {
550 #define VLAN_VID_MASK 0x0fff
551 #define VLAN_PRIO_SHIFT 13
552
553         fprintf(file,
554                 "\t  -- TX VLAN configuration\n"
555                 "\t       accept_tag1           :%s\n"
556                 "\t       accept_untag1         :%s\n"
557                 "\t       insert_tag1_en        :%s\n"
558                 "\t       default_vlan_tag1 = %d, qos = %d\n"
559                 "\t       accept_tag2           :%s\n"
560                 "\t       accept_untag2         :%s\n"
561                 "\t       insert_tag2_en        :%s\n"
562                 "\t       default_vlan_tag2 = %d, qos = %d\n"
563                 "\t       vlan_shift_mode       :%s\n",
564                 hns3_get_bit(req->vport_vlan_cfg,
565                         HNS3_ACCEPT_TAG1_B) ? "Enable" : "Disable",
566                 hns3_get_bit(req->vport_vlan_cfg,
567                         HNS3_ACCEPT_UNTAG1_B) ? "Enable" : "Disable",
568                 hns3_get_bit(req->vport_vlan_cfg,
569                         HNS3_PORT_INS_TAG1_EN_B) ? "Enable" : "Disable",
570                 req->def_vlan_tag1 & VLAN_VID_MASK,
571                 req->def_vlan_tag1 >> VLAN_PRIO_SHIFT,
572                 hns3_get_bit(req->vport_vlan_cfg,
573                         HNS3_ACCEPT_TAG2_B) ? "Enable" : "Disable",
574                 hns3_get_bit(req->vport_vlan_cfg,
575                         HNS3_ACCEPT_UNTAG2_B) ? "Enable" : "Disable",
576                 hns3_get_bit(req->vport_vlan_cfg,
577                         HNS3_PORT_INS_TAG2_EN_B) ? "Enable" : "Disable",
578                 req->def_vlan_tag2 & VLAN_VID_MASK,
579                 req->def_vlan_tag2 >> VLAN_PRIO_SHIFT,
580                 hns3_get_bit(req->vport_vlan_cfg,
581                         HNS3_TAG_SHIFT_MODE_EN_B) ? "Enable" :
582                         "Disable");
583 }
584
585 static int
586 get_vlan_tx_offload_cfg(FILE *file, struct hns3_hw *hw)
587 {
588         struct hns3_vport_vtag_tx_cfg_cmd *req;
589         struct hns3_cmd_desc desc;
590         uint16_t vport_id;
591         uint8_t bitmap;
592         int ret;
593
594         hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_VLAN_PORT_TX_CFG, true);
595         req = (struct hns3_vport_vtag_tx_cfg_cmd *)desc.data;
596         vport_id = HNS3_PF_FUNC_ID;
597         req->vf_offset = vport_id / HNS3_VF_NUM_PER_CMD;
598         bitmap = 1 << (vport_id % HNS3_VF_NUM_PER_BYTE);
599         req->vf_bitmap[req->vf_offset] = bitmap;
600         /*
601          * current version VF is not supported when PF is driven by DPDK driver,
602          * just need to configure tx parameters for PF vport.
603          */
604         ret = hns3_cmd_send(hw, &desc, 1);
605         if (ret != 0) {
606                 hns3_err(hw,
607                         "NIC IMP exec ret=%d desc_num=%d optcode=0x%x!",
608                         ret, 1, rte_le_to_cpu_16(desc.opcode));
609                 return ret;
610         }
611
612         parse_tx_vlan_cfg(file, req);
613
614         return 0;
615 }
616
617 static void
618 get_port_pvid_info(FILE *file, struct hns3_hw *hw)
619 {
620         fprintf(file, "\t  -- pvid status: %s\n",
621                 hw->port_base_vlan_cfg.state ? "on" : "off");
622 }
623
624 static void
625 get_vlan_config_info(FILE *file, struct hns3_hw *hw)
626 {
627         int ret;
628
629         fprintf(file, "  - VLAN Config Info:\n");
630         ret = get_vlan_filter_cfg(file, hw);
631         if (ret < 0)
632                 return;
633
634         ret = get_vlan_rx_offload_cfg(file, hw);
635         if (ret < 0)
636                 return;
637
638         ret = get_vlan_tx_offload_cfg(file, hw);
639         if (ret < 0)
640                 return;
641
642         get_port_pvid_info(file, hw);
643 }
644
645 static void
646 get_tm_conf_shaper_info(FILE *file, struct hns3_tm_conf *conf)
647 {
648         struct hns3_shaper_profile_list *shaper_profile_list =
649                 &conf->shaper_profile_list;
650         struct hns3_tm_shaper_profile *shaper_profile;
651
652         if (!conf->nb_shaper_profile)
653                 return;
654
655         fprintf(file, "  shaper_profile:\n");
656         TAILQ_FOREACH(shaper_profile, shaper_profile_list, node) {
657                 fprintf(file,
658                         "    id=%u reference_count=%u peak_rate=%" PRIu64 "Bps\n",
659                         shaper_profile->shaper_profile_id,
660                         shaper_profile->reference_count,
661                         shaper_profile->profile.peak.rate);
662         }
663 }
664
665 static void
666 get_tm_conf_port_node_info(FILE *file, struct hns3_tm_conf *conf)
667 {
668         if (!conf->root)
669                 return;
670
671         fprintf(file,
672                 "  port_node:\n"
673                 "    node_id=%u reference_count=%u shaper_profile_id=%d\n",
674                 conf->root->id, conf->root->reference_count,
675                 conf->root->shaper_profile ?
676                 (int)conf->root->shaper_profile->shaper_profile_id : -1);
677 }
678
679 static void
680 get_tm_conf_tc_node_info(FILE *file, struct hns3_tm_conf *conf)
681 {
682         struct hns3_tm_node_list *tc_list = &conf->tc_list;
683         struct hns3_tm_node *tc_node[HNS3_MAX_TC_NUM];
684         struct hns3_tm_node *tm_node;
685         uint32_t tidx;
686
687         if (!conf->nb_tc_node)
688                 return;
689
690         fprintf(file, "  tc_node:\n");
691         memset(tc_node, 0, sizeof(tc_node));
692         TAILQ_FOREACH(tm_node, tc_list, node) {
693                 tidx = hns3_tm_calc_node_tc_no(conf, tm_node->id);
694                 if (tidx < HNS3_MAX_TC_NUM)
695                         tc_node[tidx] = tm_node;
696         }
697
698         for (tidx = 0; tidx < HNS3_MAX_TC_NUM; tidx++) {
699                 tm_node = tc_node[tidx];
700                 if (tm_node == NULL)
701                         continue;
702                 fprintf(file,
703                         "    id=%u TC%u reference_count=%u parent_id=%d "
704                         "shaper_profile_id=%d\n",
705                         tm_node->id, hns3_tm_calc_node_tc_no(conf, tm_node->id),
706                         tm_node->reference_count,
707                         tm_node->parent ? (int)tm_node->parent->id : -1,
708                         tm_node->shaper_profile ?
709                         (int)tm_node->shaper_profile->shaper_profile_id : -1);
710         }
711 }
712
713 static void
714 get_tm_conf_queue_format_info(FILE *file, struct hns3_tm_node **queue_node,
715                               uint32_t *queue_node_tc,  uint32_t nb_tx_queues)
716 {
717 #define PERLINE_QUEUES  32
718 #define PERLINE_STRIDE  8
719 #define LINE_BUF_SIZE   1024
720         uint32_t i, j, line_num, start_queue, end_queue;
721         char tmpbuf[LINE_BUF_SIZE] = {0};
722
723         line_num = (nb_tx_queues + PERLINE_QUEUES - 1) / PERLINE_QUEUES;
724         for (i = 0; i < line_num; i++) {
725                 start_queue = i * PERLINE_QUEUES;
726                 end_queue = (i + 1) * PERLINE_QUEUES - 1;
727                 if (end_queue > nb_tx_queues - 1)
728                         end_queue = nb_tx_queues - 1;
729                 fprintf(file, "    %04u - %04u | ", start_queue, end_queue);
730                 for (j = start_queue; j < nb_tx_queues; j++) {
731                         if (j >= end_queue + 1)
732                                 break;
733                         if (j > start_queue && j % PERLINE_STRIDE == 0)
734                                 fprintf(file, ":");
735                         fprintf(file, "%u",
736                                 queue_node[j] ? queue_node_tc[j] :
737                                 HNS3_MAX_TC_NUM);
738                 }
739                 fprintf(file, "%s\n", tmpbuf);
740         }
741 }
742
743 static void
744 get_tm_conf_queue_node_info(FILE *file, struct hns3_tm_conf *conf,
745                             uint32_t nb_tx_queues)
746 {
747         struct hns3_tm_node_list *queue_list = &conf->queue_list;
748         uint32_t nb_queue_node = conf->nb_leaf_nodes_max + 1;
749         struct hns3_tm_node *queue_node[nb_queue_node];
750         uint32_t queue_node_tc[nb_queue_node];
751         struct hns3_tm_node *tm_node;
752
753         if (!conf->nb_queue_node)
754                 return;
755
756         fprintf(file,
757                 "  queue_node:\n"
758                 "    tx queue id | mapped tc (8 mean node not exist)\n");
759
760         memset(queue_node, 0, sizeof(queue_node));
761         memset(queue_node_tc, 0, sizeof(queue_node_tc));
762         nb_tx_queues = RTE_MIN(nb_tx_queues, nb_queue_node);
763         TAILQ_FOREACH(tm_node, queue_list, node) {
764                 if (tm_node->id >= nb_queue_node)
765                         continue;
766                 queue_node[tm_node->id] = tm_node;
767                 queue_node_tc[tm_node->id] = tm_node->parent ?
768                         hns3_tm_calc_node_tc_no(conf, tm_node->parent->id) : 0;
769                 nb_tx_queues = RTE_MAX(nb_tx_queues, tm_node->id + 1);
770         }
771
772         get_tm_conf_queue_format_info(file, queue_node, queue_node_tc,
773                                       nb_tx_queues);
774 }
775
776 static void
777 get_tm_conf_info(FILE *file, struct rte_eth_dev *dev)
778 {
779         struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
780         struct hns3_tm_conf *conf = &pf->tm_conf;
781
782         fprintf(file, "  - TM config info:\n");
783         fprintf(file,
784                 "\t  -- nb_leaf_nodes_max=%u nb_nodes_max=%u\n"
785                 "\t  -- nb_shaper_profile=%u nb_tc_node=%u nb_queue_node=%u\n"
786                 "\t  -- committed=%u\n",
787                 conf->nb_leaf_nodes_max, conf->nb_nodes_max,
788                 conf->nb_shaper_profile, conf->nb_tc_node, conf->nb_queue_node,
789                 conf->committed);
790
791         get_tm_conf_shaper_info(file, conf);
792         get_tm_conf_port_node_info(file, conf);
793         get_tm_conf_tc_node_info(file, conf);
794         get_tm_conf_queue_node_info(file, conf, dev->data->nb_tx_queues);
795 }
796
797 static void
798 hns3_fc_mode_to_rxtx_pause(enum hns3_fc_mode fc_mode, bool *rx_pause,
799                            bool *tx_pause)
800 {
801         switch (fc_mode) {
802         case HNS3_FC_NONE:
803                 *tx_pause = false;
804                 *rx_pause = false;
805                 break;
806         case HNS3_FC_RX_PAUSE:
807                 *rx_pause = true;
808                 *tx_pause = false;
809                 break;
810         case HNS3_FC_TX_PAUSE:
811                 *rx_pause = false;
812                 *tx_pause = true;
813                 break;
814         case HNS3_FC_FULL:
815                 *rx_pause = true;
816                 *tx_pause = true;
817                 break;
818         default:
819                 *rx_pause = false;
820                 *tx_pause = false;
821                 break;
822         }
823 }
824
825 static bool
826 is_link_fc_mode(struct hns3_adapter *hns)
827 {
828         struct hns3_hw *hw = &hns->hw;
829         struct hns3_pf *pf = &hns->pf;
830
831         if (hw->current_fc_status == HNS3_FC_STATUS_PFC)
832                 return false;
833
834         if (hw->num_tc > 1 && !pf->support_multi_tc_pause)
835                 return false;
836
837         return true;
838 }
839
840 static void
841 get_link_fc_info(FILE *file, struct rte_eth_dev *dev)
842 {
843         struct hns3_adapter *hns = dev->data->dev_private;
844         struct hns3_hw *hw = &hns->hw;
845         struct rte_eth_fc_conf fc_conf;
846         bool rx_pause1;
847         bool tx_pause1;
848         bool rx_pause2;
849         bool tx_pause2;
850         int ret;
851
852         if (!is_link_fc_mode(hns))
853                 return;
854
855         ret = hns3_flow_ctrl_get(dev, &fc_conf);
856         if (ret)  {
857                 fprintf(file, "get device flow control info fail!\n");
858                 return;
859         }
860
861         hns3_fc_mode_to_rxtx_pause(hw->requested_fc_mode,
862                                    &rx_pause1, &tx_pause1);
863         hns3_fc_mode_to_rxtx_pause((enum hns3_fc_mode)fc_conf.mode,
864                                    &rx_pause2, &tx_pause2);
865
866         fprintf(file,
867                 "\t  -- link_fc_info:\n"
868                 "\t       Requested fc:\n"
869                 "\t         Rx: %s\n"
870                 "\t         Tx: %s\n"
871                 "\t       Current fc:\n"
872                 "\t         Rx: %s\n"
873                 "\t         Tx: %s\n"
874                 "\t       Autonegotiate: %s\n"
875                 "\t       Pause time:   0x%x\n",
876                 rx_pause1 ? "On" : "Off", tx_pause1 ? "On" : "Off",
877                 rx_pause2 ? "On" : "Off", tx_pause2 ? "On" : "Off",
878                 fc_conf.autoneg == RTE_ETH_LINK_AUTONEG ? "On" : "Off",
879                 fc_conf.pause_time);
880 }
881
882 static void
883 get_flow_ctrl_info(FILE *file, struct rte_eth_dev *dev)
884 {
885         struct hns3_adapter *hns = dev->data->dev_private;
886         struct hns3_hw *hw = &hns->hw;
887
888         fprintf(file, "  - Flow Ctrl Info:\n");
889         fprintf(file,
890                 "\t  -- fc_common_info:\n"
891                 "\t       current_fc_status=%u\n"
892                 "\t       requested_fc_mode=%u\n",
893                 hw->current_fc_status,
894                 hw->requested_fc_mode);
895
896         get_link_fc_info(file, dev);
897 }
898
899 int
900 hns3_eth_dev_priv_dump(struct rte_eth_dev *dev, FILE *file)
901 {
902         struct hns3_adapter *hns = dev->data->dev_private;
903         struct hns3_hw *hw = &hns->hw;
904
905         get_device_basic_info(file, dev);
906         get_dev_feature_capability(file, hw);
907
908         /* VF only supports dumping basic info and feaure capability */
909         if (hns->is_vf)
910                 return 0;
911
912         get_dev_mac_info(file, hns);
913         get_rxtx_queue_info(file, dev);
914         get_vlan_config_info(file, hw);
915         get_fdir_basic_info(file, &hns->pf);
916         get_tm_conf_info(file, dev);
917         get_flow_ctrl_info(file, dev);
918
919         return 0;
920 }