ac027a8dbe7a428cdfa02da958fac358490c80df
[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 <rte_kvargs.h>
6 #include <rte_bus_pci.h>
7 #include <ethdev_pci.h>
8 #include <rte_pci.h>
9
10 #include "hns3_common.h"
11 #include "hns3_logs.h"
12 #include "hns3_regs.h"
13 #include "hns3_rxtx.h"
14
15 static const char *
16 get_adapter_state_name(uint32_t state)
17 {
18         static const char * const state_name[] = {
19                 "UNINITIALIZED",
20                 "INITIALIZED",
21                 "CONFIGURING",
22                 "CONFIGURED",
23                 "STARTING",
24                 "STARTED",
25                 "STOPPING",
26                 "CLOSING",
27                 "CLOSED",
28                 "REMOVED",
29                 "NSTATES"
30         };
31
32         if (state < RTE_DIM(state_name))
33                 return state_name[state];
34         else
35                 return "unknown";
36 }
37
38 static const char *
39 get_io_func_hint_name(uint32_t hint)
40 {
41         switch (hint) {
42         case HNS3_IO_FUNC_HINT_NONE:
43                 return "none";
44         case HNS3_IO_FUNC_HINT_VEC:
45                 return "vec";
46         case HNS3_IO_FUNC_HINT_SVE:
47                 return "sve";
48         case HNS3_IO_FUNC_HINT_SIMPLE:
49                 return "simple";
50         case HNS3_IO_FUNC_HINT_COMMON:
51                 return "common";
52         default:
53                 return "unknown";
54         }
55 }
56
57 static void
58 get_dev_mac_info(FILE *file, struct hns3_adapter *hns)
59 {
60         struct hns3_hw *hw = &hns->hw;
61         struct hns3_pf *pf = &hns->pf;
62
63         fprintf(file, "  - MAC Info:\n");
64         fprintf(file,
65                 "\t  -- query_type=%u\n"
66                 "\t  -- supported_speed=0x%x\n"
67                 "\t  -- advertising=0x%x\n"
68                 "\t  -- lp_advertising=0x%x\n"
69                 "\t  -- support_autoneg=%s\n"
70                 "\t  -- support_fc_autoneg=%s\n",
71                 hw->mac.query_type,
72                 hw->mac.supported_speed,
73                 hw->mac.advertising,
74                 hw->mac.lp_advertising,
75                 hw->mac.support_autoneg != 0 ? "Yes" : "No",
76                 pf->support_fc_autoneg ? "Yes" : "No");
77 }
78
79 static void
80 get_dev_feature_capability(FILE *file, struct hns3_hw *hw)
81 {
82         const char * const caps_name[] = {
83                 "DCB",
84                 "COPPER",
85                 "FD QUEUE REGION",
86                 "PTP",
87                 "TX PUSH",
88                 "INDEP TXRX",
89                 "STASH",
90                 "SIMPLE BD",
91                 "RXD Advanced Layout",
92                 "OUTER UDP CKSUM",
93                 "RAS IMP",
94                 "TM",
95                 "VF VLAN FILTER MOD",
96         };
97         uint32_t i;
98
99         fprintf(file, "  - Dev Capability:\n");
100         for (i = 0; i < RTE_DIM(caps_name); i++)
101                 fprintf(file, "\t  -- support %s: %s\n", caps_name[i],
102                         hw->capability & BIT(i) ? "yes" : "no");
103 }
104
105 static void
106 get_device_basic_info(FILE *file, struct rte_eth_dev *dev)
107 {
108         struct hns3_adapter *hns = dev->data->dev_private;
109         struct hns3_hw *hw = &hns->hw;
110
111         fprintf(file,
112                 "  - Device Base Info:\n"
113                 "\t  -- name: %s\n"
114                 "\t  -- adapter_state=%s\n"
115                 "\t  -- nb_rx_queues=%u nb_tx_queues=%u\n"
116                 "\t  -- total_tqps_num=%u tqps_num=%u intr_tqps_num=%u\n"
117                 "\t  -- rss_size_max=%u alloc_rss_size=%u tx_qnum_per_tc=%u\n"
118                 "\t  -- min_tx_pkt_len=%u intr_mapping_mode=%u vlan_mode=%u\n"
119                 "\t  -- tso_mode=%u max_non_tso_bd_num=%u\n"
120                 "\t  -- max_tm_rate=%u Mbps\n"
121                 "\t  -- set link down: %s\n"
122                 "\t  -- rx_func_hint=%s tx_func_hint=%s\n"
123                 "\t  -- dev_flags: lsc=%d\n"
124                 "\t  -- intr_conf: lsc=%u rxq=%u\n",
125                 dev->data->name,
126                 get_adapter_state_name(hw->adapter_state),
127                 dev->data->nb_rx_queues, dev->data->nb_tx_queues,
128                 hw->total_tqps_num, hw->tqps_num, hw->intr_tqps_num,
129                 hw->rss_size_max, hw->alloc_rss_size, hw->tx_qnum_per_tc,
130                 hw->min_tx_pkt_len, hw->intr.mapping_mode, hw->vlan_mode,
131                 hw->tso_mode, hw->max_non_tso_bd_num,
132                 hw->max_tm_rate,
133                 hw->set_link_down ? "Yes" : "No",
134                 get_io_func_hint_name(hns->rx_func_hint),
135                 get_io_func_hint_name(hns->tx_func_hint),
136                 !!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC),
137                 dev->data->dev_conf.intr_conf.lsc,
138                 dev->data->dev_conf.intr_conf.rxq);
139 }
140
141 /*
142  * Note: caller must make sure queue_id < nb_queues
143  *       nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
144  *                           eth_dev->data->nb_tx_queues)
145  */
146 static struct hns3_rx_queue *
147 get_rx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
148 {
149         struct hns3_adapter *hns = dev->data->dev_private;
150         struct hns3_hw *hw = &hns->hw;
151         unsigned int offset;
152         void **rx_queues;
153
154         if (queue_id < dev->data->nb_rx_queues) {
155                 rx_queues = dev->data->rx_queues;
156                 offset = queue_id;
157         } else {
158                 /*
159                  * For kunpeng930, fake queue is not exist. But since the queues
160                  * are usually accessd in pairs, this branch may still exist.
161                  */
162                 if (hns3_dev_get_support(hw, INDEP_TXRX))
163                         return NULL;
164
165                 rx_queues = hw->fkq_data.rx_queues;
166                 offset = queue_id - dev->data->nb_rx_queues;
167         }
168
169         if (rx_queues != NULL && rx_queues[offset] != NULL)
170                 return rx_queues[offset];
171
172         hns3_err(hw, "Detect rx_queues is NULL!\n");
173         return NULL;
174 }
175
176 /*
177  * Note: caller must make sure queue_id < nb_queues
178  *       nb_queues = RTE_MAX(eth_dev->data->nb_rx_queues,
179  *                           eth_dev->data->nb_tx_queues)
180  */
181 static struct hns3_tx_queue *
182 get_tx_queue(struct rte_eth_dev *dev, unsigned int queue_id)
183 {
184         struct hns3_adapter *hns = dev->data->dev_private;
185         struct hns3_hw *hw = &hns->hw;
186         unsigned int offset;
187         void **tx_queues;
188
189         if (queue_id < dev->data->nb_tx_queues) {
190                 tx_queues = dev->data->tx_queues;
191                 offset = queue_id;
192         } else {
193                 /*
194                  * For kunpeng930, fake queue is not exist. But since the queues
195                  * are usually accessd in pairs, this branch may still exist.
196                  */
197                 if (hns3_dev_get_support(hw, INDEP_TXRX))
198                         return NULL;
199                 tx_queues = hw->fkq_data.tx_queues;
200                 offset = queue_id - dev->data->nb_tx_queues;
201         }
202
203         if (tx_queues != NULL && tx_queues[offset] != NULL)
204                 return tx_queues[offset];
205
206         hns3_err(hw, "Detect tx_queues is NULL!\n");
207         return NULL;
208 }
209
210 static void
211 get_rxtx_fake_queue_info(FILE *file, struct rte_eth_dev *dev)
212 {
213         struct hns3_adapter *hns = dev->data->dev_private;
214         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
215         struct hns3_rx_queue *rxq;
216         struct hns3_tx_queue *txq;
217         unsigned int queue_id;
218
219         if (dev->data->nb_rx_queues != dev->data->nb_tx_queues &&
220             !hns3_dev_get_support(hw, INDEP_TXRX)) {
221                 queue_id = RTE_MIN(dev->data->nb_rx_queues,
222                                    dev->data->nb_tx_queues);
223                 rxq = get_rx_queue(dev, queue_id);
224                 if (rxq == NULL)
225                         return;
226                 txq = get_tx_queue(dev, queue_id);
227                 if (txq == NULL)
228                         return;
229                 fprintf(file,
230                         "\t  -- first fake_queue rxtx info:\n"
231                         "\t       rx: port=%u nb_desc=%u free_thresh=%u\n"
232                         "\t       tx: port=%u nb_desc=%u\n",
233                         rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
234                         txq->port_id, txq->nb_tx_desc);
235         }
236 }
237
238 static void
239 get_queue_enable_state(struct hns3_hw *hw, uint32_t *queue_state,
240                         uint32_t nb_queues, bool is_rxq)
241 {
242 #define STATE_SIZE (sizeof(*queue_state) * CHAR_BIT)
243         uint32_t queue_en_reg;
244         uint32_t reg_offset;
245         uint32_t state;
246         uint32_t i;
247
248         queue_en_reg = is_rxq ? HNS3_RING_RX_EN_REG : HNS3_RING_TX_EN_REG;
249         for (i = 0; i < nb_queues; i++) {
250                 reg_offset = hns3_get_tqp_reg_offset(i);
251                 state = hns3_read_dev(hw, reg_offset + HNS3_RING_EN_REG);
252                 if (hns3_dev_get_support(hw, INDEP_TXRX))
253                         state = state && hns3_read_dev(hw, reg_offset +
254                                                        queue_en_reg);
255                 hns3_set_bit(queue_state[i / STATE_SIZE],
256                                 i % STATE_SIZE, state);
257         }
258 }
259
260 static void
261 print_queue_state_perline(FILE *file, const uint32_t *queue_state,
262                           uint32_t nb_queues, uint32_t line_num)
263 {
264 #define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
265         uint32_t qid = line_num * NUM_QUEUE_PER_LINE;
266         uint32_t j;
267
268         for (j = 0; j < NUM_QUEUE_PER_LINE; j++) {
269                 fprintf(file, "%1lx", hns3_get_bit(queue_state[line_num], j));
270
271                 if (qid % CHAR_BIT == CHAR_BIT - 1) {
272                         fprintf(file, "%s",
273                                 j == NUM_QUEUE_PER_LINE - 1 ? "\n" : ":");
274                 }
275                 qid++;
276                 if (qid >= nb_queues) {
277                         fprintf(file, "\n");
278                         break;
279                 }
280         }
281 }
282
283 static void
284 display_queue_enable_state(FILE *file, const uint32_t *queue_state,
285                            uint32_t nb_queues, bool is_rxq)
286 {
287 #define NUM_QUEUE_PER_LINE (sizeof(*queue_state) * CHAR_BIT)
288         uint32_t i;
289
290         if (nb_queues == 0) {
291                 fprintf(file, "\t       %s queue number is 0\n",
292                                 is_rxq ? "Rx" : "Tx");
293                 return;
294         }
295
296         fprintf(file, "\t       %s queue id | enable state bitMap\n",
297                         is_rxq ? "rx" : "tx");
298
299         for (i = 0; i < (nb_queues - 1) / NUM_QUEUE_PER_LINE + 1; i++) {
300                 uint32_t line_end = (i + 1) * NUM_QUEUE_PER_LINE - 1;
301                 uint32_t line_start = i * NUM_QUEUE_PER_LINE;
302                 fprintf(file, "\t       %04u - %04u | ", line_start,
303                         nb_queues - 1 > line_end ? line_end : nb_queues - 1);
304
305
306                 print_queue_state_perline(file, queue_state, nb_queues, i);
307         }
308 }
309
310 static void
311 get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev)
312 {
313 #define MAX_TQP_NUM 1280
314 #define QUEUE_BITMAP_SIZE (MAX_TQP_NUM / 32)
315         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
316         uint32_t rx_queue_state[QUEUE_BITMAP_SIZE] = {0};
317         uint32_t tx_queue_state[QUEUE_BITMAP_SIZE] = {0};
318         uint32_t nb_rx_queues;
319         uint32_t nb_tx_queues;
320
321         nb_rx_queues = dev->data->nb_rx_queues;
322         nb_tx_queues = dev->data->nb_tx_queues;
323
324         fprintf(file, "\t  -- enable state:\n");
325         get_queue_enable_state(hw, rx_queue_state, nb_rx_queues, true);
326         display_queue_enable_state(file, rx_queue_state, nb_rx_queues,
327                                          true);
328
329         get_queue_enable_state(hw, tx_queue_state, nb_tx_queues, false);
330         display_queue_enable_state(file, tx_queue_state, nb_tx_queues,
331                                          false);
332 }
333
334 static void
335 get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev)
336 {
337         struct hns3_rx_queue *rxq;
338         struct hns3_tx_queue *txq;
339         unsigned int queue_id = 0;
340
341         rxq = get_rx_queue(dev, queue_id);
342         if (rxq == NULL)
343                 return;
344         txq = get_tx_queue(dev, queue_id);
345         if (txq == NULL)
346                 return;
347         fprintf(file, "  - Rx/Tx Queue Info:\n");
348         fprintf(file,
349                 "\t  -- nb_rx_queues=%u nb_tx_queues=%u, "
350                 "first queue rxtx info:\n"
351                 "\t       rx: port=%u nb_desc=%u free_thresh=%u\n"
352                 "\t       tx: port=%u nb_desc=%u\n"
353                 "\t  -- tx push: %s\n",
354                 dev->data->nb_rx_queues,
355                 dev->data->nb_tx_queues,
356                 rxq->port_id, rxq->nb_rx_desc, rxq->rx_free_thresh,
357                 txq->port_id, txq->nb_tx_desc,
358                 txq->tx_push_enable ? "enabled" : "disabled");
359
360         get_rxtx_fake_queue_info(file, dev);
361         get_rxtx_queue_enable_state(file, dev);
362 }
363
364 int
365 hns3_eth_dev_priv_dump(struct rte_eth_dev *dev, FILE *file)
366 {
367         struct hns3_adapter *hns = dev->data->dev_private;
368         struct hns3_hw *hw = &hns->hw;
369
370         get_device_basic_info(file, dev);
371         get_dev_feature_capability(file, hw);
372
373         /* VF only supports dumping basic info and feaure capability */
374         if (hns->is_vf)
375                 return 0;
376
377         get_dev_mac_info(file, hns);
378         get_rxtx_queue_info(file, dev);
379
380         return 0;
381 }