DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH] ethdev: add dump regs for telemetry
@ 2023-12-14  1:56 Jie Hai
  2023-12-14 12:49 ` Ferruh Yigit
                   ` (10 more replies)
  0 siblings, 11 replies; 134+ messages in thread
From: Jie Hai @ 2023-12-14  1:56 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: lihuisong, fengchengwen, liudongdong3, haijie1

The ethdev library now registers a telemetry command for
dump regs.

An example usage is shown below:
--> /ethdev/regs,test
{
  "/ethdev/regs": {
    "regs_offset": 0,
    "regs_length": 3192,
    "regs_width": 4,
    "device_version": "0x1080f00",
    "regs_file": "port_0_regs_test"
  }
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 93 +++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index b01028ce9b60..33ec4739aa9b 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -5,6 +5,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_telemetry.h>
 
@@ -1395,6 +1396,96 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static int
+eth_dev_get_port_regs(uint16_t port_id, struct rte_dev_reg_info *reg_info,
+		      const char *file_name)
+{
+	uint64_t buf_size;
+	size_t nr_written;
+	void *data;
+	FILE *fp;
+	int ret;
+
+	ret = rte_eth_dev_get_reg_info(port_id, reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Error getting device reg info: %d\n", ret);
+		return ret;
+	}
+
+	buf_size = reg_info->length * reg_info->width;
+	data = rte_zmalloc(NULL, buf_size, 0);
+	if (!data) {
+		RTE_ETHDEV_LOG(ERR,
+			"Error allocating %zu bytes buffer\n", buf_size);
+		return -ENOMEM;
+	}
+
+	reg_info->data = data;
+	ret = rte_eth_dev_get_reg_info(port_id, reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Error getting regs from device: %d\n", ret);
+		goto out;
+	}
+
+	fp = fopen(file_name, "wb");
+	if (fp == NULL) {
+		printf("Error during opening '%s' for writing: %s\n",
+			file_name, strerror(errno));
+		ret = -EINVAL;
+	} else {
+		nr_written = fwrite(reg_info->data, 1, buf_size, fp);
+		if (nr_written != buf_size)
+			printf("Error during writing %s: %s\n",
+				file_name, strerror(errno));
+		fclose(fp);
+	}
+
+out:
+	rte_free(data);
+	reg_info->data = NULL;
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	struct rte_dev_reg_info reg_info = {0};
+	char file_name[RTE_TEL_MAX_STRING_LEN];
+	const char *suffix;
+	uint16_t port_id;
+	char *end_param;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	suffix = strtok_r(end_param, ",", &end_param);
+	if (!suffix || strlen(suffix) == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Please pass suffix parameters ethdev telemetry command\n");
+		return -EINVAL;
+	}
+	snprintf(file_name, RTE_TEL_MAX_STRING_LEN, "port_%u_regs_%s",
+		 port_id, suffix);
+	ret = eth_dev_get_port_regs(port_id, &reg_info, file_name);
+	if (ret != 0)
+		return ret;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "regs_offset", reg_info.offset);
+	rte_tel_data_add_dict_uint(d, "regs_length", reg_info.length);
+	rte_tel_data_add_dict_uint(d, "regs_width", reg_info.width);
+	rte_tel_data_add_dict_uint_hex(d, "device_version", reg_info.version, 0);
+	rte_tel_data_add_dict_string(d, "regs_file", file_name);
+
+	return 0;
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1527,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns regs for a port. Parameters: int port_id, char *suffix");
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
@ 2023-12-14 12:49 ` Ferruh Yigit
  2024-01-09  2:19   ` Jie Hai
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 134+ messages in thread
From: Ferruh Yigit @ 2023-12-14 12:49 UTC (permalink / raw)
  To: Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko, Bruce Richardson
  Cc: lihuisong, fengchengwen, liudongdong3

On 12/14/2023 1:56 AM, Jie Hai wrote:
> The ethdev library now registers a telemetry command for
> dump regs.
> 
> An example usage is shown below:
> --> /ethdev/regs,test
> {
>   "/ethdev/regs": {
>     "regs_offset": 0,
>     "regs_length": 3192,
>     "regs_width": 4,
>     "device_version": "0x1080f00",
>     "regs_file": "port_0_regs_test"
>   }
> }
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  lib/ethdev/rte_ethdev_telemetry.c | 93 +++++++++++++++++++++++++++++++
>  1 file changed, 93 insertions(+)
> 
> diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
> index b01028ce9b60..33ec4739aa9b 100644
> --- a/lib/ethdev/rte_ethdev_telemetry.c
> +++ b/lib/ethdev/rte_ethdev_telemetry.c
> @@ -5,6 +5,7 @@
>  #include <ctype.h>
>  #include <stdlib.h>
>  
> +#include <rte_malloc.h>
>  #include <rte_kvargs.h>
>  #include <rte_telemetry.h>
>  
> @@ -1395,6 +1396,96 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
>  	return ret;
>  }
>  
> +static int
> +eth_dev_get_port_regs(uint16_t port_id, struct rte_dev_reg_info *reg_info,
> +		      const char *file_name)
> +{
> +	uint64_t buf_size;
> +	size_t nr_written;
> +	void *data;
> +	FILE *fp;
> +	int ret;
> +
> +	ret = rte_eth_dev_get_reg_info(port_id, reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Error getting device reg info: %d\n", ret);
> +		return ret;
> +	}
> +
> +	buf_size = reg_info->length * reg_info->width;
> +	data = rte_zmalloc(NULL, buf_size, 0);
> +	if (!data) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Error allocating %zu bytes buffer\n", buf_size);
> +		return -ENOMEM;
> +	}
> +
> +	reg_info->data = data;
> +	ret = rte_eth_dev_get_reg_info(port_id, reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Error getting regs from device: %d\n", ret);
> +		goto out;
> +	}
> +
> +	fp = fopen(file_name, "wb");
> +	if (fp == NULL) {
> +		printf("Error during opening '%s' for writing: %s\n",
> +			file_name, strerror(errno));
> +		ret = -EINVAL;
> +	} else {
> +		nr_written = fwrite(reg_info->data, 1, buf_size, fp);
>

Above code writes register data to a file.

I am not sure about this kind of usage of telemetry command, that it
cause data to be written to a file.

My understanding is, telemetry usage is based on what telemetry client
receives.
What do you think just keep the 'reg_info' fields excluding data to the
file?


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2023-12-14 12:49 ` Ferruh Yigit
@ 2024-01-09  2:19   ` Jie Hai
  2024-01-09  2:41     ` Jie Hai
  2024-01-09 18:06     ` Ferruh Yigit
  0 siblings, 2 replies; 134+ messages in thread
From: Jie Hai @ 2024-01-09  2:19 UTC (permalink / raw)
  To: Ferruh Yigit, dev, Thomas Monjalon, Andrew Rybchenko, Bruce Richardson
  Cc: lihuisong, fengchengwen, liudongdong3

On 2023/12/14 20:49, Ferruh Yigit wrote:
> On 12/14/2023 1:56 AM, Jie Hai wrote:
>> The ethdev library now registers a telemetry command for
>> dump regs.
>>
>> An example usage is shown below:
>> --> /ethdev/regs,test
>> {
>>    "/ethdev/regs": {
>>      "regs_offset": 0,
>>      "regs_length": 3192,
>>      "regs_width": 4,
>>      "device_version": "0x1080f00",
>>      "regs_file": "port_0_regs_test"
>>    }
>> }

> 
> Above code writes register data to a file.
> 
> I am not sure about this kind of usage of telemetry command, that it
> cause data to be written to a file.
> 
> My understanding is, telemetry usage is based on what telemetry client
> receives.
> What do you think just keep the 'reg_info' fields excluding data to the
> file?
> 
> .Hi, Ferruh

I tried to write all register information to telemetry data,
but gave up because some drivers had too many registers (eg.ixgbe)
to carry. Therefore, the writing data to file approach is selected.

When we query a register, the register content is the key.
The information such as the width and length is only auxiliary
information. If the register data cannot be obtained, the auxiliary 
information is optional. So I don't think register data should be removed.

In my opinion, writing a file is a more appropriate way to do it.
I wonder if there's a better way.

Best regards,
Thanks

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-09  2:19   ` Jie Hai
@ 2024-01-09  2:41     ` Jie Hai
  2024-01-09 18:06     ` Ferruh Yigit
  1 sibling, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-01-09  2:41 UTC (permalink / raw)
  To: Ferruh Yigit, dev, Thomas Monjalon, Andrew Rybchenko, Bruce Richardson
  Cc: lihuisong, fengchengwen, liudongdong3

On 2024/1/9 10:19, Jie Hai wrote:
> On 2023/12/14 20:49, Ferruh Yigit wrote:
>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>> The ethdev library now registers a telemetry command for
>>> dump regs.
>>>
>>> An example usage is shown below:
>>> --> /ethdev/regs,test
>>> {
>>>    "/ethdev/regs": {
>>>      "regs_offset": 0,
>>>      "regs_length": 3192,
>>>      "regs_width": 4,
>>>      "device_version": "0x1080f00",
>>>      "regs_file": "port_0_regs_test"
>>>    }
>>> }
> 
>>
>> Above code writes register data to a file.
>>
>> I am not sure about this kind of usage of telemetry command, that it
>> cause data to be written to a file.
>>
>> My understanding is, telemetry usage is based on what telemetry client
>> receives.
>> What do you think just keep the 'reg_info' fields excluding data to the
>> file?
>>
>> .Hi, Ferruh
> 
> I tried to write all register information to telemetry data,
> but gave up because some drivers had too many registers (eg.ixgbe)
Sorry, correct it. It is i40e who has the most registers.
> to carry. Therefore, the writing data to file approach is selected.
> 
> When we query a register, the register content is the key.
> The information such as the width and length is only auxiliary
> information. If the register data cannot be obtained, the auxiliary 
> information is optional. So I don't think register data should be removed.
> 
> In my opinion, writing a file is a more appropriate way to do it.
> I wonder if there's a better way.
> 
> Best regards,
> Thanks

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-09  2:19   ` Jie Hai
  2024-01-09  2:41     ` Jie Hai
@ 2024-01-09 18:06     ` Ferruh Yigit
  2024-01-10  1:38       ` fengchengwen
  1 sibling, 1 reply; 134+ messages in thread
From: Ferruh Yigit @ 2024-01-09 18:06 UTC (permalink / raw)
  To: Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko, Bruce Richardson
  Cc: lihuisong, fengchengwen, liudongdong3

On 1/9/2024 2:19 AM, Jie Hai wrote:
> On 2023/12/14 20:49, Ferruh Yigit wrote:
>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>> The ethdev library now registers a telemetry command for
>>> dump regs.
>>>
>>> An example usage is shown below:
>>> --> /ethdev/regs,test
>>> {
>>>    "/ethdev/regs": {
>>>      "regs_offset": 0,
>>>      "regs_length": 3192,
>>>      "regs_width": 4,
>>>      "device_version": "0x1080f00",
>>>      "regs_file": "port_0_regs_test"
>>>    }
>>> }
> 
>>
>> Above code writes register data to a file.
>>
>> I am not sure about this kind of usage of telemetry command, that it
>> cause data to be written to a file.
>>
>> My understanding is, telemetry usage is based on what telemetry client
>> receives.
>> What do you think just keep the 'reg_info' fields excluding data to the
>> file?
>>
>> .Hi, Ferruh
> 
> I tried to write all register information to telemetry data,
> but gave up because some drivers had too many registers (eg.ixgbe)
> to carry. Therefore, the writing data to file approach is selected.
> 
> When we query a register, the register content is the key.
> The information such as the width and length is only auxiliary
> information. If the register data cannot be obtained, the auxiliary
> information is optional. So I don't think register data should be removed.
> 
> In my opinion, writing a file is a more appropriate way to do it.
> I wonder if there's a better way.
> 
> 

Is there a usecase to get register information from telemetry interface?


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-09 18:06     ` Ferruh Yigit
@ 2024-01-10  1:38       ` fengchengwen
  2024-01-10 12:15         ` Ferruh Yigit
  0 siblings, 1 reply; 134+ messages in thread
From: fengchengwen @ 2024-01-10  1:38 UTC (permalink / raw)
  To: Ferruh Yigit, Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko,
	Bruce Richardson
  Cc: lihuisong, liudongdong3

Hi Ferruh,

On 2024/1/10 2:06, Ferruh Yigit wrote:
> On 1/9/2024 2:19 AM, Jie Hai wrote:
>> On 2023/12/14 20:49, Ferruh Yigit wrote:
>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>>> The ethdev library now registers a telemetry command for
>>>> dump regs.
>>>>
>>>> An example usage is shown below:
>>>> --> /ethdev/regs,test
>>>> {
>>>>    "/ethdev/regs": {
>>>>      "regs_offset": 0,
>>>>      "regs_length": 3192,
>>>>      "regs_width": 4,
>>>>      "device_version": "0x1080f00",
>>>>      "regs_file": "port_0_regs_test"
>>>>    }
>>>> }
>>
>>>
>>> Above code writes register data to a file.
>>>
>>> I am not sure about this kind of usage of telemetry command, that it
>>> cause data to be written to a file.
>>>
>>> My understanding is, telemetry usage is based on what telemetry client
>>> receives.
>>> What do you think just keep the 'reg_info' fields excluding data to the
>>> file?
>>>
>>> .Hi, Ferruh
>>
>> I tried to write all register information to telemetry data,
>> but gave up because some drivers had too many registers (eg.ixgbe)
>> to carry. Therefore, the writing data to file approach is selected.
>>
>> When we query a register, the register content is the key.
>> The information such as the width and length is only auxiliary
>> information. If the register data cannot be obtained, the auxiliary
>> information is optional. So I don't think register data should be removed.
>>
>> In my opinion, writing a file is a more appropriate way to do it.
>> I wonder if there's a better way.
>>
>>
> 
> Is there a usecase to get register information from telemetry interface?

Among the available tools:
1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
              and also cost more resource, like hugepage, cores.

From our users, they prefer use the second 'telemetry', so I think we should move
more status-query-points to telemetry.

As for this question, I think it's okay to get register info from telemetry.



Another question, we have some internal registers, which:
1. Is not suitable expose by xstats, because they may includes configuration
2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).

So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
"xxxx" : 0x1234
"yyyy" : 0x100

Will the community accept this kind of telemetry points which limit one driver ?

Thanks.

> 
> .
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-10  1:38       ` fengchengwen
@ 2024-01-10 12:15         ` Ferruh Yigit
  2024-01-10 14:09           ` Thomas Monjalon
  2024-01-11  1:55           ` fengchengwen
  0 siblings, 2 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-01-10 12:15 UTC (permalink / raw)
  To: fengchengwen, Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko,
	Bruce Richardson
  Cc: lihuisong, liudongdong3

On 1/10/2024 1:38 AM, fengchengwen wrote:
> Hi Ferruh,
> 
> On 2024/1/10 2:06, Ferruh Yigit wrote:
>> On 1/9/2024 2:19 AM, Jie Hai wrote:
>>> On 2023/12/14 20:49, Ferruh Yigit wrote:
>>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>>>> The ethdev library now registers a telemetry command for
>>>>> dump regs.
>>>>>
>>>>> An example usage is shown below:
>>>>> --> /ethdev/regs,test
>>>>> {
>>>>>    "/ethdev/regs": {
>>>>>      "regs_offset": 0,
>>>>>      "regs_length": 3192,
>>>>>      "regs_width": 4,
>>>>>      "device_version": "0x1080f00",
>>>>>      "regs_file": "port_0_regs_test"
>>>>>    }
>>>>> }
>>>
>>>>
>>>> Above code writes register data to a file.
>>>>
>>>> I am not sure about this kind of usage of telemetry command, that it
>>>> cause data to be written to a file.
>>>>
>>>> My understanding is, telemetry usage is based on what telemetry client
>>>> receives.
>>>> What do you think just keep the 'reg_info' fields excluding data to the
>>>> file?
>>>>
>>>> .Hi, Ferruh
>>>
>>> I tried to write all register information to telemetry data,
>>> but gave up because some drivers had too many registers (eg.ixgbe)
>>> to carry. Therefore, the writing data to file approach is selected.
>>>
>>> When we query a register, the register content is the key.
>>> The information such as the width and length is only auxiliary
>>> information. If the register data cannot be obtained, the auxiliary
>>> information is optional. So I don't think register data should be removed.
>>>
>>> In my opinion, writing a file is a more appropriate way to do it.
>>> I wonder if there's a better way.
>>>
>>>
>>
>> Is there a usecase to get register information from telemetry interface?
> 
> Among the available tools:
> 1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
> 2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
>               and also cost more resource, like hugepage, cores.
> 
> From our users, they prefer use the second 'telemetry', so I think we should move
> more status-query-points to telemetry.
> 
> As for this question, I think it's okay to get register info from telemetry.
> 
> 
>
> Another question, we have some internal registers, which:
> 1. Is not suitable expose by xstats, because they may includes configuration
> 2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).
> 
> So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
> "xxxx" : 0x1234
> "yyyy" : 0x100
> 
> Will the community accept this kind of telemetry points which limit one driver ?
> 

Hi Chengwen,

I see there is a usecase/requirement.

With this patch, even using file, only register values are dumped and
isn't it hard to find value of specific register?

("xxxx" : 0x1234) approach looks better, but instead of making this
telemetry support for specific driver, what about making it in two steps.

First add new dev_ops, (or update existing one), to get registers with
"name: value" format, (in a way to allow empty name), or even perhaps
"name: offset, value" format.
And in second stage add telemetry support around it.
(Name being optional lets us wrap exiting 'get_reg' dev_ops with new one)

When adding dev_ops, it may get an additional 'filter' parameter, to get
only subset of regs, like "mac*" to get regs name staring with "mac",
this may help for the cases there are too many registers you mentioned.

Anyway, we can discuss more about its design, but what do you think
about first having a dev_ops for this?


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-10 12:15         ` Ferruh Yigit
@ 2024-01-10 14:09           ` Thomas Monjalon
  2024-01-10 15:48             ` Ferruh Yigit
  2024-01-11  1:55           ` fengchengwen
  1 sibling, 1 reply; 134+ messages in thread
From: Thomas Monjalon @ 2024-01-10 14:09 UTC (permalink / raw)
  To: fengchengwen, Jie Hai, dev, Andrew Rybchenko, Bruce Richardson,
	Ferruh Yigit
  Cc: lihuisong, liudongdong3

10/01/2024 13:15, Ferruh Yigit:
> On 1/10/2024 1:38 AM, fengchengwen wrote:
> > Hi Ferruh,
> > 
> > On 2024/1/10 2:06, Ferruh Yigit wrote:
> >> On 1/9/2024 2:19 AM, Jie Hai wrote:
> >>> On 2023/12/14 20:49, Ferruh Yigit wrote:
> >>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
> >>>>> The ethdev library now registers a telemetry command for
> >>>>> dump regs.
> >>>>>
> >>>>> An example usage is shown below:
> >>>>> --> /ethdev/regs,test
> >>>>> {
> >>>>>    "/ethdev/regs": {
> >>>>>      "regs_offset": 0,
> >>>>>      "regs_length": 3192,
> >>>>>      "regs_width": 4,
> >>>>>      "device_version": "0x1080f00",
> >>>>>      "regs_file": "port_0_regs_test"
> >>>>>    }
> >>>>> }
> >>>
> >>>>
> >>>> Above code writes register data to a file.
> >>>>
> >>>> I am not sure about this kind of usage of telemetry command, that it
> >>>> cause data to be written to a file.
> >>>>
> >>>> My understanding is, telemetry usage is based on what telemetry client
> >>>> receives.
> >>>> What do you think just keep the 'reg_info' fields excluding data to the
> >>>> file?
> >>>>
> >>>> .Hi, Ferruh
> >>>
> >>> I tried to write all register information to telemetry data,
> >>> but gave up because some drivers had too many registers (eg.ixgbe)
> >>> to carry. Therefore, the writing data to file approach is selected.
> >>>
> >>> When we query a register, the register content is the key.
> >>> The information such as the width and length is only auxiliary
> >>> information. If the register data cannot be obtained, the auxiliary
> >>> information is optional. So I don't think register data should be removed.
> >>>
> >>> In my opinion, writing a file is a more appropriate way to do it.
> >>> I wonder if there's a better way.
> >>>
> >>>
> >>
> >> Is there a usecase to get register information from telemetry interface?
> > 
> > Among the available tools:
> > 1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
> > 2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
> >               and also cost more resource, like hugepage, cores.
> > 
> > From our users, they prefer use the second 'telemetry', so I think we should move
> > more status-query-points to telemetry.
> > 
> > As for this question, I think it's okay to get register info from telemetry.
> > 
> > 
> >
> > Another question, we have some internal registers, which:
> > 1. Is not suitable expose by xstats, because they may includes configuration
> > 2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).
> > 
> > So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
> > "xxxx" : 0x1234
> > "yyyy" : 0x100
> > 
> > Will the community accept this kind of telemetry points which limit one driver ?
> > 
> 
> Hi Chengwen,
> 
> I see there is a usecase/requirement.
> 
> With this patch, even using file, only register values are dumped and
> isn't it hard to find value of specific register?
> 
> ("xxxx" : 0x1234) approach looks better, but instead of making this
> telemetry support for specific driver, what about making it in two steps.
> 
> First add new dev_ops, (or update existing one), to get registers with
> "name: value" format, (in a way to allow empty name), or even perhaps
> "name: offset, value" format.

I'm OK to add an API for dumping registers, and guess what?
We already have it: rte_eth_dev_get_reg_info().
We may extend it to query a subset of registers.

> And in second stage add telemetry support around it.
> (Name being optional lets us wrap exiting 'get_reg' dev_ops with new one)

I am against overloading telemetry for debug purpose.

> When adding dev_ops, it may get an additional 'filter' parameter, to get
> only subset of regs, like "mac*" to get regs name staring with "mac",
> this may help for the cases there are too many registers you mentioned.
> 
> Anyway, we can discuss more about its design, but what do you think
> about first having a dev_ops for this?




^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-10 14:09           ` Thomas Monjalon
@ 2024-01-10 15:48             ` Ferruh Yigit
  0 siblings, 0 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-01-10 15:48 UTC (permalink / raw)
  To: Thomas Monjalon, fengchengwen, Jie Hai, dev, Andrew Rybchenko,
	Bruce Richardson
  Cc: lihuisong, liudongdong3

On 1/10/2024 2:09 PM, Thomas Monjalon wrote:
> 10/01/2024 13:15, Ferruh Yigit:
>> On 1/10/2024 1:38 AM, fengchengwen wrote:
>>> Hi Ferruh,
>>>
>>> On 2024/1/10 2:06, Ferruh Yigit wrote:
>>>> On 1/9/2024 2:19 AM, Jie Hai wrote:
>>>>> On 2023/12/14 20:49, Ferruh Yigit wrote:
>>>>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>>>>>> The ethdev library now registers a telemetry command for
>>>>>>> dump regs.
>>>>>>>
>>>>>>> An example usage is shown below:
>>>>>>> --> /ethdev/regs,test
>>>>>>> {
>>>>>>>    "/ethdev/regs": {
>>>>>>>      "regs_offset": 0,
>>>>>>>      "regs_length": 3192,
>>>>>>>      "regs_width": 4,
>>>>>>>      "device_version": "0x1080f00",
>>>>>>>      "regs_file": "port_0_regs_test"
>>>>>>>    }
>>>>>>> }
>>>>>
>>>>>>
>>>>>> Above code writes register data to a file.
>>>>>>
>>>>>> I am not sure about this kind of usage of telemetry command, that it
>>>>>> cause data to be written to a file.
>>>>>>
>>>>>> My understanding is, telemetry usage is based on what telemetry client
>>>>>> receives.
>>>>>> What do you think just keep the 'reg_info' fields excluding data to the
>>>>>> file?
>>>>>>
>>>>>> .Hi, Ferruh
>>>>>
>>>>> I tried to write all register information to telemetry data,
>>>>> but gave up because some drivers had too many registers (eg.ixgbe)
>>>>> to carry. Therefore, the writing data to file approach is selected.
>>>>>
>>>>> When we query a register, the register content is the key.
>>>>> The information such as the width and length is only auxiliary
>>>>> information. If the register data cannot be obtained, the auxiliary
>>>>> information is optional. So I don't think register data should be removed.
>>>>>
>>>>> In my opinion, writing a file is a more appropriate way to do it.
>>>>> I wonder if there's a better way.
>>>>>
>>>>>
>>>>
>>>> Is there a usecase to get register information from telemetry interface?
>>>
>>> Among the available tools:
>>> 1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
>>> 2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
>>>               and also cost more resource, like hugepage, cores.
>>>
>>> From our users, they prefer use the second 'telemetry', so I think we should move
>>> more status-query-points to telemetry.
>>>
>>> As for this question, I think it's okay to get register info from telemetry.
>>>
>>>
>>>
>>> Another question, we have some internal registers, which:
>>> 1. Is not suitable expose by xstats, because they may includes configuration
>>> 2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).
>>>
>>> So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
>>> "xxxx" : 0x1234
>>> "yyyy" : 0x100
>>>
>>> Will the community accept this kind of telemetry points which limit one driver ?
>>>
>>
>> Hi Chengwen,
>>
>> I see there is a usecase/requirement.
>>
>> With this patch, even using file, only register values are dumped and
>> isn't it hard to find value of specific register?
>>
>> ("xxxx" : 0x1234) approach looks better, but instead of making this
>> telemetry support for specific driver, what about making it in two steps.
>>
>> First add new dev_ops, (or update existing one), to get registers with
>> "name: value" format, (in a way to allow empty name), or even perhaps
>> "name: offset, value" format.
> 
> I'm OK to add an API for dumping registers, and guess what?
> We already have it: rte_eth_dev_get_reg_info().
> We may extend it to query a subset of registers.
> 

This patch already using 'rte_eth_dev_get_reg_info()', but issue is how
it is used, it gets filename from telemetry and dumps registers to that
file.

>> And in second stage add telemetry support around it.
>> (Name being optional lets us wrap exiting 'get_reg' dev_ops with new one)
> 
> I am against overloading telemetry for debug purpose.
> 

Reading some registers can be debugging or monitoring, I believe it is
in the gray area.

>> When adding dev_ops, it may get an additional 'filter' parameter, to get
>> only subset of regs, like "mac*" to get regs name staring with "mac",
>> this may help for the cases there are too many registers you mentioned.
>>
>> Anyway, we can discuss more about its design, but what do you think
>> about first having a dev_ops for this?
> 
> 
> 


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-10 12:15         ` Ferruh Yigit
  2024-01-10 14:09           ` Thomas Monjalon
@ 2024-01-11  1:55           ` fengchengwen
  2024-01-11 11:11             ` Ferruh Yigit
  1 sibling, 1 reply; 134+ messages in thread
From: fengchengwen @ 2024-01-11  1:55 UTC (permalink / raw)
  To: Ferruh Yigit, Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko,
	Bruce Richardson
  Cc: lihuisong, liudongdong3

Hi Ferruh,

On 2024/1/10 20:15, Ferruh Yigit wrote:
> On 1/10/2024 1:38 AM, fengchengwen wrote:
>> Hi Ferruh,
>>
>> On 2024/1/10 2:06, Ferruh Yigit wrote:
>>> On 1/9/2024 2:19 AM, Jie Hai wrote:
>>>> On 2023/12/14 20:49, Ferruh Yigit wrote:
>>>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>>>>> The ethdev library now registers a telemetry command for
>>>>>> dump regs.
>>>>>>
>>>>>> An example usage is shown below:
>>>>>> --> /ethdev/regs,test
>>>>>> {
>>>>>>    "/ethdev/regs": {
>>>>>>      "regs_offset": 0,
>>>>>>      "regs_length": 3192,
>>>>>>      "regs_width": 4,
>>>>>>      "device_version": "0x1080f00",
>>>>>>      "regs_file": "port_0_regs_test"
>>>>>>    }
>>>>>> }
>>>>
>>>>>
>>>>> Above code writes register data to a file.
>>>>>
>>>>> I am not sure about this kind of usage of telemetry command, that it
>>>>> cause data to be written to a file.
>>>>>
>>>>> My understanding is, telemetry usage is based on what telemetry client
>>>>> receives.
>>>>> What do you think just keep the 'reg_info' fields excluding data to the
>>>>> file?
>>>>>
>>>>> .Hi, Ferruh
>>>>
>>>> I tried to write all register information to telemetry data,
>>>> but gave up because some drivers had too many registers (eg.ixgbe)
>>>> to carry. Therefore, the writing data to file approach is selected.
>>>>
>>>> When we query a register, the register content is the key.
>>>> The information such as the width and length is only auxiliary
>>>> information. If the register data cannot be obtained, the auxiliary
>>>> information is optional. So I don't think register data should be removed.
>>>>
>>>> In my opinion, writing a file is a more appropriate way to do it.
>>>> I wonder if there's a better way.
>>>>
>>>>
>>>
>>> Is there a usecase to get register information from telemetry interface?
>>
>> Among the available tools:
>> 1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
>> 2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
>>               and also cost more resource, like hugepage, cores.
>>
>> From our users, they prefer use the second 'telemetry', so I think we should move
>> more status-query-points to telemetry.
>>
>> As for this question, I think it's okay to get register info from telemetry.
>>
>>
>>
>> Another question, we have some internal registers, which:
>> 1. Is not suitable expose by xstats, because they may includes configuration
>> 2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).
>>
>> So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
>> "xxxx" : 0x1234
>> "yyyy" : 0x100
>>
>> Will the community accept this kind of telemetry points which limit one driver ?
>>
> 
> Hi Chengwen,
> 
> I see there is a usecase/requirement.
> 
> With this patch, even using file, only register values are dumped and
> isn't it hard to find value of specific register?
> 
> ("xxxx" : 0x1234) approach looks better, but instead of making this
> telemetry support for specific driver, what about making it in two steps.
> 
> First add new dev_ops, (or update existing one), to get registers with
> "name: value" format, (in a way to allow empty name), or even perhaps
> "name: offset, value" format.
> And in second stage add telemetry support around it.
> (Name being optional lets us wrap exiting 'get_reg' dev_ops with new one)
> 
> When adding dev_ops, it may get an additional 'filter' parameter, to get
> only subset of regs, like "mac*" to get regs name staring with "mac",
> this may help for the cases there are too many registers you mentioned.
> 
> Anyway, we can discuss more about its design, but what do you think
> about first having a dev_ops for this?

I prefer extend struct rte_dev_reg_info, like this:

struct rte_eth_reg_name {
	char name[RTE_ETH_REG_NAME_SIZE];
};

struct rte_dev_reg_info {
	void *data; /**< Buffer for return registers */
	uint32_t offset; /**< Start register table location for access */
	uint32_t length; /**< Number of registers to fetch */
	uint32_t width; /**< Size of device register */
	uint32_t version; /**< Device version */
/* Note: below two fields are new added. */
	char *filter; /**< Filter for target subset of registers. This field could affects register selection for data/length/name.  */
	struct rte_eth_reg_name *names; /**< Registers name saver. */
};

For driver which don't identify the new filter and names fields:
  1. .get_reg return the all registers value.
  2. and driver will not touch the name fields.
  3. rte_eth_dev_get_reg_info() could detect name fileds not filled, and then it fill with default names, e.g. offset-1/offset-2/...

For driver which identify the new filter and names fields:
  1. rte_eth_dev_get_reg_info() will return filtered register's value and also their names.

So that those which invoke rte_eth_dev_get_reg_info() could extra prepare names, and it call the same API will get data and name.


Add one new .get_reg_name ops and corresponding API like: rte_eth_dev_get_reg_name() could also feasible.
But I think the rte_eth_dev_get_reg_info()'s name is too broad, the info could includes value and also it's name.
So I prefer not add one new ops.


Another question? what are the supported values of filters ?
I prefer report by dev_info ops, something like a string array end with NULL.
Use could query from rte_eth_dev_info_get API.

Thanks.

> 
> .
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-11  1:55           ` fengchengwen
@ 2024-01-11 11:11             ` Ferruh Yigit
  2024-01-11 12:43               ` fengchengwen
  0 siblings, 1 reply; 134+ messages in thread
From: Ferruh Yigit @ 2024-01-11 11:11 UTC (permalink / raw)
  To: fengchengwen, Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko,
	Bruce Richardson
  Cc: lihuisong, liudongdong3

On 1/11/2024 1:55 AM, fengchengwen wrote:
> Hi Ferruh,
> 
> On 2024/1/10 20:15, Ferruh Yigit wrote:
>> On 1/10/2024 1:38 AM, fengchengwen wrote:
>>> Hi Ferruh,
>>>
>>> On 2024/1/10 2:06, Ferruh Yigit wrote:
>>>> On 1/9/2024 2:19 AM, Jie Hai wrote:
>>>>> On 2023/12/14 20:49, Ferruh Yigit wrote:
>>>>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>>>>>> The ethdev library now registers a telemetry command for
>>>>>>> dump regs.
>>>>>>>
>>>>>>> An example usage is shown below:
>>>>>>> --> /ethdev/regs,test
>>>>>>> {
>>>>>>>    "/ethdev/regs": {
>>>>>>>      "regs_offset": 0,
>>>>>>>      "regs_length": 3192,
>>>>>>>      "regs_width": 4,
>>>>>>>      "device_version": "0x1080f00",
>>>>>>>      "regs_file": "port_0_regs_test"
>>>>>>>    }
>>>>>>> }
>>>>>
>>>>>>
>>>>>> Above code writes register data to a file.
>>>>>>
>>>>>> I am not sure about this kind of usage of telemetry command, that it
>>>>>> cause data to be written to a file.
>>>>>>
>>>>>> My understanding is, telemetry usage is based on what telemetry client
>>>>>> receives.
>>>>>> What do you think just keep the 'reg_info' fields excluding data to the
>>>>>> file?
>>>>>>
>>>>>> .Hi, Ferruh
>>>>>
>>>>> I tried to write all register information to telemetry data,
>>>>> but gave up because some drivers had too many registers (eg.ixgbe)
>>>>> to carry. Therefore, the writing data to file approach is selected.
>>>>>
>>>>> When we query a register, the register content is the key.
>>>>> The information such as the width and length is only auxiliary
>>>>> information. If the register data cannot be obtained, the auxiliary
>>>>> information is optional. So I don't think register data should be removed.
>>>>>
>>>>> In my opinion, writing a file is a more appropriate way to do it.
>>>>> I wonder if there's a better way.
>>>>>
>>>>>
>>>>
>>>> Is there a usecase to get register information from telemetry interface?
>>>
>>> Among the available tools:
>>> 1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
>>> 2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
>>>               and also cost more resource, like hugepage, cores.
>>>
>>> From our users, they prefer use the second 'telemetry', so I think we should move
>>> more status-query-points to telemetry.
>>>
>>> As for this question, I think it's okay to get register info from telemetry.
>>>
>>>
>>>
>>> Another question, we have some internal registers, which:
>>> 1. Is not suitable expose by xstats, because they may includes configuration
>>> 2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).
>>>
>>> So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
>>> "xxxx" : 0x1234
>>> "yyyy" : 0x100
>>>
>>> Will the community accept this kind of telemetry points which limit one driver ?
>>>
>>
>> Hi Chengwen,
>>
>> I see there is a usecase/requirement.
>>
>> With this patch, even using file, only register values are dumped and
>> isn't it hard to find value of specific register?
>>
>> ("xxxx" : 0x1234) approach looks better, but instead of making this
>> telemetry support for specific driver, what about making it in two steps.
>>
>> First add new dev_ops, (or update existing one), to get registers with
>> "name: value" format, (in a way to allow empty name), or even perhaps
>> "name: offset, value" format.
>> And in second stage add telemetry support around it.
>> (Name being optional lets us wrap exiting 'get_reg' dev_ops with new one)
>>
>> When adding dev_ops, it may get an additional 'filter' parameter, to get
>> only subset of regs, like "mac*" to get regs name staring with "mac",
>> this may help for the cases there are too many registers you mentioned.
>>
>> Anyway, we can discuss more about its design, but what do you think
>> about first having a dev_ops for this?
> 
> I prefer extend struct rte_dev_reg_info, like this:
> 
> struct rte_eth_reg_name {
> 	char name[RTE_ETH_REG_NAME_SIZE];
> };
> 
> struct rte_dev_reg_info {
> 	void *data; /**< Buffer for return registers */
> 	uint32_t offset; /**< Start register table location for access */
> 	uint32_t length; /**< Number of registers to fetch */
> 	uint32_t width; /**< Size of device register */
> 	uint32_t version; /**< Device version */
> /* Note: below two fields are new added. */
> 	char *filter; /**< Filter for target subset of registers. This field could affects register selection for data/length/name.  */
> 	struct rte_eth_reg_name *names; /**< Registers name saver. */
> };
> 

ack

> For driver which don't identify the new filter and names fields:
>   1. .get_reg return the all registers value.
>

ack


>   2. and driver will not touch the name fields.
>   3. rte_eth_dev_get_reg_info() could detect name fileds not filled, and then it fill with default names, e.g. offset-1/offset-2/...
> 

Is there a benefit to provide default names? API can clear the 'names'
buffer, and driver may or may not fill it. If names not filled, API
behaves like existing one, it will just provide register values.


> For driver which identify the new filter and names fields:
>   1. rte_eth_dev_get_reg_info() will return filtered register's value and also their names.
> 

ack

> So that those which invoke rte_eth_dev_get_reg_info() could extra prepare names, and it call the same API will get data and name.
> 
> 
> Add one new .get_reg_name ops and corresponding API like: rte_eth_dev_get_reg_name() could also feasible.
> But I think the rte_eth_dev_get_reg_info()'s name is too broad, the info could includes value and also it's name.
> So I prefer not add one new ops.
> 

ack

> 
> Another question? what are the supported values of filters ?
> I prefer report by dev_info ops, something like a string array end with NULL.
> Use could query from rte_eth_dev_info_get API.
> 

I don't think there is a need to populate predefined filter list, it can
be free text with simple '*' and '.' wildcard support and ',' to support
list of text.

User may get full list first, later can filter the ones they are interested.
Like: "*mac*,*rss*" can match all register names that has 'mac' and
'rss' in it.


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH] ethdev: add dump regs for telemetry
  2024-01-11 11:11             ` Ferruh Yigit
@ 2024-01-11 12:43               ` fengchengwen
  0 siblings, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-01-11 12:43 UTC (permalink / raw)
  To: Ferruh Yigit, Jie Hai, dev, Thomas Monjalon, Andrew Rybchenko,
	Bruce Richardson
  Cc: lihuisong, liudongdong3

Hi Ferruh,

On 2024/1/11 19:11, Ferruh Yigit wrote:
> On 1/11/2024 1:55 AM, fengchengwen wrote:
>> Hi Ferruh,
>>
>> On 2024/1/10 20:15, Ferruh Yigit wrote:
>>> On 1/10/2024 1:38 AM, fengchengwen wrote:
>>>> Hi Ferruh,
>>>>
>>>> On 2024/1/10 2:06, Ferruh Yigit wrote:
>>>>> On 1/9/2024 2:19 AM, Jie Hai wrote:
>>>>>> On 2023/12/14 20:49, Ferruh Yigit wrote:
>>>>>>> On 12/14/2023 1:56 AM, Jie Hai wrote:
>>>>>>>> The ethdev library now registers a telemetry command for
>>>>>>>> dump regs.
>>>>>>>>
>>>>>>>> An example usage is shown below:
>>>>>>>> --> /ethdev/regs,test
>>>>>>>> {
>>>>>>>>    "/ethdev/regs": {
>>>>>>>>      "regs_offset": 0,
>>>>>>>>      "regs_length": 3192,
>>>>>>>>      "regs_width": 4,
>>>>>>>>      "device_version": "0x1080f00",
>>>>>>>>      "regs_file": "port_0_regs_test"
>>>>>>>>    }
>>>>>>>> }
>>>>>>
>>>>>>>
>>>>>>> Above code writes register data to a file.
>>>>>>>
>>>>>>> I am not sure about this kind of usage of telemetry command, that it
>>>>>>> cause data to be written to a file.
>>>>>>>
>>>>>>> My understanding is, telemetry usage is based on what telemetry client
>>>>>>> receives.
>>>>>>> What do you think just keep the 'reg_info' fields excluding data to the
>>>>>>> file?
>>>>>>>
>>>>>>> .Hi, Ferruh
>>>>>>
>>>>>> I tried to write all register information to telemetry data,
>>>>>> but gave up because some drivers had too many registers (eg.ixgbe)
>>>>>> to carry. Therefore, the writing data to file approach is selected.
>>>>>>
>>>>>> When we query a register, the register content is the key.
>>>>>> The information such as the width and length is only auxiliary
>>>>>> information. If the register data cannot be obtained, the auxiliary
>>>>>> information is optional. So I don't think register data should be removed.
>>>>>>
>>>>>> In my opinion, writing a file is a more appropriate way to do it.
>>>>>> I wonder if there's a better way.
>>>>>>
>>>>>>
>>>>>
>>>>> Is there a usecase to get register information from telemetry interface?
>>>>
>>>> Among the available tools:
>>>> 1, ethtool/proc-info: should use multi-process mechanism to connect to the main process
>>>> 2, telemetry: easier, lighter load, and it don't need re-probe the ethdev in the secondary process,
>>>>               and also cost more resource, like hugepage, cores.
>>>>
>>>> From our users, they prefer use the second 'telemetry', so I think we should move
>>>> more status-query-points to telemetry.
>>>>
>>>> As for this question, I think it's okay to get register info from telemetry.
>>>>
>>>>
>>>>
>>>> Another question, we have some internal registers, which:
>>>> 1. Is not suitable expose by xstats, because they may includes configuration
>>>> 2. Is not suitable expose by dumps, because this dumps is hard to understand (because it only has value).
>>>>
>>>> So we plan to add some telemetry points in the driver itself, so we could display them like xstats:
>>>> "xxxx" : 0x1234
>>>> "yyyy" : 0x100
>>>>
>>>> Will the community accept this kind of telemetry points which limit one driver ?
>>>>
>>>
>>> Hi Chengwen,
>>>
>>> I see there is a usecase/requirement.
>>>
>>> With this patch, even using file, only register values are dumped and
>>> isn't it hard to find value of specific register?
>>>
>>> ("xxxx" : 0x1234) approach looks better, but instead of making this
>>> telemetry support for specific driver, what about making it in two steps.
>>>
>>> First add new dev_ops, (or update existing one), to get registers with
>>> "name: value" format, (in a way to allow empty name), or even perhaps
>>> "name: offset, value" format.
>>> And in second stage add telemetry support around it.
>>> (Name being optional lets us wrap exiting 'get_reg' dev_ops with new one)
>>>
>>> When adding dev_ops, it may get an additional 'filter' parameter, to get
>>> only subset of regs, like "mac*" to get regs name staring with "mac",
>>> this may help for the cases there are too many registers you mentioned.
>>>
>>> Anyway, we can discuss more about its design, but what do you think
>>> about first having a dev_ops for this?
>>
>> I prefer extend struct rte_dev_reg_info, like this:
>>
>> struct rte_eth_reg_name {
>> 	char name[RTE_ETH_REG_NAME_SIZE];
>> };
>>
>> struct rte_dev_reg_info {
>> 	void *data; /**< Buffer for return registers */
>> 	uint32_t offset; /**< Start register table location for access */
>> 	uint32_t length; /**< Number of registers to fetch */
>> 	uint32_t width; /**< Size of device register */
>> 	uint32_t version; /**< Device version */
>> /* Note: below two fields are new added. */
>> 	char *filter; /**< Filter for target subset of registers. This field could affects register selection for data/length/name.  */
>> 	struct rte_eth_reg_name *names; /**< Registers name saver. */
>> };
>>
> 
> ack
> 
>> For driver which don't identify the new filter and names fields:
>>   1. .get_reg return the all registers value.
>>
> 
> ack
> 
> 
>>   2. and driver will not touch the name fields.
>>   3. rte_eth_dev_get_reg_info() could detect name fileds not filled, and then it fill with default names, e.g. offset-1/offset-2/...
>>
> 
> Is there a benefit to provide default names? API can clear the 'names'
> buffer, and driver may or may not fill it. If names not filled, API
> behaves like existing one, it will just provide register values.

ok

> 
> 
>> For driver which identify the new filter and names fields:
>>   1. rte_eth_dev_get_reg_info() will return filtered register's value and also their names.
>>
> 
> ack
> 
>> So that those which invoke rte_eth_dev_get_reg_info() could extra prepare names, and it call the same API will get data and name.
>>
>>
>> Add one new .get_reg_name ops and corresponding API like: rte_eth_dev_get_reg_name() could also feasible.
>> But I think the rte_eth_dev_get_reg_info()'s name is too broad, the info could includes value and also it's name.
>> So I prefer not add one new ops.
>>
> 
> ack
> 
>>
>> Another question? what are the supported values of filters ?
>> I prefer report by dev_info ops, something like a string array end with NULL.
>> Use could query from rte_eth_dev_info_get API.
>>
> 
> I don't think there is a need to populate predefined filter list, it can
> be free text with simple '*' and '.' wildcard support and ',' to support
> list of text.
> 
> User may get full list first, later can filter the ones they are interested.
> Like: "*mac*,*rss*" can match all register names that has 'mac' and
> 'rss' in it.

ok.

Our team will send v1 ASAP.

Thanks.

> 
> .
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 0/7] support dump reigser names and filter them
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
  2023-12-14 12:49 ` Ferruh Yigit
@ 2024-02-05 10:51 ` Jie Hai
  2024-02-05 10:51   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
                     ` (6 more replies)
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
                   ` (8 subsequent siblings)
  10 siblings, 7 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient
for users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext
is added to support the capability of exporting the name of the
corresponding register and filtering by names.

The hns3 driver and telemetry are examples for that.

--
v2:
1. fix compile error.
2. add new API to support it instead of the old one.
3. split patches on hns3 driver.

Jie Hai (7):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: fix dump counter of registers
  net/hns3: remove dump format of registers
  net/hns3: add names for registers
  net/hns3: support filter directly accessed registers
  net/hns3: support filter dump of registers

 doc/guides/rel_notes/release_24_03.rst |    8 +
 drivers/net/hns3/hns3_regs.c           | 1342 +++++++++++++++++++++---
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   36 +
 lib/ethdev/rte_ethdev.h                |   22 +
 lib/ethdev/rte_ethdev_telemetry.c      |  126 +++
 6 files changed, 1373 insertions(+), 172 deletions(-)

-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 1/7] ethdev: support report register names and filter
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  2024-02-07 17:00     ` Ferruh Yigit
  2024-02-05 10:51   ` [PATCH v2 2/7] ethdev: add telemetry cmd for registers Jie Hai
                     ` (5 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

For compatibility, the original API rte_eth_dev_get_reg_info()
does not use the name and filter fields. The new API
rte_eth_dev_get_reg_info_ext() is added to support reporting
names and filtering by names. If the drivers does not report
the names, set them to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  8 ++++++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 22 ++++++++++++++++
 4 files changed, 77 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215c6..5d402341223a 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -75,6 +75,11 @@ New Features
   * Added support for Atomic Rules' TK242 packet-capture family of devices
     with PCI IDs: ``0x1024, 0x1025, 0x1026``.
 
+* **Added support for dumping regiters with names and filter.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+  * the registers by their names and get the information of registers(names,
+  * values and other attributes).
 
 Removed Items
 -------------
@@ -124,6 +129,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of regiters and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..2f4541bd46c8 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 128
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..3e0294e49092 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+	reg_info.names = NULL;
+	reg_info.filter = NULL;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			sprintf(info->names[i].name, "offset_%x",
+				info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 2687c23fa6fb..3abc2ad3f865 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5053,6 +5053,28 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in. If info->data is
+ *   NULL, the function fills in the width and length fields. If non-NULL,
+ *   the values of registers whose name contains the filter string are put
+ *   into the buffer pointed at by the data field. Do the same for the names
+ *   of registers if info->names is not NULL.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 2/7] ethdev: add telemetry cmd for registers
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
  2024-02-05 10:51   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  2024-02-07 17:03     ` Ferruh Yigit
  2024-02-05 10:51   ` [PATCH v2 3/7] net/hns3: fix dump counter of registers Jie Hai
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds a telemetry command for registers dump,
and supports get registers with specified names.
The length of the string exported by telemetry is limited
by MAX_OUTPUT_LEN. Therefore, the filter should be more
precise.

An example usage is shown below:
--> /ethdev/regs,0,INTR
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "HNS3_CMDQ_INTR_STS_REG": "0x0",
      "HNS3_CMDQ_INTR_EN_REG": "0x2",
      "HNS3_CMDQ_INTR_GEN_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

or as below if the number of registers not exceed the
RTE_TEL_MAX_DICT_ENTRIES:
--> /ethdev/regs,0,ppp
{
  "/ethdev/regs": {
    "registers_length": 156,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "ppp_key_drop_num": "0x0",
    "ppp_rlt_drop_num": "0x0",
    "ssu_ppp_mac_key_num_l": "0x1",
    "ssu_ppp_mac_key_num_h": "0x0",
    "ssu_ppp_host_key_num_l": "0x1",
    "ssu_ppp_host_key_num_h": "0x0",
    "ppp_ssu_mac_rlt_num_l": "0x1",
        ...
   }
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 126 ++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..f1ebb2fae632 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -5,6 +5,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_telemetry.h>
 
@@ -1395,6 +1396,129 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES] = {NULL};
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t *data;
+	int ret = 0;
+	uint32_t i;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	data = reg_info->data;
+	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
+		for (i = 0; i < reg_info->length; i++, data++)
+			rte_tel_data_add_dict_uint_hex(d,
+				reg_info->names[i].name, *data, 0);
+		return 0;
+	}
+
+	for (i = 0; i < reg_info->length; i++, data++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
+			if (i != 0)
+				rte_tel_data_add_dict_container(d, group_name,
+								group, 0);
+
+			group = rte_tel_data_alloc();
+			if (group == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			rte_tel_data_start_dict(group);
+			snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
+					"group_%u", grp_num);
+			if (grp_num >= RTE_TEL_MAX_DICT_ENTRIES) {
+				RTE_ETHDEV_LOG_LINE(NOTICE,
+					"Too many regs, please filter");
+				return 0;
+			}
+			groups[grp_num++] = group;
+		}
+		rte_tel_data_add_dict_uint_hex(group, reg_info->names[i].name,
+						*data, 0);
+	}
+	if (i % RTE_TEL_MAX_DICT_ENTRIES != 0)
+		rte_tel_data_add_dict_container(d, group_name, group, 0);
+
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (!reg_info.data)
+		return -ENOMEM;
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (!reg_info.names) {
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter = NULL;
+	uint16_t port_id;
+	char *end_param;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1560,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns regs for a port. Parameters: int port_id, string filter");
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 3/7] net/hns3: fix dump counter of registers
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
  2024-02-05 10:51   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-05 10:51   ` [PATCH v2 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  2024-02-05 10:51   ` [PATCH v2 4/7] net/hns3: remove dump format " Jie Hai
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")

Signed-off-by: Jie Hai <haijie1@huawei.com>
Cc: stable@dpdk.org
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..d77170481a3d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -135,7 +135,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 4/7] net/hns3: remove dump format of registers
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
                     ` (2 preceding siblings ...)
  2024-02-05 10:51   ` [PATCH v2 3/7] net/hns3: fix dump counter of registers Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  2024-02-05 10:51   ` [PATCH v2 5/7] net/hns3: add names for registers Jie Hai
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between diffent register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 67 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 49 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d77170481a3d..b1c0d538a3c8 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
 					  HNS3_CMDQ_TX_ADDR_H_REG,
@@ -119,23 +116,22 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
+	cmdq_cnt = sizeof(cmdq_reg_addrs);
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
+	ring_cnt = sizeof(ring_reg_addrs);
+	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
+	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -144,18 +140,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -276,18 +270,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -302,7 +284,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -313,7 +294,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -321,7 +301,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -330,7 +309,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -406,17 +384,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -424,11 +400,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -475,7 +448,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -520,7 +492,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
@@ -528,8 +499,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 5/7] net/hns3: add names for registers
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
                     ` (3 preceding siblings ...)
  2024-02-05 10:51   ` [PATCH v2 4/7] net/hns3: remove dump format " Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  2024-02-05 10:51   ` [PATCH v2 6/7] net/hns3: support filter directly accessed registers Jie Hai
  2024-02-05 10:51   ` [PATCH v2 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds names for all registers to be dumped.
For those who can be directly accessed by their addresses,
a new structure containing both name and address is added
and the related arrays is refactored and renamed.

For the remaining modules, there may be different meanings
on different platforms for the same field. Therefore, two
name fields are provided.

There are some 64-bit registers, dump them as two 32-bit
registers.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 877 ++++++++++++++++++++++++++++++++---
 1 file changed, 801 insertions(+), 76 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b1c0d538a3c8..b7e4f78eecde 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,67 +14,84 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct direct_reg_list {
+	const char *name;
+	uint32_t addr;
+};
+
+#define STR(s) #s
+
+static const struct direct_reg_list cmdq_reg_list[] = {
+	{STR(HNS3_CMDQ_TX_ADDR_L_REG),		HNS3_CMDQ_TX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_TX_ADDR_H_REG),		HNS3_CMDQ_TX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_TX_DEPTH_REG),		HNS3_CMDQ_TX_DEPTH_REG},
+	{STR(HNS3_CMDQ_TX_TAIL_REG),		HNS3_CMDQ_TX_TAIL_REG},
+	{STR(HNS3_CMDQ_TX_HEAD_REG),		HNS3_CMDQ_TX_HEAD_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_L_REG),		HNS3_CMDQ_RX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_H_REG),		HNS3_CMDQ_RX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_RX_DEPTH_REG),		HNS3_CMDQ_RX_DEPTH_REG},
+	{STR(HNS3_CMDQ_RX_TAIL_REG),		HNS3_CMDQ_RX_TAIL_REG},
+	{STR(HNS3_CMDQ_RX_HEAD_REG),		HNS3_CMDQ_RX_HEAD_REG},
+	{STR(HNS3_VECTOR0_CMDQ_SRC_REG),	HNS3_VECTOR0_CMDQ_SRC_REG},
+	{STR(HNS3_CMDQ_INTR_STS_REG),		HNS3_CMDQ_INTR_STS_REG},
+	{STR(HNS3_CMDQ_INTR_EN_REG),		HNS3_CMDQ_INTR_EN_REG},
+	{STR(HNS3_CMDQ_INTR_GEN_REG),		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct direct_reg_list common_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_VECTOR0_OTER_EN_REG),		HNS3_VECTOR0_OTER_EN_REG},
+	{STR(HNS3_MISC_RESET_STS_REG),		HNS3_MISC_RESET_STS_REG},
+	{STR(HNS3_VECTOR0_OTHER_INT_STS_REG),	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{STR(HNS3_GLOBAL_RESET_REG),		HNS3_GLOBAL_RESET_REG},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list common_vf_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list ring_reg_list[] = {
+	{STR(HNS3_RING_RX_BASEADDR_L_REG),	HNS3_RING_RX_BASEADDR_L_REG},
+	{STR(HNS3_RING_RX_BASEADDR_H_REG),	HNS3_RING_RX_BASEADDR_H_REG},
+	{STR(HNS3_RING_RX_BD_NUM_REG),		HNS3_RING_RX_BD_NUM_REG},
+	{STR(HNS3_RING_RX_BD_LEN_REG),		HNS3_RING_RX_BD_LEN_REG},
+	{STR(HNS3_RING_RX_EN_REG),		HNS3_RING_RX_EN_REG},
+	{STR(HNS3_RING_RX_MERGE_EN_REG),	HNS3_RING_RX_MERGE_EN_REG},
+	{STR(HNS3_RING_RX_TAIL_REG),		HNS3_RING_RX_TAIL_REG},
+	{STR(HNS3_RING_RX_HEAD_REG),		HNS3_RING_RX_HEAD_REG},
+	{STR(HNS3_RING_RX_FBDNUM_REG),		HNS3_RING_RX_FBDNUM_REG},
+	{STR(HNS3_RING_RX_OFFSET_REG),		HNS3_RING_RX_OFFSET_REG},
+	{STR(HNS3_RING_RX_FBD_OFFSET_REG),	HNS3_RING_RX_FBD_OFFSET_REG},
+	{STR(HNS3_RING_RX_STASH_REG),		HNS3_RING_RX_STASH_REG},
+	{STR(HNS3_RING_RX_BD_ERR_REG),		HNS3_RING_RX_BD_ERR_REG},
+	{STR(HNS3_RING_TX_BASEADDR_L_REG),	HNS3_RING_TX_BASEADDR_L_REG},
+	{STR(HNS3_RING_TX_BASEADDR_H_REG),	HNS3_RING_TX_BASEADDR_H_REG},
+	{STR(HNS3_RING_TX_BD_NUM_REG),		HNS3_RING_TX_BD_NUM_REG},
+	{STR(HNS3_RING_TX_EN_REG),		HNS3_RING_TX_EN_REG},
+	{STR(HNS3_RING_TX_PRIORITY_REG),	HNS3_RING_TX_PRIORITY_REG},
+	{STR(HNS3_RING_TX_TC_REG),		HNS3_RING_TX_TC_REG},
+	{STR(HNS3_RING_TX_MERGE_EN_REG),	HNS3_RING_TX_MERGE_EN_REG},
+	{STR(HNS3_RING_TX_TAIL_REG),		HNS3_RING_TX_TAIL_REG},
+	{STR(HNS3_RING_TX_HEAD_REG),		HNS3_RING_TX_HEAD_REG},
+	{STR(HNS3_RING_TX_FBDNUM_REG),		HNS3_RING_TX_FBDNUM_REG},
+	{STR(HNS3_RING_TX_OFFSET_REG),		HNS3_RING_TX_OFFSET_REG},
+	{STR(HNS3_RING_TX_EBD_NUM_REG),		HNS3_RING_TX_EBD_NUM_REG},
+	{STR(HNS3_RING_TX_EBD_OFFSET_REG),	HNS3_RING_TX_EBD_OFFSET_REG},
+	{STR(HNS3_RING_TX_BD_ERR_REG),		HNS3_RING_TX_BD_ERR_REG},
+	{STR(HNS3_RING_EN_REG),			HNS3_RING_EN_REG},
+};
+
+static const struct direct_reg_list tqp_intr_reg_list[] = {
+	{STR(HNS3_TQP_INTR_CTRL_REG),	HNS3_TQP_INTR_CTRL_REG},
+	{STR(HNS3_TQP_INTR_GL0_REG),	HNS3_TQP_INTR_GL0_REG},
+	{STR(HNS3_TQP_INTR_GL1_REG),	HNS3_TQP_INTR_GL1_REG},
+	{STR(HNS3_TQP_INTR_GL2_REG),	HNS3_TQP_INTR_GL2_REG},
+	{STR(HNS3_TQP_INTR_RL_REG),	HNS3_TQP_INTR_RL_REG},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_BIOS_COMMON_REG,
@@ -91,6 +108,708 @@ static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_SSU_REG_2
 };
 
+struct hns3_reg_entry {
+	const char *new_name;
+	const char *old_name;
+};
+
+static struct hns3_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"ssu_btmp_ageing_st_b0"},
+	{"ssu_btmp_ageing_st_b1"},
+	{"ssu_btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"ssu_lo_pri_unicast_rlt_drop_num"},
+	{"ssu_hi_pri_multicast_rlt_drop_num"},
+
+	{"ssu_lo_pri_multicast_rlt_drop_num"},
+	{"ssu_ncsi_packet_curr_buffer_cnt"},
+	{"dfx_ssu0_rsv5",		"ssu_btmp_ageing_rls_cnt_bank0"},
+	{"dfx_ssu0_rsv6",		"ssu_btmp_ageing_rls_cnt_bank1"},
+	{"dfx_ssu0_rsv7",		"ssu_btmp_ageing_rls_cnt_bank2"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ssu_ncsi_rx_packet_in_cnt_l"},
+	{"ssu_ncsi_rx_packet_in_cnt_h"},
+	{"ssu_ncsi_tx_packet_out_cnt_l"},
+	{"ssu_ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"ssu_mb_uncopy_num"},
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+	{"ssu_bank_unbalance_drop_cnt"},
+	{"ssu_bank_unbalance_rx_drop_cnt"},
+
+	{"ssu_nic_l2_eer_drop_pkt_cnt"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt"},
+	{"ssu_nic_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_rx_oq_glb_drop_pkt_cnt"},
+	{"ssu_dfx_ssu0_rsv8"},
+
+	{"ssu_lo_pri_unicast_cur_cnt"},
+	{"ssu_hi_pri_multicast_cur_cnt"},
+	{"ssu_lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"ssu_packet_tc_curr_buffer_cnt_0"},
+	{"ssu_packet_tc_curr_buffer_cnt_1"},
+	{"ssu_packet_tc_curr_buffer_cnt_2"},
+	{"ssu_packet_tc_curr_buffer_cnt_3"},
+	{"ssu_packet_tc_curr_buffer_cnt_4"},
+
+	{"ssu_packet_tc_curr_buffer_cnt_5"},
+	{"ssu_packet_tc_curr_buffer_cnt_6"},
+	{"ssu_packet_tc_curr_buffer_cnt_7"},
+	{"ssu_packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"ssu_rx_packet_in_cnt_l"},
+	{"ssu_rx_packet_in_cnt_h"},
+	{"ssu_rx_packet_out_cnt_l"},
+	{"ssu_rx_packet_out_cnt_h"},
+	{"ssu_tx_packet_in_cnt_l"},
+	{"ssu_tx_packet_in_cnt_h"},
+
+	{"ssu_tx_packet_out_cnt_l"},
+	{"ssu_tx_packet_out_cnt_h"},
+	{"ssu_roc_rx_packet_in_cnt_l"},
+	{"ssu_roc_rx_packet_in_cnt_h"},
+	{"ssu_roc_tx_packet_in_cnt_l"},
+	{"ssu_roc_tx_packet_in_cnt_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_0_l"},
+	{"ssu_rx_packet_tc_in_cnt_0_h"},
+	{"ssu_rx_packet_tc_in_cnt_1_l"},
+	{"ssu_rx_packet_tc_in_cnt_1_h"},
+	{"ssu_rx_packet_tc_in_cnt_2_l"},
+	{"ssu_rx_packet_tc_in_cnt_2_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_3_l"},
+	{"ssu_rx_packet_tc_in_cnt_3_h"},
+	{"ssu_rx_packet_tc_in_cnt_4_l"},
+	{"ssu_rx_packet_tc_in_cnt_4_h"},
+	{"ssu_rx_packet_tc_in_cnt_5_l"},
+	{"ssu_rx_packet_tc_in_cnt_5_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_6_l"},
+	{"ssu_rx_packet_tc_in_cnt_6_h"},
+	{"ssu_rx_packet_tc_in_cnt_7_l"},
+	{"ssu_rx_packet_tc_in_cnt_7_h"},
+	{"ssu_rx_packet_tc_out_cnt_0_l"},
+	{"ssu_rx_packet_tc_out_cnt_0_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_1_l"},
+	{"ssu_rx_packet_tc_out_cnt_1_h"},
+	{"ssu_rx_packet_tc_out_cnt_2_l"},
+	{"ssu_rx_packet_tc_out_cnt_2_h"},
+	{"ssu_rx_packet_tc_out_cnt_3_l"},
+	{"ssu_rx_packet_tc_out_cnt_3_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_4_l"},
+	{"ssu_rx_packet_tc_out_cnt_4_h"},
+	{"ssu_rx_packet_tc_out_cnt_5_l"},
+	{"ssu_rx_packet_tc_out_cnt_5_h"},
+	{"ssu_rx_packet_tc_out_cnt_6_l"},
+	{"ssu_rx_packet_tc_out_cnt_6_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_7_l"},
+	{"ssu_rx_packet_tc_out_cnt_7_h"},
+	{"ssu_tx_packet_tc_in_cnt_0_l"},
+	{"ssu_tx_packet_tc_in_cnt_0_h"},
+	{"ssu_tx_packet_tc_in_cnt_1_l"},
+	{"ssu_tx_packet_tc_in_cnt_1_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_2_l"},
+	{"ssu_tx_packet_tc_in_cnt_2_h"},
+	{"ssu_tx_packet_tc_in_cnt_3_l"},
+	{"ssu_tx_packet_tc_in_cnt_3_h"},
+	{"ssu_tx_packet_tc_in_cnt_4_l"},
+	{"ssu_tx_packet_tc_in_cnt_4_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_5_l"},
+	{"ssu_tx_packet_tc_in_cnt_5_h"},
+	{"ssu_tx_packet_tc_in_cnt_6_l"},
+	{"ssu_tx_packet_tc_in_cnt_6_h"},
+	{"ssu_tx_packet_tc_in_cnt_7_l"},
+	{"ssu_tx_packet_tc_in_cnt_7_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_0_l"},
+	{"ssu_tx_packet_tc_out_cnt_0_h"},
+	{"ssu_tx_packet_tc_out_cnt_1_l"},
+	{"ssu_tx_packet_tc_out_cnt_1_h"},
+	{"ssu_tx_packet_tc_out_cnt_2_l"},
+	{"ssu_tx_packet_tc_out_cnt_2_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_3_l"},
+	{"ssu_tx_packet_tc_out_cnt_3_h"},
+	{"ssu_tx_packet_tc_out_cnt_4_l"},
+	{"ssu_tx_packet_tc_out_cnt_4_h"},
+	{"ssu_tx_packet_tc_out_cnt_5_l"},
+	{"ssu_tx_packet_tc_out_cnt_5_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_6_l"},
+	{"ssu_tx_packet_tc_out_cnt_6_h"},
+	{"ssu_tx_packet_tc_out_cnt_7_l"},
+	{"ssu_tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_mul_car_drop_pkt_cnt_l",	"igu_egu_rsv0"},
+	{"igu_egu_mul_car_drop_pkt_cnt_h",	"igu_egu_rsv1"},
+	{"igu_egu_bro_car_drop_pkt_cnt_l",	"igu_egu_rsv2"},
+	{"igu_egu_bro_car_drop_pkt_cnt_h",	"igu_egu_rsv3"},
+	{"igu_egu_rsv0",		"igu_egu_rsv4"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_currport_tnl_index",	"rpu_tc_queue_num"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rsv1",		"ppp_rslt_descr_sts"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_snq_hit_cnt_l",	"ppp_um_tbl_vmdq1_hit_cnt_l"},
+	{"ppp_um_tbl_snq_hit_cnt_h",	"ppp_um_tbl_vmdq1_hit_cnt_h"},
+	{"ppp_rsv5",			"ppp_mta_tbl_hit_cnt_l"},
+	{"ppp_rsv6",			"ppp_mta_tbl_hit_cnt_h"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_rsv7",	"ppp_vlan_mirr_cnt_l"},
+	{"ppp_rsv8",	"ppp_vlan_mirr_cnt_h"},
+
+	{"ppp_rsv9",	"ppp_ig_mirr_cnt_l"},
+	{"ppp_rsv10",	"ppp_ig_mirr_cnt_h"},
+	{"ppp_rsv11",	"ppp_eg_mirr_cnt_l"},
+	{"ppp_rsv12",	"ppp_eg_mirr_cnt_h"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_rcb_tx_mem_serr_cnt",	"rcb_axi_rd_fbd_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+struct hns3_dfx_reg_entry {
+	const struct hns3_reg_entry *regs;
+	uint32_t entry_num;
+};
+
+struct hns3_dfx_reg_entry hns3_dfx_reg_list[] = {
+	{dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	{dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	{dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	{dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list)},
+	{dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	{dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	{dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	{dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	{dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	{dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	{dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	{dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+};
+
 static int
 hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 		  uint32_t *regs_num_64_bit)
@@ -108,6 +827,12 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_SIZE !=
+			RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -122,13 +847,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = sizeof(cmdq_reg_addrs);
+	cmdq_cnt = RTE_DIM(cmdq_reg_list);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = sizeof(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
-	ring_cnt = sizeof(ring_reg_addrs);
-	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
+	ring_cnt = RTE_DIM(ring_reg_list);
+	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -281,33 +1006,33 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	size_t i;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(cmdq_reg_list);
 	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_vf_reg_list);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_reg_list);
 	for (i = 0; i < reg_num; i++)
 		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
 		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
 
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
+						ring_reg_list[i].addr + reg_offset);
 	}
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
+			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
 	}
 	return data - origin_data_ptr;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 6/7] net/hns3: support filter directly accessed registers
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
                     ` (4 preceding siblings ...)
  2024-02-05 10:51   ` [PATCH v2 5/7] net/hns3: add names for registers Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  2024-02-05 10:51   ` [PATCH v2 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch supports reporting names of registers which
can be directly accessed by addresses and filtering
them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 185 +++++++++++++++++++++++++++++------
 1 file changed, 156 insertions(+), 29 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b7e4f78eecde..ac07563ebaec 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -837,8 +837,24 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static uint32_t
+hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
+			 uint32_t len, char *filter)
+{
+	uint32_t i;
+	uint32_t count = 0;
+
+	for (i = 0 ; i < len; i++) {
+		if (filter != NULL && !strstr(list[i].name, filter))
+			continue;
+		count++;
+	}
+
+	return count;
+}
+
 static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
@@ -847,13 +863,18 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = RTE_DIM(cmdq_reg_list);
+	cmdq_cnt = hns3_get_direct_regs_cnt(cmdq_reg_list,
+					    RTE_DIM(cmdq_reg_list), filter);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_vf_reg_list,
+					RTE_DIM(common_vf_reg_list), filter);
 	else
-		common_cnt = RTE_DIM(common_reg_list);
-	ring_cnt = RTE_DIM(ring_reg_list);
-	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_reg_list,
+					RTE_DIM(common_reg_list), filter);
+	ring_cnt = hns3_get_direct_regs_cnt(ring_reg_list,
+					    RTE_DIM(ring_reg_list), filter);
+	tqp_intr_cnt = hns3_get_direct_regs_cnt(tqp_intr_reg_list,
+					RTE_DIM(tqp_intr_reg_list), filter);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -995,47 +1016,151 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+
+static uint32_t
+hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
+	uint32_t *data = regs->data;
 	size_t reg_num;
-	uint16_t j;
+	data += count;
 	size_t i;
 
-	/* fetching per-PF registers values from PF PCIe register space */
 	reg_num = RTE_DIM(cmdq_reg_list);
-	for (i = 0; i < reg_num; i++)
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(cmdq_reg_list[i].name, regs->filter))
+			continue;
 		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", cmdq_reg_list[i].name);
+	}
 
-	if (hns->is_vf)
-		reg_num = RTE_DIM(common_vf_reg_list);
-	else
-		reg_num = RTE_DIM(common_reg_list);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+	return count;
+}
+static uint32_t
+hns3_direct_access_common_reg(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs,
+			      uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
+
+	reg_num = RTE_DIM(common_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_vf_common_reg(struct hns3_hw *hw,
+				 struct rte_dev_reg_info *regs,
+				 uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
 
+	reg_num = RTE_DIM(common_vf_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_vf_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_vf_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_ring_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(ring_reg_list[i].name, regs->filter))
+				continue;
 			*data++ = hns3_read_dev(hw,
 						ring_reg_list[i].addr + reg_offset);
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, ring_reg_list[i].name);
+		}
 	}
 
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(tqp_intr_reg_list[i].name, regs->filter))
+				continue;
+
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+		}
 	}
-	return data - origin_data_ptr;
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_regs(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs,
+			uint32_t count)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+
+	count = hns3_direct_access_cmdq_reg(hw, regs, count);
+	if (!hns->is_vf)
+		count = hns3_direct_access_common_reg(hw, regs, count);
+	else
+		count = hns3_direct_access_vf_common_reg(hw, regs, count);
+
+	count = hns3_direct_access_ring_reg(hw, regs, count);
+	count = hns3_direct_access_tqp_intr_reg(hw, regs, count);
+
+	return count;
 }
 
 static int
@@ -1177,11 +1302,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
+	uint32_t count = 0;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
+	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
@@ -1193,13 +1319,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	}
 
 	/* Only full register dump is supported */
-	if (regs->length && regs->length != length)
+	if ((regs->length && regs->length != length) || regs->names == NULL)
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
+	count = hns3_direct_access_regs(hw, regs, count);
+	data += count;
 
 	if (hns->is_vf)
 		return 0;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v2 7/7] net/hns3: support filter dump of registers
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
                     ` (5 preceding siblings ...)
  2024-02-05 10:51   ` [PATCH v2 6/7] net/hns3: support filter directly accessed registers Jie Hai
@ 2024-02-05 10:51   ` Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch supports reporting names of the dfx registers
which filtering them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 271 +++++++++++++++++++++++++++++------
 1 file changed, 224 insertions(+), 47 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index ac07563ebaec..53b5a2dbe15f 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,7 +12,8 @@
 
 #define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw,
+				uint32_t *count, char *filter);
 
 struct direct_reg_list {
 	const char *name;
@@ -853,12 +854,41 @@ hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
 	return count;
 }
 
+static uint32_t
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, char *filter)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+	uint32_t i;
+	uint32_t count = 0;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	for (i = 0 ; i < regs_num_32_bit; i++) {
+		if (filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	for (i = 0 ; i < regs_num_64_bit * HNS3_64_BIT_REG_SIZE; i++) {
+		if (filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	return count;
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
-	uint32_t regs_num_32_bit, regs_num_64_bit;
 	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
@@ -880,16 +910,9 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
+		dfx_reg_cnt = hns3_get_32_64_regs_cnt(hw, filter);
 
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt, filter);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -903,19 +926,19 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 }
 
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
 	struct hns3_cmd_desc *desc;
 	uint32_t *reg_val = data;
 	uint32_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_32_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
 			       HNS3_32_BIT_REG_RTN_DATANUM);
@@ -959,20 +982,66 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_32_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_32_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_32_bit_list[i].new_name);
+	}
+}
+
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs_filtered(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_32_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_32_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		rte_free(data);
+		return ret;
+	}
+
+	hns3_filter_32_bit_regs(regs, count, data);
+	return 0;
+}
+
+static int
+hns3_get_64_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
 	struct hns3_cmd_desc *desc;
 	uint64_t *reg_val = data;
 	uint64_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_64_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
 			       HNS3_64_BIT_REG_RTN_DATANUM);
@@ -1016,6 +1085,52 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_64_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_64_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_64_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_64_bit_regs_filtered(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret = 0;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_64_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_64_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		goto out;
+	}
+
+	hns3_filter_64_bit_regs(regs, count, data);
+out:
+	rte_free(data);
+	return 0;
+}
 
 static uint32_t
 hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
@@ -1107,7 +1222,7 @@ hns3_direct_access_ring_reg(struct hns3_hw *hw,
 			*data++ = hns3_read_dev(hw,
 						ring_reg_list[i].addr + reg_offset);
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, ring_reg_list[i].name);
+				 "queue_%u_%s", j, ring_reg_list[i].name);
 		}
 	}
 
@@ -1137,7 +1252,7 @@ hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+				 "queue_%u_%s", j, tqp_intr_reg_list[i].name);
 		}
 	}
 
@@ -1239,31 +1354,48 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count, char *filter)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num, data_len, reg_num = 0;
+	const struct hns3_reg_entry *regs;
 	uint32_t bd_num_list[opcode_num];
+	uint32_t i, j;
 	int ret;
-	int i;
 
 	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < (uint32_t)opcode_num; i++) {
+		bd_num = bd_num_list[i];
+		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM;
+		if (data_len != hns3_dfx_reg_list[i].entry_num) {
+			hns3_err(hw, "The number of registers(%u) diff from registers list(%u)!\n",
+				 data_len, hns3_dfx_reg_list[i].entry_num);
+			return -EINVAL;
+		}
 
+		regs = hns3_dfx_reg_list[i].regs;
+		for (j = 0; j < data_len; j++) {
+			if (filter != NULL &&
+				!strstr(regs[j].new_name, filter))
+				continue;
+			reg_num++;
+		}
+	}
+
+	*count += reg_num;
 	return 0;
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, uint32_t *data)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
 	int ret;
 	int i;
 
@@ -1287,32 +1419,85 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+		data += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
+static void
+hns3_filter_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+		     uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data = regs->data;
+	const char *name = NULL;
+	uint32_t i, j, cnt;
+
+	cnt = *count;
+	regs_data += cnt;
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++) {
+		for (j = 0; j < hns3_dfx_reg_list[i].entry_num; j++) {
+			if (hw->revision < PCI_REVISION_ID_HIP09_A &&
+				hns3_dfx_reg_list[i].regs[j].old_name != NULL)
+				name = hns3_dfx_reg_list[i].regs[j].old_name;
+			else
+				name = hns3_dfx_reg_list[i].regs[j].new_name;
+
+			if (regs->filter != NULL && !strstr(name, regs->filter)) {
+				data++;
+				continue;
+			}
+
+			snprintf(regs->names[cnt++].name,
+				 RTE_ETH_REG_NAME_SIZE, "%s", name);
+			*regs_data++ = *data++;
+		}
+	}
+	*count = cnt;
+}
+
+static int
+hns3_get_dfx_regs_filtered(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			   uint32_t *count)
+{
+	uint32_t reg_num = 0;
+	uint32_t *data;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++)
+		reg_num += hns3_dfx_reg_list[i].entry_num;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * reg_num, 0);
+	if (data == NULL) {
+		hns3_err(hw, "No memory for dfx regs!\n");
+		return -ENOMEM;
+	}
+	ret = hns3_get_dfx_regs(hw, data);
+	if (ret != 0)
+		goto out;
+
+	hns3_filter_dfx_regs(hw, regs, count, data);
+out:
+	rte_free(data);
+	return ret;
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t count = 0;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -1326,31 +1511,23 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 
 	/* fetching per-PF registers values from PF PCIe register space */
 	count = hns3_direct_access_regs(hw, regs, count);
-	data += count;
 
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
-	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
+	ret = hns3_get_32_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
+	ret = hns3_get_64_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	ret = hns3_get_dfx_regs_filtered(hw, regs, &count);
+	regs->length = count;
+	return 0;
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v2 1/7] ethdev: support report register names and filter
  2024-02-05 10:51   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-07 17:00     ` Ferruh Yigit
  2024-02-20  8:43       ` Jie Hai
  0 siblings, 1 reply; 134+ messages in thread
From: Ferruh Yigit @ 2024-02-07 17:00 UTC (permalink / raw)
  To: Jie Hai, dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui

On 2/5/2024 10:51 AM, Jie Hai wrote:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> For compatibility, the original API rte_eth_dev_get_reg_info()
> does not use the name and filter fields. The new API
> rte_eth_dev_get_reg_info_ext() is added to support reporting
> names and filtering by names. If the drivers does not report
> the names, set them to "offset_XXX".
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>  lib/ethdev/rte_dev_info.h              | 11 ++++++++
>  lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev.h                | 22 ++++++++++++++++
>  4 files changed, 77 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index 84d3144215c6..5d402341223a 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -75,6 +75,11 @@ New Features
>    * Added support for Atomic Rules' TK242 packet-capture family of devices
>      with PCI IDs: ``0x1024, 0x1025, 0x1026``.
>  
> +* **Added support for dumping regiters with names and filter.**
>

s/regiters/registers/

> +
> +  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
> +  * the registers by their names and get the information of registers(names,
> +  * values and other attributes).
>  

'*' makes a bullet, but above seems one sentences, if so please only
keep the first '*'.

>  Removed Items
>  -------------
> @@ -124,6 +129,9 @@ ABI Changes
>  
>  * No ABI change that would break compatibility with 23.11.
>  
> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
> +  structure for reporting names of regiters and filtering them by names.
> +
>  

This will break the ABI.

Think about a case, an application compiled with an old version of DPDK,
later same application started to use this version without re-compile,
application will send old version of 'struct rte_dev_reg_info', but new
version of DPDK will try to access or update new fields of the 'struct
rte_dev_reg_info'

One option is:
- to add a new 'struct rte_dev_reg_info_ext',
- 'rte_eth_dev_get_reg_info()' still uses old 'struct rte_dev_reg_info'
- 'get_reg()' dev_ops will use this new 'struct rte_dev_reg_info_ext'
- Add deprecation notice to update 'rte_eth_dev_get_reg_info()' to use
new struct in next LTS release


>  Known Issues
>  ------------
> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
> index 67cf0ae52668..2f4541bd46c8 100644
> --- a/lib/ethdev/rte_dev_info.h
> +++ b/lib/ethdev/rte_dev_info.h
> @@ -11,6 +11,11 @@ extern "C" {
>  
>  #include <stdint.h>
>  
> +#define RTE_ETH_REG_NAME_SIZE 128
> +struct rte_eth_reg_name {
> +	char name[RTE_ETH_REG_NAME_SIZE];
> +};
> +
>  /*
>   * Placeholder for accessing device registers
>   */
> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };
>  
>  /*
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index f1c658f49e80..3e0294e49092 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>  
>  int
>  rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
> +{
> +	struct rte_dev_reg_info reg_info;
> +	int ret;
> +
> +	if (info == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Cannot get ethdev port %u register info to NULL",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	reg_info.length = info->length;
> +	reg_info.data = info->data;
> +	reg_info.names = NULL;
> +	reg_info.filter = NULL;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0)
> +		return ret;
> +
> +	info->length = reg_info.length;
> +	info->width = reg_info.width;
> +	info->version = reg_info.version;
> +	info->offset = reg_info.offset;
> +
> +	return 0;
> +}
> +
> +int
> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>  {
>  	struct rte_eth_dev *dev;
> +	uint32_t i;
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>  
>  	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>  
> +	/* Report the default names if drivers not report. */
> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
> +		for (i = 0; i < info->length; i++)
> +			sprintf(info->names[i].name, "offset_%x",
> +				info->offset + i * info->width);
>

Better to use 'snprintf()'

>  	return ret;
>  }
>  
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 2687c23fa6fb..3abc2ad3f865 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5053,6 +5053,28 @@ __rte_experimental
>  int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>  		struct rte_power_monitor_cond *pmc);
>  
> +/**
> + * Retrieve the filtered device registers (values and names) and
> + * register attributes (number of registers and register size)
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param info
> + *   Pointer to rte_dev_reg_info structure to fill in. If info->data is
> + *   NULL, the function fills in the width and length fields. If non-NULL,
> + *   the values of registers whose name contains the filter string are put
> + *   into the buffer pointed at by the data field. Do the same for the names
> + *   of registers if info->names is not NULL.
>

May be good to mention if info->names is not NULL, but driver doesn't
support names, ehtdev fills the names automatically.

As both 'rte_eth_dev_get_reg_info()' & 'rte_eth_dev_get_reg_info_ext()'
use same dev_ops ('get_reg()'), it is possible that driver doesn't
support filtering, so if the user provides info->filter but driver
doesn't support it, I think API should return error, what do you think?

And can you please make it clear above, if filtering is provided with
info->data = NULL, are the returned width and length fields for filtered
number of registers or all registers?


> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EIO) if device is removed.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
> +
>

Can you please make the new API as experimental. That is the requirement
for new APIs.

Also need to add the API to version.map


>  /**
>   * Retrieve device registers and register attributes (number of registers and
>   * register size)


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v2 2/7] ethdev: add telemetry cmd for registers
  2024-02-05 10:51   ` [PATCH v2 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-02-07 17:03     ` Ferruh Yigit
  2024-02-22  9:01       ` Jie Hai
  0 siblings, 1 reply; 134+ messages in thread
From: Ferruh Yigit @ 2024-02-07 17:03 UTC (permalink / raw)
  To: Jie Hai, dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui

On 2/5/2024 10:51 AM, Jie Hai wrote:
> This patch adds a telemetry command for registers dump,
> and supports get registers with specified names.
> The length of the string exported by telemetry is limited
> by MAX_OUTPUT_LEN. Therefore, the filter should be more
> precise.
> 
> An example usage is shown below:
> --> /ethdev/regs,0,INTR
> {
>   "/ethdev/regs": {
>     "registers_length": 318,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "group_0": {
>       "HNS3_CMDQ_INTR_STS_REG": "0x0",
>       "HNS3_CMDQ_INTR_EN_REG": "0x2",
>       "HNS3_CMDQ_INTR_GEN_REG": "0x0",
>       "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
>       "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
>       "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
>       "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
>       ...
>       },
>     "group_1": {
>         ...
>     },
>     ...
> }
> 

What is the intention of 'RTE_TEL_MAX_DICT_ENTRIES' and grouping above?

> or as below if the number of registers not exceed the
> RTE_TEL_MAX_DICT_ENTRIES:
> --> /ethdev/regs,0,ppp
> {
>   "/ethdev/regs": {
>     "registers_length": 156,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "ppp_key_drop_num": "0x0",
>     "ppp_rlt_drop_num": "0x0",
>     "ssu_ppp_mac_key_num_l": "0x1",
>     "ssu_ppp_mac_key_num_h": "0x0",
>     "ssu_ppp_host_key_num_l": "0x1",
>     "ssu_ppp_host_key_num_h": "0x0",
>     "ppp_ssu_mac_rlt_num_l": "0x1",
>         ...
>    }
> }
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v2 1/7] ethdev: support report register names and filter
  2024-02-07 17:00     ` Ferruh Yigit
@ 2024-02-20  8:43       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20  8:43 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui

Hi, Ferruh,
Thanks for your review.

On 2024/2/8 1:00, Ferruh Yigit wrote:
> On 2/5/2024 10:51 AM, Jie Hai wrote:
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> For compatibility, the original API rte_eth_dev_get_reg_info()
>> does not use the name and filter fields. The new API
>> rte_eth_dev_get_reg_info_ext() is added to support reporting
>> names and filtering by names. If the drivers does not report
>> the names, set them to "offset_XXX".
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>>   lib/ethdev/rte_dev_info.h              | 11 ++++++++
>>   lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
>>   lib/ethdev/rte_ethdev.h                | 22 ++++++++++++++++
>>   4 files changed, 77 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
>> index 84d3144215c6..5d402341223a 100644
>> --- a/doc/guides/rel_notes/release_24_03.rst
>> +++ b/doc/guides/rel_notes/release_24_03.rst
>> @@ -75,6 +75,11 @@ New Features
>>     * Added support for Atomic Rules' TK242 packet-capture family of devices
>>       with PCI IDs: ``0x1024, 0x1025, 0x1026``.
>>   
>> +* **Added support for dumping regiters with names and filter.**
>>
> 
> s/regiters/registers/
Will correct in v3.
> 
>> +
>> +  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
>> +  * the registers by their names and get the information of registers(names,
>> +  * values and other attributes).
>>   
> 
> '*' makes a bullet, but above seems one sentences, if so please only
> keep the first '*'.
Will correct in v3.
> 
>>   Removed Items
>>   -------------
>> @@ -124,6 +129,9 @@ ABI Changes
>>   
>>   * No ABI change that would break compatibility with 23.11.
>>   
>> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
>> +  structure for reporting names of regiters and filtering them by names.
>> +
>>   
> 
> This will break the ABI.
> 
> Think about a case, an application compiled with an old version of DPDK,
> later same application started to use this version without re-compile,
> application will send old version of 'struct rte_dev_reg_info', but new
> version of DPDK will try to access or update new fields of the 'struct
> rte_dev_reg_info'
> 
Actually, we use a local variable "struct rte_dev_reg_info reg_info" in
'rte_eth_dev_get_reg_info()' to pass to the driver, and the new fields
are set to zero. The old drivers do not visit the new fields.
We make constrains that if filter is NULL, do not filter and get info of 
all registers.
For an old version APP and new version ethdev, driver will not visit the 
new fields. so it does not break the ABI.
> One option is:
> - to add a new 'struct rte_dev_reg_info_ext',
> - 'rte_eth_dev_get_reg_info()' still uses old 'struct rte_dev_reg_info'
> - 'get_reg()' dev_ops will use this new 'struct rte_dev_reg_info_ext'
> - Add deprecation notice to update 'rte_eth_dev_get_reg_info()' to use
> new struct in next LTS release
> 

> 
>>   Known Issues
>>   ------------
>> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
>> index 67cf0ae52668..2f4541bd46c8 100644
>> --- a/lib/ethdev/rte_dev_info.h
>> +++ b/lib/ethdev/rte_dev_info.h
>> @@ -11,6 +11,11 @@ extern "C" {
>>   
>>   #include <stdint.h>
>>   
>> +#define RTE_ETH_REG_NAME_SIZE 128
>> +struct rte_eth_reg_name {
>> +	char name[RTE_ETH_REG_NAME_SIZE];
>> +};
>> +
>>   /*
>>    * Placeholder for accessing device registers
>>    */
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
>>   
>>   /*
>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>> index f1c658f49e80..3e0294e49092 100644
>> --- a/lib/ethdev/rte_ethdev.c
>> +++ b/lib/ethdev/rte_ethdev.c
>> @@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>>   
>>   int
>>   rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>> +{
>> +	struct rte_dev_reg_info reg_info;
>> +	int ret;
>> +
>> +	if (info == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Cannot get ethdev port %u register info to NULL",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	reg_info.length = info->length;
>> +	reg_info.data = info->data;
>> +	reg_info.names = NULL;
>> +	reg_info.filter = NULL;
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	info->length = reg_info.length;
>> +	info->width = reg_info.width;
>> +	info->version = reg_info.version;
>> +	info->offset = reg_info.offset;
>> +
>> +	return 0;
>> +}
>> +
>> +int
>> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>>   {
>>   	struct rte_eth_dev *dev;
>> +	uint32_t i;
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> @@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>>   
>>   	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>>   
>> +	/* Report the default names if drivers not report. */
>> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
>> +		for (i = 0; i < info->length; i++)
>> +			sprintf(info->names[i].name, "offset_%x",
>> +				info->offset + i * info->width);
>>
> 
> Better to use 'snprintf()'
> 
Will correct in v3.
>>   	return ret;
>>   }
>>   
>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
>> index 2687c23fa6fb..3abc2ad3f865 100644
>> --- a/lib/ethdev/rte_ethdev.h
>> +++ b/lib/ethdev/rte_ethdev.h
>> @@ -5053,6 +5053,28 @@ __rte_experimental
>>   int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>>   		struct rte_power_monitor_cond *pmc);
>>   
>> +/**
>> + * Retrieve the filtered device registers (values and names) and
>> + * register attributes (number of registers and register size)
>> + *
>> + * @param port_id
>> + *   The port identifier of the Ethernet device.
>> + * @param info
>> + *   Pointer to rte_dev_reg_info structure to fill in. If info->data is
>> + *   NULL, the function fills in the width and length fields. If non-NULL,
>> + *   the values of registers whose name contains the filter string are put
>> + *   into the buffer pointed at by the data field. Do the same for the names
>> + *   of registers if info->names is not NULL.
>>
> 
> May be good to mention if info->names is not NULL, but driver doesn't
> support names, ehtdev fills the names automatically.
> 
> As both 'rte_eth_dev_get_reg_info()' & 'rte_eth_dev_get_reg_info_ext()'
> use same dev_ops ('get_reg()'), it is possible that driver doesn't
> support filtering, so if the user provides info->filter but driver
> doesn't support it, I think API should return error, what do you think?
> 
> And can you please make it clear above, if filtering is provided with
> info->data = NULL, are the returned width and length fields for filtered
> number of registers or all registers?
> 
> 
Will correct in v3.
>> + * @return
>> + *   - (0) if successful.
>> + *   - (-ENOTSUP) if hardware doesn't support.
>> + *   - (-EINVAL) if bad parameter.
>> + *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EIO) if device is removed.
>> + *   - others depends on the specific operations implementation.
>> + */
>> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
>> +
>>
> 
> Can you please make the new API as experimental. That is the requirement
> for new APIs.
> 
> Also need to add the API to version.map
Will correct in v3.
> 
> 
>>   /**
>>    * Retrieve device registers and register attributes (number of registers and
>>    * register size)
> 
> .

Best regards,
Jie Hai

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 0/7] support dump reigser names and filter them
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
  2023-12-14 12:49 ` Ferruh Yigit
  2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
@ 2024-02-20 10:58 ` Jie Hai
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
                     ` (6 more replies)
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
                   ` (7 subsequent siblings)
  10 siblings, 7 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient
for users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext
is added to support the capability of exporting the name of the
corresponding register and filtering by names.

The hns3 driver and telemetry are examples for that.

--
v3:
1. fix mispellings.
2. use snprintf instead of sprintf.
3. add more comment on rte_eth_dev_get_reg_info_ext.
4. add __rte_experimental.
5. add version map.

v2:
1. fix compile error.
2. add new API to support it instead of the old one.
3. split patches on hns3 driver.

Jie Hai (7):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: fix dump counter of registers
  net/hns3: remove dump format of registers
  net/hns3: add names for registers
  net/hns3: support filter directly accessed registers
  net/hns3: support filter dump of registers

 doc/guides/rel_notes/release_24_03.rst |    9 +
 drivers/net/hns3/hns3_regs.c           | 1359 +++++++++++++++++++++---
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   36 +
 lib/ethdev/rte_ethdev.h                |   28 +
 lib/ethdev/rte_ethdev_telemetry.c      |  126 +++
 lib/ethdev/version.map                 |    1 +
 7 files changed, 1397 insertions(+), 173 deletions(-)

-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  2024-02-20 15:09     ` Stephen Hemminger
                       ` (3 more replies)
  2024-02-20 10:58   ` [PATCH v3 2/7] ethdev: add telemetry cmd for registers Jie Hai
                     ` (5 subsequent siblings)
  6 siblings, 4 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by names. And the original API
rte_eth_dev_get_reg_info() does not use the name and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  9 +++++++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 28 ++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 5 files changed, 85 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index db8be50c6dfd..f8882ba36bb9 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -102,6 +102,12 @@ New Features
 
   * Added support for comparing result between packet fields or value.
 
+* **Added support for dumping regiters with names and filter.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+    the registers by their names and get the information of registers(names,
+    values and other attributes).
+
 
 Removed Items
 -------------
@@ -154,6 +160,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of registers and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..2f4541bd46c8 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 128
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..9eb4e696a51a 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+	reg_info.names = NULL;
+	reg_info.filter = NULL;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"offset_%x", info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index a14ca15f34ce..4b4aa8d2152e 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5066,6 +5066,34 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   If info->filter is not NULL and the driver does not support names or
+ *   filter, return error. If info->filter is NULL, return info for all
+ *   registers (seen as filter none).
+ *   If info->data is NULL, the function fills in the width and length fields.
+ *   If non-NULL, ethdev considers there are enough spaces to store the
+ *   registers, and the values of registers whose name contains the filter
+ *   string are put into the buffer pointed at by the data field. Do the same
+ *   for the names of registers if info->names is not NULL. If drivers do not
+ *   report names, default names are given by ethdev.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 8678b6991eee..2bdafce693c3 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,7 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 2/7] ethdev: add telemetry cmd for registers
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  2024-02-20 10:58   ` [PATCH v3 3/7] net/hns3: fix dump counter of registers Jie Hai
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds a telemetry command for registers dump,
and supports get registers with specified names.
The length of the string exported by telemetry is limited
by MAX_OUTPUT_LEN. Therefore, the filter should be more
precise.

An example usage is shown below:
--> /ethdev/regs,0,INTR
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "HNS3_CMDQ_INTR_STS_REG": "0x0",
      "HNS3_CMDQ_INTR_EN_REG": "0x2",
      "HNS3_CMDQ_INTR_GEN_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

or as below if the number of registers not exceed the
RTE_TEL_MAX_DICT_ENTRIES:
--> /ethdev/regs,0,ppp
{
  "/ethdev/regs": {
    "registers_length": 156,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "ppp_key_drop_num": "0x0",
    "ppp_rlt_drop_num": "0x0",
    "ssu_ppp_mac_key_num_l": "0x1",
    "ssu_ppp_mac_key_num_h": "0x0",
    "ssu_ppp_host_key_num_l": "0x1",
    "ssu_ppp_host_key_num_h": "0x0",
    "ppp_ssu_mac_rlt_num_l": "0x1",
        ...
   }
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 126 ++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..f1ebb2fae632 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -5,6 +5,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_telemetry.h>
 
@@ -1395,6 +1396,129 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES] = {NULL};
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t *data;
+	int ret = 0;
+	uint32_t i;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	data = reg_info->data;
+	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
+		for (i = 0; i < reg_info->length; i++, data++)
+			rte_tel_data_add_dict_uint_hex(d,
+				reg_info->names[i].name, *data, 0);
+		return 0;
+	}
+
+	for (i = 0; i < reg_info->length; i++, data++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
+			if (i != 0)
+				rte_tel_data_add_dict_container(d, group_name,
+								group, 0);
+
+			group = rte_tel_data_alloc();
+			if (group == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			rte_tel_data_start_dict(group);
+			snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
+					"group_%u", grp_num);
+			if (grp_num >= RTE_TEL_MAX_DICT_ENTRIES) {
+				RTE_ETHDEV_LOG_LINE(NOTICE,
+					"Too many regs, please filter");
+				return 0;
+			}
+			groups[grp_num++] = group;
+		}
+		rte_tel_data_add_dict_uint_hex(group, reg_info->names[i].name,
+						*data, 0);
+	}
+	if (i % RTE_TEL_MAX_DICT_ENTRIES != 0)
+		rte_tel_data_add_dict_container(d, group_name, group, 0);
+
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (!reg_info.data)
+		return -ENOMEM;
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (!reg_info.names) {
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter = NULL;
+	uint16_t port_id;
+	char *end_param;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1560,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns regs for a port. Parameters: int port_id, string filter");
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 3/7] net/hns3: fix dump counter of registers
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-20 10:58   ` [PATCH v3 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  2024-02-20 10:58   ` [PATCH v3 4/7] net/hns3: remove dump format " Jie Hai
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")

Signed-off-by: Jie Hai <haijie1@huawei.com>
Cc: stable@dpdk.org
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..d77170481a3d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -135,7 +135,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 4/7] net/hns3: remove dump format of registers
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
                     ` (2 preceding siblings ...)
  2024-02-20 10:58   ` [PATCH v3 3/7] net/hns3: fix dump counter of registers Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  2024-02-20 10:58   ` [PATCH v3 5/7] net/hns3: add names for registers Jie Hai
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 67 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 49 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d77170481a3d..b1c0d538a3c8 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
 					  HNS3_CMDQ_TX_ADDR_H_REG,
@@ -119,23 +116,22 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
+	cmdq_cnt = sizeof(cmdq_reg_addrs);
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
+	ring_cnt = sizeof(ring_reg_addrs);
+	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
+	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -144,18 +140,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -276,18 +270,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -302,7 +284,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -313,7 +294,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -321,7 +301,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -330,7 +309,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -406,17 +384,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -424,11 +400,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -475,7 +448,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -520,7 +492,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
@@ -528,8 +499,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 5/7] net/hns3: add names for registers
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
                     ` (3 preceding siblings ...)
  2024-02-20 10:58   ` [PATCH v3 4/7] net/hns3: remove dump format " Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  2024-02-20 10:58   ` [PATCH v3 6/7] net/hns3: support filter directly accessed registers Jie Hai
  2024-02-20 10:58   ` [PATCH v3 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds names for all registers to be dumped.
For those who can be directly accessed by their addresses,
a new structure containing both name and address is added
and the related arrays is refactored and renamed.

For the remaining modules, there may be different meanings
on different platforms for the same field. Therefore, two
name fields are provided.

There are some 64-bit registers, dump them as two 32-bit
registers.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 877 ++++++++++++++++++++++++++++++++---
 1 file changed, 801 insertions(+), 76 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b1c0d538a3c8..b7e4f78eecde 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,67 +14,84 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct direct_reg_list {
+	const char *name;
+	uint32_t addr;
+};
+
+#define STR(s) #s
+
+static const struct direct_reg_list cmdq_reg_list[] = {
+	{STR(HNS3_CMDQ_TX_ADDR_L_REG),		HNS3_CMDQ_TX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_TX_ADDR_H_REG),		HNS3_CMDQ_TX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_TX_DEPTH_REG),		HNS3_CMDQ_TX_DEPTH_REG},
+	{STR(HNS3_CMDQ_TX_TAIL_REG),		HNS3_CMDQ_TX_TAIL_REG},
+	{STR(HNS3_CMDQ_TX_HEAD_REG),		HNS3_CMDQ_TX_HEAD_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_L_REG),		HNS3_CMDQ_RX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_H_REG),		HNS3_CMDQ_RX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_RX_DEPTH_REG),		HNS3_CMDQ_RX_DEPTH_REG},
+	{STR(HNS3_CMDQ_RX_TAIL_REG),		HNS3_CMDQ_RX_TAIL_REG},
+	{STR(HNS3_CMDQ_RX_HEAD_REG),		HNS3_CMDQ_RX_HEAD_REG},
+	{STR(HNS3_VECTOR0_CMDQ_SRC_REG),	HNS3_VECTOR0_CMDQ_SRC_REG},
+	{STR(HNS3_CMDQ_INTR_STS_REG),		HNS3_CMDQ_INTR_STS_REG},
+	{STR(HNS3_CMDQ_INTR_EN_REG),		HNS3_CMDQ_INTR_EN_REG},
+	{STR(HNS3_CMDQ_INTR_GEN_REG),		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct direct_reg_list common_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_VECTOR0_OTER_EN_REG),		HNS3_VECTOR0_OTER_EN_REG},
+	{STR(HNS3_MISC_RESET_STS_REG),		HNS3_MISC_RESET_STS_REG},
+	{STR(HNS3_VECTOR0_OTHER_INT_STS_REG),	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{STR(HNS3_GLOBAL_RESET_REG),		HNS3_GLOBAL_RESET_REG},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list common_vf_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list ring_reg_list[] = {
+	{STR(HNS3_RING_RX_BASEADDR_L_REG),	HNS3_RING_RX_BASEADDR_L_REG},
+	{STR(HNS3_RING_RX_BASEADDR_H_REG),	HNS3_RING_RX_BASEADDR_H_REG},
+	{STR(HNS3_RING_RX_BD_NUM_REG),		HNS3_RING_RX_BD_NUM_REG},
+	{STR(HNS3_RING_RX_BD_LEN_REG),		HNS3_RING_RX_BD_LEN_REG},
+	{STR(HNS3_RING_RX_EN_REG),		HNS3_RING_RX_EN_REG},
+	{STR(HNS3_RING_RX_MERGE_EN_REG),	HNS3_RING_RX_MERGE_EN_REG},
+	{STR(HNS3_RING_RX_TAIL_REG),		HNS3_RING_RX_TAIL_REG},
+	{STR(HNS3_RING_RX_HEAD_REG),		HNS3_RING_RX_HEAD_REG},
+	{STR(HNS3_RING_RX_FBDNUM_REG),		HNS3_RING_RX_FBDNUM_REG},
+	{STR(HNS3_RING_RX_OFFSET_REG),		HNS3_RING_RX_OFFSET_REG},
+	{STR(HNS3_RING_RX_FBD_OFFSET_REG),	HNS3_RING_RX_FBD_OFFSET_REG},
+	{STR(HNS3_RING_RX_STASH_REG),		HNS3_RING_RX_STASH_REG},
+	{STR(HNS3_RING_RX_BD_ERR_REG),		HNS3_RING_RX_BD_ERR_REG},
+	{STR(HNS3_RING_TX_BASEADDR_L_REG),	HNS3_RING_TX_BASEADDR_L_REG},
+	{STR(HNS3_RING_TX_BASEADDR_H_REG),	HNS3_RING_TX_BASEADDR_H_REG},
+	{STR(HNS3_RING_TX_BD_NUM_REG),		HNS3_RING_TX_BD_NUM_REG},
+	{STR(HNS3_RING_TX_EN_REG),		HNS3_RING_TX_EN_REG},
+	{STR(HNS3_RING_TX_PRIORITY_REG),	HNS3_RING_TX_PRIORITY_REG},
+	{STR(HNS3_RING_TX_TC_REG),		HNS3_RING_TX_TC_REG},
+	{STR(HNS3_RING_TX_MERGE_EN_REG),	HNS3_RING_TX_MERGE_EN_REG},
+	{STR(HNS3_RING_TX_TAIL_REG),		HNS3_RING_TX_TAIL_REG},
+	{STR(HNS3_RING_TX_HEAD_REG),		HNS3_RING_TX_HEAD_REG},
+	{STR(HNS3_RING_TX_FBDNUM_REG),		HNS3_RING_TX_FBDNUM_REG},
+	{STR(HNS3_RING_TX_OFFSET_REG),		HNS3_RING_TX_OFFSET_REG},
+	{STR(HNS3_RING_TX_EBD_NUM_REG),		HNS3_RING_TX_EBD_NUM_REG},
+	{STR(HNS3_RING_TX_EBD_OFFSET_REG),	HNS3_RING_TX_EBD_OFFSET_REG},
+	{STR(HNS3_RING_TX_BD_ERR_REG),		HNS3_RING_TX_BD_ERR_REG},
+	{STR(HNS3_RING_EN_REG),			HNS3_RING_EN_REG},
+};
+
+static const struct direct_reg_list tqp_intr_reg_list[] = {
+	{STR(HNS3_TQP_INTR_CTRL_REG),	HNS3_TQP_INTR_CTRL_REG},
+	{STR(HNS3_TQP_INTR_GL0_REG),	HNS3_TQP_INTR_GL0_REG},
+	{STR(HNS3_TQP_INTR_GL1_REG),	HNS3_TQP_INTR_GL1_REG},
+	{STR(HNS3_TQP_INTR_GL2_REG),	HNS3_TQP_INTR_GL2_REG},
+	{STR(HNS3_TQP_INTR_RL_REG),	HNS3_TQP_INTR_RL_REG},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_BIOS_COMMON_REG,
@@ -91,6 +108,708 @@ static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_SSU_REG_2
 };
 
+struct hns3_reg_entry {
+	const char *new_name;
+	const char *old_name;
+};
+
+static struct hns3_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"ssu_btmp_ageing_st_b0"},
+	{"ssu_btmp_ageing_st_b1"},
+	{"ssu_btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"ssu_lo_pri_unicast_rlt_drop_num"},
+	{"ssu_hi_pri_multicast_rlt_drop_num"},
+
+	{"ssu_lo_pri_multicast_rlt_drop_num"},
+	{"ssu_ncsi_packet_curr_buffer_cnt"},
+	{"dfx_ssu0_rsv5",		"ssu_btmp_ageing_rls_cnt_bank0"},
+	{"dfx_ssu0_rsv6",		"ssu_btmp_ageing_rls_cnt_bank1"},
+	{"dfx_ssu0_rsv7",		"ssu_btmp_ageing_rls_cnt_bank2"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ssu_ncsi_rx_packet_in_cnt_l"},
+	{"ssu_ncsi_rx_packet_in_cnt_h"},
+	{"ssu_ncsi_tx_packet_out_cnt_l"},
+	{"ssu_ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"ssu_mb_uncopy_num"},
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+	{"ssu_bank_unbalance_drop_cnt"},
+	{"ssu_bank_unbalance_rx_drop_cnt"},
+
+	{"ssu_nic_l2_eer_drop_pkt_cnt"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt"},
+	{"ssu_nic_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_rx_oq_glb_drop_pkt_cnt"},
+	{"ssu_dfx_ssu0_rsv8"},
+
+	{"ssu_lo_pri_unicast_cur_cnt"},
+	{"ssu_hi_pri_multicast_cur_cnt"},
+	{"ssu_lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"ssu_packet_tc_curr_buffer_cnt_0"},
+	{"ssu_packet_tc_curr_buffer_cnt_1"},
+	{"ssu_packet_tc_curr_buffer_cnt_2"},
+	{"ssu_packet_tc_curr_buffer_cnt_3"},
+	{"ssu_packet_tc_curr_buffer_cnt_4"},
+
+	{"ssu_packet_tc_curr_buffer_cnt_5"},
+	{"ssu_packet_tc_curr_buffer_cnt_6"},
+	{"ssu_packet_tc_curr_buffer_cnt_7"},
+	{"ssu_packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"ssu_rx_packet_in_cnt_l"},
+	{"ssu_rx_packet_in_cnt_h"},
+	{"ssu_rx_packet_out_cnt_l"},
+	{"ssu_rx_packet_out_cnt_h"},
+	{"ssu_tx_packet_in_cnt_l"},
+	{"ssu_tx_packet_in_cnt_h"},
+
+	{"ssu_tx_packet_out_cnt_l"},
+	{"ssu_tx_packet_out_cnt_h"},
+	{"ssu_roc_rx_packet_in_cnt_l"},
+	{"ssu_roc_rx_packet_in_cnt_h"},
+	{"ssu_roc_tx_packet_in_cnt_l"},
+	{"ssu_roc_tx_packet_in_cnt_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_0_l"},
+	{"ssu_rx_packet_tc_in_cnt_0_h"},
+	{"ssu_rx_packet_tc_in_cnt_1_l"},
+	{"ssu_rx_packet_tc_in_cnt_1_h"},
+	{"ssu_rx_packet_tc_in_cnt_2_l"},
+	{"ssu_rx_packet_tc_in_cnt_2_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_3_l"},
+	{"ssu_rx_packet_tc_in_cnt_3_h"},
+	{"ssu_rx_packet_tc_in_cnt_4_l"},
+	{"ssu_rx_packet_tc_in_cnt_4_h"},
+	{"ssu_rx_packet_tc_in_cnt_5_l"},
+	{"ssu_rx_packet_tc_in_cnt_5_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_6_l"},
+	{"ssu_rx_packet_tc_in_cnt_6_h"},
+	{"ssu_rx_packet_tc_in_cnt_7_l"},
+	{"ssu_rx_packet_tc_in_cnt_7_h"},
+	{"ssu_rx_packet_tc_out_cnt_0_l"},
+	{"ssu_rx_packet_tc_out_cnt_0_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_1_l"},
+	{"ssu_rx_packet_tc_out_cnt_1_h"},
+	{"ssu_rx_packet_tc_out_cnt_2_l"},
+	{"ssu_rx_packet_tc_out_cnt_2_h"},
+	{"ssu_rx_packet_tc_out_cnt_3_l"},
+	{"ssu_rx_packet_tc_out_cnt_3_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_4_l"},
+	{"ssu_rx_packet_tc_out_cnt_4_h"},
+	{"ssu_rx_packet_tc_out_cnt_5_l"},
+	{"ssu_rx_packet_tc_out_cnt_5_h"},
+	{"ssu_rx_packet_tc_out_cnt_6_l"},
+	{"ssu_rx_packet_tc_out_cnt_6_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_7_l"},
+	{"ssu_rx_packet_tc_out_cnt_7_h"},
+	{"ssu_tx_packet_tc_in_cnt_0_l"},
+	{"ssu_tx_packet_tc_in_cnt_0_h"},
+	{"ssu_tx_packet_tc_in_cnt_1_l"},
+	{"ssu_tx_packet_tc_in_cnt_1_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_2_l"},
+	{"ssu_tx_packet_tc_in_cnt_2_h"},
+	{"ssu_tx_packet_tc_in_cnt_3_l"},
+	{"ssu_tx_packet_tc_in_cnt_3_h"},
+	{"ssu_tx_packet_tc_in_cnt_4_l"},
+	{"ssu_tx_packet_tc_in_cnt_4_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_5_l"},
+	{"ssu_tx_packet_tc_in_cnt_5_h"},
+	{"ssu_tx_packet_tc_in_cnt_6_l"},
+	{"ssu_tx_packet_tc_in_cnt_6_h"},
+	{"ssu_tx_packet_tc_in_cnt_7_l"},
+	{"ssu_tx_packet_tc_in_cnt_7_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_0_l"},
+	{"ssu_tx_packet_tc_out_cnt_0_h"},
+	{"ssu_tx_packet_tc_out_cnt_1_l"},
+	{"ssu_tx_packet_tc_out_cnt_1_h"},
+	{"ssu_tx_packet_tc_out_cnt_2_l"},
+	{"ssu_tx_packet_tc_out_cnt_2_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_3_l"},
+	{"ssu_tx_packet_tc_out_cnt_3_h"},
+	{"ssu_tx_packet_tc_out_cnt_4_l"},
+	{"ssu_tx_packet_tc_out_cnt_4_h"},
+	{"ssu_tx_packet_tc_out_cnt_5_l"},
+	{"ssu_tx_packet_tc_out_cnt_5_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_6_l"},
+	{"ssu_tx_packet_tc_out_cnt_6_h"},
+	{"ssu_tx_packet_tc_out_cnt_7_l"},
+	{"ssu_tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_mul_car_drop_pkt_cnt_l",	"igu_egu_rsv0"},
+	{"igu_egu_mul_car_drop_pkt_cnt_h",	"igu_egu_rsv1"},
+	{"igu_egu_bro_car_drop_pkt_cnt_l",	"igu_egu_rsv2"},
+	{"igu_egu_bro_car_drop_pkt_cnt_h",	"igu_egu_rsv3"},
+	{"igu_egu_rsv0",		"igu_egu_rsv4"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_currport_tnl_index",	"rpu_tc_queue_num"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rsv1",		"ppp_rslt_descr_sts"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_snq_hit_cnt_l",	"ppp_um_tbl_vmdq1_hit_cnt_l"},
+	{"ppp_um_tbl_snq_hit_cnt_h",	"ppp_um_tbl_vmdq1_hit_cnt_h"},
+	{"ppp_rsv5",			"ppp_mta_tbl_hit_cnt_l"},
+	{"ppp_rsv6",			"ppp_mta_tbl_hit_cnt_h"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_rsv7",	"ppp_vlan_mirr_cnt_l"},
+	{"ppp_rsv8",	"ppp_vlan_mirr_cnt_h"},
+
+	{"ppp_rsv9",	"ppp_ig_mirr_cnt_l"},
+	{"ppp_rsv10",	"ppp_ig_mirr_cnt_h"},
+	{"ppp_rsv11",	"ppp_eg_mirr_cnt_l"},
+	{"ppp_rsv12",	"ppp_eg_mirr_cnt_h"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_rcb_tx_mem_serr_cnt",	"rcb_axi_rd_fbd_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+struct hns3_dfx_reg_entry {
+	const struct hns3_reg_entry *regs;
+	uint32_t entry_num;
+};
+
+struct hns3_dfx_reg_entry hns3_dfx_reg_list[] = {
+	{dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	{dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	{dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	{dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list)},
+	{dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	{dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	{dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	{dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	{dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	{dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	{dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	{dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+};
+
 static int
 hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 		  uint32_t *regs_num_64_bit)
@@ -108,6 +827,12 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_SIZE !=
+			RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -122,13 +847,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = sizeof(cmdq_reg_addrs);
+	cmdq_cnt = RTE_DIM(cmdq_reg_list);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = sizeof(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
-	ring_cnt = sizeof(ring_reg_addrs);
-	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
+	ring_cnt = RTE_DIM(ring_reg_list);
+	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -281,33 +1006,33 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	size_t i;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(cmdq_reg_list);
 	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_vf_reg_list);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_reg_list);
 	for (i = 0; i < reg_num; i++)
 		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
 		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
 
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
+						ring_reg_list[i].addr + reg_offset);
 	}
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
+			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
 	}
 	return data - origin_data_ptr;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 6/7] net/hns3: support filter directly accessed registers
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
                     ` (4 preceding siblings ...)
  2024-02-20 10:58   ` [PATCH v3 5/7] net/hns3: add names for registers Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  2024-02-20 10:58   ` [PATCH v3 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch supports reporting names of registers which
can be directly accessed by addresses and filtering
them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 198 +++++++++++++++++++++++++++++------
 1 file changed, 167 insertions(+), 31 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b7e4f78eecde..3e3d0326260d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -837,8 +837,24 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static uint32_t
+hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
+			 uint32_t len, char *filter)
+{
+	uint32_t i;
+	uint32_t count = 0;
+
+	for (i = 0 ; i < len; i++) {
+		if (filter != NULL && !strstr(list[i].name, filter))
+			continue;
+		count++;
+	}
+
+	return count;
+}
+
 static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
@@ -847,13 +863,18 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = RTE_DIM(cmdq_reg_list);
+	cmdq_cnt = hns3_get_direct_regs_cnt(cmdq_reg_list,
+					    RTE_DIM(cmdq_reg_list), filter);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_vf_reg_list,
+					RTE_DIM(common_vf_reg_list), filter);
 	else
-		common_cnt = RTE_DIM(common_reg_list);
-	ring_cnt = RTE_DIM(ring_reg_list);
-	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_reg_list,
+					RTE_DIM(common_reg_list), filter);
+	ring_cnt = hns3_get_direct_regs_cnt(ring_reg_list,
+					    RTE_DIM(ring_reg_list), filter);
+	tqp_intr_cnt = hns3_get_direct_regs_cnt(tqp_intr_reg_list,
+					RTE_DIM(tqp_intr_reg_list), filter);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -995,47 +1016,160 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+
+static uint32_t
+hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
+	uint32_t *data = regs->data;
 	size_t reg_num;
-	uint16_t j;
+	data += count;
 	size_t i;
 
-	/* fetching per-PF registers values from PF PCIe register space */
 	reg_num = RTE_DIM(cmdq_reg_list);
-	for (i = 0; i < reg_num; i++)
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(cmdq_reg_list[i].name, regs->filter))
+			continue;
 		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", cmdq_reg_list[i].name);
+	}
 
-	if (hns->is_vf)
-		reg_num = RTE_DIM(common_vf_reg_list);
-	else
-		reg_num = RTE_DIM(common_reg_list);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+	return count;
+}
+static uint32_t
+hns3_direct_access_common_reg(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs,
+			      uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
 
+	reg_num = RTE_DIM(common_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_vf_common_reg(struct hns3_hw *hw,
+				 struct rte_dev_reg_info *regs,
+				 uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
+
+	reg_num = RTE_DIM(common_vf_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_vf_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_vf_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_ring_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_list[i].addr + reg_offset);
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(ring_reg_list[i].name, regs->filter))
+				continue;
+			*data++ = hns3_read_dev(hw, ring_reg_list[i].addr +
+						    reg_offset);
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, ring_reg_list[i].name);
+		}
 	}
 
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(tqp_intr_reg_list[i].name, regs->filter))
+				continue;
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+		}
 	}
-	return data - origin_data_ptr;
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_regs(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs,
+			uint32_t count)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+
+	count = hns3_direct_access_cmdq_reg(hw, regs, count);
+	if (!hns->is_vf)
+		count = hns3_direct_access_common_reg(hw, regs, count);
+	else
+		count = hns3_direct_access_vf_common_reg(hw, regs, count);
+
+	count = hns3_direct_access_ring_reg(hw, regs, count);
+	count = hns3_direct_access_tqp_intr_reg(hw, regs, count);
+
+	return count;
 }
 
 static int
@@ -1177,11 +1311,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
+	uint32_t count = 0;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
+	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
@@ -1193,13 +1328,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	}
 
 	/* Only full register dump is supported */
-	if (regs->length && regs->length != length)
+	if ((regs->length && regs->length != length))
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
+	count = hns3_direct_access_regs(hw, regs, count);
+	data += count;
 
 	if (hns->is_vf)
 		return 0;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v3 7/7] net/hns3: support filter dump of registers
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
                     ` (5 preceding siblings ...)
  2024-02-20 10:58   ` [PATCH v3 6/7] net/hns3: support filter directly accessed registers Jie Hai
@ 2024-02-20 10:58   ` Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch supports reporting names of the dfx registers
which filtering them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 277 +++++++++++++++++++++++++++++------
 1 file changed, 230 insertions(+), 47 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 3e3d0326260d..ae451dc14a2e 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,7 +12,8 @@
 
 #define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw,
+				uint32_t *count, char *filter);
 
 struct direct_reg_list {
 	const char *name;
@@ -853,12 +854,41 @@ hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
 	return count;
 }
 
+static uint32_t
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, char *filter)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+	uint32_t i;
+	uint32_t count = 0;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	for (i = 0 ; i < regs_num_32_bit; i++) {
+		if (filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	for (i = 0 ; i < regs_num_64_bit * HNS3_64_BIT_REG_SIZE; i++) {
+		if (filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	return count;
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
-	uint32_t regs_num_32_bit, regs_num_64_bit;
 	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
@@ -880,16 +910,9 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
+		dfx_reg_cnt = hns3_get_32_64_regs_cnt(hw, filter);
 
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt, filter);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -903,19 +926,19 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, char *filter)
 }
 
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
 	struct hns3_cmd_desc *desc;
 	uint32_t *reg_val = data;
 	uint32_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_32_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
 			       HNS3_32_BIT_REG_RTN_DATANUM);
@@ -959,20 +982,68 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_32_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_32_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_32_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_32_bit_regs_filtered(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_32_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_32_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		rte_free(data);
+		return ret;
+	}
+
+	hns3_filter_32_bit_regs(regs, count, data);
+	return 0;
+}
+
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
 	struct hns3_cmd_desc *desc;
 	uint64_t *reg_val = data;
 	uint64_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_64_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
 			       HNS3_64_BIT_REG_RTN_DATANUM);
@@ -1016,6 +1087,54 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_64_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_64_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_64_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_64_bit_regs_filtered(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret = 0;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_64_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_64_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		goto out;
+	}
+
+	hns3_filter_64_bit_regs(regs, count, data);
+out:
+	rte_free(data);
+	return 0;
+}
 
 static uint32_t
 hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
@@ -1115,7 +1234,7 @@ hns3_direct_access_ring_reg(struct hns3_hw *hw,
 			if (regs->names == NULL)
 				continue;
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, ring_reg_list[i].name);
+				 "queue_%u_%s", j, ring_reg_list[i].name);
 		}
 	}
 
@@ -1146,7 +1265,7 @@ hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
 			if (regs->names == NULL)
 				continue;
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+				 "queue_%u_%s", j, tqp_intr_reg_list[i].name);
 		}
 	}
 
@@ -1248,31 +1367,48 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count, char *filter)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num, data_len, reg_num = 0;
+	const struct hns3_reg_entry *regs;
 	uint32_t bd_num_list[opcode_num];
+	uint32_t i, j;
 	int ret;
-	int i;
 
 	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < (uint32_t)opcode_num; i++) {
+		bd_num = bd_num_list[i];
+		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM;
+		if (data_len != hns3_dfx_reg_list[i].entry_num) {
+			hns3_err(hw, "The number of registers(%u) diff from registers list(%u)!\n",
+				 data_len, hns3_dfx_reg_list[i].entry_num);
+			return -EINVAL;
+		}
 
+		regs = hns3_dfx_reg_list[i].regs;
+		for (j = 0; j < data_len; j++) {
+			if (filter != NULL &&
+				!strstr(regs[j].new_name, filter))
+				continue;
+			reg_num++;
+		}
+	}
+
+	*count += reg_num;
 	return 0;
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, uint32_t *data)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
 	int ret;
 	int i;
 
@@ -1296,32 +1432,87 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+		data += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
+static void
+hns3_filter_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+		     uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data = regs->data;
+	const char *name = NULL;
+	uint32_t i, j, cnt;
+
+	cnt = *count;
+	regs_data += cnt;
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++) {
+		for (j = 0; j < hns3_dfx_reg_list[i].entry_num; j++) {
+			if (hw->revision < PCI_REVISION_ID_HIP09_A &&
+				hns3_dfx_reg_list[i].regs[j].old_name != NULL)
+				name = hns3_dfx_reg_list[i].regs[j].old_name;
+			else
+				name = hns3_dfx_reg_list[i].regs[j].new_name;
+
+			if (regs->filter != NULL && !strstr(name, regs->filter)) {
+				data++;
+				continue;
+			}
+			*regs_data++ = *data++;
+
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[cnt++].name,
+				 RTE_ETH_REG_NAME_SIZE, "%s", name);
+		}
+	}
+	*count = cnt;
+}
+
+static int
+hns3_get_dfx_regs_filtered(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			   uint32_t *count)
+{
+	uint32_t reg_num = 0;
+	uint32_t *data;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++)
+		reg_num += hns3_dfx_reg_list[i].entry_num;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * reg_num, 0);
+	if (data == NULL) {
+		hns3_err(hw, "No memory for dfx regs!\n");
+		return -ENOMEM;
+	}
+	ret = hns3_get_dfx_regs(hw, data);
+	if (ret != 0)
+		goto out;
+
+	hns3_filter_dfx_regs(hw, regs, count, data);
+out:
+	rte_free(data);
+	return ret;
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t count = 0;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -1335,31 +1526,23 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 
 	/* fetching per-PF registers values from PF PCIe register space */
 	count = hns3_direct_access_regs(hw, regs, count);
-	data += count;
 
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
-	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
+	ret = hns3_get_32_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
+	ret = hns3_get_64_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	ret = hns3_get_dfx_regs_filtered(hw, regs, &count);
+	regs->length = count;
+	return 0;
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-20 15:09     ` Stephen Hemminger
  2024-02-26  2:33       ` Jie Hai
  2024-02-20 15:13     ` Stephen Hemminger
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 134+ messages in thread
From: Stephen Hemminger @ 2024-02-20 15:09 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On Tue, 20 Feb 2024 18:58:17 +0800
Jie Hai <haijie1@huawei.com> wrote:

> +* **Added support for dumping regiters with names and filter.**

Spelling

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-20 15:09     ` Stephen Hemminger
@ 2024-02-20 15:13     ` Stephen Hemminger
  2024-02-26  2:41       ` Jie Hai
  2024-02-20 15:14     ` Stephen Hemminger
  2024-02-20 15:14     ` Stephen Hemminger
  3 siblings, 1 reply; 134+ messages in thread
From: Stephen Hemminger @ 2024-02-20 15:13 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On Tue, 20 Feb 2024 18:58:17 +0800
Jie Hai <haijie1@huawei.com> wrote:

> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by names. And the original API
> rte_eth_dev_get_reg_info() does not use the name and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "offset_XXX".
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  doc/guides/rel_notes/release_24_03.rst |  9 +++++++
>  lib/ethdev/rte_dev_info.h              | 11 ++++++++
>  lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev.h                | 28 ++++++++++++++++++++
>  lib/ethdev/version.map                 |  1 +
>  5 files changed, 85 insertions(+)

Could you add support to DPDK ethtool for displaying these?

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-20 15:09     ` Stephen Hemminger
  2024-02-20 15:13     ` Stephen Hemminger
@ 2024-02-20 15:14     ` Stephen Hemminger
  2024-02-26  2:57       ` Jie Hai
  2024-02-20 15:14     ` Stephen Hemminger
  3 siblings, 1 reply; 134+ messages in thread
From: Stephen Hemminger @ 2024-02-20 15:14 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On Tue, 20 Feb 2024 18:58:17 +0800
Jie Hai <haijie1@huawei.com> wrote:

> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };

filter and names should be const, i.e won't get modified by call.

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
                       ` (2 preceding siblings ...)
  2024-02-20 15:14     ` Stephen Hemminger
@ 2024-02-20 15:14     ` Stephen Hemminger
  2024-02-26  2:33       ` Jie Hai
  3 siblings, 1 reply; 134+ messages in thread
From: Stephen Hemminger @ 2024-02-20 15:14 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On Tue, 20 Feb 2024 18:58:17 +0800
Jie Hai <haijie1@huawei.com> wrote:

>  int
>  rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
> +{
> +	struct rte_dev_reg_info reg_info = { 0 };
> +	int ret;
> +
> +	if (info == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Cannot get ethdev port %u register info to NULL",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	reg_info.length = info->length;
> +	reg_info.data = info->data;
> +	reg_info.names = NULL;
> +	reg_info.filter = NULL;

Those NULL assignments are unnecessary, already initialized structure.

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v2 2/7] ethdev: add telemetry cmd for registers
  2024-02-07 17:03     ` Ferruh Yigit
@ 2024-02-22  9:01       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-22  9:01 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui

On 2024/2/8 1:03, Ferruh Yigit wrote:
> On 2/5/2024 10:51 AM, Jie Hai wrote:
>> This patch adds a telemetry command for registers dump,
>> and supports get registers with specified names.
>> The length of the string exported by telemetry is limited
>> by MAX_OUTPUT_LEN. Therefore, the filter should be more
>> precise.
>>
>> An example usage is shown below:
>> --> /ethdev/regs,0,INTR
>> {
>>    "/ethdev/regs": {
>>      "registers_length": 318,
>>      "registers_width": 4,
>>      "register_offset": "0x0",
>>      "version": "0x1140011",
>>      "group_0": {
>>        "HNS3_CMDQ_INTR_STS_REG": "0x0",
>>        "HNS3_CMDQ_INTR_EN_REG": "0x2",
>>        "HNS3_CMDQ_INTR_GEN_REG": "0x0",
>>        "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
>>        "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
>>        "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
>>        "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
>>        ...
>>        },
>>      "group_1": {
>>          ...
>>      },
>>      ...
>> }
>>
> 
> What is the intention of 'RTE_TEL_MAX_DICT_ENTRIES' and grouping above?
> 
For a dict in telemetry, the total num of elements is 
RTE_TEL_MAX_DICT_ENTRIES which is 256.
The number of registers may be greater than that.
One option is to seperate the registers in different groups,
each group can be stored in a dict A and can be an entry of another dict B.
RTE_TEL_MAX_DICT_ENTRIES is used so that B has as less as possible 
elements and to make full use of the memory allocated.

>> or as below if the number of registers not exceed the
>> RTE_TEL_MAX_DICT_ENTRIES:
>> --> /ethdev/regs,0,ppp
>> {
>>    "/ethdev/regs": {
>>      "registers_length": 156,
>>      "registers_width": 4,
>>      "register_offset": "0x0",
>>      "version": "0x1140011",
>>      "ppp_key_drop_num": "0x0",
>>      "ppp_rlt_drop_num": "0x0",
>>      "ssu_ppp_mac_key_num_l": "0x1",
>>      "ssu_ppp_mac_key_num_h": "0x0",
>>      "ssu_ppp_host_key_num_l": "0x1",
>>      "ssu_ppp_host_key_num_h": "0x0",
>>      "ppp_ssu_mac_rlt_num_l": "0x1",
>>          ...
>>     }
>> }
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
> 
> .

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 15:09     ` Stephen Hemminger
@ 2024-02-26  2:33       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  2:33 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On 2024/2/20 23:09, Stephen Hemminger wrote:
> On Tue, 20 Feb 2024 18:58:17 +0800
> Jie Hai <haijie1@huawei.com> wrote:
> 
>> +* **Added support for dumping regiters with names and filter.**
> 
> Spelling
> .
Hi, Stephen,

Thanks for your review.
Will fix in V4.

Best Regards,
Jie Hai


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 15:14     ` Stephen Hemminger
@ 2024-02-26  2:33       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  2:33 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On 2024/2/20 23:14, Stephen Hemminger wrote:
> On Tue, 20 Feb 2024 18:58:17 +0800
> Jie Hai <haijie1@huawei.com> wrote:
> 
>>   int
>>   rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>> +{
>> +	struct rte_dev_reg_info reg_info = { 0 };
>> +	int ret;
>> +
>> +	if (info == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Cannot get ethdev port %u register info to NULL",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	reg_info.length = info->length;
>> +	reg_info.data = info->data;
>> +	reg_info.names = NULL;
>> +	reg_info.filter = NULL;
> 
> Those NULL assignments are unnecessary, already initialized structure.
> .
Hi, Stephen,

Thanks for your review.
Will fix in V4.

Best Regards,
Jie Hai


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 15:13     ` Stephen Hemminger
@ 2024-02-26  2:41       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  2:41 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On 2024/2/20 23:13, Stephen Hemminger wrote:
> On Tue, 20 Feb 2024 18:58:17 +0800
> Jie Hai <haijie1@huawei.com> wrote:
> 
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> The new API rte_eth_dev_get_reg_info_ext() is added to support
>> reporting names and filtering by names. And the original API
>> rte_eth_dev_get_reg_info() does not use the name and filter fields.
>> A local variable is used in rte_eth_dev_get_reg_info for
>> compatibility. If the drivers does not report the names, set them
>> to "offset_XXX".
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   doc/guides/rel_notes/release_24_03.rst |  9 +++++++
>>   lib/ethdev/rte_dev_info.h              | 11 ++++++++
>>   lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
>>   lib/ethdev/rte_ethdev.h                | 28 ++++++++++++++++++++
>>   lib/ethdev/version.map                 |  1 +
>>   5 files changed, 85 insertions(+)
> 
> Could you add support to DPDK ethtool for displaying these?
> .
Hi, Stephen,

Thanks for your review.
The app proc-info and ethtool already support dump registers with
the rte_eth_dev_get_reg_info API. For the use of the new API,
I think it's better to discuss whether to add or replace the
API of the two apps after the API of the new version is applied.

Best Regards,
Jie Hai


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v3 1/7] ethdev: support report register names and filter
  2024-02-20 15:14     ` Stephen Hemminger
@ 2024-02-26  2:57       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  2:57 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

On 2024/2/20 23:14, Stephen Hemminger wrote:
> On Tue, 20 Feb 2024 18:58:17 +0800
> Jie Hai <haijie1@huawei.com> wrote:
> 
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
> 
> filter and names should be const, i.e won't get modified by call.
> .
The "filter" can be a pointer to a const string. It's OK to add const.

The "names" could be modified. The APPs are free to assign space for 
regisger names and  "names" point to the first element.
And the ethdev and drivers are free to modifiy each element.


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 0/7] support dump reigser names and filter them
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (2 preceding siblings ...)
  2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
@ 2024-02-26  3:07 ` Jie Hai
  2024-02-26  3:07   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
                     ` (6 more replies)
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
                   ` (6 subsequent siblings)
  10 siblings, 7 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient
for users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext
is added to support the capability of exporting the name of the
corresponding register and filtering by names.

The hns3 driver and telemetry are examples for that.


--
v4:
1. fix mispellings.
2. add const to 'filter'.
3. remove redundant assigning.

v3:
1. fix mispellings.
2. use snprintf instead of sprintf.
3. add more comment on rte_eth_dev_get_reg_info_ext.
4. add __rte_experimental.
5. add version map.

v2:
1. fix compile error.
2. add new API to support it instead of the old one.
3. split patches on hns3 driver.

Jie Hai (7):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: fix dump counter of registers
  net/hns3: remove dump format of registers
  net/hns3: add names for registers
  net/hns3: support filter directly accessed registers
  net/hns3: support filter dump of registers

 doc/guides/rel_notes/release_24_03.rst |    8 +
 drivers/net/hns3/hns3_regs.c           | 1359 +++++++++++++++++++++---
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   34 +
 lib/ethdev/rte_ethdev.h                |   28 +
 lib/ethdev/rte_ethdev_telemetry.c      |  126 +++
 lib/ethdev/version.map                 |    1 +
 7 files changed, 1394 insertions(+), 173 deletions(-)

-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  2024-02-26  8:01     ` fengchengwen
  2024-02-29  9:52     ` Thomas Monjalon
  2024-02-26  3:07   ` [PATCH v4 2/7] ethdev: add telemetry cmd for registers Jie Hai
                     ` (5 subsequent siblings)
  6 siblings, 2 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by names. And the original API
rte_eth_dev_get_reg_info() does not use the name and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  8 ++++++
 lib/ethdev/rte_dev_info.h              | 11 +++++++++
 lib/ethdev/rte_ethdev.c                | 34 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 28 +++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 5 files changed, 82 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 32d0ad8cf6a7..fa46da427dca 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -132,6 +132,11 @@ New Features
     to support TLS v1.2, TLS v1.3 and DTLS v1.2.
   * Added PMD API to allow raw submission of instructions to CPT.
 
+  * **Added support for dumping registers with names and filter.**
+
+    * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+      the registers by their names and get the information of registers(names,
+      values and other attributes).
 
 Removed Items
 -------------
@@ -197,6 +202,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of registers and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..0ad4a43b9526 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 128
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..9ef50c633ce3 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6408,6 +6437,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"offset_%x", info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index ed27360447a3..09e2d5fdb49b 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5066,6 +5066,34 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   If info->filter is not NULL and the driver does not support names or
+ *   filter, return error. If info->filter is NULL, return info for all
+ *   registers (seen as filter none).
+ *   If info->data is NULL, the function fills in the width and length fields.
+ *   If non-NULL, ethdev considers there are enough spaces to store the
+ *   registers, and the values of registers whose name contains the filter
+ *   string are put into the buffer pointed at by the data field. Do the same
+ *   for the names of registers if info->names is not NULL. If drivers do not
+ *   report names, default names are given by ethdev.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17e4eac8a4cc..c41a64e404db 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,7 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 2/7] ethdev: add telemetry cmd for registers
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
  2024-02-26  3:07   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  2024-02-26  9:09     ` fengchengwen
  2024-02-26  3:07   ` [PATCH v4 3/7] net/hns3: fix dump counter of registers Jie Hai
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds a telemetry command for registers dump,
and supports get registers with specified names.
The length of the string exported by telemetry is limited
by MAX_OUTPUT_LEN. Therefore, the filter should be more
precise.

An example usage is shown below:
--> /ethdev/regs,0,INTR
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "HNS3_CMDQ_INTR_STS_REG": "0x0",
      "HNS3_CMDQ_INTR_EN_REG": "0x2",
      "HNS3_CMDQ_INTR_GEN_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

or as below if the number of registers not exceed the
RTE_TEL_MAX_DICT_ENTRIES:
--> /ethdev/regs,0,ppp
{
  "/ethdev/regs": {
    "registers_length": 156,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "ppp_key_drop_num": "0x0",
    "ppp_rlt_drop_num": "0x0",
    "ssu_ppp_mac_key_num_l": "0x1",
    "ssu_ppp_mac_key_num_h": "0x0",
    "ssu_ppp_host_key_num_l": "0x1",
    "ssu_ppp_host_key_num_h": "0x0",
    "ppp_ssu_mac_rlt_num_l": "0x1",
        ...
   }
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 126 ++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..f1ebb2fae632 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -5,6 +5,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_telemetry.h>
 
@@ -1395,6 +1396,129 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES] = {NULL};
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t *data;
+	int ret = 0;
+	uint32_t i;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	data = reg_info->data;
+	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
+		for (i = 0; i < reg_info->length; i++, data++)
+			rte_tel_data_add_dict_uint_hex(d,
+				reg_info->names[i].name, *data, 0);
+		return 0;
+	}
+
+	for (i = 0; i < reg_info->length; i++, data++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
+			if (i != 0)
+				rte_tel_data_add_dict_container(d, group_name,
+								group, 0);
+
+			group = rte_tel_data_alloc();
+			if (group == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			rte_tel_data_start_dict(group);
+			snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
+					"group_%u", grp_num);
+			if (grp_num >= RTE_TEL_MAX_DICT_ENTRIES) {
+				RTE_ETHDEV_LOG_LINE(NOTICE,
+					"Too many regs, please filter");
+				return 0;
+			}
+			groups[grp_num++] = group;
+		}
+		rte_tel_data_add_dict_uint_hex(group, reg_info->names[i].name,
+						*data, 0);
+	}
+	if (i % RTE_TEL_MAX_DICT_ENTRIES != 0)
+		rte_tel_data_add_dict_container(d, group_name, group, 0);
+
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (!reg_info.data)
+		return -ENOMEM;
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (!reg_info.names) {
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter = NULL;
+	uint16_t port_id;
+	char *end_param;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1560,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns regs for a port. Parameters: int port_id, string filter");
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 3/7] net/hns3: fix dump counter of registers
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
  2024-02-26  3:07   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-26  3:07   ` [PATCH v4 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  2024-02-26  3:07   ` [PATCH v4 4/7] net/hns3: remove dump format " Jie Hai
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")

Signed-off-by: Jie Hai <haijie1@huawei.com>
Cc: stable@dpdk.org
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..d77170481a3d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -135,7 +135,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 4/7] net/hns3: remove dump format of registers
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
                     ` (2 preceding siblings ...)
  2024-02-26  3:07   ` [PATCH v4 3/7] net/hns3: fix dump counter of registers Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  2024-02-26  3:07   ` [PATCH v4 5/7] net/hns3: add names for registers Jie Hai
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 67 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 49 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d77170481a3d..b1c0d538a3c8 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
 					  HNS3_CMDQ_TX_ADDR_H_REG,
@@ -119,23 +116,22 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
+	cmdq_cnt = sizeof(cmdq_reg_addrs);
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
+	ring_cnt = sizeof(ring_reg_addrs);
+	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
+	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -144,18 +140,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -276,18 +270,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -302,7 +284,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -313,7 +294,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -321,7 +301,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -330,7 +309,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -406,17 +384,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -424,11 +400,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -475,7 +448,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -520,7 +492,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
@@ -528,8 +499,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 5/7] net/hns3: add names for registers
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
                     ` (3 preceding siblings ...)
  2024-02-26  3:07   ` [PATCH v4 4/7] net/hns3: remove dump format " Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  2024-02-26  3:07   ` [PATCH v4 6/7] net/hns3: support filter directly accessed registers Jie Hai
  2024-02-26  3:07   ` [PATCH v4 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds names for all registers to be dumped.
For those who can be directly accessed by their addresses,
a new structure containing both name and address is added
and the related arrays is refactored and renamed.

For the remaining modules, there may be different meanings
on different platforms for the same field. Therefore, two
name fields are provided.

There are some 64-bit registers, dump them as two 32-bit
registers.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 877 ++++++++++++++++++++++++++++++++---
 1 file changed, 801 insertions(+), 76 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b1c0d538a3c8..b7e4f78eecde 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,67 +14,84 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct direct_reg_list {
+	const char *name;
+	uint32_t addr;
+};
+
+#define STR(s) #s
+
+static const struct direct_reg_list cmdq_reg_list[] = {
+	{STR(HNS3_CMDQ_TX_ADDR_L_REG),		HNS3_CMDQ_TX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_TX_ADDR_H_REG),		HNS3_CMDQ_TX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_TX_DEPTH_REG),		HNS3_CMDQ_TX_DEPTH_REG},
+	{STR(HNS3_CMDQ_TX_TAIL_REG),		HNS3_CMDQ_TX_TAIL_REG},
+	{STR(HNS3_CMDQ_TX_HEAD_REG),		HNS3_CMDQ_TX_HEAD_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_L_REG),		HNS3_CMDQ_RX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_H_REG),		HNS3_CMDQ_RX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_RX_DEPTH_REG),		HNS3_CMDQ_RX_DEPTH_REG},
+	{STR(HNS3_CMDQ_RX_TAIL_REG),		HNS3_CMDQ_RX_TAIL_REG},
+	{STR(HNS3_CMDQ_RX_HEAD_REG),		HNS3_CMDQ_RX_HEAD_REG},
+	{STR(HNS3_VECTOR0_CMDQ_SRC_REG),	HNS3_VECTOR0_CMDQ_SRC_REG},
+	{STR(HNS3_CMDQ_INTR_STS_REG),		HNS3_CMDQ_INTR_STS_REG},
+	{STR(HNS3_CMDQ_INTR_EN_REG),		HNS3_CMDQ_INTR_EN_REG},
+	{STR(HNS3_CMDQ_INTR_GEN_REG),		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct direct_reg_list common_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_VECTOR0_OTER_EN_REG),		HNS3_VECTOR0_OTER_EN_REG},
+	{STR(HNS3_MISC_RESET_STS_REG),		HNS3_MISC_RESET_STS_REG},
+	{STR(HNS3_VECTOR0_OTHER_INT_STS_REG),	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{STR(HNS3_GLOBAL_RESET_REG),		HNS3_GLOBAL_RESET_REG},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list common_vf_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list ring_reg_list[] = {
+	{STR(HNS3_RING_RX_BASEADDR_L_REG),	HNS3_RING_RX_BASEADDR_L_REG},
+	{STR(HNS3_RING_RX_BASEADDR_H_REG),	HNS3_RING_RX_BASEADDR_H_REG},
+	{STR(HNS3_RING_RX_BD_NUM_REG),		HNS3_RING_RX_BD_NUM_REG},
+	{STR(HNS3_RING_RX_BD_LEN_REG),		HNS3_RING_RX_BD_LEN_REG},
+	{STR(HNS3_RING_RX_EN_REG),		HNS3_RING_RX_EN_REG},
+	{STR(HNS3_RING_RX_MERGE_EN_REG),	HNS3_RING_RX_MERGE_EN_REG},
+	{STR(HNS3_RING_RX_TAIL_REG),		HNS3_RING_RX_TAIL_REG},
+	{STR(HNS3_RING_RX_HEAD_REG),		HNS3_RING_RX_HEAD_REG},
+	{STR(HNS3_RING_RX_FBDNUM_REG),		HNS3_RING_RX_FBDNUM_REG},
+	{STR(HNS3_RING_RX_OFFSET_REG),		HNS3_RING_RX_OFFSET_REG},
+	{STR(HNS3_RING_RX_FBD_OFFSET_REG),	HNS3_RING_RX_FBD_OFFSET_REG},
+	{STR(HNS3_RING_RX_STASH_REG),		HNS3_RING_RX_STASH_REG},
+	{STR(HNS3_RING_RX_BD_ERR_REG),		HNS3_RING_RX_BD_ERR_REG},
+	{STR(HNS3_RING_TX_BASEADDR_L_REG),	HNS3_RING_TX_BASEADDR_L_REG},
+	{STR(HNS3_RING_TX_BASEADDR_H_REG),	HNS3_RING_TX_BASEADDR_H_REG},
+	{STR(HNS3_RING_TX_BD_NUM_REG),		HNS3_RING_TX_BD_NUM_REG},
+	{STR(HNS3_RING_TX_EN_REG),		HNS3_RING_TX_EN_REG},
+	{STR(HNS3_RING_TX_PRIORITY_REG),	HNS3_RING_TX_PRIORITY_REG},
+	{STR(HNS3_RING_TX_TC_REG),		HNS3_RING_TX_TC_REG},
+	{STR(HNS3_RING_TX_MERGE_EN_REG),	HNS3_RING_TX_MERGE_EN_REG},
+	{STR(HNS3_RING_TX_TAIL_REG),		HNS3_RING_TX_TAIL_REG},
+	{STR(HNS3_RING_TX_HEAD_REG),		HNS3_RING_TX_HEAD_REG},
+	{STR(HNS3_RING_TX_FBDNUM_REG),		HNS3_RING_TX_FBDNUM_REG},
+	{STR(HNS3_RING_TX_OFFSET_REG),		HNS3_RING_TX_OFFSET_REG},
+	{STR(HNS3_RING_TX_EBD_NUM_REG),		HNS3_RING_TX_EBD_NUM_REG},
+	{STR(HNS3_RING_TX_EBD_OFFSET_REG),	HNS3_RING_TX_EBD_OFFSET_REG},
+	{STR(HNS3_RING_TX_BD_ERR_REG),		HNS3_RING_TX_BD_ERR_REG},
+	{STR(HNS3_RING_EN_REG),			HNS3_RING_EN_REG},
+};
+
+static const struct direct_reg_list tqp_intr_reg_list[] = {
+	{STR(HNS3_TQP_INTR_CTRL_REG),	HNS3_TQP_INTR_CTRL_REG},
+	{STR(HNS3_TQP_INTR_GL0_REG),	HNS3_TQP_INTR_GL0_REG},
+	{STR(HNS3_TQP_INTR_GL1_REG),	HNS3_TQP_INTR_GL1_REG},
+	{STR(HNS3_TQP_INTR_GL2_REG),	HNS3_TQP_INTR_GL2_REG},
+	{STR(HNS3_TQP_INTR_RL_REG),	HNS3_TQP_INTR_RL_REG},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_BIOS_COMMON_REG,
@@ -91,6 +108,708 @@ static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_SSU_REG_2
 };
 
+struct hns3_reg_entry {
+	const char *new_name;
+	const char *old_name;
+};
+
+static struct hns3_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"ssu_btmp_ageing_st_b0"},
+	{"ssu_btmp_ageing_st_b1"},
+	{"ssu_btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"ssu_lo_pri_unicast_rlt_drop_num"},
+	{"ssu_hi_pri_multicast_rlt_drop_num"},
+
+	{"ssu_lo_pri_multicast_rlt_drop_num"},
+	{"ssu_ncsi_packet_curr_buffer_cnt"},
+	{"dfx_ssu0_rsv5",		"ssu_btmp_ageing_rls_cnt_bank0"},
+	{"dfx_ssu0_rsv6",		"ssu_btmp_ageing_rls_cnt_bank1"},
+	{"dfx_ssu0_rsv7",		"ssu_btmp_ageing_rls_cnt_bank2"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ssu_ncsi_rx_packet_in_cnt_l"},
+	{"ssu_ncsi_rx_packet_in_cnt_h"},
+	{"ssu_ncsi_tx_packet_out_cnt_l"},
+	{"ssu_ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"ssu_mb_uncopy_num"},
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+	{"ssu_bank_unbalance_drop_cnt"},
+	{"ssu_bank_unbalance_rx_drop_cnt"},
+
+	{"ssu_nic_l2_eer_drop_pkt_cnt"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt"},
+	{"ssu_nic_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_rx_oq_glb_drop_pkt_cnt"},
+	{"ssu_dfx_ssu0_rsv8"},
+
+	{"ssu_lo_pri_unicast_cur_cnt"},
+	{"ssu_hi_pri_multicast_cur_cnt"},
+	{"ssu_lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"ssu_packet_tc_curr_buffer_cnt_0"},
+	{"ssu_packet_tc_curr_buffer_cnt_1"},
+	{"ssu_packet_tc_curr_buffer_cnt_2"},
+	{"ssu_packet_tc_curr_buffer_cnt_3"},
+	{"ssu_packet_tc_curr_buffer_cnt_4"},
+
+	{"ssu_packet_tc_curr_buffer_cnt_5"},
+	{"ssu_packet_tc_curr_buffer_cnt_6"},
+	{"ssu_packet_tc_curr_buffer_cnt_7"},
+	{"ssu_packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"ssu_rx_packet_in_cnt_l"},
+	{"ssu_rx_packet_in_cnt_h"},
+	{"ssu_rx_packet_out_cnt_l"},
+	{"ssu_rx_packet_out_cnt_h"},
+	{"ssu_tx_packet_in_cnt_l"},
+	{"ssu_tx_packet_in_cnt_h"},
+
+	{"ssu_tx_packet_out_cnt_l"},
+	{"ssu_tx_packet_out_cnt_h"},
+	{"ssu_roc_rx_packet_in_cnt_l"},
+	{"ssu_roc_rx_packet_in_cnt_h"},
+	{"ssu_roc_tx_packet_in_cnt_l"},
+	{"ssu_roc_tx_packet_in_cnt_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_0_l"},
+	{"ssu_rx_packet_tc_in_cnt_0_h"},
+	{"ssu_rx_packet_tc_in_cnt_1_l"},
+	{"ssu_rx_packet_tc_in_cnt_1_h"},
+	{"ssu_rx_packet_tc_in_cnt_2_l"},
+	{"ssu_rx_packet_tc_in_cnt_2_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_3_l"},
+	{"ssu_rx_packet_tc_in_cnt_3_h"},
+	{"ssu_rx_packet_tc_in_cnt_4_l"},
+	{"ssu_rx_packet_tc_in_cnt_4_h"},
+	{"ssu_rx_packet_tc_in_cnt_5_l"},
+	{"ssu_rx_packet_tc_in_cnt_5_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_6_l"},
+	{"ssu_rx_packet_tc_in_cnt_6_h"},
+	{"ssu_rx_packet_tc_in_cnt_7_l"},
+	{"ssu_rx_packet_tc_in_cnt_7_h"},
+	{"ssu_rx_packet_tc_out_cnt_0_l"},
+	{"ssu_rx_packet_tc_out_cnt_0_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_1_l"},
+	{"ssu_rx_packet_tc_out_cnt_1_h"},
+	{"ssu_rx_packet_tc_out_cnt_2_l"},
+	{"ssu_rx_packet_tc_out_cnt_2_h"},
+	{"ssu_rx_packet_tc_out_cnt_3_l"},
+	{"ssu_rx_packet_tc_out_cnt_3_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_4_l"},
+	{"ssu_rx_packet_tc_out_cnt_4_h"},
+	{"ssu_rx_packet_tc_out_cnt_5_l"},
+	{"ssu_rx_packet_tc_out_cnt_5_h"},
+	{"ssu_rx_packet_tc_out_cnt_6_l"},
+	{"ssu_rx_packet_tc_out_cnt_6_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_7_l"},
+	{"ssu_rx_packet_tc_out_cnt_7_h"},
+	{"ssu_tx_packet_tc_in_cnt_0_l"},
+	{"ssu_tx_packet_tc_in_cnt_0_h"},
+	{"ssu_tx_packet_tc_in_cnt_1_l"},
+	{"ssu_tx_packet_tc_in_cnt_1_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_2_l"},
+	{"ssu_tx_packet_tc_in_cnt_2_h"},
+	{"ssu_tx_packet_tc_in_cnt_3_l"},
+	{"ssu_tx_packet_tc_in_cnt_3_h"},
+	{"ssu_tx_packet_tc_in_cnt_4_l"},
+	{"ssu_tx_packet_tc_in_cnt_4_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_5_l"},
+	{"ssu_tx_packet_tc_in_cnt_5_h"},
+	{"ssu_tx_packet_tc_in_cnt_6_l"},
+	{"ssu_tx_packet_tc_in_cnt_6_h"},
+	{"ssu_tx_packet_tc_in_cnt_7_l"},
+	{"ssu_tx_packet_tc_in_cnt_7_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_0_l"},
+	{"ssu_tx_packet_tc_out_cnt_0_h"},
+	{"ssu_tx_packet_tc_out_cnt_1_l"},
+	{"ssu_tx_packet_tc_out_cnt_1_h"},
+	{"ssu_tx_packet_tc_out_cnt_2_l"},
+	{"ssu_tx_packet_tc_out_cnt_2_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_3_l"},
+	{"ssu_tx_packet_tc_out_cnt_3_h"},
+	{"ssu_tx_packet_tc_out_cnt_4_l"},
+	{"ssu_tx_packet_tc_out_cnt_4_h"},
+	{"ssu_tx_packet_tc_out_cnt_5_l"},
+	{"ssu_tx_packet_tc_out_cnt_5_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_6_l"},
+	{"ssu_tx_packet_tc_out_cnt_6_h"},
+	{"ssu_tx_packet_tc_out_cnt_7_l"},
+	{"ssu_tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_mul_car_drop_pkt_cnt_l",	"igu_egu_rsv0"},
+	{"igu_egu_mul_car_drop_pkt_cnt_h",	"igu_egu_rsv1"},
+	{"igu_egu_bro_car_drop_pkt_cnt_l",	"igu_egu_rsv2"},
+	{"igu_egu_bro_car_drop_pkt_cnt_h",	"igu_egu_rsv3"},
+	{"igu_egu_rsv0",		"igu_egu_rsv4"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_currport_tnl_index",	"rpu_tc_queue_num"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rsv1",		"ppp_rslt_descr_sts"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_snq_hit_cnt_l",	"ppp_um_tbl_vmdq1_hit_cnt_l"},
+	{"ppp_um_tbl_snq_hit_cnt_h",	"ppp_um_tbl_vmdq1_hit_cnt_h"},
+	{"ppp_rsv5",			"ppp_mta_tbl_hit_cnt_l"},
+	{"ppp_rsv6",			"ppp_mta_tbl_hit_cnt_h"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_rsv7",	"ppp_vlan_mirr_cnt_l"},
+	{"ppp_rsv8",	"ppp_vlan_mirr_cnt_h"},
+
+	{"ppp_rsv9",	"ppp_ig_mirr_cnt_l"},
+	{"ppp_rsv10",	"ppp_ig_mirr_cnt_h"},
+	{"ppp_rsv11",	"ppp_eg_mirr_cnt_l"},
+	{"ppp_rsv12",	"ppp_eg_mirr_cnt_h"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_rcb_tx_mem_serr_cnt",	"rcb_axi_rd_fbd_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+struct hns3_dfx_reg_entry {
+	const struct hns3_reg_entry *regs;
+	uint32_t entry_num;
+};
+
+struct hns3_dfx_reg_entry hns3_dfx_reg_list[] = {
+	{dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	{dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	{dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	{dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list)},
+	{dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	{dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	{dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	{dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	{dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	{dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	{dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	{dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+};
+
 static int
 hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 		  uint32_t *regs_num_64_bit)
@@ -108,6 +827,12 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_SIZE !=
+			RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -122,13 +847,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = sizeof(cmdq_reg_addrs);
+	cmdq_cnt = RTE_DIM(cmdq_reg_list);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = sizeof(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
-	ring_cnt = sizeof(ring_reg_addrs);
-	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
+	ring_cnt = RTE_DIM(ring_reg_list);
+	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -281,33 +1006,33 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	size_t i;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(cmdq_reg_list);
 	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_vf_reg_list);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_reg_list);
 	for (i = 0; i < reg_num; i++)
 		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
 		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
 
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
+						ring_reg_list[i].addr + reg_offset);
 	}
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
+			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
 	}
 	return data - origin_data_ptr;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 6/7] net/hns3: support filter directly accessed registers
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
                     ` (4 preceding siblings ...)
  2024-02-26  3:07   ` [PATCH v4 5/7] net/hns3: add names for registers Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  2024-02-26  3:07   ` [PATCH v4 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch supports reporting names of registers which
can be directly accessed by addresses and filtering
them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 198 +++++++++++++++++++++++++++++------
 1 file changed, 167 insertions(+), 31 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b7e4f78eecde..7c3bd162f067 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -837,8 +837,24 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static uint32_t
+hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
+			 uint32_t len, const char *filter)
+{
+	uint32_t i;
+	uint32_t count = 0;
+
+	for (i = 0 ; i < len; i++) {
+		if (filter != NULL && !strstr(list[i].name, filter))
+			continue;
+		count++;
+	}
+
+	return count;
+}
+
 static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
@@ -847,13 +863,18 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = RTE_DIM(cmdq_reg_list);
+	cmdq_cnt = hns3_get_direct_regs_cnt(cmdq_reg_list,
+					    RTE_DIM(cmdq_reg_list), filter);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_vf_reg_list,
+					RTE_DIM(common_vf_reg_list), filter);
 	else
-		common_cnt = RTE_DIM(common_reg_list);
-	ring_cnt = RTE_DIM(ring_reg_list);
-	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_reg_list,
+					RTE_DIM(common_reg_list), filter);
+	ring_cnt = hns3_get_direct_regs_cnt(ring_reg_list,
+					    RTE_DIM(ring_reg_list), filter);
+	tqp_intr_cnt = hns3_get_direct_regs_cnt(tqp_intr_reg_list,
+					RTE_DIM(tqp_intr_reg_list), filter);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -995,47 +1016,160 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+
+static uint32_t
+hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
+	uint32_t *data = regs->data;
 	size_t reg_num;
-	uint16_t j;
+	data += count;
 	size_t i;
 
-	/* fetching per-PF registers values from PF PCIe register space */
 	reg_num = RTE_DIM(cmdq_reg_list);
-	for (i = 0; i < reg_num; i++)
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(cmdq_reg_list[i].name, regs->filter))
+			continue;
 		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", cmdq_reg_list[i].name);
+	}
 
-	if (hns->is_vf)
-		reg_num = RTE_DIM(common_vf_reg_list);
-	else
-		reg_num = RTE_DIM(common_reg_list);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+	return count;
+}
+static uint32_t
+hns3_direct_access_common_reg(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs,
+			      uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
 
+	reg_num = RTE_DIM(common_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_vf_common_reg(struct hns3_hw *hw,
+				 struct rte_dev_reg_info *regs,
+				 uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
+
+	reg_num = RTE_DIM(common_vf_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_vf_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_vf_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_ring_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_list[i].addr + reg_offset);
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(ring_reg_list[i].name, regs->filter))
+				continue;
+			*data++ = hns3_read_dev(hw, ring_reg_list[i].addr +
+						    reg_offset);
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, ring_reg_list[i].name);
+		}
 	}
 
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(tqp_intr_reg_list[i].name, regs->filter))
+				continue;
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+		}
 	}
-	return data - origin_data_ptr;
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_regs(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs,
+			uint32_t count)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+
+	count = hns3_direct_access_cmdq_reg(hw, regs, count);
+	if (!hns->is_vf)
+		count = hns3_direct_access_common_reg(hw, regs, count);
+	else
+		count = hns3_direct_access_vf_common_reg(hw, regs, count);
+
+	count = hns3_direct_access_ring_reg(hw, regs, count);
+	count = hns3_direct_access_tqp_intr_reg(hw, regs, count);
+
+	return count;
 }
 
 static int
@@ -1177,11 +1311,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
+	uint32_t count = 0;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
+	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
@@ -1193,13 +1328,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	}
 
 	/* Only full register dump is supported */
-	if (regs->length && regs->length != length)
+	if ((regs->length && regs->length != length))
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
+	count = hns3_direct_access_regs(hw, regs, count);
+	data += count;
 
 	if (hns->is_vf)
 		return 0;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v4 7/7] net/hns3: support filter dump of registers
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
                     ` (5 preceding siblings ...)
  2024-02-26  3:07   ` [PATCH v4 6/7] net/hns3: support filter directly accessed registers Jie Hai
@ 2024-02-26  3:07   ` Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch supports reporting names of the dfx registers
which filtering them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 277 +++++++++++++++++++++++++++++------
 1 file changed, 230 insertions(+), 47 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 7c3bd162f067..8b6bf0a513fa 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,7 +12,8 @@
 
 #define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw,
+				uint32_t *count, const char *filter);
 
 struct direct_reg_list {
 	const char *name;
@@ -853,12 +854,41 @@ hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
 	return count;
 }
 
+static uint32_t
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, const char *filter)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+	uint32_t i;
+	uint32_t count = 0;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	for (i = 0 ; i < regs_num_32_bit; i++) {
+		if (filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	for (i = 0 ; i < regs_num_64_bit * HNS3_64_BIT_REG_SIZE; i++) {
+		if (filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	return count;
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
-	uint32_t regs_num_32_bit, regs_num_64_bit;
 	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
@@ -880,16 +910,9 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
+		dfx_reg_cnt = hns3_get_32_64_regs_cnt(hw, filter);
 
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt, filter);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -903,19 +926,19 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 }
 
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
 	struct hns3_cmd_desc *desc;
 	uint32_t *reg_val = data;
 	uint32_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_32_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
 			       HNS3_32_BIT_REG_RTN_DATANUM);
@@ -959,20 +982,68 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_32_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_32_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_32_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_32_bit_regs_filtered(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_32_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_32_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		rte_free(data);
+		return ret;
+	}
+
+	hns3_filter_32_bit_regs(regs, count, data);
+	return 0;
+}
+
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
 	struct hns3_cmd_desc *desc;
 	uint64_t *reg_val = data;
 	uint64_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_64_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
 			       HNS3_64_BIT_REG_RTN_DATANUM);
@@ -1016,6 +1087,54 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_64_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_64_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_64_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_64_bit_regs_filtered(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret = 0;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_64_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_64_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		goto out;
+	}
+
+	hns3_filter_64_bit_regs(regs, count, data);
+out:
+	rte_free(data);
+	return 0;
+}
 
 static uint32_t
 hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
@@ -1115,7 +1234,7 @@ hns3_direct_access_ring_reg(struct hns3_hw *hw,
 			if (regs->names == NULL)
 				continue;
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, ring_reg_list[i].name);
+				 "queue_%u_%s", j, ring_reg_list[i].name);
 		}
 	}
 
@@ -1146,7 +1265,7 @@ hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
 			if (regs->names == NULL)
 				continue;
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+				 "queue_%u_%s", j, tqp_intr_reg_list[i].name);
 		}
 	}
 
@@ -1248,31 +1367,48 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count, const char *filter)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num, data_len, reg_num = 0;
+	const struct hns3_reg_entry *regs;
 	uint32_t bd_num_list[opcode_num];
+	uint32_t i, j;
 	int ret;
-	int i;
 
 	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < (uint32_t)opcode_num; i++) {
+		bd_num = bd_num_list[i];
+		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM;
+		if (data_len != hns3_dfx_reg_list[i].entry_num) {
+			hns3_err(hw, "The number of registers(%u) diff from registers list(%u)!\n",
+				 data_len, hns3_dfx_reg_list[i].entry_num);
+			return -EINVAL;
+		}
 
+		regs = hns3_dfx_reg_list[i].regs;
+		for (j = 0; j < data_len; j++) {
+			if (filter != NULL &&
+				!strstr(regs[j].new_name, filter))
+				continue;
+			reg_num++;
+		}
+	}
+
+	*count += reg_num;
 	return 0;
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, uint32_t *data)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
 	int ret;
 	int i;
 
@@ -1296,32 +1432,87 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+		data += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
+static void
+hns3_filter_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+		     uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data = regs->data;
+	const char *name = NULL;
+	uint32_t i, j, cnt;
+
+	cnt = *count;
+	regs_data += cnt;
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++) {
+		for (j = 0; j < hns3_dfx_reg_list[i].entry_num; j++) {
+			if (hw->revision < PCI_REVISION_ID_HIP09_A &&
+				hns3_dfx_reg_list[i].regs[j].old_name != NULL)
+				name = hns3_dfx_reg_list[i].regs[j].old_name;
+			else
+				name = hns3_dfx_reg_list[i].regs[j].new_name;
+
+			if (regs->filter != NULL && !strstr(name, regs->filter)) {
+				data++;
+				continue;
+			}
+			*regs_data++ = *data++;
+
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[cnt++].name,
+				 RTE_ETH_REG_NAME_SIZE, "%s", name);
+		}
+	}
+	*count = cnt;
+}
+
+static int
+hns3_get_dfx_regs_filtered(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			   uint32_t *count)
+{
+	uint32_t reg_num = 0;
+	uint32_t *data;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++)
+		reg_num += hns3_dfx_reg_list[i].entry_num;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * reg_num, 0);
+	if (data == NULL) {
+		hns3_err(hw, "No memory for dfx regs!\n");
+		return -ENOMEM;
+	}
+	ret = hns3_get_dfx_regs(hw, data);
+	if (ret != 0)
+		goto out;
+
+	hns3_filter_dfx_regs(hw, regs, count, data);
+out:
+	rte_free(data);
+	return ret;
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t count = 0;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -1335,31 +1526,23 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 
 	/* fetching per-PF registers values from PF PCIe register space */
 	count = hns3_direct_access_regs(hw, regs, count);
-	data += count;
 
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
-	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
+	ret = hns3_get_32_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
+	ret = hns3_get_64_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	ret = hns3_get_dfx_regs_filtered(hw, regs, &count);
+	regs->length = count;
+	return 0;
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  3:07   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-26  8:01     ` fengchengwen
  2024-03-06  7:22       ` Jie Hai
  2024-02-29  9:52     ` Thomas Monjalon
  1 sibling, 1 reply; 134+ messages in thread
From: fengchengwen @ 2024-02-26  8:01 UTC (permalink / raw)
  To: Jie Hai, dev; +Cc: lihuisong, liuyonglong, huangdengdui, ferruh.yigit

Hi Jie,

On 2024/2/26 11:07, Jie Hai wrote:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by names. And the original API
> rte_eth_dev_get_reg_info() does not use the name and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "offset_XXX".
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>  lib/ethdev/rte_dev_info.h              | 11 +++++++++
>  lib/ethdev/rte_ethdev.c                | 34 ++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev.h                | 28 +++++++++++++++++++++
>  lib/ethdev/version.map                 |  1 +
>  5 files changed, 82 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index 32d0ad8cf6a7..fa46da427dca 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -132,6 +132,11 @@ New Features
>      to support TLS v1.2, TLS v1.3 and DTLS v1.2.
>    * Added PMD API to allow raw submission of instructions to CPT.
>  
> +  * **Added support for dumping registers with names and filter.**
> +
> +    * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
> +      the registers by their names and get the information of registers(names,
> +      values and other attributes).
>  
>  Removed Items
>  -------------
> @@ -197,6 +202,9 @@ ABI Changes
>  
>  * No ABI change that would break compatibility with 23.11.
>  
> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
> +  structure for reporting names of registers and filtering them by names.
> +
>  
>  Known Issues
>  ------------
> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
> index 67cf0ae52668..0ad4a43b9526 100644
> --- a/lib/ethdev/rte_dev_info.h
> +++ b/lib/ethdev/rte_dev_info.h
> @@ -11,6 +11,11 @@ extern "C" {
>  
>  #include <stdint.h>
>  
> +#define RTE_ETH_REG_NAME_SIZE 128

Almost all stats name size is 64, why not keep consistent?

> +struct rte_eth_reg_name {
> +	char name[RTE_ETH_REG_NAME_SIZE];
> +};
> +
>  /*
>   * Placeholder for accessing device registers
>   */
> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	const char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };
>  
>  /*
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index f1c658f49e80..9ef50c633ce3 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>  
>  int
>  rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
> +{
> +	struct rte_dev_reg_info reg_info = { 0 };
> +	int ret;
> +
> +	if (info == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Cannot get ethdev port %u register info to NULL",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	reg_info.length = info->length;
> +	reg_info.data = info->data;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0)
> +		return ret;
> +
> +	info->length = reg_info.length;
> +	info->width = reg_info.width;
> +	info->version = reg_info.version;
> +	info->offset = reg_info.offset;
> +
> +	return 0;
> +}
> +
> +int
> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>  {
>  	struct rte_eth_dev *dev;
> +	uint32_t i;
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -6408,6 +6437,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>  
>  	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>  
> +	/* Report the default names if drivers not report. */
> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
> +		for (i = 0; i < info->length; i++)
> +			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
> +				"offset_%x", info->offset + i * info->width);

%x has no prefix "0x", may lead to confused.
How about use %u ?

Another question, if app don't zero names' memory, then its value is random, so it will not enter this logic.
Suggest memset item[0]'s name memory before invoke PMD ops.

>  	return ret;
>  }
>  
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index ed27360447a3..09e2d5fdb49b 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5066,6 +5066,34 @@ __rte_experimental
>  int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>  		struct rte_power_monitor_cond *pmc);
>  
> +/**
> + * Retrieve the filtered device registers (values and names) and
> + * register attributes (number of registers and register size)
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param info
> + *   Pointer to rte_dev_reg_info structure to fill in.
> + *   If info->filter is not NULL and the driver does not support names or
> + *   filter, return error. If info->filter is NULL, return info for all
> + *   registers (seen as filter none).
> + *   If info->data is NULL, the function fills in the width and length fields.
> + *   If non-NULL, ethdev considers there are enough spaces to store the
> + *   registers, and the values of registers whose name contains the filter
> + *   string are put into the buffer pointed at by the data field. Do the same
> + *   for the names of registers if info->names is not NULL. If drivers do not
> + *   report names, default names are given by ethdev.

It's a little hard to understand. Suggest use '-' for each field, just like rte_eth_remove_tx_callback

> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EIO) if device is removed.
> + *   - others depends on the specific operations implementation.
> + */
> +__rte_experimental
> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
> +
>  /**
>   * Retrieve device registers and register attributes (number of registers and
>   * register size)
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index 17e4eac8a4cc..c41a64e404db 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -325,6 +325,7 @@ EXPERIMENTAL {
>  	rte_flow_template_table_resizable;
>  	rte_flow_template_table_resize;
>  	rte_flow_template_table_resize_complete;
> +	rte_eth_dev_get_reg_info_ext;

should place with alphabetical order.

Thanks

>  };
>  
>  INTERNAL {
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v4 2/7] ethdev: add telemetry cmd for registers
  2024-02-26  3:07   ` [PATCH v4 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-02-26  9:09     ` fengchengwen
  2024-03-06  7:18       ` Jie Hai
  0 siblings, 1 reply; 134+ messages in thread
From: fengchengwen @ 2024-02-26  9:09 UTC (permalink / raw)
  To: Jie Hai, dev; +Cc: lihuisong, liuyonglong, huangdengdui, ferruh.yigit

Hi Jie,

On 2024/2/26 11:07, Jie Hai wrote:
> This patch adds a telemetry command for registers dump,
> and supports get registers with specified names.
> The length of the string exported by telemetry is limited
> by MAX_OUTPUT_LEN. Therefore, the filter should be more
> precise.
> 
> An example usage is shown below:
> --> /ethdev/regs,0,INTR
> {
>   "/ethdev/regs": {
>     "registers_length": 318,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "group_0": {
>       "HNS3_CMDQ_INTR_STS_REG": "0x0",
>       "HNS3_CMDQ_INTR_EN_REG": "0x2",
>       "HNS3_CMDQ_INTR_GEN_REG": "0x0",
>       "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
>       "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
>       "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
>       "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
>       ...
>       },
>     "group_1": {
>         ...
>     },
>     ...
> }
> 
> or as below if the number of registers not exceed the
> RTE_TEL_MAX_DICT_ENTRIES:
> --> /ethdev/regs,0,ppp
> {
>   "/ethdev/regs": {
>     "registers_length": 156,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "ppp_key_drop_num": "0x0",
>     "ppp_rlt_drop_num": "0x0",
>     "ssu_ppp_mac_key_num_l": "0x1",
>     "ssu_ppp_mac_key_num_h": "0x0",
>     "ssu_ppp_host_key_num_l": "0x1",
>     "ssu_ppp_host_key_num_h": "0x0",
>     "ppp_ssu_mac_rlt_num_l": "0x1",
>         ...
>    }
> }
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  lib/ethdev/rte_ethdev_telemetry.c | 126 ++++++++++++++++++++++++++++++
>  1 file changed, 126 insertions(+)
> 
> diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
> index 6b873e7abe68..f1ebb2fae632 100644
> --- a/lib/ethdev/rte_ethdev_telemetry.c
> +++ b/lib/ethdev/rte_ethdev_telemetry.c
> @@ -5,6 +5,7 @@
>  #include <ctype.h>
>  #include <stdlib.h>
>  
> +#include <rte_malloc.h>
>  #include <rte_kvargs.h>
>  #include <rte_telemetry.h>
>  
> @@ -1395,6 +1396,129 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
>  	return ret;
>  }
>  
> +static int
> +eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
> +{
> +	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES] = {NULL};

no need zero.

> +	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
> +	struct rte_tel_data *group = NULL;
> +	uint32_t grp_num = 0;
> +	uint32_t *data;
> +	int ret = 0;
> +	uint32_t i;
> +
> +	rte_tel_data_start_dict(d);
> +	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
> +	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
> +	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
> +	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
> +
> +	data = reg_info->data;
> +	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
> +		for (i = 0; i < reg_info->length; i++, data++)
> +			rte_tel_data_add_dict_uint_hex(d,
> +				reg_info->names[i].name, *data, 0);

The above format is OK for reg_info->width==4.
There maybe reg_info->width == 8, pls support it.

> +		return 0;
> +	}
> +
> +	for (i = 0; i < reg_info->length; i++, data++) {
> +		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
> +			if (i != 0)
> +				rte_tel_data_add_dict_container(d, group_name,
> +								group, 0);
> +
> +			group = rte_tel_data_alloc();
> +			if (group == NULL) {
> +				ret = -ENOMEM;
> +				goto out;
> +			}
> +			rte_tel_data_start_dict(group);
> +			snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
> +					"group_%u", grp_num);

grp_num + 1 ?

> +			if (grp_num >= RTE_TEL_MAX_DICT_ENTRIES) {
> +				RTE_ETHDEV_LOG_LINE(NOTICE,
> +					"Too many regs, please filter");

how about add more descrip: stop format!

> +				return 0;

this group's memory was leak.

How about move the extream case before for loop:

uint32_t length = reg_info->lenght;
if (length > RTE_TEL_MAX_DICT_ENTRIES * RTE_TEL_MAX_DICT_ENTRIES) {
    LOG(xxx);
    length = RTE_TEL_MAX_DICT_ENTRIES * RTE_TEL_MAX_DICT_ENTRIES;
}

> +			}
> +			groups[grp_num++] = group;
> +		}
> +		rte_tel_data_add_dict_uint_hex(group, reg_info->names[i].name,
> +						*data, 0);
> +	}
> +	if (i % RTE_TEL_MAX_DICT_ENTRIES != 0)
> +		rte_tel_data_add_dict_container(d, group_name, group, 0);

how about move all add dict in here.
for (i = 0; i < grp_num; i++) {
    snprintf(group_name, xxx);
    rte_tel_data_add_dict_container(d, group_name, group[i], 0);
}

> +
> +	return 0;
> +out:
> +	for (i = 0; i < grp_num; i++)
> +		rte_tel_data_free(groups[i]);
> +
> +	return ret;
> +}
> +
> +static int
> +eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
> +{
> +	struct rte_dev_reg_info reg_info;
> +	int ret;
> +
> +	memset(&reg_info, 0, sizeof(reg_info));
> +	reg_info.filter = filter;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Error getting device reg info: %d", ret);
> +		return ret;
> +	}
> +
> +	reg_info.data = calloc(reg_info.length, reg_info.width);
> +	if (!reg_info.data)

pls use if (reg_info.data == NULL), and add error log

> +		return -ENOMEM;
> +
> +	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
> +	if (!reg_info.names) {

pls use if (reg_info.names == NULL), and add error log

> +		free(reg_info.data);
> +		return -ENOMEM;
> +	}
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Error getting regs from device: %d", ret);
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	ret = eth_dev_store_regs(d, &reg_info);
> +out:
> +	free(reg_info.data);
> +	free(reg_info.names);
> +
> +	return ret;
> +}
> +
> +static int
> +eth_dev_handle_port_regs(const char *cmd __rte_unused,
> +		const char *params,
> +		struct rte_tel_data *d)
> +{
> +	char *filter = NULL;
> +	uint16_t port_id;
> +	char *end_param;
> +	int ret;
> +
> +	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
> +	if (ret != 0)
> +		return ret;
> +
> +	filter = strtok(end_param, ",");
> +	if (filter != NULL && strlen(filter) == 0)
> +		filter = NULL;
> +
> +	return eth_dev_get_port_regs(port_id, d, filter);
> +}
> +
>  RTE_INIT(ethdev_init_telemetry)
>  {
>  	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
> @@ -1436,4 +1560,6 @@ RTE_INIT(ethdev_init_telemetry)
>  			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
>  	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
>  			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
> +	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
> +			"Returns regs for a port. Parameters: int port_id, string filter");
>  }
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  3:07   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-26  8:01     ` fengchengwen
@ 2024-02-29  9:52     ` Thomas Monjalon
  2024-03-05  7:45       ` Jie Hai
  1 sibling, 1 reply; 134+ messages in thread
From: Thomas Monjalon @ 2024-02-29  9:52 UTC (permalink / raw)
  To: ferruh.yigit, Jie Hai
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui

26/02/2024 04:07, Jie Hai:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by names. And the original API
> rte_eth_dev_get_reg_info() does not use the name and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "offset_XXX".

Isn't it possible to implement filtering in the original function?
What would it break?

> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	const char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };

I suppose this is an ABI break?
Confirmed: http://mails.dpdk.org/archives/test-report/2024-February/587314.html



^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-29  9:52     ` Thomas Monjalon
@ 2024-03-05  7:45       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-03-05  7:45 UTC (permalink / raw)
  To: Thomas Monjalon, ferruh.yigit
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui

Hi, Thomas ,

Thanks for your review.
On 2024/2/29 17:52, Thomas Monjalon wrote:
> 26/02/2024 04:07, Jie Hai:
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> The new API rte_eth_dev_get_reg_info_ext() is added to support
>> reporting names and filtering by names. And the original API
>> rte_eth_dev_get_reg_info() does not use the name and filter fields.
>> A local variable is used in rte_eth_dev_get_reg_info for
>> compatibility. If the drivers does not report the names, set them
>> to "offset_XXX".
> 
> Isn't it possible to implement filtering in the original function?
> What would it break?
> 
If we implement filtering in the original function
rte_eth_dev_get_reg_info(), ABI would be broken and
old app cannot run with linked to the new library.

Existing binary applications will have backwards compatibility with our 
current patch.
Although the ABI is modified, the old app can still behave normally in 
the case of dynamic linking with the new library.
And the new APP using rte_eth_dev_get_reg_info() works well with  the 
old library.
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	const char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
> 
> I suppose this is an ABI break?
> Confirmed: http://mails.dpdk.org/archives/test-report/2024-February/587314.html
> 
I think  it is ABI change but not ABI break. please see above.
> 
> .
Best regards,
Jie Hai

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v4 2/7] ethdev: add telemetry cmd for registers
  2024-02-26  9:09     ` fengchengwen
@ 2024-03-06  7:18       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-03-06  7:18 UTC (permalink / raw)
  To: fengchengwen, dev; +Cc: lihuisong, liuyonglong, huangdengdui, ferruh.yigit

Hi, Chengwen,
Thanks for your review, all will be modified in next version.

Best Regards,
Jie Hai
On 2024/2/26 17:09, fengchengwen wrote:
> Hi Jie,
> 
> On 2024/2/26 11:07, Jie Hai wrote:
>> This patch adds a telemetry command for registers dump,
>> and supports get registers with specified names.
>> The length of the string exported by telemetry is limited
>> by MAX_OUTPUT_LEN. Therefore, the filter should be more
>> precise.
>>
>> An example usage is shown below:
>> --> /ethdev/regs,0,INTR
>> {
>>    "/ethdev/regs": {
>>      "registers_length": 318,
>>      "registers_width": 4,
>>      "register_offset": "0x0",
>>      "version": "0x1140011",
>>      "group_0": {
>>        "HNS3_CMDQ_INTR_STS_REG": "0x0",
>>        "HNS3_CMDQ_INTR_EN_REG": "0x2",
>>        "HNS3_CMDQ_INTR_GEN_REG": "0x0",
>>        "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
>>        "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
>>        "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
>>        "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
>>        ...
>>        },
>>      "group_1": {
>>          ...
>>      },
>>      ...
>> }
>>
>> or as below if the number of registers not exceed the
>> RTE_TEL_MAX_DICT_ENTRIES:
>> --> /ethdev/regs,0,ppp
>> {
>>    "/ethdev/regs": {
>>      "registers_length": 156,
>>      "registers_width": 4,
>>      "register_offset": "0x0",
>>      "version": "0x1140011",
>>      "ppp_key_drop_num": "0x0",
>>      "ppp_rlt_drop_num": "0x0",
>>      "ssu_ppp_mac_key_num_l": "0x1",
>>      "ssu_ppp_mac_key_num_h": "0x0",
>>      "ssu_ppp_host_key_num_l": "0x1",
>>      "ssu_ppp_host_key_num_h": "0x0",
>>      "ppp_ssu_mac_rlt_num_l": "0x1",
>>          ...
>>     }
>> }
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   lib/ethdev/rte_ethdev_telemetry.c | 126 ++++++++++++++++++++++++++++++
>>   1 file changed, 126 insertions(+)
>>
>> diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
>> index 6b873e7abe68..f1ebb2fae632 100644
>> --- a/lib/ethdev/rte_ethdev_telemetry.c
>> +++ b/lib/ethdev/rte_ethdev_telemetry.c
>> @@ -5,6 +5,7 @@
>>   #include <ctype.h>
>>   #include <stdlib.h>
>>   
>> +#include <rte_malloc.h>
>>   #include <rte_kvargs.h>
>>   #include <rte_telemetry.h>
>>   
>> @@ -1395,6 +1396,129 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
>>   	return ret;
>>   }
>>   
>> +static int
>> +eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
>> +{
>> +	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES] = {NULL};
> 
> no need zero.
> 
>> +	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
>> +	struct rte_tel_data *group = NULL;
>> +	uint32_t grp_num = 0;
>> +	uint32_t *data;
>> +	int ret = 0;
>> +	uint32_t i;
>> +
>> +	rte_tel_data_start_dict(d);
>> +	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
>> +	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
>> +	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
>> +	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
>> +
>> +	data = reg_info->data;
>> +	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
>> +		for (i = 0; i < reg_info->length; i++, data++)
>> +			rte_tel_data_add_dict_uint_hex(d,
>> +				reg_info->names[i].name, *data, 0);
> 
> The above format is OK for reg_info->width==4.
> There maybe reg_info->width == 8, pls support it.
> 
>> +		return 0;
>> +	}
>> +
>> +	for (i = 0; i < reg_info->length; i++, data++) {
>> +		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
>> +			if (i != 0)
>> +				rte_tel_data_add_dict_container(d, group_name,
>> +								group, 0);
>> +
>> +			group = rte_tel_data_alloc();
>> +			if (group == NULL) {
>> +				ret = -ENOMEM;
>> +				goto out;
>> +			}
>> +			rte_tel_data_start_dict(group);
>> +			snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
>> +					"group_%u", grp_num);
> 
> grp_num + 1 ?
> 
>> +			if (grp_num >= RTE_TEL_MAX_DICT_ENTRIES) {
>> +				RTE_ETHDEV_LOG_LINE(NOTICE,
>> +					"Too many regs, please filter");
> 
> how about add more descrip: stop format!
> 
>> +				return 0;
> 
> this group's memory was leak.
> 
> How about move the extream case before for loop:
> 
> uint32_t length = reg_info->lenght;
> if (length > RTE_TEL_MAX_DICT_ENTRIES * RTE_TEL_MAX_DICT_ENTRIES) {
>      LOG(xxx);
>      length = RTE_TEL_MAX_DICT_ENTRIES * RTE_TEL_MAX_DICT_ENTRIES;
> }
> 
>> +			}
>> +			groups[grp_num++] = group;
>> +		}
>> +		rte_tel_data_add_dict_uint_hex(group, reg_info->names[i].name,
>> +						*data, 0);
>> +	}
>> +	if (i % RTE_TEL_MAX_DICT_ENTRIES != 0)
>> +		rte_tel_data_add_dict_container(d, group_name, group, 0);
> 
> how about move all add dict in here.
> for (i = 0; i < grp_num; i++) {
>      snprintf(group_name, xxx);
>      rte_tel_data_add_dict_container(d, group_name, group[i], 0);
> }
> 
>> +
>> +	return 0;
>> +out:
>> +	for (i = 0; i < grp_num; i++)
>> +		rte_tel_data_free(groups[i]);
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
>> +{
>> +	struct rte_dev_reg_info reg_info;
>> +	int ret;
>> +
>> +	memset(&reg_info, 0, sizeof(reg_info));
>> +	reg_info.filter = filter;
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Error getting device reg info: %d", ret);
>> +		return ret;
>> +	}
>> +
>> +	reg_info.data = calloc(reg_info.length, reg_info.width);
>> +	if (!reg_info.data)
> 
> pls use if (reg_info.data == NULL), and add error log
> 
>> +		return -ENOMEM;
>> +
>> +	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
>> +	if (!reg_info.names) {
> 
> pls use if (reg_info.names == NULL), and add error log
> 
>> +		free(reg_info.data);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Error getting regs from device: %d", ret);
>> +		ret = -EINVAL;
>> +		goto out;
>> +	}
>> +
>> +	ret = eth_dev_store_regs(d, &reg_info);
>> +out:
>> +	free(reg_info.data);
>> +	free(reg_info.names);
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +eth_dev_handle_port_regs(const char *cmd __rte_unused,
>> +		const char *params,
>> +		struct rte_tel_data *d)
>> +{
>> +	char *filter = NULL;
>> +	uint16_t port_id;
>> +	char *end_param;
>> +	int ret;
>> +
>> +	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	filter = strtok(end_param, ",");
>> +	if (filter != NULL && strlen(filter) == 0)
>> +		filter = NULL;
>> +
>> +	return eth_dev_get_port_regs(port_id, d, filter);
>> +}
>> +
>>   RTE_INIT(ethdev_init_telemetry)
>>   {
>>   	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
>> @@ -1436,4 +1560,6 @@ RTE_INIT(ethdev_init_telemetry)
>>   			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
>>   	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
>>   			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
>> +	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
>> +			"Returns regs for a port. Parameters: int port_id, string filter");
>>   }
>>
> .

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  8:01     ` fengchengwen
@ 2024-03-06  7:22       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-03-06  7:22 UTC (permalink / raw)
  To: fengchengwen, dev; +Cc: lihuisong, liuyonglong, huangdengdui, ferruh.yigit

Hi, fengchengwen,
On 2024/2/26 16:01, fengchengwen wrote:
> Hi Jie,
> 
> On 2024/2/26 11:07, Jie Hai wrote:
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> The new API rte_eth_dev_get_reg_info_ext() is added to support
>> reporting names and filtering by names. And the original API
>> rte_eth_dev_get_reg_info() does not use the name and filter fields.
>> A local variable is used in rte_eth_dev_get_reg_info for
>> compatibility. If the drivers does not report the names, set them
>> to "offset_XXX".
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>>   lib/ethdev/rte_dev_info.h              | 11 +++++++++
>>   lib/ethdev/rte_ethdev.c                | 34 ++++++++++++++++++++++++++
>>   lib/ethdev/rte_ethdev.h                | 28 +++++++++++++++++++++
>>   lib/ethdev/version.map                 |  1 +
>>   5 files changed, 82 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
>> index 32d0ad8cf6a7..fa46da427dca 100644
>> --- a/doc/guides/rel_notes/release_24_03.rst
>> +++ b/doc/guides/rel_notes/release_24_03.rst
>> @@ -132,6 +132,11 @@ New Features
>>       to support TLS v1.2, TLS v1.3 and DTLS v1.2.
>>     * Added PMD API to allow raw submission of instructions to CPT.
>>   
>> +  * **Added support for dumping registers with names and filter.**
>> +
>> +    * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
>> +      the registers by their names and get the information of registers(names,
>> +      values and other attributes).
>>   
>>   Removed Items
>>   -------------
>> @@ -197,6 +202,9 @@ ABI Changes
>>   
>>   * No ABI change that would break compatibility with 23.11.
>>   
>> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
>> +  structure for reporting names of registers and filtering them by names.
>> +
>>   
>>   Known Issues
>>   ------------
>> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
>> index 67cf0ae52668..0ad4a43b9526 100644
>> --- a/lib/ethdev/rte_dev_info.h
>> +++ b/lib/ethdev/rte_dev_info.h
>> @@ -11,6 +11,11 @@ extern "C" {
>>   
>>   #include <stdint.h>
>>   
>> +#define RTE_ETH_REG_NAME_SIZE 128
> 
> Almost all stats name size is 64, why not keep consistent?
> 
will correct.
>> +struct rte_eth_reg_name {
>> +	char name[RTE_ETH_REG_NAME_SIZE];
>> +};
>> +
>>   /*
>>    * Placeholder for accessing device registers
>>    */
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	const char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
>>   
>>   /*
>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>> index f1c658f49e80..9ef50c633ce3 100644
>> --- a/lib/ethdev/rte_ethdev.c
>> +++ b/lib/ethdev/rte_ethdev.c
>> @@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>>   
>>   int
>>   rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>> +{
>> +	struct rte_dev_reg_info reg_info = { 0 };
>> +	int ret;
>> +
>> +	if (info == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Cannot get ethdev port %u register info to NULL",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	reg_info.length = info->length;
>> +	reg_info.data = info->data;
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	info->length = reg_info.length;
>> +	info->width = reg_info.width;
>> +	info->version = reg_info.version;
>> +	info->offset = reg_info.offset;
>> +
>> +	return 0;
>> +}
>> +
>> +int
>> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>>   {
>>   	struct rte_eth_dev *dev;
>> +	uint32_t i;
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> @@ -6408,6 +6437,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>>   
>>   	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>>   
>> +	/* Report the default names if drivers not report. */
>> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
>> +		for (i = 0; i < info->length; i++)
>> +			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
>> +				"offset_%x", info->offset + i * info->width);
> 
> %x has no prefix "0x", may lead to confused.
> How about use %u ?
> 
That sounds better.
> Another question, if app don't zero names' memory, then its value is random, so it will not enter this logic.
> Suggest memset item[0]'s name memory before invoke PMD ops.
> 
>>   	return ret;
>>   }
>>   
>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
>> index ed27360447a3..09e2d5fdb49b 100644
>> --- a/lib/ethdev/rte_ethdev.h
>> +++ b/lib/ethdev/rte_ethdev.h
>> @@ -5066,6 +5066,34 @@ __rte_experimental
>>   int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>>   		struct rte_power_monitor_cond *pmc);
>>   
>> +/**
>> + * Retrieve the filtered device registers (values and names) and
>> + * register attributes (number of registers and register size)
>> + *
>> + * @param port_id
>> + *   The port identifier of the Ethernet device.
>> + * @param info
>> + *   Pointer to rte_dev_reg_info structure to fill in.
>> + *   If info->filter is not NULL and the driver does not support names or
>> + *   filter, return error. If info->filter is NULL, return info for all
>> + *   registers (seen as filter none).
>> + *   If info->data is NULL, the function fills in the width and length fields.
>> + *   If non-NULL, ethdev considers there are enough spaces to store the
>> + *   registers, and the values of registers whose name contains the filter
>> + *   string are put into the buffer pointed at by the data field. Do the same
>> + *   for the names of registers if info->names is not NULL. If drivers do not
>> + *   report names, default names are given by ethdev.
> 
> It's a little hard to understand. Suggest use '-' for each field, just like rte_eth_remove_tx_callback
> 
I will try.
>> + * @return
>> + *   - (0) if successful.
>> + *   - (-ENOTSUP) if hardware doesn't support.
>> + *   - (-EINVAL) if bad parameter.
>> + *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EIO) if device is removed.
>> + *   - others depends on the specific operations implementation.
>> + */
>> +__rte_experimental
>> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
>> +
>>   /**
>>    * Retrieve device registers and register attributes (number of registers and
>>    * register size)
>> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
>> index 17e4eac8a4cc..c41a64e404db 100644
>> --- a/lib/ethdev/version.map
>> +++ b/lib/ethdev/version.map
>> @@ -325,6 +325,7 @@ EXPERIMENTAL {
>>   	rte_flow_template_table_resizable;
>>   	rte_flow_template_table_resize;
>>   	rte_flow_template_table_resize_complete;
>> +	rte_eth_dev_get_reg_info_ext;
> 
> should place with alphabetical order.
> 
> Thanks
Ok.
> 
>>   };
>>   
>>   INTERNAL {
>>
> .
Thanks,
Jie Hai

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 0/7] support dump reigser names and filter them
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (3 preceding siblings ...)
  2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
@ 2024-03-07  3:02 ` Jie Hai
  2024-03-07  3:02   ` [PATCH v5 1/7] ethdev: support report register names and filter Jie Hai
                     ` (6 more replies)
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                   ` (5 subsequent siblings)
  10 siblings, 7 replies; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, haijie1

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient
for users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext
is added to support the capability of exporting the name of the
corresponding register and filtering by names.

The hns3 driver and telemetry are examples for that.

--
v5:
1. fix version map.
2. fix comment on rte_eth_dev_get_reg_info_ext.
3. set RTE_ETH_REG_NAME_SIZE to 64.
4. fix default register name.
5. add support for reg_info->width == 8 in telemetry.
6. add memeory allocate fail log.
7. fix memory access for telemetry to store extra registers.

v4:
1. fix mispellings.
2. add const to 'filter'.
3. remove redundant assigning.

v3:
1. fix mispellings.
2. use snprintf instead of sprintf.
3. add more comment on rte_eth_dev_get_reg_info_ext.
4. add __rte_experimental.
5. add version map.

v2:
1. fix compile error.
2. add new API to support it instead of the old one.
3. split patches on hns3 driver.

Jie Hai (7):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: fix dump counter of registers
  net/hns3: remove dump format of registers
  net/hns3: add names for registers
  net/hns3: support filter directly accessed registers
  net/hns3: support filter dump of registers

 doc/guides/rel_notes/release_24_03.rst |    9 +
 drivers/net/hns3/hns3_regs.c           | 1359 +++++++++++++++++++++---
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  158 +++
 lib/ethdev/version.map                 |    1 +
 7 files changed, 1432 insertions(+), 173 deletions(-)

-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 1/7] ethdev: support report register names and filter
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  2024-03-08  8:09     ` lihuisong (C)
  2024-03-07  3:02   ` [PATCH v5 2/7] ethdev: add telemetry cmd for registers Jie Hai
                     ` (5 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by names. And the original API
rte_eth_dev_get_reg_info() does not use the names and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  9 ++++++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 5 files changed, 88 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 78590c047b2e..e491579ca984 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -161,6 +161,12 @@ New Features
   * Added power-saving during polling within the ``rte_event_dequeue_burst()`` API.
   * Added support for DMA adapter.
 
+* **Added support for dumping registers with names and filter.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+    the registers by their names and get the information of registers(names,
+    values and other attributes).
+
 
 Removed Items
 -------------
@@ -228,6 +234,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of registers and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..0badb92432ae 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 64
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..82d228790692 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 		return -EINVAL;
 	}
 
+	if (info->names != NULL && info->length != 0)
+		memset(info->names, 0,
+			sizeof(struct rte_eth_reg_name) * info->length);
+
 	if (*dev->dev_ops->get_reg == NULL)
 		return -ENOTSUP;
 	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"offset_%u", info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index ed27360447a3..cd95a0d51038 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5066,6 +5066,35 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   - If info->filter is NULL, return info for all registers (seen as filter
+ *     none).
+ *   - If info->filter is not NULL, return error if the driver does not support
+ *     names or filter.
+ *   - If info->data is NULL, the function fills in the width and length fields.
+ *   - If info->data is not NULL, ethdev considers there are enough spaces to
+ *     store the registers, and the values of registers whose name contains the
+ *     filter string are put into the buffer pointed at by info->data.
+ *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
+ *     with default names.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 79f6f5293b5c..e5ec2a2a9741 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -319,6 +319,7 @@ EXPERIMENTAL {
 
 	# added in 24.03
 	__rte_eth_trace_tx_queue_count;
+	rte_eth_dev_get_reg_info_ext;
 	rte_eth_find_rss_algo;
 	rte_flow_async_update_resized;
 	rte_flow_calc_encap_hash;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 2/7] ethdev: add telemetry cmd for registers
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
  2024-03-07  3:02   ` [PATCH v5 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  2024-03-08  8:48     ` lihuisong (C)
  2024-03-07  3:02   ` [PATCH v5 3/7] net/hns3: fix dump counter of registers Jie Hai
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds a telemetry command for registers dump,
and supports get registers with specified names.
The length of the string exported by telemetry is limited
by MAX_OUTPUT_LEN. Therefore, the filter should be more
precise.

An example usage is shown below:
--> /ethdev/regs,0,INTR
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "HNS3_CMDQ_INTR_STS_REG": "0x0",
      "HNS3_CMDQ_INTR_EN_REG": "0x2",
      "HNS3_CMDQ_INTR_GEN_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
      "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
      "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

or as below if the number of registers not exceed the
RTE_TEL_MAX_DICT_ENTRIES:
--> /ethdev/regs,0,ppp
{
  "/ethdev/regs": {
    "registers_length": 156,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "ppp_key_drop_num": "0x0",
    "ppp_rlt_drop_num": "0x0",
    "ssu_ppp_mac_key_num_l": "0x1",
    "ssu_ppp_mac_key_num_h": "0x0",
    "ssu_ppp_host_key_num_l": "0x1",
    "ssu_ppp_host_key_num_h": "0x0",
    "ppp_ssu_mac_rlt_num_l": "0x1",
        ...
   }
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 158 ++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..0c570792fb5f 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -5,6 +5,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_telemetry.h>
 
@@ -1395,6 +1396,161 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static void
+eth_dev_add_u32_hex(struct rte_tel_data *d, const char *name, uint32_t **data)
+{
+	if (*data == NULL)
+		return;
+	rte_tel_data_add_dict_uint_hex(d, name, **data, 0);
+	(*data)++;
+}
+
+static void
+eth_dev_add_u64_hex(struct rte_tel_data *d, const char *name, uint64_t **data)
+{
+	if (*data == NULL)
+		return;
+	rte_tel_data_add_dict_uint_hex(d, name, **data, 0);
+	(*data)++;
+}
+
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t *data0 = NULL;
+	uint64_t *data1 = NULL;
+	uint32_t grp_num = 0;
+	int ret = 0;
+	uint32_t i;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	if (reg_info->width == sizeof(uint32_t))
+		data0 = reg_info->data;
+	else
+		data1 = reg_info->data;
+
+	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
+		for (i = 0; i < reg_info->length; i++) {
+			eth_dev_add_u32_hex(d, reg_info->names[i].name, &data0);
+			eth_dev_add_u64_hex(d, reg_info->names[i].name, &data1);
+		}
+		return 0;
+	}
+
+	for (i = 0; i < reg_info->length; i++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
+			group = rte_tel_data_alloc();
+			if (group == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			groups[grp_num++] = group;
+			rte_tel_data_start_dict(group);
+		}
+		eth_dev_add_u32_hex(group, reg_info->names[i].name, &data0);
+		eth_dev_add_u64_hex(group, reg_info->names[i].name, &data1);
+	}
+
+	for (i = 0; i < grp_num; i++) {
+		snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
+					"group_%u", i);
+		rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
+	}
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	uint32_t max_length;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	/* 4 is space for other information of registers. */
+	max_length = RTE_TEL_MAX_DICT_ENTRIES *
+			(RTE_TEL_MAX_DICT_ENTRIES - 4);
+	if (reg_info.length > max_length) {
+		RTE_ETHDEV_LOG_LINE(WARNING,
+			"Reduced register number to be obtained from %u to %u due to limited memory",
+			reg_info.length, max_length);
+		reg_info.length = max_length;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (reg_info.data == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Fail to allocate memory for reg_info.data");
+		return -ENOMEM;
+	}
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (reg_info.names == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Fail to allocate memory for reg_info.names");
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter = NULL;
+	uint16_t port_id;
+	char *end_param;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1592,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns regs for a port. Parameters: int port_id, string filter");
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 3/7] net/hns3: fix dump counter of registers
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
  2024-03-07  3:02   ` [PATCH v5 1/7] ethdev: support report register names and filter Jie Hai
  2024-03-07  3:02   ` [PATCH v5 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  2024-03-08  8:49     ` lihuisong (C)
  2024-03-07  3:02   ` [PATCH v5 4/7] net/hns3: remove dump format " Jie Hai
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Yisen Zhuang, Chengchang Tang, Lijun Ou, Chunsong Feng,
	Wei Hu (Xavier), Min Hu (Connor),
	Ferruh Yigit, Huisong Li
  Cc: fengchengwen, haijie1

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")

Signed-off-by: Jie Hai <haijie1@huawei.com>
Cc: stable@dpdk.org
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..d77170481a3d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -135,7 +135,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 4/7] net/hns3: remove dump format of registers
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
                     ` (2 preceding siblings ...)
  2024-03-07  3:02   ` [PATCH v5 3/7] net/hns3: fix dump counter of registers Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  2024-03-08  9:17     ` lihuisong (C)
  2024-03-07  3:02   ` [PATCH v5 5/7] net/hns3: add names for registers Jie Hai
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, haijie1

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 67 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 49 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d77170481a3d..b1c0d538a3c8 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
 					  HNS3_CMDQ_TX_ADDR_H_REG,
@@ -119,23 +116,22 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
+	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
+	cmdq_cnt = sizeof(cmdq_reg_addrs);
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
+	ring_cnt = sizeof(ring_reg_addrs);
+	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
+	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -144,18 +140,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -276,18 +270,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -302,7 +284,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -313,7 +294,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -321,7 +301,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -330,7 +309,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -406,17 +384,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -424,11 +400,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -475,7 +448,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -520,7 +492,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
@@ -528,8 +499,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 5/7] net/hns3: add names for registers
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
                     ` (3 preceding siblings ...)
  2024-03-07  3:02   ` [PATCH v5 4/7] net/hns3: remove dump format " Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  2024-03-08  9:41     ` lihuisong (C)
  2024-03-08 10:24     ` lihuisong (C)
  2024-03-07  3:02   ` [PATCH v5 6/7] net/hns3: support filter directly accessed registers Jie Hai
  2024-03-07  3:02   ` [PATCH v5 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 2 replies; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, haijie1

This patch adds names for all registers to be dumped.
For those who can be directly accessed by their addresses,
a new structure containing both name and address is added
and the related arrays is refactored and renamed.

For the remaining modules, there may be different meanings
on different platforms for the same field. Therefore, two
name fields are provided.

There are some 64-bit registers, dump them as two 32-bit
registers.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 877 ++++++++++++++++++++++++++++++++---
 1 file changed, 801 insertions(+), 76 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b1c0d538a3c8..b7e4f78eecde 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,67 +14,84 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct direct_reg_list {
+	const char *name;
+	uint32_t addr;
+};
+
+#define STR(s) #s
+
+static const struct direct_reg_list cmdq_reg_list[] = {
+	{STR(HNS3_CMDQ_TX_ADDR_L_REG),		HNS3_CMDQ_TX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_TX_ADDR_H_REG),		HNS3_CMDQ_TX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_TX_DEPTH_REG),		HNS3_CMDQ_TX_DEPTH_REG},
+	{STR(HNS3_CMDQ_TX_TAIL_REG),		HNS3_CMDQ_TX_TAIL_REG},
+	{STR(HNS3_CMDQ_TX_HEAD_REG),		HNS3_CMDQ_TX_HEAD_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_L_REG),		HNS3_CMDQ_RX_ADDR_L_REG},
+	{STR(HNS3_CMDQ_RX_ADDR_H_REG),		HNS3_CMDQ_RX_ADDR_H_REG},
+	{STR(HNS3_CMDQ_RX_DEPTH_REG),		HNS3_CMDQ_RX_DEPTH_REG},
+	{STR(HNS3_CMDQ_RX_TAIL_REG),		HNS3_CMDQ_RX_TAIL_REG},
+	{STR(HNS3_CMDQ_RX_HEAD_REG),		HNS3_CMDQ_RX_HEAD_REG},
+	{STR(HNS3_VECTOR0_CMDQ_SRC_REG),	HNS3_VECTOR0_CMDQ_SRC_REG},
+	{STR(HNS3_CMDQ_INTR_STS_REG),		HNS3_CMDQ_INTR_STS_REG},
+	{STR(HNS3_CMDQ_INTR_EN_REG),		HNS3_CMDQ_INTR_EN_REG},
+	{STR(HNS3_CMDQ_INTR_GEN_REG),		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct direct_reg_list common_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_VECTOR0_OTER_EN_REG),		HNS3_VECTOR0_OTER_EN_REG},
+	{STR(HNS3_MISC_RESET_STS_REG),		HNS3_MISC_RESET_STS_REG},
+	{STR(HNS3_VECTOR0_OTHER_INT_STS_REG),	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{STR(HNS3_GLOBAL_RESET_REG),		HNS3_GLOBAL_RESET_REG},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list common_vf_reg_list[] = {
+	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
+	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
+	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
+};
+
+static const struct direct_reg_list ring_reg_list[] = {
+	{STR(HNS3_RING_RX_BASEADDR_L_REG),	HNS3_RING_RX_BASEADDR_L_REG},
+	{STR(HNS3_RING_RX_BASEADDR_H_REG),	HNS3_RING_RX_BASEADDR_H_REG},
+	{STR(HNS3_RING_RX_BD_NUM_REG),		HNS3_RING_RX_BD_NUM_REG},
+	{STR(HNS3_RING_RX_BD_LEN_REG),		HNS3_RING_RX_BD_LEN_REG},
+	{STR(HNS3_RING_RX_EN_REG),		HNS3_RING_RX_EN_REG},
+	{STR(HNS3_RING_RX_MERGE_EN_REG),	HNS3_RING_RX_MERGE_EN_REG},
+	{STR(HNS3_RING_RX_TAIL_REG),		HNS3_RING_RX_TAIL_REG},
+	{STR(HNS3_RING_RX_HEAD_REG),		HNS3_RING_RX_HEAD_REG},
+	{STR(HNS3_RING_RX_FBDNUM_REG),		HNS3_RING_RX_FBDNUM_REG},
+	{STR(HNS3_RING_RX_OFFSET_REG),		HNS3_RING_RX_OFFSET_REG},
+	{STR(HNS3_RING_RX_FBD_OFFSET_REG),	HNS3_RING_RX_FBD_OFFSET_REG},
+	{STR(HNS3_RING_RX_STASH_REG),		HNS3_RING_RX_STASH_REG},
+	{STR(HNS3_RING_RX_BD_ERR_REG),		HNS3_RING_RX_BD_ERR_REG},
+	{STR(HNS3_RING_TX_BASEADDR_L_REG),	HNS3_RING_TX_BASEADDR_L_REG},
+	{STR(HNS3_RING_TX_BASEADDR_H_REG),	HNS3_RING_TX_BASEADDR_H_REG},
+	{STR(HNS3_RING_TX_BD_NUM_REG),		HNS3_RING_TX_BD_NUM_REG},
+	{STR(HNS3_RING_TX_EN_REG),		HNS3_RING_TX_EN_REG},
+	{STR(HNS3_RING_TX_PRIORITY_REG),	HNS3_RING_TX_PRIORITY_REG},
+	{STR(HNS3_RING_TX_TC_REG),		HNS3_RING_TX_TC_REG},
+	{STR(HNS3_RING_TX_MERGE_EN_REG),	HNS3_RING_TX_MERGE_EN_REG},
+	{STR(HNS3_RING_TX_TAIL_REG),		HNS3_RING_TX_TAIL_REG},
+	{STR(HNS3_RING_TX_HEAD_REG),		HNS3_RING_TX_HEAD_REG},
+	{STR(HNS3_RING_TX_FBDNUM_REG),		HNS3_RING_TX_FBDNUM_REG},
+	{STR(HNS3_RING_TX_OFFSET_REG),		HNS3_RING_TX_OFFSET_REG},
+	{STR(HNS3_RING_TX_EBD_NUM_REG),		HNS3_RING_TX_EBD_NUM_REG},
+	{STR(HNS3_RING_TX_EBD_OFFSET_REG),	HNS3_RING_TX_EBD_OFFSET_REG},
+	{STR(HNS3_RING_TX_BD_ERR_REG),		HNS3_RING_TX_BD_ERR_REG},
+	{STR(HNS3_RING_EN_REG),			HNS3_RING_EN_REG},
+};
+
+static const struct direct_reg_list tqp_intr_reg_list[] = {
+	{STR(HNS3_TQP_INTR_CTRL_REG),	HNS3_TQP_INTR_CTRL_REG},
+	{STR(HNS3_TQP_INTR_GL0_REG),	HNS3_TQP_INTR_GL0_REG},
+	{STR(HNS3_TQP_INTR_GL1_REG),	HNS3_TQP_INTR_GL1_REG},
+	{STR(HNS3_TQP_INTR_GL2_REG),	HNS3_TQP_INTR_GL2_REG},
+	{STR(HNS3_TQP_INTR_RL_REG),	HNS3_TQP_INTR_RL_REG},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_BIOS_COMMON_REG,
@@ -91,6 +108,708 @@ static const uint32_t hns3_dfx_reg_opcode_list[] = {
 	HNS3_OPC_DFX_SSU_REG_2
 };
 
+struct hns3_reg_entry {
+	const char *new_name;
+	const char *old_name;
+};
+
+static struct hns3_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"ssu_btmp_ageing_st_b0"},
+	{"ssu_btmp_ageing_st_b1"},
+	{"ssu_btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"ssu_lo_pri_unicast_rlt_drop_num"},
+	{"ssu_hi_pri_multicast_rlt_drop_num"},
+
+	{"ssu_lo_pri_multicast_rlt_drop_num"},
+	{"ssu_ncsi_packet_curr_buffer_cnt"},
+	{"dfx_ssu0_rsv5",		"ssu_btmp_ageing_rls_cnt_bank0"},
+	{"dfx_ssu0_rsv6",		"ssu_btmp_ageing_rls_cnt_bank1"},
+	{"dfx_ssu0_rsv7",		"ssu_btmp_ageing_rls_cnt_bank2"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ssu_ncsi_rx_packet_in_cnt_l"},
+	{"ssu_ncsi_rx_packet_in_cnt_h"},
+	{"ssu_ncsi_tx_packet_out_cnt_l"},
+	{"ssu_ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"ssu_mb_uncopy_num"},
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+	{"ssu_bank_unbalance_drop_cnt"},
+	{"ssu_bank_unbalance_rx_drop_cnt"},
+
+	{"ssu_nic_l2_eer_drop_pkt_cnt"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt"},
+	{"ssu_nic_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_roc_l2_eer_drop_pkt_cnt_rx"},
+	{"ssu_rx_oq_glb_drop_pkt_cnt"},
+	{"ssu_dfx_ssu0_rsv8"},
+
+	{"ssu_lo_pri_unicast_cur_cnt"},
+	{"ssu_hi_pri_multicast_cur_cnt"},
+	{"ssu_lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"ssu_packet_tc_curr_buffer_cnt_0"},
+	{"ssu_packet_tc_curr_buffer_cnt_1"},
+	{"ssu_packet_tc_curr_buffer_cnt_2"},
+	{"ssu_packet_tc_curr_buffer_cnt_3"},
+	{"ssu_packet_tc_curr_buffer_cnt_4"},
+
+	{"ssu_packet_tc_curr_buffer_cnt_5"},
+	{"ssu_packet_tc_curr_buffer_cnt_6"},
+	{"ssu_packet_tc_curr_buffer_cnt_7"},
+	{"ssu_packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"ssu_rx_packet_in_cnt_l"},
+	{"ssu_rx_packet_in_cnt_h"},
+	{"ssu_rx_packet_out_cnt_l"},
+	{"ssu_rx_packet_out_cnt_h"},
+	{"ssu_tx_packet_in_cnt_l"},
+	{"ssu_tx_packet_in_cnt_h"},
+
+	{"ssu_tx_packet_out_cnt_l"},
+	{"ssu_tx_packet_out_cnt_h"},
+	{"ssu_roc_rx_packet_in_cnt_l"},
+	{"ssu_roc_rx_packet_in_cnt_h"},
+	{"ssu_roc_tx_packet_in_cnt_l"},
+	{"ssu_roc_tx_packet_in_cnt_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_0_l"},
+	{"ssu_rx_packet_tc_in_cnt_0_h"},
+	{"ssu_rx_packet_tc_in_cnt_1_l"},
+	{"ssu_rx_packet_tc_in_cnt_1_h"},
+	{"ssu_rx_packet_tc_in_cnt_2_l"},
+	{"ssu_rx_packet_tc_in_cnt_2_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_3_l"},
+	{"ssu_rx_packet_tc_in_cnt_3_h"},
+	{"ssu_rx_packet_tc_in_cnt_4_l"},
+	{"ssu_rx_packet_tc_in_cnt_4_h"},
+	{"ssu_rx_packet_tc_in_cnt_5_l"},
+	{"ssu_rx_packet_tc_in_cnt_5_h"},
+
+	{"ssu_rx_packet_tc_in_cnt_6_l"},
+	{"ssu_rx_packet_tc_in_cnt_6_h"},
+	{"ssu_rx_packet_tc_in_cnt_7_l"},
+	{"ssu_rx_packet_tc_in_cnt_7_h"},
+	{"ssu_rx_packet_tc_out_cnt_0_l"},
+	{"ssu_rx_packet_tc_out_cnt_0_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_1_l"},
+	{"ssu_rx_packet_tc_out_cnt_1_h"},
+	{"ssu_rx_packet_tc_out_cnt_2_l"},
+	{"ssu_rx_packet_tc_out_cnt_2_h"},
+	{"ssu_rx_packet_tc_out_cnt_3_l"},
+	{"ssu_rx_packet_tc_out_cnt_3_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_4_l"},
+	{"ssu_rx_packet_tc_out_cnt_4_h"},
+	{"ssu_rx_packet_tc_out_cnt_5_l"},
+	{"ssu_rx_packet_tc_out_cnt_5_h"},
+	{"ssu_rx_packet_tc_out_cnt_6_l"},
+	{"ssu_rx_packet_tc_out_cnt_6_h"},
+
+	{"ssu_rx_packet_tc_out_cnt_7_l"},
+	{"ssu_rx_packet_tc_out_cnt_7_h"},
+	{"ssu_tx_packet_tc_in_cnt_0_l"},
+	{"ssu_tx_packet_tc_in_cnt_0_h"},
+	{"ssu_tx_packet_tc_in_cnt_1_l"},
+	{"ssu_tx_packet_tc_in_cnt_1_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_2_l"},
+	{"ssu_tx_packet_tc_in_cnt_2_h"},
+	{"ssu_tx_packet_tc_in_cnt_3_l"},
+	{"ssu_tx_packet_tc_in_cnt_3_h"},
+	{"ssu_tx_packet_tc_in_cnt_4_l"},
+	{"ssu_tx_packet_tc_in_cnt_4_h"},
+
+	{"ssu_tx_packet_tc_in_cnt_5_l"},
+	{"ssu_tx_packet_tc_in_cnt_5_h"},
+	{"ssu_tx_packet_tc_in_cnt_6_l"},
+	{"ssu_tx_packet_tc_in_cnt_6_h"},
+	{"ssu_tx_packet_tc_in_cnt_7_l"},
+	{"ssu_tx_packet_tc_in_cnt_7_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_0_l"},
+	{"ssu_tx_packet_tc_out_cnt_0_h"},
+	{"ssu_tx_packet_tc_out_cnt_1_l"},
+	{"ssu_tx_packet_tc_out_cnt_1_h"},
+	{"ssu_tx_packet_tc_out_cnt_2_l"},
+	{"ssu_tx_packet_tc_out_cnt_2_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_3_l"},
+	{"ssu_tx_packet_tc_out_cnt_3_h"},
+	{"ssu_tx_packet_tc_out_cnt_4_l"},
+	{"ssu_tx_packet_tc_out_cnt_4_h"},
+	{"ssu_tx_packet_tc_out_cnt_5_l"},
+	{"ssu_tx_packet_tc_out_cnt_5_h"},
+
+	{"ssu_tx_packet_tc_out_cnt_6_l"},
+	{"ssu_tx_packet_tc_out_cnt_6_h"},
+	{"ssu_tx_packet_tc_out_cnt_7_l"},
+	{"ssu_tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_mul_car_drop_pkt_cnt_l",	"igu_egu_rsv0"},
+	{"igu_egu_mul_car_drop_pkt_cnt_h",	"igu_egu_rsv1"},
+	{"igu_egu_bro_car_drop_pkt_cnt_l",	"igu_egu_rsv2"},
+	{"igu_egu_bro_car_drop_pkt_cnt_h",	"igu_egu_rsv3"},
+	{"igu_egu_rsv0",		"igu_egu_rsv4"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_currport_tnl_index",	"rpu_tc_queue_num"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rsv1",		"ppp_rslt_descr_sts"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_snq_hit_cnt_l",	"ppp_um_tbl_vmdq1_hit_cnt_l"},
+	{"ppp_um_tbl_snq_hit_cnt_h",	"ppp_um_tbl_vmdq1_hit_cnt_h"},
+	{"ppp_rsv5",			"ppp_mta_tbl_hit_cnt_l"},
+	{"ppp_rsv6",			"ppp_mta_tbl_hit_cnt_h"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_rsv7",	"ppp_vlan_mirr_cnt_l"},
+	{"ppp_rsv8",	"ppp_vlan_mirr_cnt_h"},
+
+	{"ppp_rsv9",	"ppp_ig_mirr_cnt_l"},
+	{"ppp_rsv10",	"ppp_ig_mirr_cnt_h"},
+	{"ppp_rsv11",	"ppp_eg_mirr_cnt_l"},
+	{"ppp_rsv12",	"ppp_eg_mirr_cnt_h"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_rcb_tx_mem_serr_cnt",	"rcb_axi_rd_fbd_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+struct hns3_dfx_reg_entry {
+	const struct hns3_reg_entry *regs;
+	uint32_t entry_num;
+};
+
+struct hns3_dfx_reg_entry hns3_dfx_reg_list[] = {
+	{dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	{dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	{dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	{dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list)},
+	{dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	{dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	{dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	{dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	{dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	{dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	{dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	{dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+};
+
 static int
 hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 		  uint32_t *regs_num_64_bit)
@@ -108,6 +827,12 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_SIZE !=
+			RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -122,13 +847,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = sizeof(cmdq_reg_addrs);
+	cmdq_cnt = RTE_DIM(cmdq_reg_list);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = sizeof(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
-	ring_cnt = sizeof(ring_reg_addrs);
-	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
+	ring_cnt = RTE_DIM(ring_reg_list);
+	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -281,33 +1006,33 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	size_t i;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(cmdq_reg_list);
 	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_vf_reg_list);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
+		reg_num = RTE_DIM(common_reg_list);
 	for (i = 0; i < reg_num; i++)
 		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
 		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
+			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
 
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
+						ring_reg_list[i].addr + reg_offset);
 	}
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
+	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
 		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
+			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
 	}
 	return data - origin_data_ptr;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 6/7] net/hns3: support filter directly accessed registers
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
                     ` (4 preceding siblings ...)
  2024-03-07  3:02   ` [PATCH v5 5/7] net/hns3: add names for registers Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  2024-03-08  9:41     ` lihuisong (C)
  2024-03-07  3:02   ` [PATCH v5 7/7] net/hns3: support filter dump of registers Jie Hai
  6 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, haijie1

This patch supports reporting names of registers which
can be directly accessed by addresses and filtering
them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 198 +++++++++++++++++++++++++++++------
 1 file changed, 167 insertions(+), 31 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index b7e4f78eecde..7c3bd162f067 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -837,8 +837,24 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static uint32_t
+hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
+			 uint32_t len, const char *filter)
+{
+	uint32_t i;
+	uint32_t count = 0;
+
+	for (i = 0 ; i < len; i++) {
+		if (filter != NULL && !strstr(list[i].name, filter))
+			continue;
+		count++;
+	}
+
+	return count;
+}
+
 static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
@@ -847,13 +863,18 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	uint32_t len;
 	int ret;
 
-	cmdq_cnt = RTE_DIM(cmdq_reg_list);
+	cmdq_cnt = hns3_get_direct_regs_cnt(cmdq_reg_list,
+					    RTE_DIM(cmdq_reg_list), filter);
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_vf_reg_list,
+					RTE_DIM(common_vf_reg_list), filter);
 	else
-		common_cnt = RTE_DIM(common_reg_list);
-	ring_cnt = RTE_DIM(ring_reg_list);
-	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
+		common_cnt = hns3_get_direct_regs_cnt(common_reg_list,
+					RTE_DIM(common_reg_list), filter);
+	ring_cnt = hns3_get_direct_regs_cnt(ring_reg_list,
+					    RTE_DIM(ring_reg_list), filter);
+	tqp_intr_cnt = hns3_get_direct_regs_cnt(tqp_intr_reg_list,
+					RTE_DIM(tqp_intr_reg_list), filter);
 
 	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
 	      tqp_intr_cnt * hw->intr_tqps_num;
@@ -995,47 +1016,160 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+
+static uint32_t
+hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
+	uint32_t *data = regs->data;
 	size_t reg_num;
-	uint16_t j;
+	data += count;
 	size_t i;
 
-	/* fetching per-PF registers values from PF PCIe register space */
 	reg_num = RTE_DIM(cmdq_reg_list);
-	for (i = 0; i < reg_num; i++)
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(cmdq_reg_list[i].name, regs->filter))
+			continue;
 		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", cmdq_reg_list[i].name);
+	}
 
-	if (hns->is_vf)
-		reg_num = RTE_DIM(common_vf_reg_list);
-	else
-		reg_num = RTE_DIM(common_reg_list);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+	return count;
+}
+static uint32_t
+hns3_direct_access_common_reg(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs,
+			      uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
 
+	reg_num = RTE_DIM(common_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_vf_common_reg(struct hns3_hw *hw,
+				 struct rte_dev_reg_info *regs,
+				 uint32_t count)
+{
+	uint32_t *data = regs->data;
+	size_t reg_num;
+	data += count;
+	size_t i;
+
+	reg_num = RTE_DIM(common_vf_reg_list);
+	for (i = 0; i < reg_num; i++) {
+		if (regs->filter != NULL &&
+			!strstr(common_vf_reg_list[i].name, regs->filter))
+			continue;
+		*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", common_vf_reg_list[i].name);
+	}
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_ring_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(ring_reg_list);
 	for (j = 0; j < hw->tqps_num; j++) {
 		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_list[i].addr + reg_offset);
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(ring_reg_list[i].name, regs->filter))
+				continue;
+			*data++ = hns3_read_dev(hw, ring_reg_list[i].addr +
+						    reg_offset);
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, ring_reg_list[i].name);
+		}
 	}
 
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
+			    struct rte_dev_reg_info *regs,
+			    uint32_t count)
+{
+	uint32_t *data = regs->data;
+	uint32_t reg_offset;
+	size_t reg_num;
+	uint16_t j;
+	size_t i;
+
+	data += count;
 	reg_num = RTE_DIM(tqp_intr_reg_list);
 	for (j = 0; j < hw->intr_tqps_num; j++) {
 		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
+		for (i = 0; i < reg_num; i++) {
+			if (regs->filter != NULL &&
+				!strstr(tqp_intr_reg_list[i].name, regs->filter))
+				continue;
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
 						reg_offset);
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
+				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+		}
 	}
-	return data - origin_data_ptr;
+
+	return count;
+}
+
+static uint32_t
+hns3_direct_access_regs(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs,
+			uint32_t count)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+
+	count = hns3_direct_access_cmdq_reg(hw, regs, count);
+	if (!hns->is_vf)
+		count = hns3_direct_access_common_reg(hw, regs, count);
+	else
+		count = hns3_direct_access_vf_common_reg(hw, regs, count);
+
+	count = hns3_direct_access_ring_reg(hw, regs, count);
+	count = hns3_direct_access_tqp_intr_reg(hw, regs, count);
+
+	return count;
 }
 
 static int
@@ -1177,11 +1311,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
+	uint32_t count = 0;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
+	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
@@ -1193,13 +1328,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	}
 
 	/* Only full register dump is supported */
-	if (regs->length && regs->length != length)
+	if ((regs->length && regs->length != length))
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
+	count = hns3_direct_access_regs(hw, regs, count);
+	data += count;
 
 	if (hns->is_vf)
 		return 0;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v5 7/7] net/hns3: support filter dump of registers
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
                     ` (5 preceding siblings ...)
  2024-03-07  3:02   ` [PATCH v5 6/7] net/hns3: support filter directly accessed registers Jie Hai
@ 2024-03-07  3:02   ` Jie Hai
  6 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-03-07  3:02 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, haijie1

This patch supports reporting names of the dfx registers
which filtering them by names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 277 +++++++++++++++++++++++++++++------
 1 file changed, 230 insertions(+), 47 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 7c3bd162f067..8b6bf0a513fa 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,7 +12,8 @@
 
 #define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw,
+				uint32_t *count, const char *filter);
 
 struct direct_reg_list {
 	const char *name;
@@ -853,12 +854,41 @@ hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
 	return count;
 }
 
+static uint32_t
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, const char *filter)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+	uint32_t i;
+	uint32_t count = 0;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	for (i = 0 ; i < regs_num_32_bit; i++) {
+		if (filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	for (i = 0 ; i < regs_num_64_bit * HNS3_64_BIT_REG_SIZE; i++) {
+		if (filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, filter))
+			continue;
+		count++;
+	}
+	return count;
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
-	uint32_t regs_num_32_bit, regs_num_64_bit;
 	uint32_t dfx_reg_cnt;
 	uint32_t len;
 	int ret;
@@ -880,16 +910,9 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 	      tqp_intr_cnt * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
+		dfx_reg_cnt = hns3_get_32_64_regs_cnt(hw, filter);
 
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt, filter);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -903,19 +926,19 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
 }
 
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
 	struct hns3_cmd_desc *desc;
 	uint32_t *reg_val = data;
 	uint32_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_32_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_32_BIT_DESC_NODATA_LEN,
 			       HNS3_32_BIT_REG_RTN_DATANUM);
@@ -959,20 +982,68 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_32_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_32_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_32_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_32_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_32_bit_regs_filtered(struct hns3_hw *hw,
+			struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_32_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_32_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		rte_free(data);
+		return ret;
+	}
+
+	hns3_filter_32_bit_regs(regs, count, data);
+	return 0;
+}
+
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, void *data)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
 	struct hns3_cmd_desc *desc;
 	uint64_t *reg_val = data;
 	uint64_t *desc_data;
+	uint32_t regs_num;
 	int cmd_num;
 	int i, k, n;
 	int ret;
 
-	if (regs_num == 0)
-		return 0;
+	regs_num = RTE_DIM(regs_64_bit_list);
 
 	cmd_num = DIV_ROUND_UP(regs_num + HNS3_64_BIT_DESC_NODATA_LEN,
 			       HNS3_64_BIT_REG_RTN_DATANUM);
@@ -1016,6 +1087,54 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
+static void
+hns3_filter_64_bit_regs(struct rte_dev_reg_info *regs,
+			uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data;
+	regs_data = regs->data;
+	regs_data += *count;
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(regs_64_bit_list); i++) {
+		if (regs->filter != NULL &&
+			!strstr(regs_64_bit_list[i].new_name, regs->filter)) {
+			data++;
+			continue;
+		}
+		*regs_data++ = *data++;
+		if (regs->names == NULL)
+			continue;
+		snprintf(regs->names[(*count)++].name, RTE_ETH_REG_NAME_SIZE,
+			 "%s", regs_64_bit_list[i].new_name);
+	}
+}
+
+static int
+hns3_get_64_bit_regs_filtered(struct hns3_hw *hw,
+			      struct rte_dev_reg_info *regs, uint32_t *count)
+{
+	uint32_t *data;
+	int ret = 0;
+
+	if (count == NULL)
+		return -EINVAL;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * RTE_DIM(regs_64_bit_list), 0);
+	if (data == NULL)
+		return -ENOMEM;
+
+	ret = hns3_get_64_bit_regs(hw, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		goto out;
+	}
+
+	hns3_filter_64_bit_regs(regs, count, data);
+out:
+	rte_free(data);
+	return 0;
+}
 
 static uint32_t
 hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
@@ -1115,7 +1234,7 @@ hns3_direct_access_ring_reg(struct hns3_hw *hw,
 			if (regs->names == NULL)
 				continue;
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, ring_reg_list[i].name);
+				 "queue_%u_%s", j, ring_reg_list[i].name);
 		}
 	}
 
@@ -1146,7 +1265,7 @@ hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
 			if (regs->names == NULL)
 				continue;
 			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
-				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
+				 "queue_%u_%s", j, tqp_intr_reg_list[i].name);
 		}
 	}
 
@@ -1248,31 +1367,48 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count, const char *filter)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num, data_len, reg_num = 0;
+	const struct hns3_reg_entry *regs;
 	uint32_t bd_num_list[opcode_num];
+	uint32_t i, j;
 	int ret;
-	int i;
 
 	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < (uint32_t)opcode_num; i++) {
+		bd_num = bd_num_list[i];
+		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM;
+		if (data_len != hns3_dfx_reg_list[i].entry_num) {
+			hns3_err(hw, "The number of registers(%u) diff from registers list(%u)!\n",
+				 data_len, hns3_dfx_reg_list[i].entry_num);
+			return -EINVAL;
+		}
 
+		regs = hns3_dfx_reg_list[i].regs;
+		for (j = 0; j < data_len; j++) {
+			if (filter != NULL &&
+				!strstr(regs[j].new_name, filter))
+				continue;
+			reg_num++;
+		}
+	}
+
+	*count += reg_num;
 	return 0;
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, uint32_t *data)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
 	int ret;
 	int i;
 
@@ -1296,32 +1432,87 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+		data += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
+static void
+hns3_filter_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+		     uint32_t *count, uint32_t *data)
+{
+	uint32_t *regs_data = regs->data;
+	const char *name = NULL;
+	uint32_t i, j, cnt;
+
+	cnt = *count;
+	regs_data += cnt;
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++) {
+		for (j = 0; j < hns3_dfx_reg_list[i].entry_num; j++) {
+			if (hw->revision < PCI_REVISION_ID_HIP09_A &&
+				hns3_dfx_reg_list[i].regs[j].old_name != NULL)
+				name = hns3_dfx_reg_list[i].regs[j].old_name;
+			else
+				name = hns3_dfx_reg_list[i].regs[j].new_name;
+
+			if (regs->filter != NULL && !strstr(name, regs->filter)) {
+				data++;
+				continue;
+			}
+			*regs_data++ = *data++;
+
+			if (regs->names == NULL)
+				continue;
+			snprintf(regs->names[cnt++].name,
+				 RTE_ETH_REG_NAME_SIZE, "%s", name);
+		}
+	}
+	*count = cnt;
+}
+
+static int
+hns3_get_dfx_regs_filtered(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			   uint32_t *count)
+{
+	uint32_t reg_num = 0;
+	uint32_t *data;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < RTE_DIM(hns3_dfx_reg_list); i++)
+		reg_num += hns3_dfx_reg_list[i].entry_num;
+
+	data = rte_zmalloc(NULL, sizeof(uint32_t) * reg_num, 0);
+	if (data == NULL) {
+		hns3_err(hw, "No memory for dfx regs!\n");
+		return -ENOMEM;
+	}
+	ret = hns3_get_dfx_regs(hw, data);
+	if (ret != 0)
+		goto out;
+
+	hns3_filter_dfx_regs(hw, regs, count, data);
+out:
+	rte_free(data);
+	return ret;
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t count = 0;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length, regs->filter);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -1335,31 +1526,23 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 
 	/* fetching per-PF registers values from PF PCIe register space */
 	count = hns3_direct_access_regs(hw, regs, count);
-	data += count;
 
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
-	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
+	ret = hns3_get_32_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
+	ret = hns3_get_64_bit_regs_filtered(hw, regs, &count);
+	if (ret != 0) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
 
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	ret = hns3_get_dfx_regs_filtered(hw, regs, &count);
+	regs->length = count;
+	return 0;
 }
-- 
2.30.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 1/7] ethdev: support report register names and filter
  2024-03-07  3:02   ` [PATCH v5 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-03-08  8:09     ` lihuisong (C)
  0 siblings, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08  8:09 UTC (permalink / raw)
  To: Jie Hai
  Cc: fengchengwen, Thomas Monjalon, Andrew Rybchenko, Ferruh Yigit, dev

Hi Jie,

With belows to changes,
Acked-by: Huisong Li <lihuisong@huawei.com>

在 2024/3/7 11:02, Jie Hai 写道:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
>
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by names. And the original API
> rte_eth_dev_get_reg_info() does not use the names and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "offset_XXX".
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>   doc/guides/rel_notes/release_24_03.rst |  9 ++++++
>   lib/ethdev/rte_dev_info.h              | 11 ++++++++
>   lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
>   lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
>   lib/ethdev/version.map                 |  1 +
>   5 files changed, 88 insertions(+)
>
> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index 78590c047b2e..e491579ca984 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -161,6 +161,12 @@ New Features
>     * Added power-saving during polling within the ``rte_event_dequeue_burst()`` API.
>     * Added support for DMA adapter.
>   
<...>
> +int
> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>   {
>   	struct rte_eth_dev *dev;
> +	uint32_t i;
>   	int ret;
>   
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>   		return -EINVAL;
>   	}
>   
> +	if (info->names != NULL && info->length != 0)
> +		memset(info->names, 0,
> +			sizeof(struct rte_eth_reg_name) * info->length);
> +
>   	if (*dev->dev_ops->get_reg == NULL)
>   		return -ENOTSUP;
>   	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
>   
>   	rte_ethdev_trace_get_reg_info(port_id, info, ret);

The trace interface in lib/ethdev/ethdev_trace.h should be added these 
new fields?

>   
Below code shouldn't be executed when ret != 0, right?
> +	/* Report the default names if drivers not report. */
> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
> +		for (i = 0; i < info->length; i++)
> +			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
> +				"offset_%u", info->offset + i * info->width);
>   	return ret;
>   }
>   
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index ed27360447a3..cd95a0d51038 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5066,6 +5066,35 @@ __rte_experimental
>   int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>   		struct rte_power_monitor_cond *pmc);
>   
> +/**
> + * Retrieve the filtered device registers (values and names) and
> + * register attributes (number of registers and register size)
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param info
> + *   Pointer to rte_dev_reg_info structure to fill in.
> + *   - If info->filter is NULL, return info for all registers (seen as filter
> + *     none).
> + *   - If info->filter is not NULL, return error if the driver does not support
> + *     names or filter.
> + *   - If info->data is NULL, the function fills in the width and length fields.
> + *   - If info->data is not NULL, ethdev considers there are enough spaces to
> + *     store the registers, and the values of registers whose name contains the
> + *     filter string are put into the buffer pointed at by info->data.
> + *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
> + *     with default names.
> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EIO) if device is removed.
> + *   - others depends on the specific operations implementation.
> + */
> +__rte_experimental
> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
> +
>   /**
>    * Retrieve device registers and register attributes (number of registers and
>    * register size)
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index 79f6f5293b5c..e5ec2a2a9741 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -319,6 +319,7 @@ EXPERIMENTAL {
>   
>   	# added in 24.03
>   	__rte_eth_trace_tx_queue_count;
> +	rte_eth_dev_get_reg_info_ext;
>   	rte_eth_find_rss_algo;
>   	rte_flow_async_update_resized;
>   	rte_flow_calc_encap_hash;

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 2/7] ethdev: add telemetry cmd for registers
  2024-03-07  3:02   ` [PATCH v5 2/7] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-03-08  8:48     ` lihuisong (C)
  0 siblings, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08  8:48 UTC (permalink / raw)
  To: Jie Hai
  Cc: fengchengwen, dev, Thomas Monjalon, Andrew Rybchenko, Ferruh Yigit


在 2024/3/7 11:02, Jie Hai 写道:
> This patch adds a telemetry command for registers dump,
> and supports get registers with specified names.
> The length of the string exported by telemetry is limited
> by MAX_OUTPUT_LEN. Therefore, the filter should be more
> precise.
>
> An example usage is shown below:
> --> /ethdev/regs,0,INTR
> {
>    "/ethdev/regs": {
>      "registers_length": 318,
>      "registers_width": 4,
>      "register_offset": "0x0",
>      "version": "0x1140011",
>      "group_0": {
>        "HNS3_CMDQ_INTR_STS_REG": "0x0",
>        "HNS3_CMDQ_INTR_EN_REG": "0x2",
>        "HNS3_CMDQ_INTR_GEN_REG": "0x0",
>        "queue_0_HNS3_TQP_INTR_CTRL_REG": "0x0",
>        "queue_0_HNS3_TQP_INTR_GL0_REG": "0xa",
>        "queue_0_HNS3_TQP_INTR_GL1_REG": "0xa",
>        "queue_0_HNS3_TQP_INTR_GL2_REG": "0x0",
>        ...
>        },
>      "group_1": {
>          ...
>      },
>      ...
> }
>
> or as below if the number of registers not exceed the
> RTE_TEL_MAX_DICT_ENTRIES:
> --> /ethdev/regs,0,ppp
> {
>    "/ethdev/regs": {
>      "registers_length": 156,
>      "registers_width": 4,
>      "register_offset": "0x0",
>      "version": "0x1140011",
>      "ppp_key_drop_num": "0x0",
>      "ppp_rlt_drop_num": "0x0",
>      "ssu_ppp_mac_key_num_l": "0x1",
>      "ssu_ppp_mac_key_num_h": "0x0",
>      "ssu_ppp_host_key_num_l": "0x1",
>      "ssu_ppp_host_key_num_h": "0x0",
>      "ppp_ssu_mac_rlt_num_l": "0x1",
>          ...
>     }
> }
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>   lib/ethdev/rte_ethdev_telemetry.c | 158 ++++++++++++++++++++++++++++++
>   1 file changed, 158 insertions(+)
>
> diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
> index 6b873e7abe68..0c570792fb5f 100644
> --- a/lib/ethdev/rte_ethdev_telemetry.c
> +++ b/lib/ethdev/rte_ethdev_telemetry.c
> @@ -5,6 +5,7 @@
>   #include <ctype.h>
>   #include <stdlib.h>
>   
> +#include <rte_malloc.h>
>   #include <rte_kvargs.h>
>   #include <rte_telemetry.h>
>   
> @@ -1395,6 +1396,161 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
>   	return ret;
>   }
>   
> +static void
> +eth_dev_add_u32_hex(struct rte_tel_data *d, const char *name, uint32_t **data)
> +{
> +	if (*data == NULL)
> +		return;
> +	rte_tel_data_add_dict_uint_hex(d, name, **data, 0);
> +	(*data)++;
suggest that move "(*data)++" to the place after called this interface.
> +}
> +
> +static void
> +eth_dev_add_u64_hex(struct rte_tel_data *d, const char *name, uint64_t **data)
> +{
> +	if (*data == NULL)
> +		return;
> +	rte_tel_data_add_dict_uint_hex(d, name, **data, 0);
> +	(*data)++;
the same as above.
> +}
> +
> +static int
> +eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
> +{
> +	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
> +	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
> +	struct rte_tel_data *group = NULL;
> +	uint32_t *data0 = NULL;
> +	uint64_t *data1 = NULL;
> +	uint32_t grp_num = 0;
> +	int ret = 0;
> +	uint32_t i;
> +
> +	rte_tel_data_start_dict(d);
> +	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
> +	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
> +	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
> +	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
> +
> +	if (reg_info->width == sizeof(uint32_t))
> +		data0 = reg_info->data;
> +	else
> +		data1 = reg_info->data;
> +
> +	if (reg_info->length <= RTE_TEL_MAX_DICT_ENTRIES) {
> +		for (i = 0; i < reg_info->length; i++) {
> +			eth_dev_add_u32_hex(d, reg_info->names[i].name, &data0);
> +			eth_dev_add_u64_hex(d, reg_info->names[i].name, &data1);
Here adding u32_hex or u64_hex should depend on the reg_info->width, right?
Even though it is ok now due to the validity check in 
eth_dev_add_u32_hex and eth_dev_add_u64_hex.
Using the validity check to control the code flow is ok.
But u32 and u64 interface are parallel.
It's obvious that one of them will be selected for execution here.
So suggest that modify it as following logic:
"
if (reg_info->width == sizeof(uint32_t))
eth_dev_add_u32_hex(d, reg_info->names[i].name, &data0)
else
eth_dev_add_u64_hex(d, reg_info->names[i].name, &data1);
"
> +		}
> +		return 0;
> +	}
> +
> +	for (i = 0; i < reg_info->length; i++) {
> +		if (i % RTE_TEL_MAX_DICT_ENTRIES == 0) {
> +			group = rte_tel_data_alloc();
> +			if (group == NULL) {
> +				ret = -ENOMEM;
> +				goto out;
> +			}
> +			groups[grp_num++] = group;
> +			rte_tel_data_start_dict(group);
> +		}
> +		eth_dev_add_u32_hex(group, reg_info->names[i].name, &data0);
> +		eth_dev_add_u64_hex(group, reg_info->names[i].name, &data1);
> +	}
> +
> +	for (i = 0; i < grp_num; i++) {
> +		snprintf(group_name, RTE_TEL_MAX_STRING_LEN,
> +					"group_%u", i);
> +		rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
> +	}
> +	return 0;
> +out:
> +	for (i = 0; i < grp_num; i++)
> +		rte_tel_data_free(groups[i]);
> +
> +	return ret;
> +}
> +
> +static int
> +eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
> +{
> +	struct rte_dev_reg_info reg_info;
> +	uint32_t max_length;
> +	int ret;
> +
> +	memset(&reg_info, 0, sizeof(reg_info));
> +	reg_info.filter = filter;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Error getting device reg info: %d", ret);
> +		return ret;
> +	}
> +
> +	/* 4 is space for other information of registers. */
> +	max_length = RTE_TEL_MAX_DICT_ENTRIES *
> +			(RTE_TEL_MAX_DICT_ENTRIES - 4);
please define a macro for this "4" and add more detail description.
> +	if (reg_info.length > max_length) {
> +		RTE_ETHDEV_LOG_LINE(WARNING,
> +			"Reduced register number to be obtained from %u to %u due to limited memory",
> +			reg_info.length, max_length);
> +		reg_info.length = max_length;
> +	}
> +
> +	reg_info.data = calloc(reg_info.length, reg_info.width);
> +	if (reg_info.data == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Fail to allocate memory for reg_info.data");
> +		return -ENOMEM;
> +	}
> +
> +	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
> +	if (reg_info.names == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Fail to allocate memory for reg_info.names");
> +		free(reg_info.data);
> +		return -ENOMEM;
> +	}
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Error getting regs from device: %d", ret);
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	ret = eth_dev_store_regs(d, &reg_info);
> +out:
> +	free(reg_info.data);
> +	free(reg_info.names);
> +
> +	return ret;
> +}
> +
> +static int
> +eth_dev_handle_port_regs(const char *cmd __rte_unused,
> +		const char *params,
> +		struct rte_tel_data *d)
> +{
> +	char *filter = NULL;
> +	uint16_t port_id;
> +	char *end_param;
> +	int ret;
> +
> +	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
> +	if (ret != 0)
> +		return ret;
> +
> +	filter = strtok(end_param, ",");
> +	if (filter != NULL && strlen(filter) == 0)
> +		filter = NULL;
> +
> +	return eth_dev_get_port_regs(port_id, d, filter);
> +}
> +
>   RTE_INIT(ethdev_init_telemetry)
>   {
>   	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
> @@ -1436,4 +1592,6 @@ RTE_INIT(ethdev_init_telemetry)
>   			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
>   	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
>   			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
> +	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
> +			"Returns regs for a port. Parameters: int port_id, string filter");

"Returns all regs or specified type regs for a port. Parameters: int port_id, string filter"?

>   }

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 3/7] net/hns3: fix dump counter of registers
  2024-03-07  3:02   ` [PATCH v5 3/7] net/hns3: fix dump counter of registers Jie Hai
@ 2024-03-08  8:49     ` lihuisong (C)
  0 siblings, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08  8:49 UTC (permalink / raw)
  To: Jie Hai, dev, Yisen Zhuang, Chengchang Tang, Lijun Ou,
	Chunsong Feng, Wei Hu (Xavier), Min Hu (Connor),
	Ferruh Yigit
  Cc: fengchengwen

Acked-by: Huisong Li <lihuisong@huawei.com>

在 2024/3/7 11:02, Jie Hai 写道:
> Since the driver dumps the queue interrupt registers according
> to the intr_tqps_num, the counter should be the same.
>
> Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
> Fixes: 936eda25e8da ("net/hns3: support dump register")
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> Cc: stable@dpdk.org
> ---
>   drivers/net/hns3/hns3_regs.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index be1be6a89c94..d77170481a3d 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -135,7 +135,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
>   	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
>   
>   	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
> -	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
> +	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
>   
>   	if (!hns->is_vf) {
>   		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 4/7] net/hns3: remove dump format of registers
  2024-03-07  3:02   ` [PATCH v5 4/7] net/hns3: remove dump format " Jie Hai
@ 2024-03-08  9:17     ` lihuisong (C)
  0 siblings, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08  9:17 UTC (permalink / raw)
  To: Jie Hai; +Cc: fengchengwen, Yisen Zhuang, dev

Hi Jie,

A few trivial comments inline,
after changed, you can add
Reviewed-by: Huisong Li <lihuisong@huawei.com>


在 2024/3/7 11:02, Jie Hai 写道:
> Since the driver is going to support reporting names of
> all registers, remove the counter and insert of separators
> between different register modules.
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>   drivers/net/hns3/hns3_regs.c | 67 ++++++++++--------------------------
>   1 file changed, 18 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index d77170481a3d..b1c0d538a3c8 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -10,12 +10,9 @@
>   #include "hns3_rxtx.h"
>   #include "hns3_regs.h"
>   
> -#define MAX_SEPARATE_NUM	4
> -#define SEPARATOR_VALUE		0xFFFFFFFF
> -#define REG_NUM_PER_LINE	4
> -#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
> +#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
how about HNS3_64_BIT_REG_OUTPUT_SIZE?
>   
> -static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
> +static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
>   
>   static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
>   					  HNS3_CMDQ_TX_ADDR_H_REG,
> @@ -119,23 +116,22 @@ static int
>   hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
>   {
>   	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> -	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
> +	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
>   	uint32_t regs_num_32_bit, regs_num_64_bit;
> -	uint32_t dfx_reg_lines;
> +	uint32_t dfx_reg_cnt;
>   	uint32_t len;
>   	int ret;
>   
> -	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
> +	cmdq_cnt = sizeof(cmdq_reg_addrs);
>   	if (hns->is_vf)
> -		common_lines =
> -			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
> +		common_cnt = sizeof(common_vf_reg_addrs);
>   	else
> -		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
> -	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
> -	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
> +		common_cnt = sizeof(common_reg_addrs);
> +	ring_cnt = sizeof(ring_reg_addrs);
> +	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
>   
> -	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
> -	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
> +	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
> +	      tqp_intr_cnt * hw->intr_tqps_num;
remove these local variable like cmdq_cnt and comon_cnt and directly 
plus all sizeof()?
>   
>   	if (!hns->is_vf) {
>   		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
> @@ -144,18 +140,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
>   				 "ret = %d.", ret);
>   			return ret;
>   		}
> -		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
> -					REG_LEN_PER_LINE + 1;
> -		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
> -					REG_LEN_PER_LINE + 1;
> +		dfx_reg_cnt = regs_num_32_bit +
> +			      regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
>   
> -		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
> +		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
>   		if (ret) {
>   			hns3_err(hw, "fail to get the number of dfx registers, "
>   				 "ret = %d.", ret);
>   			return ret;
>   		}
> -		len += dfx_reg_lines * REG_NUM_PER_LINE;
> +		len += dfx_reg_cnt;
>   	}
>   
>   	*length = len;
> @@ -276,18 +270,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
>   	return 0;
>   }
>   
> -static int
> -hns3_insert_reg_separator(int reg_num, uint32_t *data)
> -{
> -	int separator_num;
> -	int i;
> -
> -	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
> -	for (i = 0; i < separator_num; i++)
> -		*data++ = SEPARATOR_VALUE;
> -	return separator_num;
> -}
> -
>   static int
>   hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
>   {
> @@ -302,7 +284,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
>   	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
>   	for (i = 0; i < reg_num; i++)
>   		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
> -	data += hns3_insert_reg_separator(reg_num, data);
>   
>   	if (hns->is_vf)
>   		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
> @@ -313,7 +294,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
>   			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
>   		else
>   			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
> -	data += hns3_insert_reg_separator(reg_num, data);
>   
>   	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
>   	for (j = 0; j < hw->tqps_num; j++) {
> @@ -321,7 +301,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
>   		for (i = 0; i < reg_num; i++)
>   			*data++ = hns3_read_dev(hw,
>   						ring_reg_addrs[i] + reg_offset);
> -		data += hns3_insert_reg_separator(reg_num, data);
>   	}
>   
>   	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
> @@ -330,7 +309,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
>   		for (i = 0; i < reg_num; i++)
>   			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
>   						reg_offset);
> -		data += hns3_insert_reg_separator(reg_num, data);
>   	}
>   	return data - origin_data_ptr;
>   }
> @@ -406,17 +384,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
>   		index = i % HNS3_CMD_DESC_DATA_NUM;
>   		*reg++ = desc[desc_index].data[index];
>   	}
> -	reg_num += hns3_insert_reg_separator(reg_num, reg);
>   
>   	return reg_num;
>   }
>   
>   static int
> -hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
> +hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
>   {
>   	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
>   	uint32_t bd_num_list[opcode_num];
> -	uint32_t bd_num, data_len;
>   	int ret;
>   	int i;
>   
> @@ -424,11 +400,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
hns3_get_dfx_reg_line --> hns3_get_dfx_reg_num?
>   	if (ret)
>   		return ret;
>   
> -	for (i = 0; i < opcode_num; i++) {
> -		bd_num = bd_num_list[i];
> -		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
> -		*lines += data_len / REG_LEN_PER_LINE + 1;
> -	}
> +	for (i = 0; i < opcode_num; i++)
> +		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
>   
>   	return 0;
>   }
> @@ -475,7 +448,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
>   int
>   hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>   {
> -#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
>   	struct hns3_adapter *hns = eth_dev->data->dev_private;
>   	struct hns3_hw *hw = &hns->hw;
>   	uint32_t regs_num_32_bit;
> @@ -520,7 +492,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>   		return ret;
>   	}
>   	data += regs_num_32_bit;
> -	data += hns3_insert_reg_separator(regs_num_32_bit, data);
>   
>   	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
>   	if (ret) {
> @@ -528,8 +499,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>   		return ret;
>   	}
>   	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
> -	data += hns3_insert_reg_separator(regs_num_64_bit *
> -					  HNS3_64_BIT_REG_SIZE, data);
>   
>   	return  hns3_get_dfx_regs(hw, (void **)&data);
>   }

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 6/7] net/hns3: support filter directly accessed registers
  2024-03-07  3:02   ` [PATCH v5 6/7] net/hns3: support filter directly accessed registers Jie Hai
@ 2024-03-08  9:41     ` lihuisong (C)
  0 siblings, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08  9:41 UTC (permalink / raw)
  To: Jie Hai; +Cc: fengchengwen, Yisen Zhuang, dev

Reviewed-by: Huisong Li <lihuisong@huawei.com>

在 2024/3/7 11:02, Jie Hai 写道:
> This patch supports reporting names of registers which
> can be directly accessed by addresses and filtering
> them by names.
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>   drivers/net/hns3/hns3_regs.c | 198 +++++++++++++++++++++++++++++------
>   1 file changed, 167 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index b7e4f78eecde..7c3bd162f067 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -837,8 +837,24 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>   	return 0;
>   }
>   
> +static uint32_t
> +hns3_get_direct_regs_cnt(const struct direct_reg_list *list,
> +			 uint32_t len, const char *filter)
> +{
> +	uint32_t i;
> +	uint32_t count = 0;
> +
> +	for (i = 0 ; i < len; i++) {
> +		if (filter != NULL && !strstr(list[i].name, filter))
> +			continue;
> +		count++;
> +	}
> +
> +	return count;
> +}
> +
>   static int
> -hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
> +hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length, const char *filter)
>   {
>   	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
>   	uint32_t cmdq_cnt, common_cnt, ring_cnt, tqp_intr_cnt;
> @@ -847,13 +863,18 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
>   	uint32_t len;
>   	int ret;
>   
> -	cmdq_cnt = RTE_DIM(cmdq_reg_list);
> +	cmdq_cnt = hns3_get_direct_regs_cnt(cmdq_reg_list,
> +					    RTE_DIM(cmdq_reg_list), filter);
>   	if (hns->is_vf)
> -		common_cnt = sizeof(common_vf_reg_list);
> +		common_cnt = hns3_get_direct_regs_cnt(common_vf_reg_list,
> +					RTE_DIM(common_vf_reg_list), filter);
>   	else
> -		common_cnt = RTE_DIM(common_reg_list);
> -	ring_cnt = RTE_DIM(ring_reg_list);
> -	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
> +		common_cnt = hns3_get_direct_regs_cnt(common_reg_list,
> +					RTE_DIM(common_reg_list), filter);
> +	ring_cnt = hns3_get_direct_regs_cnt(ring_reg_list,
> +					    RTE_DIM(ring_reg_list), filter);
> +	tqp_intr_cnt = hns3_get_direct_regs_cnt(tqp_intr_reg_list,
> +					RTE_DIM(tqp_intr_reg_list), filter);
>   
>   	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
>   	      tqp_intr_cnt * hw->intr_tqps_num;
> @@ -995,47 +1016,160 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
>   	return 0;
>   }
>   
> -static int
> -hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
> +
> +static uint32_t
> +hns3_direct_access_cmdq_reg(struct hns3_hw *hw,
> +			    struct rte_dev_reg_info *regs,
> +			    uint32_t count)
>   {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> -	uint32_t *origin_data_ptr = data;
> -	uint32_t reg_offset;
> +	uint32_t *data = regs->data;
>   	size_t reg_num;
> -	uint16_t j;
> +	data += count;
>   	size_t i;
>   
> -	/* fetching per-PF registers values from PF PCIe register space */
>   	reg_num = RTE_DIM(cmdq_reg_list);
> -	for (i = 0; i < reg_num; i++)
> +	for (i = 0; i < reg_num; i++) {
> +		if (regs->filter != NULL &&
> +			!strstr(cmdq_reg_list[i].name, regs->filter))
> +			continue;
>   		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
> +		if (regs->names == NULL)
> +			continue;
> +		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
> +			 "%s", cmdq_reg_list[i].name);
> +	}
>   
> -	if (hns->is_vf)
> -		reg_num = RTE_DIM(common_vf_reg_list);
> -	else
> -		reg_num = RTE_DIM(common_reg_list);
> -	for (i = 0; i < reg_num; i++)
> -		if (hns->is_vf)
> -			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
> -		else
> -			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
> +	return count;
> +}
> +static uint32_t
> +hns3_direct_access_common_reg(struct hns3_hw *hw,
> +			      struct rte_dev_reg_info *regs,
> +			      uint32_t count)
> +{
> +	uint32_t *data = regs->data;
> +	size_t reg_num;
> +	data += count;
> +	size_t i;
>   
> +	reg_num = RTE_DIM(common_reg_list);
> +	for (i = 0; i < reg_num; i++) {
> +		if (regs->filter != NULL &&
> +			!strstr(common_reg_list[i].name, regs->filter))
> +			continue;
> +		*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
> +		if (regs->names == NULL)
> +			continue;
> +		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
> +			 "%s", common_reg_list[i].name);
> +	}
> +
> +	return count;
> +}
> +
> +static uint32_t
> +hns3_direct_access_vf_common_reg(struct hns3_hw *hw,
> +				 struct rte_dev_reg_info *regs,
> +				 uint32_t count)
> +{
> +	uint32_t *data = regs->data;
> +	size_t reg_num;
> +	data += count;
> +	size_t i;
> +
> +	reg_num = RTE_DIM(common_vf_reg_list);
> +	for (i = 0; i < reg_num; i++) {
> +		if (regs->filter != NULL &&
> +			!strstr(common_vf_reg_list[i].name, regs->filter))
> +			continue;
> +		*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
> +		if (regs->names == NULL)
> +			continue;
> +		snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
> +			 "%s", common_vf_reg_list[i].name);
> +	}
> +
> +	return count;
> +}
> +
> +static uint32_t
> +hns3_direct_access_ring_reg(struct hns3_hw *hw,
> +			    struct rte_dev_reg_info *regs,
> +			    uint32_t count)
> +{
> +	uint32_t *data = regs->data;
> +	uint32_t reg_offset;
> +	size_t reg_num;
> +	uint16_t j;
> +	size_t i;
> +
> +	data += count;
>   	reg_num = RTE_DIM(ring_reg_list);
>   	for (j = 0; j < hw->tqps_num; j++) {
>   		reg_offset = hns3_get_tqp_reg_offset(j);
> -		for (i = 0; i < reg_num; i++)
> -			*data++ = hns3_read_dev(hw,
> -						ring_reg_list[i].addr + reg_offset);
> +		for (i = 0; i < reg_num; i++) {
> +			if (regs->filter != NULL &&
> +				!strstr(ring_reg_list[i].name, regs->filter))
> +				continue;
> +			*data++ = hns3_read_dev(hw, ring_reg_list[i].addr +
> +						    reg_offset);
> +			if (regs->names == NULL)
> +				continue;
> +			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
> +				"queue_%u_%s", j, ring_reg_list[i].name);
> +		}
>   	}
>   
> +	return count;
> +}
> +
> +static uint32_t
> +hns3_direct_access_tqp_intr_reg(struct hns3_hw *hw,
> +			    struct rte_dev_reg_info *regs,
> +			    uint32_t count)
> +{
> +	uint32_t *data = regs->data;
> +	uint32_t reg_offset;
> +	size_t reg_num;
> +	uint16_t j;
> +	size_t i;
> +
> +	data += count;
>   	reg_num = RTE_DIM(tqp_intr_reg_list);
>   	for (j = 0; j < hw->intr_tqps_num; j++) {
>   		reg_offset = hns3_get_tqp_intr_reg_offset(j);
> -		for (i = 0; i < reg_num; i++)
> +		for (i = 0; i < reg_num; i++) {
> +			if (regs->filter != NULL &&
> +				!strstr(tqp_intr_reg_list[i].name, regs->filter))
> +				continue;
>   			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
>   						reg_offset);
> +			if (regs->names == NULL)
> +				continue;
> +			snprintf(regs->names[count++].name, RTE_ETH_REG_NAME_SIZE,
> +				"queue_%u_%s", j, tqp_intr_reg_list[i].name);
> +		}
>   	}
> -	return data - origin_data_ptr;
> +
> +	return count;
> +}
> +
> +static uint32_t
> +hns3_direct_access_regs(struct hns3_hw *hw,
> +			struct rte_dev_reg_info *regs,
> +			uint32_t count)
> +{
> +	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> +
> +	count = hns3_direct_access_cmdq_reg(hw, regs, count);
> +	if (!hns->is_vf)
> +		count = hns3_direct_access_common_reg(hw, regs, count);
> +	else
> +		count = hns3_direct_access_vf_common_reg(hw, regs, count);
> +
> +	count = hns3_direct_access_ring_reg(hw, regs, count);
> +	count = hns3_direct_access_tqp_intr_reg(hw, regs, count);
> +
> +	return count;
>   }
>   
>   static int
> @@ -1177,11 +1311,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>   	struct hns3_hw *hw = &hns->hw;
>   	uint32_t regs_num_32_bit;
>   	uint32_t regs_num_64_bit;
> +	uint32_t count = 0;
>   	uint32_t length;
>   	uint32_t *data;
>   	int ret;
>   
> -	ret = hns3_get_regs_length(hw, &length);
> +	ret = hns3_get_regs_length(hw, &length, regs->filter);
>   	if (ret)
>   		return ret;
>   
> @@ -1193,13 +1328,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>   	}
>   
>   	/* Only full register dump is supported */
> -	if (regs->length && regs->length != length)
> +	if ((regs->length && regs->length != length))
>   		return -ENOTSUP;
>   
>   	regs->version = hw->fw_version;
>   
>   	/* fetching per-PF registers values from PF PCIe register space */
> -	data += hns3_direct_access_regs(hw, data);
> +	count = hns3_direct_access_regs(hw, regs, count);
> +	data += count;
>   
>   	if (hns->is_vf)
>   		return 0;

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 5/7] net/hns3: add names for registers
  2024-03-07  3:02   ` [PATCH v5 5/7] net/hns3: add names for registers Jie Hai
@ 2024-03-08  9:41     ` lihuisong (C)
  2024-03-08 10:24     ` lihuisong (C)
  1 sibling, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08  9:41 UTC (permalink / raw)
  To: Jie Hai, dev, Yisen Zhuang; +Cc: fengchengwen

Reviewed-by: Huisong Li <lihuisong@huawei.com>

在 2024/3/7 11:02, Jie Hai 写道:
> This patch adds names for all registers to be dumped.
> For those who can be directly accessed by their addresses,
> a new structure containing both name and address is added
> and the related arrays is refactored and renamed.
>
> For the remaining modules, there may be different meanings
> on different platforms for the same field. Therefore, two
> name fields are provided.
>
> There are some 64-bit registers, dump them as two 32-bit
> registers.
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>   drivers/net/hns3/hns3_regs.c | 877 ++++++++++++++++++++++++++++++++---
>   1 file changed, 801 insertions(+), 76 deletions(-)
>
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index b1c0d538a3c8..b7e4f78eecde 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -14,67 +14,84 @@
>   
>   static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
>   
> -static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
> -					  HNS3_CMDQ_TX_ADDR_H_REG,
> -					  HNS3_CMDQ_TX_DEPTH_REG,
> -					  HNS3_CMDQ_TX_TAIL_REG,
> -					  HNS3_CMDQ_TX_HEAD_REG,
> -					  HNS3_CMDQ_RX_ADDR_L_REG,
> -					  HNS3_CMDQ_RX_ADDR_H_REG,
> -					  HNS3_CMDQ_RX_DEPTH_REG,
> -					  HNS3_CMDQ_RX_TAIL_REG,
> -					  HNS3_CMDQ_RX_HEAD_REG,
> -					  HNS3_VECTOR0_CMDQ_SRC_REG,
> -					  HNS3_CMDQ_INTR_STS_REG,
> -					  HNS3_CMDQ_INTR_EN_REG,
> -					  HNS3_CMDQ_INTR_GEN_REG};
> -
> -static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
> -					    HNS3_VECTOR0_OTER_EN_REG,
> -					    HNS3_MISC_RESET_STS_REG,
> -					    HNS3_VECTOR0_OTHER_INT_STS_REG,
> -					    HNS3_GLOBAL_RESET_REG,
> -					    HNS3_FUN_RST_ING,
> -					    HNS3_GRO_EN_REG};
> -
> -static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
> -					       HNS3_FUN_RST_ING,
> -					       HNS3_GRO_EN_REG};
> -
> -static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
> -					  HNS3_RING_RX_BASEADDR_H_REG,
> -					  HNS3_RING_RX_BD_NUM_REG,
> -					  HNS3_RING_RX_BD_LEN_REG,
> -					  HNS3_RING_RX_EN_REG,
> -					  HNS3_RING_RX_MERGE_EN_REG,
> -					  HNS3_RING_RX_TAIL_REG,
> -					  HNS3_RING_RX_HEAD_REG,
> -					  HNS3_RING_RX_FBDNUM_REG,
> -					  HNS3_RING_RX_OFFSET_REG,
> -					  HNS3_RING_RX_FBD_OFFSET_REG,
> -					  HNS3_RING_RX_STASH_REG,
> -					  HNS3_RING_RX_BD_ERR_REG,
> -					  HNS3_RING_TX_BASEADDR_L_REG,
> -					  HNS3_RING_TX_BASEADDR_H_REG,
> -					  HNS3_RING_TX_BD_NUM_REG,
> -					  HNS3_RING_TX_EN_REG,
> -					  HNS3_RING_TX_PRIORITY_REG,
> -					  HNS3_RING_TX_TC_REG,
> -					  HNS3_RING_TX_MERGE_EN_REG,
> -					  HNS3_RING_TX_TAIL_REG,
> -					  HNS3_RING_TX_HEAD_REG,
> -					  HNS3_RING_TX_FBDNUM_REG,
> -					  HNS3_RING_TX_OFFSET_REG,
> -					  HNS3_RING_TX_EBD_NUM_REG,
> -					  HNS3_RING_TX_EBD_OFFSET_REG,
> -					  HNS3_RING_TX_BD_ERR_REG,
> -					  HNS3_RING_EN_REG};
> -
> -static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
> -					      HNS3_TQP_INTR_GL0_REG,
> -					      HNS3_TQP_INTR_GL1_REG,
> -					      HNS3_TQP_INTR_GL2_REG,
> -					      HNS3_TQP_INTR_RL_REG};
> +struct direct_reg_list {
> +	const char *name;
> +	uint32_t addr;
> +};
> +
> +#define STR(s) #s
> +
> +static const struct direct_reg_list cmdq_reg_list[] = {
> +	{STR(HNS3_CMDQ_TX_ADDR_L_REG),		HNS3_CMDQ_TX_ADDR_L_REG},
> +	{STR(HNS3_CMDQ_TX_ADDR_H_REG),		HNS3_CMDQ_TX_ADDR_H_REG},
> +	{STR(HNS3_CMDQ_TX_DEPTH_REG),		HNS3_CMDQ_TX_DEPTH_REG},
> +	{STR(HNS3_CMDQ_TX_TAIL_REG),		HNS3_CMDQ_TX_TAIL_REG},
> +	{STR(HNS3_CMDQ_TX_HEAD_REG),		HNS3_CMDQ_TX_HEAD_REG},
> +	{STR(HNS3_CMDQ_RX_ADDR_L_REG),		HNS3_CMDQ_RX_ADDR_L_REG},
> +	{STR(HNS3_CMDQ_RX_ADDR_H_REG),		HNS3_CMDQ_RX_ADDR_H_REG},
> +	{STR(HNS3_CMDQ_RX_DEPTH_REG),		HNS3_CMDQ_RX_DEPTH_REG},
> +	{STR(HNS3_CMDQ_RX_TAIL_REG),		HNS3_CMDQ_RX_TAIL_REG},
> +	{STR(HNS3_CMDQ_RX_HEAD_REG),		HNS3_CMDQ_RX_HEAD_REG},
> +	{STR(HNS3_VECTOR0_CMDQ_SRC_REG),	HNS3_VECTOR0_CMDQ_SRC_REG},
> +	{STR(HNS3_CMDQ_INTR_STS_REG),		HNS3_CMDQ_INTR_STS_REG},
> +	{STR(HNS3_CMDQ_INTR_EN_REG),		HNS3_CMDQ_INTR_EN_REG},
> +	{STR(HNS3_CMDQ_INTR_GEN_REG),		HNS3_CMDQ_INTR_GEN_REG},
> +};
> +
> +static const struct direct_reg_list common_reg_list[] = {
> +	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
> +	{STR(HNS3_VECTOR0_OTER_EN_REG),		HNS3_VECTOR0_OTER_EN_REG},
> +	{STR(HNS3_MISC_RESET_STS_REG),		HNS3_MISC_RESET_STS_REG},
> +	{STR(HNS3_VECTOR0_OTHER_INT_STS_REG),	HNS3_VECTOR0_OTHER_INT_STS_REG},
> +	{STR(HNS3_GLOBAL_RESET_REG),		HNS3_GLOBAL_RESET_REG},
> +	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
> +	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
> +};
> +
> +static const struct direct_reg_list common_vf_reg_list[] = {
> +	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
> +	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
> +	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
> +};
> +
> +static const struct direct_reg_list ring_reg_list[] = {
> +	{STR(HNS3_RING_RX_BASEADDR_L_REG),	HNS3_RING_RX_BASEADDR_L_REG},
> +	{STR(HNS3_RING_RX_BASEADDR_H_REG),	HNS3_RING_RX_BASEADDR_H_REG},
> +	{STR(HNS3_RING_RX_BD_NUM_REG),		HNS3_RING_RX_BD_NUM_REG},
> +	{STR(HNS3_RING_RX_BD_LEN_REG),		HNS3_RING_RX_BD_LEN_REG},
> +	{STR(HNS3_RING_RX_EN_REG),		HNS3_RING_RX_EN_REG},
> +	{STR(HNS3_RING_RX_MERGE_EN_REG),	HNS3_RING_RX_MERGE_EN_REG},
> +	{STR(HNS3_RING_RX_TAIL_REG),		HNS3_RING_RX_TAIL_REG},
> +	{STR(HNS3_RING_RX_HEAD_REG),		HNS3_RING_RX_HEAD_REG},
> +	{STR(HNS3_RING_RX_FBDNUM_REG),		HNS3_RING_RX_FBDNUM_REG},
> +	{STR(HNS3_RING_RX_OFFSET_REG),		HNS3_RING_RX_OFFSET_REG},
> +	{STR(HNS3_RING_RX_FBD_OFFSET_REG),	HNS3_RING_RX_FBD_OFFSET_REG},
> +	{STR(HNS3_RING_RX_STASH_REG),		HNS3_RING_RX_STASH_REG},
> +	{STR(HNS3_RING_RX_BD_ERR_REG),		HNS3_RING_RX_BD_ERR_REG},
> +	{STR(HNS3_RING_TX_BASEADDR_L_REG),	HNS3_RING_TX_BASEADDR_L_REG},
> +	{STR(HNS3_RING_TX_BASEADDR_H_REG),	HNS3_RING_TX_BASEADDR_H_REG},
> +	{STR(HNS3_RING_TX_BD_NUM_REG),		HNS3_RING_TX_BD_NUM_REG},
> +	{STR(HNS3_RING_TX_EN_REG),		HNS3_RING_TX_EN_REG},
> +	{STR(HNS3_RING_TX_PRIORITY_REG),	HNS3_RING_TX_PRIORITY_REG},
> +	{STR(HNS3_RING_TX_TC_REG),		HNS3_RING_TX_TC_REG},
> +	{STR(HNS3_RING_TX_MERGE_EN_REG),	HNS3_RING_TX_MERGE_EN_REG},
> +	{STR(HNS3_RING_TX_TAIL_REG),		HNS3_RING_TX_TAIL_REG},
> +	{STR(HNS3_RING_TX_HEAD_REG),		HNS3_RING_TX_HEAD_REG},
> +	{STR(HNS3_RING_TX_FBDNUM_REG),		HNS3_RING_TX_FBDNUM_REG},
> +	{STR(HNS3_RING_TX_OFFSET_REG),		HNS3_RING_TX_OFFSET_REG},
> +	{STR(HNS3_RING_TX_EBD_NUM_REG),		HNS3_RING_TX_EBD_NUM_REG},
> +	{STR(HNS3_RING_TX_EBD_OFFSET_REG),	HNS3_RING_TX_EBD_OFFSET_REG},
> +	{STR(HNS3_RING_TX_BD_ERR_REG),		HNS3_RING_TX_BD_ERR_REG},
> +	{STR(HNS3_RING_EN_REG),			HNS3_RING_EN_REG},
> +};
> +
> +static const struct direct_reg_list tqp_intr_reg_list[] = {
> +	{STR(HNS3_TQP_INTR_CTRL_REG),	HNS3_TQP_INTR_CTRL_REG},
> +	{STR(HNS3_TQP_INTR_GL0_REG),	HNS3_TQP_INTR_GL0_REG},
> +	{STR(HNS3_TQP_INTR_GL1_REG),	HNS3_TQP_INTR_GL1_REG},
> +	{STR(HNS3_TQP_INTR_GL2_REG),	HNS3_TQP_INTR_GL2_REG},
> +	{STR(HNS3_TQP_INTR_RL_REG),	HNS3_TQP_INTR_RL_REG},
> +};
>   
>   static const uint32_t hns3_dfx_reg_opcode_list[] = {
>   	HNS3_OPC_DFX_BIOS_COMMON_REG,
> @@ -91,6 +108,708 @@ static const uint32_t hns3_dfx_reg_opcode_list[] = {
>   	HNS3_OPC_DFX_SSU_REG_2
>   };
>   
> +struct hns3_reg_entry {
> +	const char *new_name;
> +	const char *old_name;
> +};
> +
> +static struct hns3_reg_entry regs_32_bit_list[] = {
> +	{"ssu_common_err_int"},
> +	{"ssu_port_based_err_int"},
> +	{"ssu_fifo_overflow_int"},
> +	{"ssu_ets_tcg_int"},
> +	{"ssu_bp_status_0"},
> +	{"ssu_bp_status_1"},
> +
> +	{"ssu_bp_status_2"},
> +	{"ssu_bp_status_3"},
> +	{"ssu_bp_status_4"},
> +	{"ssu_bp_status_5"},
> +	{"ssu_mac_tx_pfc_ind"},
> +	{"ssu_mac_rx_pfc_ind"},
> +
> +	{"ssu_rx_oq_drop_pkt_cnt"},
> +	{"ssu_tx_oq_drop_pkt_cnt"},
> +};
> +
> +static struct hns3_reg_entry regs_64_bit_list[] = {
> +	{"ppp_get_rx_pkt_cnt_l"},
> +	{"ppp_get_rx_pkt_cnt_h"},
> +	{"ppp_get_tx_pkt_cnt_l"},
> +	{"ppp_get_tx_pkt_cnt_h"},
> +	{"ppp_send_uc_prt2host_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2host_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
> +	{"ppp_send_uc_host2host_pkt_cnt_l"},
> +	{"ppp_send_uc_host2host_pkt_cnt_h"},
> +	{"ppp_send_uc_host2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_host2prt_pkt_cnt_h"},
> +	{"ppp_send_mc_from_prt_cnt_l"},
> +	{"ppp_send_mc_from_prt_cnt_h"},
> +};
> +
> +static struct hns3_reg_entry dfx_bios_common_reg_list[] = {
> +	{"bios_rsv0"},
> +	{"bp_cpu_state"},
> +	{"dfx_msix_info_nic_0"},
> +	{"dfx_msix_info_nic_1"},
> +	{"dfx_msix_info_nic_2"},
> +	{"dfx_msix_info_nic_3"},
> +
> +	{"dfx_msix_info_roce_0"},
> +	{"dfx_msix_info_roce_1"},
> +	{"dfx_msix_info_roce_2"},
> +	{"dfx_msix_info_roce_3"},
> +	{"bios_rsv1"},
> +	{"bios_rsv2"},
> +};
> +
> +static struct hns3_reg_entry dfx_ssu_reg_0_list[] = {
> +	{"dfx_ssu0_rsv0"},
> +	{"ssu_ets_port_status"},
> +	{"ssu_ets_tcg_status"},
> +	{"dfx_ssu0_rsv1"},
> +	{"dfx_ssu0_rsv2"},
> +	{"ssu_bp_status_0"},
> +
> +	{"ssu_bp_status_1"},
> +	{"ssu_bp_status_2"},
> +	{"ssu_bp_status_3"},
> +	{"ssu_bp_status_4"},
> +	{"ssu_bp_status_5"},
> +	{"ssu_mac_tx_pfc_ind"},
> +
> +	{"mac_ssu_rx_pfc_ind"},
> +	{"ssu_btmp_ageing_st_b0"},
> +	{"ssu_btmp_ageing_st_b1"},
> +	{"ssu_btmp_ageing_st_b2"},
> +	{"dfx_ssu0_rsv3"},
> +	{"dfx_ssu0_rsv4"},
> +
> +	{"ssu_full_drop_num"},
> +	{"ssu_part_drop_num"},
> +	{"ppp_key_drop_num"},
> +	{"ppp_rlt_drop_num"},
> +	{"ssu_lo_pri_unicast_rlt_drop_num"},
> +	{"ssu_hi_pri_multicast_rlt_drop_num"},
> +
> +	{"ssu_lo_pri_multicast_rlt_drop_num"},
> +	{"ssu_ncsi_packet_curr_buffer_cnt"},
> +	{"dfx_ssu0_rsv5",		"ssu_btmp_ageing_rls_cnt_bank0"},
> +	{"dfx_ssu0_rsv6",		"ssu_btmp_ageing_rls_cnt_bank1"},
> +	{"dfx_ssu0_rsv7",		"ssu_btmp_ageing_rls_cnt_bank2"},
> +	{"ssu_mb_rd_rlt_drop_cnt"},
> +
> +	{"ssu_ppp_mac_key_num_l"},
> +	{"ssu_ppp_mac_key_num_h"},
> +	{"ssu_ppp_host_key_num_l"},
> +	{"ssu_ppp_host_key_num_h"},
> +	{"ppp_ssu_mac_rlt_num_l"},
> +	{"ppp_ssu_mac_rlt_num_h"},
> +
> +	{"ppp_ssu_host_rlt_num_l"},
> +	{"ppp_ssu_host_rlt_num_h"},
> +	{"ssu_ncsi_rx_packet_in_cnt_l"},
> +	{"ssu_ncsi_rx_packet_in_cnt_h"},
> +	{"ssu_ncsi_tx_packet_out_cnt_l"},
> +	{"ssu_ncsi_tx_packet_out_cnt_h"},
> +
> +	{"ssu_key_drop_num"},
> +	{"ssu_mb_uncopy_num"},
> +	{"ssu_rx_oq_drop_pkt_cnt"},
> +	{"ssu_tx_oq_drop_pkt_cnt"},
> +	{"ssu_bank_unbalance_drop_cnt"},
> +	{"ssu_bank_unbalance_rx_drop_cnt"},
> +
> +	{"ssu_nic_l2_eer_drop_pkt_cnt"},
> +	{"ssu_roc_l2_eer_drop_pkt_cnt"},
> +	{"ssu_nic_l2_eer_drop_pkt_cnt_rx"},
> +	{"ssu_roc_l2_eer_drop_pkt_cnt_rx"},
> +	{"ssu_rx_oq_glb_drop_pkt_cnt"},
> +	{"ssu_dfx_ssu0_rsv8"},
> +
> +	{"ssu_lo_pri_unicast_cur_cnt"},
> +	{"ssu_hi_pri_multicast_cur_cnt"},
> +	{"ssu_lo_pri_multicast_cur_cnt"},
> +	{"dfx_ssu0_rsv9"},
> +	{"dfx_ssu0_rsv10"},
> +	{"dfx_ssu0_rsv11"},
> +};
> +
> +static struct hns3_reg_entry dfx_ssu_reg_1_list[] = {
> +	{"dfx_ssu1_prt_id"},
> +	{"ssu_packet_tc_curr_buffer_cnt_0"},
> +	{"ssu_packet_tc_curr_buffer_cnt_1"},
> +	{"ssu_packet_tc_curr_buffer_cnt_2"},
> +	{"ssu_packet_tc_curr_buffer_cnt_3"},
> +	{"ssu_packet_tc_curr_buffer_cnt_4"},
> +
> +	{"ssu_packet_tc_curr_buffer_cnt_5"},
> +	{"ssu_packet_tc_curr_buffer_cnt_6"},
> +	{"ssu_packet_tc_curr_buffer_cnt_7"},
> +	{"ssu_packet_curr_buffer_cnt"},
> +	{"dfx_ssu1_rsv0"},
> +	{"dfx_ssu1_rsv1"},
> +
> +	{"ssu_rx_packet_in_cnt_l"},
> +	{"ssu_rx_packet_in_cnt_h"},
> +	{"ssu_rx_packet_out_cnt_l"},
> +	{"ssu_rx_packet_out_cnt_h"},
> +	{"ssu_tx_packet_in_cnt_l"},
> +	{"ssu_tx_packet_in_cnt_h"},
> +
> +	{"ssu_tx_packet_out_cnt_l"},
> +	{"ssu_tx_packet_out_cnt_h"},
> +	{"ssu_roc_rx_packet_in_cnt_l"},
> +	{"ssu_roc_rx_packet_in_cnt_h"},
> +	{"ssu_roc_tx_packet_in_cnt_l"},
> +	{"ssu_roc_tx_packet_in_cnt_h"},
> +
> +	{"ssu_rx_packet_tc_in_cnt_0_l"},
> +	{"ssu_rx_packet_tc_in_cnt_0_h"},
> +	{"ssu_rx_packet_tc_in_cnt_1_l"},
> +	{"ssu_rx_packet_tc_in_cnt_1_h"},
> +	{"ssu_rx_packet_tc_in_cnt_2_l"},
> +	{"ssu_rx_packet_tc_in_cnt_2_h"},
> +
> +	{"ssu_rx_packet_tc_in_cnt_3_l"},
> +	{"ssu_rx_packet_tc_in_cnt_3_h"},
> +	{"ssu_rx_packet_tc_in_cnt_4_l"},
> +	{"ssu_rx_packet_tc_in_cnt_4_h"},
> +	{"ssu_rx_packet_tc_in_cnt_5_l"},
> +	{"ssu_rx_packet_tc_in_cnt_5_h"},
> +
> +	{"ssu_rx_packet_tc_in_cnt_6_l"},
> +	{"ssu_rx_packet_tc_in_cnt_6_h"},
> +	{"ssu_rx_packet_tc_in_cnt_7_l"},
> +	{"ssu_rx_packet_tc_in_cnt_7_h"},
> +	{"ssu_rx_packet_tc_out_cnt_0_l"},
> +	{"ssu_rx_packet_tc_out_cnt_0_h"},
> +
> +	{"ssu_rx_packet_tc_out_cnt_1_l"},
> +	{"ssu_rx_packet_tc_out_cnt_1_h"},
> +	{"ssu_rx_packet_tc_out_cnt_2_l"},
> +	{"ssu_rx_packet_tc_out_cnt_2_h"},
> +	{"ssu_rx_packet_tc_out_cnt_3_l"},
> +	{"ssu_rx_packet_tc_out_cnt_3_h"},
> +
> +	{"ssu_rx_packet_tc_out_cnt_4_l"},
> +	{"ssu_rx_packet_tc_out_cnt_4_h"},
> +	{"ssu_rx_packet_tc_out_cnt_5_l"},
> +	{"ssu_rx_packet_tc_out_cnt_5_h"},
> +	{"ssu_rx_packet_tc_out_cnt_6_l"},
> +	{"ssu_rx_packet_tc_out_cnt_6_h"},
> +
> +	{"ssu_rx_packet_tc_out_cnt_7_l"},
> +	{"ssu_rx_packet_tc_out_cnt_7_h"},
> +	{"ssu_tx_packet_tc_in_cnt_0_l"},
> +	{"ssu_tx_packet_tc_in_cnt_0_h"},
> +	{"ssu_tx_packet_tc_in_cnt_1_l"},
> +	{"ssu_tx_packet_tc_in_cnt_1_h"},
> +
> +	{"ssu_tx_packet_tc_in_cnt_2_l"},
> +	{"ssu_tx_packet_tc_in_cnt_2_h"},
> +	{"ssu_tx_packet_tc_in_cnt_3_l"},
> +	{"ssu_tx_packet_tc_in_cnt_3_h"},
> +	{"ssu_tx_packet_tc_in_cnt_4_l"},
> +	{"ssu_tx_packet_tc_in_cnt_4_h"},
> +
> +	{"ssu_tx_packet_tc_in_cnt_5_l"},
> +	{"ssu_tx_packet_tc_in_cnt_5_h"},
> +	{"ssu_tx_packet_tc_in_cnt_6_l"},
> +	{"ssu_tx_packet_tc_in_cnt_6_h"},
> +	{"ssu_tx_packet_tc_in_cnt_7_l"},
> +	{"ssu_tx_packet_tc_in_cnt_7_h"},
> +
> +	{"ssu_tx_packet_tc_out_cnt_0_l"},
> +	{"ssu_tx_packet_tc_out_cnt_0_h"},
> +	{"ssu_tx_packet_tc_out_cnt_1_l"},
> +	{"ssu_tx_packet_tc_out_cnt_1_h"},
> +	{"ssu_tx_packet_tc_out_cnt_2_l"},
> +	{"ssu_tx_packet_tc_out_cnt_2_h"},
> +
> +	{"ssu_tx_packet_tc_out_cnt_3_l"},
> +	{"ssu_tx_packet_tc_out_cnt_3_h"},
> +	{"ssu_tx_packet_tc_out_cnt_4_l"},
> +	{"ssu_tx_packet_tc_out_cnt_4_h"},
> +	{"ssu_tx_packet_tc_out_cnt_5_l"},
> +	{"ssu_tx_packet_tc_out_cnt_5_h"},
> +
> +	{"ssu_tx_packet_tc_out_cnt_6_l"},
> +	{"ssu_tx_packet_tc_out_cnt_6_h"},
> +	{"ssu_tx_packet_tc_out_cnt_7_l"},
> +	{"ssu_tx_packet_tc_out_cnt_7_h"},
> +	{"dfx_ssu1_rsv2"},
> +	{"dfx_ssu1_rsv3"},
> +};
> +
> +static struct hns3_reg_entry dfx_igu_egu_reg_list[] = {
> +	{"igu_egu_prt_id"},
> +	{"igu_rx_err_pkt"},
> +	{"igu_rx_no_sof_pkt"},
> +	{"egu_tx_1588_short_pkt"},
> +	{"egu_tx_1588_pkt"},
> +	{"egu_tx_1588_err_pkt"},
> +
> +	{"igu_rx_out_l2_pkt"},
> +	{"igu_rx_out_l3_pkt"},
> +	{"igu_rx_out_l4_pkt"},
> +	{"igu_rx_in_l2_pkt"},
> +	{"igu_rx_in_l3_pkt"},
> +	{"igu_rx_in_l4_pkt"},
> +
> +	{"igu_rx_el3e_pkt"},
> +	{"igu_rx_el4e_pkt"},
> +	{"igu_rx_l3e_pkt"},
> +	{"igu_rx_l4e_pkt"},
> +	{"igu_rx_rocee_pkt"},
> +	{"igu_rx_out_udp0_pkt"},
> +
> +	{"igu_rx_in_udp0_pkt"},
> +	{"igu_egu_mul_car_drop_pkt_cnt_l",	"igu_egu_rsv0"},
> +	{"igu_egu_mul_car_drop_pkt_cnt_h",	"igu_egu_rsv1"},
> +	{"igu_egu_bro_car_drop_pkt_cnt_l",	"igu_egu_rsv2"},
> +	{"igu_egu_bro_car_drop_pkt_cnt_h",	"igu_egu_rsv3"},
> +	{"igu_egu_rsv0",		"igu_egu_rsv4"},
> +
> +	{"igu_rx_oversize_pkt_l"},
> +	{"igu_rx_oversize_pkt_h"},
> +	{"igu_rx_undersize_pkt_l"},
> +	{"igu_rx_undersize_pkt_h"},
> +	{"igu_rx_out_all_pkt_l"},
> +	{"igu_rx_out_all_pkt_h"},
> +
> +	{"igu_tx_out_all_pkt_l"},
> +	{"igu_tx_out_all_pkt_h"},
> +	{"igu_rx_uni_pkt_l"},
> +	{"igu_rx_uni_pkt_h"},
> +	{"igu_rx_multi_pkt_l"},
> +	{"igu_rx_multi_pkt_h"},
> +
> +	{"igu_rx_broad_pkt_l"},
> +	{"igu_rx_broad_pkt_h"},
> +	{"egu_tx_out_all_pkt_l"},
> +	{"egu_tx_out_all_pkt_h"},
> +	{"egu_tx_uni_pkt_l"},
> +	{"egu_tx_uni_pkt_h"},
> +
> +	{"egu_tx_multi_pkt_l"},
> +	{"egu_tx_multi_pkt_h"},
> +	{"egu_tx_broad_pkt_l"},
> +	{"egu_tx_broad_pkt_h"},
> +	{"igu_tx_key_num_l"},
> +	{"igu_tx_key_num_h"},
> +
> +	{"igu_rx_non_tun_pkt_l"},
> +	{"igu_rx_non_tun_pkt_h"},
> +	{"igu_rx_tun_pkt_l"},
> +	{"igu_rx_tun_pkt_h"},
> +	{"igu_egu_rsv5"},
> +	{"igu_egu_rsv6"},
> +};
> +
> +static struct hns3_reg_entry dfx_rpu_reg_0_list[] = {
> +	{"rpu_currport_tnl_index",	"rpu_tc_queue_num"},
> +	{"rpu_fsm_dfx_st0"},
> +	{"rpu_fsm_dfx_st1"},
> +	{"rpu_rpu_rx_pkt_drop_cnt"},
> +	{"rpu_buf_wait_timeout"},
> +	{"rpu_buf_wait_timeout_qid"},
> +};
> +
> +static struct hns3_reg_entry dfx_rpu_reg_1_list[] = {
> +	{"rpu_rsv0"},
> +	{"rpu_fifo_dfx_st0"},
> +	{"rpu_fifo_dfx_st1"},
> +	{"rpu_fifo_dfx_st2"},
> +	{"rpu_fifo_dfx_st3"},
> +	{"rpu_fifo_dfx_st4"},
> +
> +	{"rpu_fifo_dfx_st5"},
> +	{"rpu_rsv1"},
> +	{"rpu_rsv2"},
> +	{"rpu_rsv3"},
> +	{"rpu_rsv4"},
> +	{"rpu_rsv5"},
> +};
> +
> +static struct hns3_reg_entry dfx_ncsi_reg_list[] = {
> +	{"ncsi_rsv0"},
> +	{"ncsi_egu_tx_fifo_sts"},
> +	{"ncsi_pause_status"},
> +	{"ncsi_rx_ctrl_dmac_err_cnt"},
> +	{"ncsi_rx_ctrl_smac_err_cnt"},
> +	{"ncsi_rx_ctrl_cks_err_cnt"},
> +
> +	{"ncsi_rx_ctrl_pkt_err_cnt"},
> +	{"ncsi_rx_pt_dmac_err_cnt"},
> +	{"ncsi_rx_pt_smac_err_cnt"},
> +	{"ncsi_rx_pt_pkt_cnt"},
> +	{"ncsi_rx_fcs_err_cnt"},
> +	{"ncsi_tx_ctrl_dmac_err_cnt"},
> +
> +	{"ncsi_tx_ctrl_smac_err_cnt"},
> +	{"ncsi_tx_ctrl_pkt_cnt"},
> +	{"ncsi_tx_pt_dmac_err_cnt"},
> +	{"ncsi_tx_pt_smac_err_cnt"},
> +	{"ncsi_tx_pt_pkt_cnt"},
> +	{"ncsi_tx_pt_pkt_trun_cnt"},
> +
> +	{"ncsi_tx_pt_pkt_err_cnt"},
> +	{"ncsi_tx_ctrl_pkt_err_cnt"},
> +	{"ncsi_rx_ctrl_pkt_trun_cnt"},
> +	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
> +	{"ncsi_rsv1"},
> +	{"ncsi_rsv2"},
> +
> +	{"ncsi_mac_rx_octets_ok"},
> +	{"ncsi_mac_rx_octets_bad"},
> +	{"ncsi_mac_rx_uc_pkts"},
> +	{"ncsi_mac_rx_mc_pkts"},
> +	{"ncsi_mac_rx_bc_pkts"},
> +	{"ncsi_mac_rx_pkts_64octets"},
> +
> +	{"ncsi_mac_rx_pkts_64to127_octets"},
> +	{"ncsi_mac_rx_pkts_128to255_octets"},
> +	{"ncsi_mac_rx_pkts_256to511_octets"},
> +	{"ncsi_mac_rx_pkts_512to1023_octets"},
> +	{"ncsi_mac_rx_pkts_1024to1518_octets"},
> +	{"ncsi_mac_rx_pkts_1519tomax_octets"},
> +
> +	{"ncsi_mac_rx_fcs_errors"},
> +	{"ncsi_mac_rx_long_errors"},
> +	{"ncsi_mac_rx_jabber_errors"},
> +	{"ncsi_mac_rx_runt_err_cnt"},
> +	{"ncsi_mac_rx_short_err_cnt"},
> +	{"ncsi_mac_rx_filt_pkt_cnt"},
> +
> +	{"ncsi_mac_rx_octets_total_filt"},
> +	{"ncsi_mac_tx_octets_ok"},
> +	{"ncsi_mac_tx_octets_bad"},
> +	{"ncsi_mac_tx_uc_pkts"},
> +	{"ncsi_mac_tx_mc_pkts"},
> +	{"ncsi_mac_tx_bc_pkts"},
> +
> +	{"ncsi_mac_tx_pkts_64octets"},
> +	{"ncsi_mac_tx_pkts_64to127_octets"},
> +	{"ncsi_mac_tx_pkts_128to255_octets"},
> +	{"ncsi_mac_tx_pkts_256to511_octets"},
> +	{"ncsi_mac_tx_pkts_512to1023_octets"},
> +	{"ncsi_mac_tx_pkts_1024to1518_octets"},
> +
> +	{"ncsi_mac_tx_pkts_1519tomax_octets"},
> +	{"ncsi_mac_tx_underrun"},
> +	{"ncsi_mac_tx_crc_error"},
> +	{"ncsi_mac_tx_pause_frames"},
> +	{"ncsi_mac_rx_pad_pkts"},
> +	{"ncsi_mac_rx_pause_frames"},
> +};
> +
> +static struct hns3_reg_entry dfx_rtc_reg_list[] = {
> +	{"rtc_rsv0"},
> +	{"lge_igu_afifo_dfx_0"},
> +	{"lge_igu_afifo_dfx_1"},
> +	{"lge_igu_afifo_dfx_2"},
> +	{"lge_igu_afifo_dfx_3"},
> +	{"lge_igu_afifo_dfx_4"},
> +
> +	{"lge_igu_afifo_dfx_5"},
> +	{"lge_igu_afifo_dfx_6"},
> +	{"lge_igu_afifo_dfx_7"},
> +	{"lge_egu_afifo_dfx_0"},
> +	{"lge_egu_afifo_dfx_1"},
> +	{"lge_egu_afifo_dfx_2"},
> +
> +	{"lge_egu_afifo_dfx_3"},
> +	{"lge_egu_afifo_dfx_4"},
> +	{"lge_egu_afifo_dfx_5"},
> +	{"lge_egu_afifo_dfx_6"},
> +	{"lge_egu_afifo_dfx_7"},
> +	{"cge_igu_afifo_dfx_0"},
> +
> +	{"cge_igu_afifo_dfx_1"},
> +	{"cge_egu_afifo_dfx_0"},
> +	{"cge_egu_afifo_dfx_i"},
> +	{"rtc_rsv1"},
> +	{"rtc_rsv2"},
> +	{"rtc_rsv3"},
> +};
> +
> +static struct hns3_reg_entry dfx_ppp_reg_list[] = {
> +	{"ppp_rsv0"},
> +	{"ppp_drop_from_prt_pkt_cnt"},
> +	{"ppp_drop_from_host_pkt_cnt"},
> +	{"ppp_drop_tx_vlan_proc_cnt"},
> +	{"ppp_drop_mng_cnt"},
> +	{"ppp_drop_fd_cnt"},
> +
> +	{"ppp_drop_no_dst_cnt"},
> +	{"ppp_drop_mc_mbid_full_cnt"},
> +	{"ppp_drop_sc_filtered"},
> +	{"ppp_ppp_mc_drop_pkt_cnt"},
> +	{"ppp_drop_pt_cnt"},
> +	{"ppp_drop_mac_anti_spoof_cnt"},
> +
> +	{"ppp_drop_ig_vfv_cnt"},
> +	{"ppp_drop_ig_prtv_cnt"},
> +	{"ppp_drop_cnm_pfc_pause_cnt"},
> +	{"ppp_drop_torus_tc_cnt"},
> +	{"ppp_drop_torus_lpbk_cnt"},
> +	{"ppp_ppp_hfs_sts"},
> +
> +	{"ppp_mc_rslt_sts"},
> +	{"ppp_p3u_sts"},
> +	{"ppp_rsv1",		"ppp_rslt_descr_sts"},
> +	{"ppp_umv_sts_0"},
> +	{"ppp_umv_sts_1"},
> +	{"ppp_vfv_sts"},
> +
> +	{"ppp_gro_key_cnt"},
> +	{"ppp_gro_info_cnt"},
> +	{"ppp_gro_drop_cnt"},
> +	{"ppp_gro_out_cnt"},
> +	{"ppp_gro_key_match_data_cnt"},
> +	{"ppp_gro_key_match_tcam_cnt"},
> +
> +	{"ppp_gro_info_match_cnt"},
> +	{"ppp_gro_free_entry_cnt"},
> +	{"ppp_gro_inner_dfx_signal"},
> +	{"ppp_rsv2"},
> +	{"ppp_rsv3"},
> +	{"ppp_rsv4"},
> +
> +	{"ppp_get_rx_pkt_cnt_l"},
> +	{"ppp_get_rx_pkt_cnt_h"},
> +	{"ppp_get_tx_pkt_cnt_l"},
> +	{"ppp_get_tx_pkt_cnt_h"},
> +	{"ppp_send_uc_prt2host_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2host_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
> +	{"ppp_send_uc_host2host_pkt_cnt_l"},
> +	{"ppp_send_uc_host2host_pkt_cnt_h"},
> +	{"ppp_send_uc_host2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_host2prt_pkt_cnt_h"},
> +
> +	{"ppp_send_mc_from_prt_cnt_l"},
> +	{"ppp_send_mc_from_prt_cnt_h"},
> +	{"ppp_send_mc_from_host_cnt_l"},
> +	{"ppp_send_mc_from_host_cnt_h"},
> +	{"ppp_ssu_mc_rd_cnt_l"},
> +	{"ppp_ssu_mc_rd_cnt_h"},
> +
> +	{"ppp_ssu_mc_drop_cnt_l"},
> +	{"ppp_ssu_mc_drop_cnt_h"},
> +	{"ppp_ssu_mc_rd_pkt_cnt_l"},
> +	{"ppp_ssu_mc_rd_pkt_cnt_h"},
> +	{"ppp_mc_2host_pkt_cnt_l"},
> +	{"ppp_mc_2host_pkt_cnt_h"},
> +
> +	{"ppp_mc_2prt_pkt_cnt_l"},
> +	{"ppp_mc_2prt_pkt_cnt_h"},
> +	{"ppp_ntsnos_pkt_cnt_l"},
> +	{"ppp_ntsnos_pkt_cnt_h"},
> +	{"ppp_ntup_pkt_cnt_l"},
> +	{"ppp_ntup_pkt_cnt_h"},
> +
> +	{"ppp_ntlcl_pkt_cnt_l"},
> +	{"ppp_ntlcl_pkt_cnt_h"},
> +	{"ppp_nttgt_pkt_cnt_l"},
> +	{"ppp_nttgt_pkt_cnt_h"},
> +	{"ppp_rtns_pkt_cnt_l"},
> +	{"ppp_rtns_pkt_cnt_h"},
> +
> +	{"ppp_rtlpbk_pkt_cnt_l"},
> +	{"ppp_rtlpbk_pkt_cnt_h"},
> +	{"ppp_nr_pkt_cnt_l"},
> +	{"ppp_nr_pkt_cnt_h"},
> +	{"ppp_rr_pkt_cnt_l"},
> +	{"ppp_rr_pkt_cnt_h"},
> +
> +	{"ppp_mng_tbl_hit_cnt_l"},
> +	{"ppp_mng_tbl_hit_cnt_h"},
> +	{"ppp_fd_tbl_hit_cnt_l"},
> +	{"ppp_fd_tbl_hit_cnt_h"},
> +	{"ppp_fd_lkup_cnt_l"},
> +	{"ppp_fd_lkup_cnt_h"},
> +
> +	{"ppp_bc_hit_cnt"},
> +	{"ppp_bc_hit_cnt_h"},
> +	{"ppp_um_tbl_uc_hit_cnt"},
> +	{"ppp_um_tbl_uc_hit_cnt_h"},
> +	{"ppp_um_tbl_mc_hit_cnt"},
> +	{"ppp_um_tbl_mc_hit_cnt_h"},
> +
> +	{"ppp_um_tbl_snq_hit_cnt_l",	"ppp_um_tbl_vmdq1_hit_cnt_l"},
> +	{"ppp_um_tbl_snq_hit_cnt_h",	"ppp_um_tbl_vmdq1_hit_cnt_h"},
> +	{"ppp_rsv5",			"ppp_mta_tbl_hit_cnt_l"},
> +	{"ppp_rsv6",			"ppp_mta_tbl_hit_cnt_h"},
> +	{"ppp_fwd_bonding_hit_cnt_l"},
> +	{"ppp_fwd_bonding_hit_cnt_h"},
> +
> +	{"ppp_promisc_tbl_hit_cnt_l"},
> +	{"ppp_promisc_tbl_hit_cnt_h"},
> +	{"ppp_get_tunl_pkt_cnt_l"},
> +	{"ppp_get_tunl_pkt_cnt_h"},
> +	{"ppp_get_bmc_pkt_cnt_l"},
> +	{"ppp_get_bmc_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
> +	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
> +	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
> +	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
> +	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
> +	{"ppp_mc_2bmc_pkt_cnt_l"},
> +	{"ppp_mc_2bmc_pkt_cnt_h"},
> +	{"ppp_rsv7",	"ppp_vlan_mirr_cnt_l"},
> +	{"ppp_rsv8",	"ppp_vlan_mirr_cnt_h"},
> +
> +	{"ppp_rsv9",	"ppp_ig_mirr_cnt_l"},
> +	{"ppp_rsv10",	"ppp_ig_mirr_cnt_h"},
> +	{"ppp_rsv11",	"ppp_eg_mirr_cnt_l"},
> +	{"ppp_rsv12",	"ppp_eg_mirr_cnt_h"},
> +	{"ppp_rx_default_host_hit_cnt_l"},
> +	{"ppp_rx_default_host_hit_cnt_h"},
> +
> +	{"ppp_lan_pair_cnt_l"},
> +	{"ppp_lan_pair_cnt_h"},
> +	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
> +	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
> +	{"ppp_mta_tbl_hit_pkt_cnt_l"},
> +	{"ppp_mta_tbl_hit_pkt_cnt_h"},
> +
> +	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
> +	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
> +	{"ppp_rsv13"},
> +	{"ppp_rsv14"},
> +	{"ppp_rsv15"},
> +	{"ppp_rsv16"},
> +};
> +
> +static struct hns3_reg_entry dfx_rcb_reg_list[] = {
> +	{"rcb_rsv0"},
> +	{"rcb_fsm_dfx_st0"},
> +	{"rcb_fsm_dfx_st1"},
> +	{"rcb_fsm_dfx_st2"},
> +	{"rcb_fifo_dfx_st0"},
> +	{"rcb_fifo_dfx_st1"},
> +
> +	{"rcb_fifo_dfx_st2"},
> +	{"rcb_fifo_dfx_st3"},
> +	{"rcb_fifo_dfx_st4"},
> +	{"rcb_fifo_dfx_st5"},
> +	{"rcb_fifo_dfx_st6"},
> +	{"rcb_fifo_dfx_st7"},
> +
> +	{"rcb_fifo_dfx_st8"},
> +	{"rcb_fifo_dfx_st9"},
> +	{"rcb_fifo_dfx_st10"},
> +	{"rcb_fifo_dfx_st11"},
> +	{"rcb_q_credit_vld_0"},
> +	{"rcb_q_credit_vld_1"},
> +
> +	{"rcb_q_credit_vld_2"},
> +	{"rcb_q_credit_vld_3"},
> +	{"rcb_q_credit_vld_4"},
> +	{"rcb_q_credit_vld_5"},
> +	{"rcb_q_credit_vld_6"},
> +	{"rcb_q_credit_vld_7"},
> +
> +	{"rcb_q_credit_vld_8"},
> +	{"rcb_q_credit_vld_9"},
> +	{"rcb_q_credit_vld_10"},
> +	{"rcb_q_credit_vld_11"},
> +	{"rcb_q_credit_vld_12"},
> +	{"rcb_q_credit_vld_13"},
> +
> +	{"rcb_q_credit_vld_14"},
> +	{"rcb_q_credit_vld_15"},
> +	{"rcb_q_credit_vld_16"},
> +	{"rcb_q_credit_vld_17"},
> +	{"rcb_q_credit_vld_18"},
> +	{"rcb_q_credit_vld_19"},
> +
> +	{"rcb_q_credit_vld_20"},
> +	{"rcb_q_credit_vld_21"},
> +	{"rcb_q_credit_vld_22"},
> +	{"rcb_q_credit_vld_23"},
> +	{"rcb_q_credit_vld_24"},
> +	{"rcb_q_credit_vld_25"},
> +
> +	{"rcb_q_credit_vld_26"},
> +	{"rcb_q_credit_vld_27"},
> +	{"rcb_q_credit_vld_28"},
> +	{"rcb_q_credit_vld_29"},
> +	{"rcb_q_credit_vld_30"},
> +	{"rcb_q_credit_vld_31"},
> +
> +	{"rcb_gro_bd_serr_cnt"},
> +	{"rcb_gro_context_serr_cnt"},
> +	{"rcb_rx_stash_cfg_serr_cnt"},
> +	{"rcb_rcb_tx_mem_serr_cnt",	"rcb_axi_rd_fbd_serr_cnt"},
> +	{"rcb_gro_bd_merr_cnt"},
> +	{"rcb_gro_context_merr_cnt"},
> +
> +	{"rcb_rx_stash_cfg_merr_cnt"},
> +	{"rcb_axi_rd_fbd_merr_cnt"},
> +	{"rcb_rsv1"},
> +	{"rcb_rsv2"},
> +	{"rcb_rsv3"},
> +	{"rcb_rsv4"},
> +};
> +
> +static struct hns3_reg_entry dfx_tqp_reg_list[] = {
> +	{"dfx_tqp_q_num"},
> +	{"rcb_cfg_rx_ring_tail"},
> +	{"rcb_cfg_rx_ring_head"},
> +	{"rcb_cfg_rx_ring_fbdnum"},
> +	{"rcb_cfg_rx_ring_offset"},
> +	{"rcb_cfg_rx_ring_fbdoffset"},
> +
> +	{"rcb_cfg_rx_ring_pktnum_record"},
> +	{"rcb_cfg_tx_ring_tail"},
> +	{"rcb_cfg_tx_ring_head"},
> +	{"rcb_cfg_tx_ring_fbdnum"},
> +	{"rcb_cfg_tx_ring_offset"},
> +	{"rcb_cfg_tx_ring_ebdnum"},
> +};
> +
> +static struct hns3_reg_entry dfx_ssu_reg_2_list[] = {
> +	{"dfx_ssu2_oq_index"},
> +	{"dfx_ssu2_queue_cnt"},
> +	{"dfx_ssu2_rsv0"},
> +	{"dfx_ssu2_rsv1"},
> +	{"dfx_ssu2_rsv2"},
> +	{"dfx_ssu2_rsv3"},
> +};
> +
> +struct hns3_dfx_reg_entry {
> +	const struct hns3_reg_entry *regs;
> +	uint32_t entry_num;
> +};
> +
> +struct hns3_dfx_reg_entry hns3_dfx_reg_list[] = {
> +	{dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
> +	{dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
> +	{dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
> +	{dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list)},
> +	{dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
> +	{dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
> +	{dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
> +	{dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
> +	{dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
> +	{dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
> +	{dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
> +	{dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
> +};
> +
>   static int
>   hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>   		  uint32_t *regs_num_64_bit)
> @@ -108,6 +827,12 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>   
>   	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
>   	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
> +	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
> +	    *regs_num_64_bit * HNS3_64_BIT_REG_SIZE !=
> +			RTE_DIM(regs_64_bit_list)) {
> +		hns3_err(hw, "Query register number differ from the list!");
> +		return -EINVAL;
> +	}
>   
>   	return 0;
>   }
> @@ -122,13 +847,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
>   	uint32_t len;
>   	int ret;
>   
> -	cmdq_cnt = sizeof(cmdq_reg_addrs);
> +	cmdq_cnt = RTE_DIM(cmdq_reg_list);
>   	if (hns->is_vf)
> -		common_cnt = sizeof(common_vf_reg_addrs);
> +		common_cnt = sizeof(common_vf_reg_list);
>   	else
> -		common_cnt = sizeof(common_reg_addrs);
> -	ring_cnt = sizeof(ring_reg_addrs);
> -	tqp_intr_cnt = sizeof(tqp_intr_reg_addrs);
> +		common_cnt = RTE_DIM(common_reg_list);
> +	ring_cnt = RTE_DIM(ring_reg_list);
> +	tqp_intr_cnt = RTE_DIM(tqp_intr_reg_list);
>   
>   	len = cmdq_cnt + common_cnt + ring_cnt * hw->tqps_num +
>   	      tqp_intr_cnt * hw->intr_tqps_num;
> @@ -281,33 +1006,33 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
>   	size_t i;
>   
>   	/* fetching per-PF registers values from PF PCIe register space */
> -	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
> +	reg_num = RTE_DIM(cmdq_reg_list);
>   	for (i = 0; i < reg_num; i++)
> -		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
> +		*data++ = hns3_read_dev(hw, cmdq_reg_list[i].addr);
>   
>   	if (hns->is_vf)
> -		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
> +		reg_num = RTE_DIM(common_vf_reg_list);
>   	else
> -		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
> +		reg_num = RTE_DIM(common_reg_list);
>   	for (i = 0; i < reg_num; i++)
>   		if (hns->is_vf)
> -			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
> +			*data++ = hns3_read_dev(hw, common_vf_reg_list[i].addr);
>   		else
> -			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
> +			*data++ = hns3_read_dev(hw, common_reg_list[i].addr);
>   
> -	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
> +	reg_num = RTE_DIM(ring_reg_list);
>   	for (j = 0; j < hw->tqps_num; j++) {
>   		reg_offset = hns3_get_tqp_reg_offset(j);
>   		for (i = 0; i < reg_num; i++)
>   			*data++ = hns3_read_dev(hw,
> -						ring_reg_addrs[i] + reg_offset);
> +						ring_reg_list[i].addr + reg_offset);
>   	}
>   
> -	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
> +	reg_num = RTE_DIM(tqp_intr_reg_list);
>   	for (j = 0; j < hw->intr_tqps_num; j++) {
>   		reg_offset = hns3_get_tqp_intr_reg_offset(j);
>   		for (i = 0; i < reg_num; i++)
> -			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
> +			*data++ = hns3_read_dev(hw, tqp_intr_reg_list[i].addr +
>   						reg_offset);
>   	}
>   	return data - origin_data_ptr;

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v5 5/7] net/hns3: add names for registers
  2024-03-07  3:02   ` [PATCH v5 5/7] net/hns3: add names for registers Jie Hai
  2024-03-08  9:41     ` lihuisong (C)
@ 2024-03-08 10:24     ` lihuisong (C)
  1 sibling, 0 replies; 134+ messages in thread
From: lihuisong (C) @ 2024-03-08 10:24 UTC (permalink / raw)
  To: Jie Hai; +Cc: fengchengwen, Yisen Zhuang, dev


在 2024/3/7 11:02, Jie Hai 写道:
> This patch adds names for all registers to be dumped.
> For those who can be directly accessed by their addresses,
> a new structure containing both name and address is added
> and the related arrays is refactored and renamed.
>
> For the remaining modules, there may be different meanings
> on different platforms for the same field. Therefore, two
> name fields are provided.
>
> There are some 64-bit registers, dump them as two 32-bit
> registers.
>
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>   drivers/net/hns3/hns3_regs.c | 877 ++++++++++++++++++++++++++++++++---
>   1 file changed, 801 insertions(+), 76 deletions(-)
>
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index b1c0d538a3c8..b7e4f78eecde 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -14,67 +14,84 @@
>   


<...>

> +struct direct_reg_list {
> +	const char *name;
> +	uint32_t addr;
> +};
> +
> +#define STR(s) #s
please use RTE_STR()
> +
> +static const struct direct_reg_list cmdq_reg_list[] = {
> +	{STR(HNS3_CMDQ_TX_ADDR_L_REG),		HNS3_CMDQ_TX_ADDR_L_REG},
> +	{STR(HNS3_CMDQ_TX_ADDR_H_REG),		HNS3_CMDQ_TX_ADDR_H_REG},
> +	{STR(HNS3_CMDQ_TX_DEPTH_REG),		HNS3_CMDQ_TX_DEPTH_REG},
> +	{STR(HNS3_CMDQ_TX_TAIL_REG),		HNS3_CMDQ_TX_TAIL_REG},
> +	{STR(HNS3_CMDQ_TX_HEAD_REG),		HNS3_CMDQ_TX_HEAD_REG},
> +	{STR(HNS3_CMDQ_RX_ADDR_L_REG),		HNS3_CMDQ_RX_ADDR_L_REG},
> +	{STR(HNS3_CMDQ_RX_ADDR_H_REG),		HNS3_CMDQ_RX_ADDR_H_REG},
> +	{STR(HNS3_CMDQ_RX_DEPTH_REG),		HNS3_CMDQ_RX_DEPTH_REG},
> +	{STR(HNS3_CMDQ_RX_TAIL_REG),		HNS3_CMDQ_RX_TAIL_REG},
> +	{STR(HNS3_CMDQ_RX_HEAD_REG),		HNS3_CMDQ_RX_HEAD_REG},
> +	{STR(HNS3_VECTOR0_CMDQ_SRC_REG),	HNS3_VECTOR0_CMDQ_SRC_REG},
> +	{STR(HNS3_CMDQ_INTR_STS_REG),		HNS3_CMDQ_INTR_STS_REG},
> +	{STR(HNS3_CMDQ_INTR_EN_REG),		HNS3_CMDQ_INTR_EN_REG},
> +	{STR(HNS3_CMDQ_INTR_GEN_REG),		HNS3_CMDQ_INTR_GEN_REG},
> +};
> +
> +static const struct direct_reg_list common_reg_list[] = {
> +	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
> +	{STR(HNS3_VECTOR0_OTER_EN_REG),		HNS3_VECTOR0_OTER_EN_REG},
> +	{STR(HNS3_MISC_RESET_STS_REG),		HNS3_MISC_RESET_STS_REG},
> +	{STR(HNS3_VECTOR0_OTHER_INT_STS_REG),	HNS3_VECTOR0_OTHER_INT_STS_REG},
> +	{STR(HNS3_GLOBAL_RESET_REG),		HNS3_GLOBAL_RESET_REG},
> +	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
> +	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
> +};
> +
> +static const struct direct_reg_list common_vf_reg_list[] = {
> +	{STR(HNS3_MISC_VECTOR_REG_BASE),	HNS3_MISC_VECTOR_REG_BASE},
> +	{STR(HNS3_FUN_RST_ING),			HNS3_FUN_RST_ING},
> +	{STR(HNS3_GRO_EN_REG),			HNS3_GRO_EN_REG},
> +};
> +
> +static const struct direct_reg_list ring_reg_list[] = {
> +	{STR(HNS3_RING_RX_BASEADDR_L_REG),	HNS3_RING_RX_BASEADDR_L_REG},
> +	{STR(HNS3_RING_RX_BASEADDR_H_REG),	HNS3_RING_RX_BASEADDR_H_REG},
> +	{STR(HNS3_RING_RX_BD_NUM_REG),		HNS3_RING_RX_BD_NUM_REG},
> +	{STR(HNS3_RING_RX_BD_LEN_REG),		HNS3_RING_RX_BD_LEN_REG},
> +	{STR(HNS3_RING_RX_EN_REG),		HNS3_RING_RX_EN_REG},
> +	{STR(HNS3_RING_RX_MERGE_EN_REG),	HNS3_RING_RX_MERGE_EN_REG},
> +	{STR(HNS3_RING_RX_TAIL_REG),		HNS3_RING_RX_TAIL_REG},
> +	{STR(HNS3_RING_RX_HEAD_REG),		HNS3_RING_RX_HEAD_REG},
> +	{STR(HNS3_RING_RX_FBDNUM_REG),		HNS3_RING_RX_FBDNUM_REG},
> +	{STR(HNS3_RING_RX_OFFSET_REG),		HNS3_RING_RX_OFFSET_REG},
> +	{STR(HNS3_RING_RX_FBD_OFFSET_REG),	HNS3_RING_RX_FBD_OFFSET_REG},
> +	{STR(HNS3_RING_RX_STASH_REG),		HNS3_RING_RX_STASH_REG},
> +	{STR(HNS3_RING_RX_BD_ERR_REG),		HNS3_RING_RX_BD_ERR_REG},
> +	{STR(HNS3_RING_TX_BASEADDR_L_REG),	HNS3_RING_TX_BASEADDR_L_REG},
> +	{STR(HNS3_RING_TX_BASEADDR_H_REG),	HNS3_RING_TX_BASEADDR_H_REG},
> +	{STR(HNS3_RING_TX_BD_NUM_REG),		HNS3_RING_TX_BD_NUM_REG},
> +	{STR(HNS3_RING_TX_EN_REG),		HNS3_RING_TX_EN_REG},
> +	{STR(HNS3_RING_TX_PRIORITY_REG),	HNS3_RING_TX_PRIORITY_REG},
> +	{STR(HNS3_RING_TX_TC_REG),		HNS3_RING_TX_TC_REG},
> +	{STR(HNS3_RING_TX_MERGE_EN_REG),	HNS3_RING_TX_MERGE_EN_REG},
> +	{STR(HNS3_RING_TX_TAIL_REG),		HNS3_RING_TX_TAIL_REG},
> +	{STR(HNS3_RING_TX_HEAD_REG),		HNS3_RING_TX_HEAD_REG},
> +	{STR(HNS3_RING_TX_FBDNUM_REG),		HNS3_RING_TX_FBDNUM_REG},
> +	{STR(HNS3_RING_TX_OFFSET_REG),		HNS3_RING_TX_OFFSET_REG},
> +	{STR(HNS3_RING_TX_EBD_NUM_REG),		HNS3_RING_TX_EBD_NUM_REG},
> +	{STR(HNS3_RING_TX_EBD_OFFSET_REG),	HNS3_RING_TX_EBD_OFFSET_REG},
> +	{STR(HNS3_RING_TX_BD_ERR_REG),		HNS3_RING_TX_BD_ERR_REG},
> +	{STR(HNS3_RING_EN_REG),			HNS3_RING_EN_REG},
> +};
> +
> +static const struct direct_reg_list tqp_intr_reg_list[] = {
> +	{STR(HNS3_TQP_INTR_CTRL_REG),	HNS3_TQP_INTR_CTRL_REG},
> +	{STR(HNS3_TQP_INTR_GL0_REG),	HNS3_TQP_INTR_GL0_REG},
> +	{STR(HNS3_TQP_INTR_GL1_REG),	HNS3_TQP_INTR_GL1_REG},
> +	{STR(HNS3_TQP_INTR_GL2_REG),	HNS3_TQP_INTR_GL2_REG},
> +	{STR(HNS3_TQP_INTR_RL_REG),	HNS3_TQP_INTR_RL_REG},
> +};
>   
>   static const uint32_t hns3_dfx_reg_opcode_list[] = {
>   	HNS3_OPC_DFX_BIOS_COMMON_REG,
> @@ -91,6 +108,708 @@ static const uint32_t hns3_dfx_reg_opcode_list[] = {
>   	HNS3_OPC_DFX_SSU_REG_2
>   };
>   
> +struct hns3_reg_entry {
> +	const char *new_name;
> +	const char *old_name;
> +};
This is not good.
> +
> +static struct hns3_reg_entry regs_32_bit_list[] = {
> +	{"ssu_common_err_int"},
> +	{"ssu_port_based_err_int"},
> +	{"ssu_fifo_overflow_int"},
> +	{"ssu_ets_tcg_int"},
> +	{"ssu_bp_status_0"},
> +	{"ssu_bp_status_1"},
> +
> +	{"ssu_bp_status_2"},
> +	{"ssu_bp_status_3"},
> +	{"ssu_bp_status_4"},
> +	{"ssu_bp_status_5"},
> +	{"ssu_mac_tx_pfc_ind"},
> +	{"ssu_mac_rx_pfc_ind"},
> +
> +	{"ssu_rx_oq_drop_pkt_cnt"},
> +	{"ssu_tx_oq_drop_pkt_cnt"},
<...>
> +
> +static struct hns3_reg_entry dfx_rtc_reg_list[] = {
> +	{"rtc_rsv0"},
> +	{"lge_igu_afifo_dfx_0"},
> +	{"lge_igu_afifo_dfx_1"},
> +	{"lge_igu_afifo_dfx_2"},
> +	{"lge_igu_afifo_dfx_3"},
> +	{"lge_igu_afifo_dfx_4"},
> +
> +	{"lge_igu_afifo_dfx_5"},
> +	{"lge_igu_afifo_dfx_6"},
> +	{"lge_igu_afifo_dfx_7"},
> +	{"lge_egu_afifo_dfx_0"},
> +	{"lge_egu_afifo_dfx_1"},
> +	{"lge_egu_afifo_dfx_2"},
> +
> +	{"lge_egu_afifo_dfx_3"},
> +	{"lge_egu_afifo_dfx_4"},
> +	{"lge_egu_afifo_dfx_5"},
> +	{"lge_egu_afifo_dfx_6"},
> +	{"lge_egu_afifo_dfx_7"},
> +	{"cge_igu_afifo_dfx_0"},
> +
> +	{"cge_igu_afifo_dfx_1"},
> +	{"cge_egu_afifo_dfx_0"},
> +	{"cge_egu_afifo_dfx_i"},
> +	{"rtc_rsv1"},
> +	{"rtc_rsv2"},
> +	{"rtc_rsv3"},
> +};
> +
> +static struct hns3_reg_entry dfx_ppp_reg_list[] = {
> +	{"ppp_rsv0"},
> +	{"ppp_drop_from_prt_pkt_cnt"},
> +	{"ppp_drop_from_host_pkt_cnt"},
> +	{"ppp_drop_tx_vlan_proc_cnt"},
> +	{"ppp_drop_mng_cnt"},
> +	{"ppp_drop_fd_cnt"},
> +
> +	{"ppp_drop_no_dst_cnt"},
> +	{"ppp_drop_mc_mbid_full_cnt"},
> +	{"ppp_drop_sc_filtered"},
> +	{"ppp_ppp_mc_drop_pkt_cnt"},
> +	{"ppp_drop_pt_cnt"},
> +	{"ppp_drop_mac_anti_spoof_cnt"},
> +
> +	{"ppp_drop_ig_vfv_cnt"},
> +	{"ppp_drop_ig_prtv_cnt"},
> +	{"ppp_drop_cnm_pfc_pause_cnt"},
> +	{"ppp_drop_torus_tc_cnt"},
> +	{"ppp_drop_torus_lpbk_cnt"},
> +	{"ppp_ppp_hfs_sts"},
> +
> +	{"ppp_mc_rslt_sts"},
> +	{"ppp_p3u_sts"},
> +	{"ppp_rsv1",		"ppp_rslt_descr_sts"},
> +	{"ppp_umv_sts_0"},
> +	{"ppp_umv_sts_1"},
> +	{"ppp_vfv_sts"},
> +
> +	{"ppp_gro_key_cnt"},
> +	{"ppp_gro_info_cnt"},
> +	{"ppp_gro_drop_cnt"},
> +	{"ppp_gro_out_cnt"},
> +	{"ppp_gro_key_match_data_cnt"},
> +	{"ppp_gro_key_match_tcam_cnt"},
> +
> +	{"ppp_gro_info_match_cnt"},
> +	{"ppp_gro_free_entry_cnt"},
> +	{"ppp_gro_inner_dfx_signal"},
> +	{"ppp_rsv2"},
> +	{"ppp_rsv3"},
> +	{"ppp_rsv4"},
> +
> +	{"ppp_get_rx_pkt_cnt_l"},
> +	{"ppp_get_rx_pkt_cnt_h"},
> +	{"ppp_get_tx_pkt_cnt_l"},
> +	{"ppp_get_tx_pkt_cnt_h"},
> +	{"ppp_send_uc_prt2host_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2host_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
> +	{"ppp_send_uc_host2host_pkt_cnt_l"},
> +	{"ppp_send_uc_host2host_pkt_cnt_h"},
> +	{"ppp_send_uc_host2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_host2prt_pkt_cnt_h"},
> +
> +	{"ppp_send_mc_from_prt_cnt_l"},
> +	{"ppp_send_mc_from_prt_cnt_h"},
> +	{"ppp_send_mc_from_host_cnt_l"},
> +	{"ppp_send_mc_from_host_cnt_h"},
> +	{"ppp_ssu_mc_rd_cnt_l"},
> +	{"ppp_ssu_mc_rd_cnt_h"},
> +
> +	{"ppp_ssu_mc_drop_cnt_l"},
> +	{"ppp_ssu_mc_drop_cnt_h"},
> +	{"ppp_ssu_mc_rd_pkt_cnt_l"},
> +	{"ppp_ssu_mc_rd_pkt_cnt_h"},
> +	{"ppp_mc_2host_pkt_cnt_l"},
> +	{"ppp_mc_2host_pkt_cnt_h"},
> +
> +	{"ppp_mc_2prt_pkt_cnt_l"},
> +	{"ppp_mc_2prt_pkt_cnt_h"},
> +	{"ppp_ntsnos_pkt_cnt_l"},
> +	{"ppp_ntsnos_pkt_cnt_h"},
> +	{"ppp_ntup_pkt_cnt_l"},
> +	{"ppp_ntup_pkt_cnt_h"},
> +
> +	{"ppp_ntlcl_pkt_cnt_l"},
> +	{"ppp_ntlcl_pkt_cnt_h"},
> +	{"ppp_nttgt_pkt_cnt_l"},
> +	{"ppp_nttgt_pkt_cnt_h"},
> +	{"ppp_rtns_pkt_cnt_l"},
> +	{"ppp_rtns_pkt_cnt_h"},
> +
> +	{"ppp_rtlpbk_pkt_cnt_l"},
> +	{"ppp_rtlpbk_pkt_cnt_h"},
> +	{"ppp_nr_pkt_cnt_l"},
> +	{"ppp_nr_pkt_cnt_h"},
> +	{"ppp_rr_pkt_cnt_l"},
> +	{"ppp_rr_pkt_cnt_h"},
> +
> +	{"ppp_mng_tbl_hit_cnt_l"},
> +	{"ppp_mng_tbl_hit_cnt_h"},
> +	{"ppp_fd_tbl_hit_cnt_l"},
> +	{"ppp_fd_tbl_hit_cnt_h"},
> +	{"ppp_fd_lkup_cnt_l"},
> +	{"ppp_fd_lkup_cnt_h"},
> +
> +	{"ppp_bc_hit_cnt"},
> +	{"ppp_bc_hit_cnt_h"},
> +	{"ppp_um_tbl_uc_hit_cnt"},
> +	{"ppp_um_tbl_uc_hit_cnt_h"},
> +	{"ppp_um_tbl_mc_hit_cnt"},
> +	{"ppp_um_tbl_mc_hit_cnt_h"},
> +
> +	{"ppp_um_tbl_snq_hit_cnt_l",	"ppp_um_tbl_vmdq1_hit_cnt_l"},
> +	{"ppp_um_tbl_snq_hit_cnt_h",	"ppp_um_tbl_vmdq1_hit_cnt_h"},
> +	{"ppp_rsv5",			"ppp_mta_tbl_hit_cnt_l"},
> +	{"ppp_rsv6",			"ppp_mta_tbl_hit_cnt_h"},
If there are different names for these register,
how about use a common name like ppp_func_reg1、ppp_func_reg2?
or do not show the new register name on latter platform and only use the 
original name, "ppp_rsv5/6".
Because we don't know if this register name will be changed on the new 
plaform in furture.
> +	{"ppp_fwd_bonding_hit_cnt_l"},
> +	{"ppp_fwd_bonding_hit_cnt_h"},
> +
> +	{"ppp_promisc_tbl_hit_cnt_l"},
> +	{"ppp_promisc_tbl_hit_cnt_h"},
> +	{"ppp_get_tunl_pkt_cnt_l"},
> +	{"ppp_get_tunl_pkt_cnt_h"},
> +	{"ppp_get_bmc_pkt_cnt_l"},
> +	{"ppp_get_bmc_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
> +	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
> +	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
> +	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
> +	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
> +	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
> +
> +	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
> +	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
> +	{"ppp_mc_2bmc_pkt_cnt_l"},
> +	{"ppp_mc_2bmc_pkt_cnt_h"},
> +	{"ppp_rsv7",	"ppp_vlan_mirr_cnt_l"},
> +	{"ppp_rsv8",	"ppp_vlan_mirr_cnt_h"},
> +
> +	{"ppp_rsv9",	"ppp_ig_mirr_cnt_l"},
> +	{"ppp_rsv10",	"ppp_ig_mirr_cnt_h"},
> +	{"ppp_rsv11",	"ppp_eg_mirr_cnt_l"},
> +	{"ppp_rsv12",	"ppp_eg_mirr_cnt_h"},
> +	{"ppp_rx_default_host_hit_cnt_l"},
> +	{"ppp_rx_default_host_hit_cnt_h"},
> +
> +	{"ppp_lan_pair_cnt_l"},
> +	{"ppp_lan_pair_cnt_h"},
> +	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
> +	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
> +	{"ppp_mta_tbl_hit_pkt_cnt_l"},
> +	{"ppp_mta_tbl_hit_pkt_cnt_h"},
> +
> +	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
> +	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
> +	{"ppp_rsv13"},
> +	{"ppp_rsv14"},
> +	{"ppp_rsv15"},
> +	{"ppp_rsv16"},
> +};
> +
<...>

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 0/8] support dump reigser names and filter
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (4 preceding siblings ...)
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
@ 2024-07-22  6:58 ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 1/8] ethdev: support report register " Jie Hai
                     ` (8 more replies)
  2024-09-05  6:26 ` [RESEND " Jie Hai
                   ` (4 subsequent siblings)
  10 siblings, 9 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient for
users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
to support the capability of exporting the name of the corresponding
register and filtering by module names.

The hns3 driver and telemetry are examples for that.

Jie Hai (8):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: remove some basic address dump
  net/hns3: fix dump counter of registers
  net/hns3: remove separators between register module
  net/hns3: refactor register dump
  net/hns3: support report names of registers
  net/hns3: support filter registers by module names

 doc/guides/rel_notes/release_24_07.rst |    8 +
 drivers/net/hns3/hns3_regs.c           | 1394 +++++++++++++++++++-----
 lib/ethdev/ethdev_trace.h              |    2 +
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  128 +++
 lib/ethdev/version.map                 |    3 +
 8 files changed, 1347 insertions(+), 266 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 1/8] ethdev: support report register names and filter
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 2/8] ethdev: add telemetry cmd for registers Jie Hai
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: lihuisong, fengchengwen

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their module names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by modules. And the original API
rte_eth_dev_get_reg_info() does not use the names and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "index_XXX", which means the location in the register table.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 doc/guides/rel_notes/release_24_07.rst |  8 ++++++
 lib/ethdev/ethdev_trace.h              |  2 ++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 91 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_07.rst b/doc/guides/rel_notes/release_24_07.rst
index 058609b0f36b..b0bb49c8f29e 100644
--- a/doc/guides/rel_notes/release_24_07.rst
+++ b/doc/guides/rel_notes/release_24_07.rst
@@ -186,6 +186,12 @@ New Features
   * Added defer queue reclamation via RCU.
   * Added SVE support for bulk lookup.
 
+* **Added support for dumping registers with names and filtering by modules.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to filter the
+    registers by module names and get the information (names, values and other
+    attributes) of the filtered registers.
+
 
 Removed Items
 -------------
@@ -241,6 +247,8 @@ ABI Changes
    This section is a comment. Do not overwrite or remove it.
    Also, make sure to start the actual text at the margin.
    =======================================================
+   * ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+     structure for filtering by modules and reporting names of registers.
 
 * No ABI change that would break compatibility with 23.11.
 
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 3bec87bfdb70..0c4780a09ef5 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -1152,6 +1152,8 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_u32(info->length);
 	rte_trace_point_emit_u32(info->width);
 	rte_trace_point_emit_u32(info->version);
+	rte_trace_point_emit_ptr(info->names);
+	rte_trace_point_emit_ptr(info->filter);
 	rte_trace_point_emit_int(ret);
 )
 
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..26b777f9836e 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 64
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Name of target module, filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..30ca4a0043c5 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 		return -EINVAL;
 	}
 
+	if (info->names != NULL && info->length != 0)
+		memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length);
+
 	if (*dev->dev_ops->get_reg == NULL)
 		return -ENOTSUP;
 	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) {
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"index_%u", info->offset + i);
+	}
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 548fada1c7ad..02cb3c07f742 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5071,6 +5071,35 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   - If info->filter is NULL, return info for all registers (seen as filter
+ *     none).
+ *   - If info->filter is not NULL, return error if the driver does not support
+ *     filter. Fill the length field with filtered register number.
+ *   - If info->data is NULL, the function fills in the width and length fields.
+ *   - If info->data is not NULL, ethdev considers there are enough spaces to
+ *     store the registers, and the values of registers with the filter string
+ *     as the module name are put into the buffer pointed at by info->data.
+ *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
+ *     with default names.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 79f6f5293b5c..e3289e999382 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,9 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+
+	# added in 24.07
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 2/8] ethdev: add telemetry cmd for registers
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
  2024-07-22  6:58   ` [PATCH v6 1/8] ethdev: support report register " Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 3/8] net/hns3: remove some basic address dump Jie Hai
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: lihuisong, fengchengwen

This patch adds a telemetry command for registers dump,
and supports obtaining the registers of a specified module.

In one way, the number of registers that can be exported
is limited by the number of elements carried by dict and
container. In another way, the length of the string
exported by telemetry is limited by MAX_OUTPUT_LEN.
Therefore, when the number of registers to be exported
exceeds, some information will be lost. Warn on the former
case.

An example usage is shown below:
--> /ethdev/regs,0,ring
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "Q0_ring_rx_bd_num": "0x0",
      "Q0_ring_rx_bd_len": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 128 ++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..1d59c693883e 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -1395,6 +1395,132 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static void
+eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
+		     uint32_t idx)
+{
+	if (reg_info->width == sizeof(uint32_t))
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint32_t *)reg_info->data + idx), 0);
+	else
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint64_t *)reg_info->data + idx), 0);
+}
+
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t i;
+	int ret;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	for (i = 0; i < reg_info->length; i++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
+			eth_dev_add_reg_data(group, reg_info, i);
+			continue;
+		}
+
+		group = rte_tel_data_alloc();
+		if (group == NULL) {
+			ret = -ENOMEM;
+			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
+			goto out;
+		}
+		groups[grp_num++] = group;
+		rte_tel_data_start_dict(group);
+		eth_dev_add_reg_data(group, reg_info, i);
+	}
+
+	for (i = 0; i < grp_num; i++) {
+		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
+		ret = rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
+		if (ret == -ENOSPC) {
+			RTE_ETHDEV_LOG_LINE(WARNING,
+				"Reduce register number to be displayed from %u to %u due to limited capacity of telemetry",
+				reg_info->length, i * RTE_TEL_MAX_DICT_ENTRIES);
+			break;
+		}
+	}
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (reg_info.data == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.data");
+		return -ENOMEM;
+	}
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (reg_info.names == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.names");
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter, *end_param;
+	uint16_t port_id;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1562,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 3/8] net/hns3: remove some basic address dump
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
  2024-07-22  6:58   ` [PATCH v6 1/8] ethdev: support report register " Jie Hai
  2024-07-22  6:58   ` [PATCH v6 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 4/8] net/hns3: fix dump counter of registers Jie Hai
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

For security reasons, some address registers are not suitable
to be exposed, remove them.

Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li<lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..53d829a4fc68 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -17,13 +17,9 @@
 
 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
+static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
 					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
 					  HNS3_CMDQ_RX_DEPTH_REG,
 					  HNS3_CMDQ_RX_TAIL_REG,
 					  HNS3_CMDQ_RX_HEAD_REG,
@@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
 					       HNS3_FUN_RST_ING,
 					       HNS3_GRO_EN_REG};
 
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
+static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
 					  HNS3_RING_RX_BD_LEN_REG,
 					  HNS3_RING_RX_EN_REG,
 					  HNS3_RING_RX_MERGE_EN_REG,
@@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
 					  HNS3_RING_RX_FBD_OFFSET_REG,
 					  HNS3_RING_RX_STASH_REG,
 					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
 					  HNS3_RING_TX_BD_NUM_REG,
 					  HNS3_RING_TX_EN_REG,
 					  HNS3_RING_TX_PRIORITY_REG,
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 4/8] net/hns3: fix dump counter of registers
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                     ` (2 preceding siblings ...)
  2024-07-22  6:58   ` [PATCH v6 3/8] net/hns3: remove some basic address dump Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 5/8] net/hns3: remove separators between register module Jie Hai
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Yisen Zhuang, Chengchang Tang, Lijun Ou, Huisong Li,
	Hao Chen, Ferruh Yigit, Min Hu (Connor),
	Chunsong Feng
  Cc: fengchengwen, thomas, ferruh.yigit

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")
Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 53d829a4fc68..d9c546470dbe 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -127,7 +127,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 5/8] net/hns3: remove separators between register module
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                     ` (3 preceding siblings ...)
  2024-07-22  6:58   ` [PATCH v6 4/8] net/hns3: fix dump counter of registers Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 6/8] net/hns3: refactor register dump Jie Hai
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 68 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 50 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d9c546470dbe..c8e3fb118e4b 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
@@ -111,23 +108,21 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
+	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = sizeof(cmdq_reg_addrs) + common_cnt +
+		sizeof(ring_reg_addrs) * hw->tqps_num +
+		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
+	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -136,18 +131,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -268,18 +261,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -294,7 +275,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -305,7 +285,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -313,7 +292,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -322,7 +300,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -398,17 +375,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -416,11 +391,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -467,7 +439,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -512,16 +483,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 6/8] net/hns3: refactor register dump
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                     ` (4 preceding siblings ...)
  2024-07-22  6:58   ` [PATCH v6 5/8] net/hns3: remove separators between register module Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 7/8] net/hns3: support report names of registers Jie Hai
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

This patch refactors codes dumping registers from firmware.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++---------------
 1 file changed, 115 insertions(+), 88 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index c8e3fb118e4b..89858c2b1c09 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -104,12 +104,93 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static int
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
+			uint32_t list_size)
+{
+#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
+	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
+	uint32_t index, desc_index;
+	uint32_t bd_num;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	/* The last BD does not need a next flag */
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+
+	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
+	if (ret) {
+		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
+		return ret;
+	}
+
+	/* The first data in the first BD is a reserved field */
+	for (i = 1; i <= list_size; i++) {
+		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
+		index = i % HNS3_CMD_DESC_DATA_NUM;
+		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
+		bd_num_list[i - 1] = bd_num;
+	}
+
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num_list[opcode_num];
+	int ret;
+	int i;
+
+	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+
+	return 0;
+}
+
+static int
+hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int ret;
+
+	ret = hns3_get_32_64_regs_cnt(hw, count);
+	if (ret < 0)
+		return ret;
+
+	return hns3_get_dfx_reg_cnt(hw, count);
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_cnt;
+	uint32_t dfx_reg_cnt = 0;
 	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
@@ -125,16 +206,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -304,41 +376,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	return data - origin_data_ptr;
 }
 
-static int
-hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
-			uint32_t list_size)
-{
-#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
-	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
-	uint32_t index, desc_index;
-	uint32_t bd_num;
-	uint32_t i;
-	int ret;
-
-	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
-		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
-	}
-	/* The last BD does not need a next flag */
-	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-
-	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
-	if (ret) {
-		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
-		return ret;
-	}
-
-	/* The first data in the first BD is a reserved field */
-	for (i = 1; i <= list_size; i++) {
-		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
-		index = i % HNS3_CMD_DESC_DATA_NUM;
-		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
-		bd_num_list[i - 1] = bd_num;
-	}
-
-	return 0;
-}
-
 static int
 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
 			int bd_num, uint32_t opcode)
@@ -379,24 +416,6 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 	return reg_num;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-
-	return 0;
-}
-
 static int
 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 {
@@ -436,13 +455,41 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 	return ret;
 }
 
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+{
+	uint32_t regs_num_32_bit;
+	uint32_t regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "Get register number failed, ret = %d", ret);
+		return ret;
+	}
+
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_32_bit;
+
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+
+	return hns3_get_dfx_regs(hw, (void **)&data);
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
@@ -470,26 +517,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
 	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_32_bit;
-
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	return  hns3_get_regs_from_firmware(hw, data);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 7/8] net/hns3: support report names of registers
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                     ` (5 preceding siblings ...)
  2024-07-22  6:58   ` [PATCH v6 6/8] net/hns3: refactor register dump Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-07-22  6:58   ` [PATCH v6 8/8] net/hns3: support filter registers by module names Jie Hai
  2024-08-09  9:22   ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

This patch adds names for register lists, and support report
names of registers. Some registers has different names on
different platform, use names of HIP08 as default names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 1090 +++++++++++++++++++++++++++++-----
 1 file changed, 957 insertions(+), 133 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 89858c2b1c09..622d2e1c3d02 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,73 +14,829 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct hns3_dirt_reg_entry {
+	const char *name;
+	uint32_t addr;
+};
+
+static const struct hns3_dirt_reg_entry cmdq_reg_list[] = {
+	{"cmdq_tx_depth",		HNS3_CMDQ_TX_DEPTH_REG},
+	{"cmdq_tx_tail",		HNS3_CMDQ_TX_TAIL_REG},
+	{"cmdq_tx_head",		HNS3_CMDQ_TX_HEAD_REG},
+	{"cmdq_rx_depth",		HNS3_CMDQ_RX_DEPTH_REG},
+	{"cmdq_rx_tail",		HNS3_CMDQ_RX_TAIL_REG},
+	{"cmdq_rx_head",		HNS3_CMDQ_RX_HEAD_REG},
+	{"vector0_cmdq_src",		HNS3_VECTOR0_CMDQ_SRC_REG},
+	{"cmdq_intr_sts",		HNS3_CMDQ_INTR_STS_REG},
+	{"cmdq_intr_en",		HNS3_CMDQ_INTR_EN_REG},
+	{"cmdq_intr_gen",		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"vector0_oter_en",		HNS3_VECTOR0_OTER_EN_REG},
+	{"misc_reset_sts",		HNS3_MISC_RESET_STS_REG},
+	{"vector0_other_int_sts",	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{"global_reset",		HNS3_GLOBAL_RESET_REG},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_vf_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry ring_reg_list[] = {
+	{"ring_rx_bd_num",		HNS3_RING_RX_BD_NUM_REG},
+	{"ring_rx_bd_len",		HNS3_RING_RX_BD_LEN_REG},
+	{"ring_rx_en",			HNS3_RING_RX_EN_REG},
+	{"ring_rx_merge_en",		HNS3_RING_RX_MERGE_EN_REG},
+	{"ring_rx_tail",		HNS3_RING_RX_TAIL_REG},
+	{"ring_rx_head",		HNS3_RING_RX_HEAD_REG},
+	{"ring_rx_fbdnum",		HNS3_RING_RX_FBDNUM_REG},
+	{"ring_rx_offset",		HNS3_RING_RX_OFFSET_REG},
+	{"ring_rx_fbd_offset",		HNS3_RING_RX_FBD_OFFSET_REG},
+	{"ring_rx_stash",		HNS3_RING_RX_STASH_REG},
+	{"ring_rx_bd_err",		HNS3_RING_RX_BD_ERR_REG},
+	{"ring_tx_bd_num",		HNS3_RING_TX_BD_NUM_REG},
+	{"ring_tx_en",			HNS3_RING_TX_EN_REG},
+	{"ring_tx_priority",		HNS3_RING_TX_PRIORITY_REG},
+	{"ring_tx_tc",			HNS3_RING_TX_TC_REG},
+	{"ring_tx_merge_en",		HNS3_RING_TX_MERGE_EN_REG},
+	{"ring_tx_tail",		HNS3_RING_TX_TAIL_REG},
+	{"ring_tx_head",		HNS3_RING_TX_HEAD_REG},
+	{"ring_tx_fbdnum",		HNS3_RING_TX_FBDNUM_REG},
+	{"ring_tx_offset",		HNS3_RING_TX_OFFSET_REG},
+	{"ring_tx_ebd_num",		HNS3_RING_TX_EBD_NUM_REG},
+	{"ring_tx_ebd_offset",		HNS3_RING_TX_EBD_OFFSET_REG},
+	{"ring_tx_bd_err",		HNS3_RING_TX_BD_ERR_REG},
+	{"ring_en",			HNS3_RING_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry tqp_intr_reg_list[] = {
+	{"tqp_intr_ctrl",		HNS3_TQP_INTR_CTRL_REG},
+	{"tqp_intr_gl0",		HNS3_TQP_INTR_GL0_REG},
+	{"tqp_intr_gl1",		HNS3_TQP_INTR_GL1_REG},
+	{"tqp_intr_gl2",		HNS3_TQP_INTR_GL2_REG},
+	{"tqp_intr_rl",			HNS3_TQP_INTR_RL_REG},
+};
+
+struct hns3_dfx_reg_entry {
+	/**
+	 * name_v1 -- default register name for all platforms (HIP08/HIP09/newer).
+	 * name_v2 -- register name different from the default for HIP09.
+	 * If there are more platform with different register name, name_vXX is extended.
+	 * If the platform is newer than HIP09, use default name.
+	 */
+	const char *name_v1;
+	const char *name_v2;
+};
+
+static struct hns3_dfx_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_dfx_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_dfx_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"btmp_ageing_st_b0"},
+	{"btmp_ageing_st_b1"},
+	{"btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"lo_pri_unicast_rlt_drop_num"},
+	{"hi_pri_multicast_rlt_drop_num"},
+
+	{"lo_pri_multicast_rlt_drop_num"},
+	{"ncsi_packet_curr_buffer_cnt"},
+	{"btmp_ageing_rls_cnt_bank0",		"dfx_ssu0_rsv5"},
+	{"btmp_ageing_rls_cnt_bank1",		"dfx_ssu0_rsv6"},
+	{"btmp_ageing_rls_cnt_bank2",		"dfx_ssu0_rsv7"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ncsi_rx_packet_in_cnt_l"},
+	{"ncsi_rx_packet_in_cnt_h"},
+	{"ncsi_tx_packet_out_cnt_l"},
+	{"ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"mb_uncopy_num"},
+	{"rx_oq_drop_pkt_cnt"},
+	{"tx_oq_drop_pkt_cnt"},
+	{"bank_unbalance_drop_cnt"},
+	{"bank_unbalance_rx_drop_cnt"},
+
+	{"nic_l2_eer_drop_pkt_cnt"},
+	{"roc_l2_eer_drop_pkt_cnt"},
+	{"nic_l2_eer_drop_pkt_cnt_rx"},
+	{"roc_l2_eer_drop_pkt_cnt_rx"},
+	{"rx_oq_glb_drop_pkt_cnt"},
+	{"dfx_ssu0_rsv8"},
+
+	{"lo_pri_unicast_cur_cnt"},
+	{"hi_pri_multicast_cur_cnt"},
+	{"lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"packet_tc_curr_buffer_cnt_0"},
+	{"packet_tc_curr_buffer_cnt_1"},
+	{"packet_tc_curr_buffer_cnt_2"},
+	{"packet_tc_curr_buffer_cnt_3"},
+	{"packet_tc_curr_buffer_cnt_4"},
+
+	{"packet_tc_curr_buffer_cnt_5"},
+	{"packet_tc_curr_buffer_cnt_6"},
+	{"packet_tc_curr_buffer_cnt_7"},
+	{"packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"rx_packet_in_cnt_l"},
+	{"rx_packet_in_cnt_h"},
+	{"rx_packet_out_cnt_l"},
+	{"rx_packet_out_cnt_h"},
+	{"tx_packet_in_cnt_l"},
+	{"tx_packet_in_cnt_h"},
+
+	{"tx_packet_out_cnt_l"},
+	{"tx_packet_out_cnt_h"},
+	{"roc_rx_packet_in_cnt_l"},
+	{"roc_rx_packet_in_cnt_h"},
+	{"roc_tx_packet_in_cnt_l"},
+	{"roc_tx_packet_in_cnt_h"},
+
+	{"rx_packet_tc_in_cnt_0_l"},
+	{"rx_packet_tc_in_cnt_0_h"},
+	{"rx_packet_tc_in_cnt_1_l"},
+	{"rx_packet_tc_in_cnt_1_h"},
+	{"rx_packet_tc_in_cnt_2_l"},
+	{"rx_packet_tc_in_cnt_2_h"},
+
+	{"rx_packet_tc_in_cnt_3_l"},
+	{"rx_packet_tc_in_cnt_3_h"},
+	{"rx_packet_tc_in_cnt_4_l"},
+	{"rx_packet_tc_in_cnt_4_h"},
+	{"rx_packet_tc_in_cnt_5_l"},
+	{"rx_packet_tc_in_cnt_5_h"},
+
+	{"rx_packet_tc_in_cnt_6_l"},
+	{"rx_packet_tc_in_cnt_6_h"},
+	{"rx_packet_tc_in_cnt_7_l"},
+	{"rx_packet_tc_in_cnt_7_h"},
+	{"rx_packet_tc_out_cnt_0_l"},
+	{"rx_packet_tc_out_cnt_0_h"},
+
+	{"rx_packet_tc_out_cnt_1_l"},
+	{"rx_packet_tc_out_cnt_1_h"},
+	{"rx_packet_tc_out_cnt_2_l"},
+	{"rx_packet_tc_out_cnt_2_h"},
+	{"rx_packet_tc_out_cnt_3_l"},
+	{"rx_packet_tc_out_cnt_3_h"},
+
+	{"rx_packet_tc_out_cnt_4_l"},
+	{"rx_packet_tc_out_cnt_4_h"},
+	{"rx_packet_tc_out_cnt_5_l"},
+	{"rx_packet_tc_out_cnt_5_h"},
+	{"rx_packet_tc_out_cnt_6_l"},
+	{"rx_packet_tc_out_cnt_6_h"},
+
+	{"rx_packet_tc_out_cnt_7_l"},
+	{"rx_packet_tc_out_cnt_7_h"},
+	{"tx_packet_tc_in_cnt_0_l"},
+	{"tx_packet_tc_in_cnt_0_h"},
+	{"tx_packet_tc_in_cnt_1_l"},
+	{"tx_packet_tc_in_cnt_1_h"},
+
+	{"tx_packet_tc_in_cnt_2_l"},
+	{"tx_packet_tc_in_cnt_2_h"},
+	{"tx_packet_tc_in_cnt_3_l"},
+	{"tx_packet_tc_in_cnt_3_h"},
+	{"tx_packet_tc_in_cnt_4_l"},
+	{"tx_packet_tc_in_cnt_4_h"},
+
+	{"tx_packet_tc_in_cnt_5_l"},
+	{"tx_packet_tc_in_cnt_5_h"},
+	{"tx_packet_tc_in_cnt_6_l"},
+	{"tx_packet_tc_in_cnt_6_h"},
+	{"tx_packet_tc_in_cnt_7_l"},
+	{"tx_packet_tc_in_cnt_7_h"},
+
+	{"tx_packet_tc_out_cnt_0_l"},
+	{"tx_packet_tc_out_cnt_0_h"},
+	{"tx_packet_tc_out_cnt_1_l"},
+	{"tx_packet_tc_out_cnt_1_h"},
+	{"tx_packet_tc_out_cnt_2_l"},
+	{"tx_packet_tc_out_cnt_2_h"},
+
+	{"tx_packet_tc_out_cnt_3_l"},
+	{"tx_packet_tc_out_cnt_3_h"},
+	{"tx_packet_tc_out_cnt_4_l"},
+	{"tx_packet_tc_out_cnt_4_h"},
+	{"tx_packet_tc_out_cnt_5_l"},
+	{"tx_packet_tc_out_cnt_5_h"},
+
+	{"tx_packet_tc_out_cnt_6_l"},
+	{"tx_packet_tc_out_cnt_6_h"},
+	{"tx_packet_tc_out_cnt_7_l"},
+	{"tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_rsv0",		"igu_egu_mul_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv1",		"igu_egu_mul_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv2",		"igu_egu_bro_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv3",		"igu_egu_bro_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv4",		"igu_egu_rsv0"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_tc_queue_num",		"rpu_currport_tnl_index"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rslt_descr_sts",		"ppp_rsv1"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_vmdq1_hit_cnt_l",	"ppp_um_tbl_snq_hit_cnt_l"},
+	{"ppp_um_tbl_vmdq1_hit_cnt_h",	"ppp_um_tbl_snq_hit_cnt_h"},
+	{"ppp_mta_tbl_hit_cnt_l",	"ppp_rsv5"},
+	{"ppp_mta_tbl_hit_cnt_h",	"ppp_rsv6"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_vlan_mirr_cnt_l",		"ppp_rsv7"},
+	{"ppp_vlan_mirr_cnt_h",		"ppp_rsv8"},
+
+	{"ppp_ig_mirr_cnt_l",		"ppp_rsv9"},
+	{"ppp_ig_mirr_cnt_h",		"ppp_rsv10"},
+	{"ppp_eg_mirr_cnt_l",		"ppp_rsv11"},
+	{"ppp_eg_mirr_cnt_h",		"ppp_rsv12"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_axi_rd_fbd_serr_cnt",	"rcb_rcb_tx_mem_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_dfx_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+enum hns3_reg_modules {
+	HNS3_BIOS_COMMON = 0,
+	HNS3_SSU_0,
+	HNS3_SSU_1,
+	HNS3_IGU_EGU,
+	HNS3_RPU_0,
+	HNS3_RPU_1,
+	HNS3_NCSI,
+	HNS3_RTC,
+	HNS3_PPP,
+	HNS3_RCB,
+	HNS3_TQP,
+	HNS3_SSU_2,
+
+	HNS3_CMDQ = 12,
+	HNS3_COMMON_PF,
+	HNS3_COMMON_VF,
+	HNS3_RING,
+	HNS3_TQP_INTR,
+
+	HNS3_32_BIT_DFX,
+	HNS3_64_BIT_DFX,
+};
+
+struct hns3_reg_list {
+	const void *reg_list;
+	uint32_t entry_num;
+};
+
+static struct hns3_reg_list hns3_reg_lists[] = {
+	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
+	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+
+	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
+	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
+	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
+	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
+	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
+
+	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
+	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
-	HNS3_OPC_DFX_BIOS_COMMON_REG,
-	HNS3_OPC_DFX_SSU_REG_0,
-	HNS3_OPC_DFX_SSU_REG_1,
-	HNS3_OPC_DFX_IGU_EGU_REG,
-	HNS3_OPC_DFX_RPU_REG_0,
-	HNS3_OPC_DFX_RPU_REG_1,
-	HNS3_OPC_DFX_NCSI_REG,
-	HNS3_OPC_DFX_RTC_REG,
-	HNS3_OPC_DFX_PPP_REG,
-	HNS3_OPC_DFX_RCB_REG,
-	HNS3_OPC_DFX_TQP_REG,
-	HNS3_OPC_DFX_SSU_REG_2
+	[HNS3_BIOS_COMMON]	=	HNS3_OPC_DFX_BIOS_COMMON_REG,
+	[HNS3_SSU_0]		=	HNS3_OPC_DFX_SSU_REG_0,
+	[HNS3_SSU_1]		=	HNS3_OPC_DFX_SSU_REG_1,
+	[HNS3_IGU_EGU]		=	HNS3_OPC_DFX_IGU_EGU_REG,
+	[HNS3_RPU_0]		=	HNS3_OPC_DFX_RPU_REG_0,
+	[HNS3_RPU_1]		=	HNS3_OPC_DFX_RPU_REG_1,
+	[HNS3_NCSI]		=	HNS3_OPC_DFX_NCSI_REG,
+	[HNS3_RTC]		=	HNS3_OPC_DFX_RTC_REG,
+	[HNS3_PPP]		=	HNS3_OPC_DFX_PPP_REG,
+	[HNS3_RCB]		=	HNS3_OPC_DFX_RCB_REG,
+	[HNS3_TQP]		=	HNS3_OPC_DFX_TQP_REG,
+	[HNS3_SSU_2]		=	HNS3_OPC_DFX_SSU_REG_2
 };
 
 static int
@@ -100,6 +856,11 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE != RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -161,6 +922,7 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
+	uint32_t reg_num;
 	int ret;
 	int i;
 
@@ -168,8 +930,14 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < opcode_num; i++) {
+		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+		if (reg_num != hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module!");
+			return -EINVAL;
+		}
+		*count += reg_num;
+	}
 
 	return 0;
 }
@@ -196,14 +964,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	int ret;
 
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = RTE_DIM(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
 
-	len = sizeof(cmdq_reg_addrs) + common_cnt +
-		sizeof(ring_reg_addrs) * hw->tqps_num +
-		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
-	len /= sizeof(uint32_t);
+	len = RTE_DIM(cmdq_reg_list) + common_cnt +
+		RTE_DIM(ring_reg_list) * hw->tqps_num +
+		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
@@ -219,13 +986,31 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	return 0;
 }
 
+static void
+hns3_fill_dfx_regs_name(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			const struct hns3_dfx_reg_entry *reg_list, uint32_t reg_num)
+{
+	uint32_t i, cnt = regs->length;
+	const char *name;
+
+	if (regs->names == NULL)
+		return;
+
+	for (i = 0; i < reg_num; i++) {
+		name = reg_list[i].name_v1;
+		if (hw->revision == PCI_REVISION_ID_HIP09_A && reg_list[i].name_v2 != NULL)
+			name = reg_list[i].name_v2;
+		snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, "%s", name);
+	}
+}
+
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint32_t *reg_val = data;
 	uint32_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -254,6 +1039,9 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_32_bit_list, regs_num);
+	reg_val += regs->length;
+	regs->length += regs_num;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = &desc[i].data[0];
@@ -265,7 +1053,6 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_32(*desc_data++);
-
 			regs_num--;
 			if (regs_num == 0)
 				break;
@@ -277,12 +1064,12 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 }
 
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint64_t *reg_val = data;
 	uint64_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -311,6 +1098,9 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_64_bit_list, regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE);
+	reg_val += regs->length;
+	regs->length += regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = (uint64_t *)(&desc[i].data[0]);
@@ -322,7 +1112,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_64(*desc_data++);
-
 			regs_num--;
 			if (!regs_num)
 				break;
@@ -333,47 +1122,80 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+static void
+hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			     enum hns3_reg_modules idx)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
-	size_t reg_num;
-	uint16_t j;
-	size_t i;
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint32_t *data = regs->data;
+	size_t reg_num, i, cnt;
+
+	data += regs->length;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	cnt = regs->length;
+	for (i = 0; i < reg_num; i++) {
+		*data++ = hns3_read_dev(hw, reg_list[i].addr);
+		if (regs->names != NULL)
+			snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE,
+				 "%s", reg_list[i].name);
+	}
 
-	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+	regs->length += reg_num;
+}
+
+static uint32_t
+hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
+{
+	if (idx == HNS3_RING)
+		return hns3_get_tqp_reg_offset(queue_id);
+	else if (idx == HNS3_TQP_INTR)
+		return hns3_get_tqp_intr_reg_offset(queue_id);
+
+	return 0;
+}
+
+static void
+hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+				 enum hns3_reg_modules idx)
+{
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint16_t tqp_num, reg_offset;
+	uint32_t *data = regs->data;
+	uint32_t reg_num, i, j;
+
+	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+		return;
+
+	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	data += regs->length;
+	for (i = 0; i < tqp_num; i++) {
+		reg_offset = hns3_get_module_tqp_reg_offset(idx, i);
+		for (j = 0; j < reg_num; j++) {
+			*data++ = hns3_read_dev(hw, reg_list[j].addr + reg_offset);
+			if (regs->names != NULL)
+				snprintf(regs->names[regs->length].name,
+					 RTE_ETH_REG_NAME_SIZE, "Q%u_%s", i, reg_list[j].name);
+			regs->length++;
+		}
+	}
+}
+
+static void
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->tqps_num; j++) {
-		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
-	}
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->intr_tqps_num; j++) {
-		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
-						reg_offset);
-	}
-	return data - origin_data_ptr;
+	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
 }
 
 static int
@@ -417,13 +1239,13 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t max_bd_num, bd_num, opcode;
+	uint32_t max_bd_num, bd_num, opcode, regs_num;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
+	uint32_t *data = regs->data;
 	int ret;
 	int i;
 
@@ -447,42 +1269,47 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+
+		data += regs->length;
+		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
+		regs->length += regs_num;
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
+	if (hns->is_vf)
+		return 0;
+
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 	if (ret) {
 		hns3_err(hw, "Get register number failed, ret = %d", ret);
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-	return hns3_get_dfx_regs(hw, (void **)&data);
+	return hns3_get_dfx_regs(hw, regs);
 }
 
 int
@@ -491,15 +1318,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -510,13 +1335,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
+	/* to count the number of filled registers */
+	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
-
-	if (hns->is_vf)
-		return 0;
+	hns3_direct_access_regs(hw, regs);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, data);
+	return  hns3_get_regs_from_firmware(hw, regs);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v6 8/8] net/hns3: support filter registers by module names
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                     ` (6 preceding siblings ...)
  2024-07-22  6:58   ` [PATCH v6 7/8] net/hns3: support report names of registers Jie Hai
@ 2024-07-22  6:58   ` Jie Hai
  2024-08-09  9:22   ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-07-22  6:58 UTC (permalink / raw)
  To: dev, Yisen Zhuang; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

This patch support dumping registers which name contains the
`filter` string. The module names are in lower case and so is
the `filter`. Available module names are cmdq, common_pf,
common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
ssu, ppp, rpu, ncsi, rtc, rcb, etc.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 309 ++++++++++++++++++++---------------
 1 file changed, 180 insertions(+), 129 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 622d2e1c3d02..265d9b433653 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,8 +12,6 @@
 
 #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
-
 struct hns3_dirt_reg_entry {
 	const char *name;
 	uint32_t addr;
@@ -795,33 +793,77 @@ enum hns3_reg_modules {
 	HNS3_64_BIT_DFX,
 };
 
+#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
+#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
+			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
+#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
+
 struct hns3_reg_list {
 	const void *reg_list;
 	uint32_t entry_num;
+	const char *module;
 };
 
 static struct hns3_reg_list hns3_reg_lists[] = {
-	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
-	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
-	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
-	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
-	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
-	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
-	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
-	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
-	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
-	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
-	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
-	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
-
-	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
-	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
-	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
-	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
-	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
-
-	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
-	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
+	[HNS3_BIOS_COMMON] = {
+		dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list),	"bios"
+	},
+	[HNS3_SSU_0] = {
+		dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list),		"ssu"
+	},
+	[HNS3_SSU_1] = {
+		dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list),		"ssu"
+	},
+	[HNS3_IGU_EGU] = {
+		dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list),		"igu_egu"
+	},
+	[HNS3_RPU_0] = {
+		dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list),		"rpu"
+	},
+	[HNS3_RPU_1] = {
+		dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list),		"rpu"
+	},
+	[HNS3_NCSI] = {
+		dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list),		"ncsi"
+	},
+	[HNS3_RTC] = {
+		dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list),		"rtc"
+	},
+	[HNS3_PPP] = {
+		dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list),		"ppp"
+	},
+	[HNS3_RCB] = {
+		dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list),		"rcb"
+	},
+	[HNS3_TQP] = {
+		dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list),		"tqp"
+	},
+	[HNS3_SSU_2] = {
+		dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list),		"ssu"
+	},
+
+	[HNS3_CMDQ] = {
+		cmdq_reg_list,			RTE_DIM(cmdq_reg_list),		"cmdq"
+	},
+	[HNS3_COMMON_PF] = {
+		common_reg_list,		RTE_DIM(common_reg_list),	"common_pf"
+	},
+	[HNS3_COMMON_VF] = {
+		common_vf_reg_list,		RTE_DIM(common_vf_reg_list),	"common_vf"
+	},
+	[HNS3_RING] = {
+		ring_reg_list,			RTE_DIM(ring_reg_list),		"ring"
+	},
+	[HNS3_TQP_INTR] = {
+		tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list),	"tqp_intr"
+	},
+
+	[HNS3_32_BIT_DFX] = {
+		regs_32_bit_list,		RTE_DIM(regs_32_bit_list),	"32_bit_dfx"
+	},
+	[HNS3_64_BIT_DFX] = {
+		regs_64_bit_list,		RTE_DIM(regs_64_bit_list),	"64_bit_dfx"
+	},
 };
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
@@ -865,21 +907,52 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
-static int
-hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+static bool
+hns3_check_module_match(const char *module, const char *filter)
 {
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	int ret;
+	if (filter != NULL && strcmp(filter, module) != 0)
+		return false;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "fail to get the number of registers, "
-			 "ret = %d.", ret);
-		return ret;
+	return true;
+}
+
+#define HNS3_MAX_MODULES_LEN 512
+static uint32_t
+hns3_check_module_names(const char *filter, char *names)
+{
+	uint32_t ret = 0, pos = 0;
+	size_t i;
+
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if (hns3_check_module_match(hns3_reg_lists[i].module, filter))
+			ret |= HNS3_MODULE_MASK(i);
+		if (HNS3_MAX_MODULES_LEN - pos <= strlen(hns3_reg_lists[i].module))
+			return -ENOMEM;
+		snprintf(&names[pos], HNS3_MAX_MODULES_LEN - pos, " %s", hns3_reg_lists[i].module);
+		pos += strlen(hns3_reg_lists[i].module) + 1;
 	}
+	return ret;
+}
 
-	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-	return 0;
+static uint32_t
+hns3_check_filter(struct hns3_hw *hw, const char *filter)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	char names[HNS3_MAX_MODULES_LEN + 1] = {0};
+	uint32_t modules = 0;
+
+	if (filter == NULL)
+		return (1 << RTE_DIM(hns3_reg_lists)) - 1;
+
+	modules = hns3_check_module_names(filter, names);
+	if (hns->is_vf)
+		modules &= HNS3_VF_MODULES;
+	else
+		modules &= ~HNS3_VF_ONLY_MODULES;
+	if (modules == 0)
+		hns3_err(hw, "mismatched module name! Available names are:\n%s.", names);
+
+	return modules;
 }
 
 static int
@@ -917,73 +990,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
 	return 0;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	uint32_t reg_num;
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++) {
-		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-		if (reg_num != hns3_reg_lists[i].entry_num) {
-			hns3_err(hw, "Query register number differ from the list for module!");
-			return -EINVAL;
-		}
-		*count += reg_num;
-	}
-
-	return 0;
-}
-
-static int
-hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int ret;
-
-	ret = hns3_get_32_64_regs_cnt(hw, count);
-	if (ret < 0)
-		return ret;
-
-	return hns3_get_dfx_reg_cnt(hw, count);
-}
-
-static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+static uint32_t
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t dfx_reg_cnt = 0;
-	uint32_t common_cnt;
-	uint32_t len;
-	int ret;
-
-	if (hns->is_vf)
-		common_cnt = RTE_DIM(common_vf_reg_list);
-	else
-		common_cnt = RTE_DIM(common_reg_list);
+	uint32_t reg_num = 0, length = 0;
+	uint32_t i;
 
-	len = RTE_DIM(cmdq_reg_list) + common_cnt +
-		RTE_DIM(ring_reg_list) * hw->tqps_num +
-		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if ((BIT(i) & modules) == 0)
+			continue;
+		reg_num = hns3_reg_lists[i].entry_num;
+		if (i == HNS3_RING)
+			reg_num *= hw->tqps_num;
+		else if (i == HNS3_TQP_INTR)
+			reg_num *= hw->intr_tqps_num;
 
-	if (!hns->is_vf) {
-		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of dfx registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		len += dfx_reg_cnt;
+		length += reg_num;
 	}
 
-	*length = len;
-	return 0;
+	return length;
 }
 
 static void
@@ -1124,12 +1149,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
 
 static void
 hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-			     enum hns3_reg_modules idx)
+			     uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint32_t *data = regs->data;
 	size_t reg_num, i, cnt;
 
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
+		return;
+
 	data += regs->length;
 	reg_num = hns3_reg_lists[idx].entry_num;
 	reg_list = hns3_reg_lists[idx].reg_list;
@@ -1157,14 +1185,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
 
 static void
 hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-				 enum hns3_reg_modules idx)
+				 uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint16_t tqp_num, reg_offset;
 	uint32_t *data = regs->data;
 	uint32_t reg_num, i, j;
 
-	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
 		return;
 
 	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
@@ -1184,18 +1212,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
 }
 
 static void
-hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-
-	if (hns->is_vf)
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
-	else
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
-
-	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
 }
 
 static int
@@ -1239,7 +1262,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode, regs_num;
@@ -1264,6 +1287,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 	for (i = 0; i < opcode_num; i++) {
 		opcode = hns3_dfx_reg_opcode_list[i];
 		bd_num = bd_num_list[i];
+		if ((modules & HNS3_MODULE_MASK(i)) == 0)
+			continue;
 		if (bd_num == 0)
 			continue;
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
@@ -1272,6 +1297,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 
 		data += regs->length;
 		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		if (regs_num !=  hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module %s!",
+				 hns3_reg_lists[i].module);
+			return -EINVAL;
+		}
 		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
 		regs->length += regs_num;
 	}
@@ -1281,14 +1311,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
-	if (hns->is_vf)
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
+	    (modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0)
 		return 0;
 
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -1297,19 +1327,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	return hns3_get_dfx_regs(hw, regs);
+	return 0;
+}
+
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	int ret;
+
+	if (hns->is_vf)
+		return 0;
+
+	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
+	if (ret != 0)
+		return ret;
+
+	return hns3_get_dfx_regs(hw, regs, modules);
 }
 
 int
@@ -1317,13 +1367,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	uint32_t modules = 0;
 	uint32_t length;
-	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
-	if (ret)
-		return ret;
+	modules = hns3_check_filter(hw, regs->filter);
+	if (modules == 0)
+		return -EINVAL;
 
+	length = hns3_get_regs_length(hw, modules);
 	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
@@ -1339,8 +1390,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	hns3_direct_access_regs(hw, regs);
+	hns3_direct_access_regs(hw, regs, modules);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, regs);
+	return  hns3_get_regs_from_firmware(hw, regs, modules);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v6 0/8] support dump reigser names and filter
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
                     ` (7 preceding siblings ...)
  2024-07-22  6:58   ` [PATCH v6 8/8] net/hns3: support filter registers by module names Jie Hai
@ 2024-08-09  9:22   ` Jie Hai
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-08-09  9:22 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, thomas, ferruh.yigit

All maintainers,

Hi, kindly ping for review.

Thanks,
Jie Hai

On 2024/7/22 14:58, Jie Hai wrote:
> The registers can be dumped through the API rte_eth_dev_get_reg_info.
> However, only register values are exported, which is inconvenient for
> users to interpret. Therefore, an extension of the structure
> "rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
> to support the capability of exporting the name of the corresponding
> register and filtering by module names.
> 
> The hns3 driver and telemetry are examples for that.
> 
> Jie Hai (8):
>    ethdev: support report register names and filter
>    ethdev: add telemetry cmd for registers
>    net/hns3: remove some basic address dump
>    net/hns3: fix dump counter of registers
>    net/hns3: remove separators between register module
>    net/hns3: refactor register dump
>    net/hns3: support report names of registers
>    net/hns3: support filter registers by module names
> 
>   doc/guides/rel_notes/release_24_07.rst |    8 +
>   drivers/net/hns3/hns3_regs.c           | 1394 +++++++++++++++++++-----
>   lib/ethdev/ethdev_trace.h              |    2 +
>   lib/ethdev/rte_dev_info.h              |   11 +
>   lib/ethdev/rte_ethdev.c                |   38 +
>   lib/ethdev/rte_ethdev.h                |   29 +
>   lib/ethdev/rte_ethdev_telemetry.c      |  128 +++
>   lib/ethdev/version.map                 |    3 +
>   8 files changed, 1347 insertions(+), 266 deletions(-)
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 0/8] support dump reigser names and filter
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (5 preceding siblings ...)
  2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
@ 2024-09-05  6:26 ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 1/8] ethdev: support report register " Jie Hai
                     ` (7 more replies)
  2024-09-14  6:53 ` [PATCH v7 0/8] support dump reigser names and filter Jie Hai
                   ` (3 subsequent siblings)
  10 siblings, 8 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient for
users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
to support the capability of exporting the name of the corresponding
register and filtering by module names.

The hns3 driver and telemetry are examples for that.

Jie Hai (8):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: remove some basic address dump
  net/hns3: fix dump counter of registers
  net/hns3: remove separators between register module
  net/hns3: refactor register dump
  net/hns3: support report names of registers
  net/hns3: support filter registers by module names

 doc/guides/rel_notes/release_24_11.rst |    7 +
 drivers/net/hns3/hns3_regs.c           | 1394 +++++++++++++++++++-----
 lib/ethdev/ethdev_trace.h              |    2 +
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  128 +++
 lib/ethdev/version.map                 |    3 +
 8 files changed, 1346 insertions(+), 266 deletions(-)
 mode change 100644 => 100755 doc/guides/rel_notes/release_24_11.rst

-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 1/8] ethdev: support report register names and filter
  2024-09-05  6:26 ` [RESEND " Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 2/8] ethdev: add telemetry cmd for registers Jie Hai
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their module names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by modules. And the original API
rte_eth_dev_get_reg_info() does not use the names and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "index_XXX", which means the location in the register table.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 doc/guides/rel_notes/release_24_11.rst |  7 +++++
 lib/ethdev/ethdev_trace.h              |  2 ++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 90 insertions(+)
 mode change 100644 => 100755 doc/guides/rel_notes/release_24_11.rst

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
old mode 100644
new mode 100755
index 0ff70d9057..acec1c60a6
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -54,6 +54,11 @@ New Features
      This section is a comment. Do not overwrite or remove it.
      Also, make sure to start the actual text at the margin.
      =======================================================
+* **Added support for dumping registers with names and filtering by modules.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to filter the
+    registers by module names and get the information (names, values and other
+    attributes) of the filtered registers.
 
 
 Removed Items
@@ -100,6 +105,8 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for filtering by modules and reporting names of registers.
 
 Known Issues
 ------------
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 3bec87bfdb..0c4780a09e 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -1152,6 +1152,8 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_u32(info->length);
 	rte_trace_point_emit_u32(info->width);
 	rte_trace_point_emit_u32(info->version);
+	rte_trace_point_emit_ptr(info->names);
+	rte_trace_point_emit_ptr(info->filter);
 	rte_trace_point_emit_int(ret);
 )
 
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae526..26b777f983 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 64
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Name of target module, filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e..30ca4a0043 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 		return -EINVAL;
 	}
 
+	if (info->names != NULL && info->length != 0)
+		memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length);
+
 	if (*dev->dev_ops->get_reg == NULL)
 		return -ENOTSUP;
 	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) {
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"index_%u", info->offset + i);
+	}
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 548fada1c7..02cb3c07f7 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5071,6 +5071,35 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   - If info->filter is NULL, return info for all registers (seen as filter
+ *     none).
+ *   - If info->filter is not NULL, return error if the driver does not support
+ *     filter. Fill the length field with filtered register number.
+ *   - If info->data is NULL, the function fills in the width and length fields.
+ *   - If info->data is not NULL, ethdev considers there are enough spaces to
+ *     store the registers, and the values of registers with the filter string
+ *     as the module name are put into the buffer pointed at by info->data.
+ *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
+ *     with default names.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 1669055ca5..abc2ff5bb4 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,9 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+
+	# added in 24.07
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 2/8] ethdev: add telemetry cmd for registers
  2024-09-05  6:26 ` [RESEND " Jie Hai
  2024-09-05  6:26   ` [RESEND v6 1/8] ethdev: support report register " Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 3/8] net/hns3: remove some basic address dump Jie Hai
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds a telemetry command for registers dump,
and supports obtaining the registers of a specified module.

In one way, the number of registers that can be exported
is limited by the number of elements carried by dict and
container. In another way, the length of the string
exported by telemetry is limited by MAX_OUTPUT_LEN.
Therefore, when the number of registers to be exported
exceeds, some information will be lost. Warn on the former
case.

An example usage is shown below:
--> /ethdev/regs,0,ring
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "Q0_ring_rx_bd_num": "0x0",
      "Q0_ring_rx_bd_len": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 128 ++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe..1d59c69388 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -1395,6 +1395,132 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static void
+eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
+		     uint32_t idx)
+{
+	if (reg_info->width == sizeof(uint32_t))
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint32_t *)reg_info->data + idx), 0);
+	else
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint64_t *)reg_info->data + idx), 0);
+}
+
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t i;
+	int ret;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	for (i = 0; i < reg_info->length; i++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
+			eth_dev_add_reg_data(group, reg_info, i);
+			continue;
+		}
+
+		group = rte_tel_data_alloc();
+		if (group == NULL) {
+			ret = -ENOMEM;
+			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
+			goto out;
+		}
+		groups[grp_num++] = group;
+		rte_tel_data_start_dict(group);
+		eth_dev_add_reg_data(group, reg_info, i);
+	}
+
+	for (i = 0; i < grp_num; i++) {
+		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
+		ret = rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
+		if (ret == -ENOSPC) {
+			RTE_ETHDEV_LOG_LINE(WARNING,
+				"Reduce register number to be displayed from %u to %u due to limited capacity of telemetry",
+				reg_info->length, i * RTE_TEL_MAX_DICT_ENTRIES);
+			break;
+		}
+	}
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (reg_info.data == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.data");
+		return -ENOMEM;
+	}
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (reg_info.names == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.names");
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter, *end_param;
+	uint16_t port_id;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1562,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 3/8] net/hns3: remove some basic address dump
  2024-09-05  6:26 ` [RESEND " Jie Hai
  2024-09-05  6:26   ` [RESEND v6 1/8] ethdev: support report register " Jie Hai
  2024-09-05  6:26   ` [RESEND v6 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 4/8] net/hns3: fix dump counter of registers Jie Hai
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

For security reasons, some address registers are not suitable
to be exposed, remove them.

Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li<lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c..53d829a4fc 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -17,13 +17,9 @@
 
 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
+static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
 					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
 					  HNS3_CMDQ_RX_DEPTH_REG,
 					  HNS3_CMDQ_RX_TAIL_REG,
 					  HNS3_CMDQ_RX_HEAD_REG,
@@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
 					       HNS3_FUN_RST_ING,
 					       HNS3_GRO_EN_REG};
 
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
+static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
 					  HNS3_RING_RX_BD_LEN_REG,
 					  HNS3_RING_RX_EN_REG,
 					  HNS3_RING_RX_MERGE_EN_REG,
@@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
 					  HNS3_RING_RX_FBD_OFFSET_REG,
 					  HNS3_RING_RX_STASH_REG,
 					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
 					  HNS3_RING_TX_BD_NUM_REG,
 					  HNS3_RING_TX_EN_REG,
 					  HNS3_RING_TX_PRIORITY_REG,
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 4/8] net/hns3: fix dump counter of registers
  2024-09-05  6:26 ` [RESEND " Jie Hai
                     ` (2 preceding siblings ...)
  2024-09-05  6:26   ` [RESEND v6 3/8] net/hns3: remove some basic address dump Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 5/8] net/hns3: remove separators between register module Jie Hai
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")
Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 53d829a4fc..d9c546470d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -127,7 +127,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 5/8] net/hns3: remove separators between register module
  2024-09-05  6:26 ` [RESEND " Jie Hai
                     ` (3 preceding siblings ...)
  2024-09-05  6:26   ` [RESEND v6 4/8] net/hns3: fix dump counter of registers Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 6/8] net/hns3: refactor register dump Jie Hai
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 68 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 50 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d9c546470d..c8e3fb118e 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
@@ -111,23 +108,21 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
+	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = sizeof(cmdq_reg_addrs) + common_cnt +
+		sizeof(ring_reg_addrs) * hw->tqps_num +
+		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
+	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -136,18 +131,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -268,18 +261,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -294,7 +275,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -305,7 +285,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -313,7 +292,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -322,7 +300,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -398,17 +375,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -416,11 +391,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -467,7 +439,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -512,16 +483,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 6/8] net/hns3: refactor register dump
  2024-09-05  6:26 ` [RESEND " Jie Hai
                     ` (4 preceding siblings ...)
  2024-09-05  6:26   ` [RESEND v6 5/8] net/hns3: remove separators between register module Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 7/8] net/hns3: support report names of registers Jie Hai
  2024-09-05  6:26   ` [RESEND v6 8/8] net/hns3: support filter registers by module names Jie Hai
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch refactors codes dumping registers from firmware.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++---------------
 1 file changed, 115 insertions(+), 88 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index c8e3fb118e..89858c2b1c 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -104,12 +104,93 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static int
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
+			uint32_t list_size)
+{
+#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
+	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
+	uint32_t index, desc_index;
+	uint32_t bd_num;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	/* The last BD does not need a next flag */
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+
+	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
+	if (ret) {
+		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
+		return ret;
+	}
+
+	/* The first data in the first BD is a reserved field */
+	for (i = 1; i <= list_size; i++) {
+		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
+		index = i % HNS3_CMD_DESC_DATA_NUM;
+		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
+		bd_num_list[i - 1] = bd_num;
+	}
+
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num_list[opcode_num];
+	int ret;
+	int i;
+
+	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+
+	return 0;
+}
+
+static int
+hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int ret;
+
+	ret = hns3_get_32_64_regs_cnt(hw, count);
+	if (ret < 0)
+		return ret;
+
+	return hns3_get_dfx_reg_cnt(hw, count);
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_cnt;
+	uint32_t dfx_reg_cnt = 0;
 	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
@@ -125,16 +206,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -304,41 +376,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	return data - origin_data_ptr;
 }
 
-static int
-hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
-			uint32_t list_size)
-{
-#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
-	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
-	uint32_t index, desc_index;
-	uint32_t bd_num;
-	uint32_t i;
-	int ret;
-
-	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
-		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
-	}
-	/* The last BD does not need a next flag */
-	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-
-	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
-	if (ret) {
-		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
-		return ret;
-	}
-
-	/* The first data in the first BD is a reserved field */
-	for (i = 1; i <= list_size; i++) {
-		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
-		index = i % HNS3_CMD_DESC_DATA_NUM;
-		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
-		bd_num_list[i - 1] = bd_num;
-	}
-
-	return 0;
-}
-
 static int
 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
 			int bd_num, uint32_t opcode)
@@ -379,24 +416,6 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 	return reg_num;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-
-	return 0;
-}
-
 static int
 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 {
@@ -436,13 +455,41 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 	return ret;
 }
 
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+{
+	uint32_t regs_num_32_bit;
+	uint32_t regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "Get register number failed, ret = %d", ret);
+		return ret;
+	}
+
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_32_bit;
+
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+
+	return hns3_get_dfx_regs(hw, (void **)&data);
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
@@ -470,26 +517,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
 	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_32_bit;
-
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	return  hns3_get_regs_from_firmware(hw, data);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 7/8] net/hns3: support report names of registers
  2024-09-05  6:26 ` [RESEND " Jie Hai
                     ` (5 preceding siblings ...)
  2024-09-05  6:26   ` [RESEND v6 6/8] net/hns3: refactor register dump Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  2024-09-05  6:26   ` [RESEND v6 8/8] net/hns3: support filter registers by module names Jie Hai
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds names for register lists, and support report
names of registers. Some registers has different names on
different platform, use names of HIP08 as default names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 1090 +++++++++++++++++++++++++++++-----
 1 file changed, 957 insertions(+), 133 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 89858c2b1c..622d2e1c3d 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,73 +14,829 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct hns3_dirt_reg_entry {
+	const char *name;
+	uint32_t addr;
+};
+
+static const struct hns3_dirt_reg_entry cmdq_reg_list[] = {
+	{"cmdq_tx_depth",		HNS3_CMDQ_TX_DEPTH_REG},
+	{"cmdq_tx_tail",		HNS3_CMDQ_TX_TAIL_REG},
+	{"cmdq_tx_head",		HNS3_CMDQ_TX_HEAD_REG},
+	{"cmdq_rx_depth",		HNS3_CMDQ_RX_DEPTH_REG},
+	{"cmdq_rx_tail",		HNS3_CMDQ_RX_TAIL_REG},
+	{"cmdq_rx_head",		HNS3_CMDQ_RX_HEAD_REG},
+	{"vector0_cmdq_src",		HNS3_VECTOR0_CMDQ_SRC_REG},
+	{"cmdq_intr_sts",		HNS3_CMDQ_INTR_STS_REG},
+	{"cmdq_intr_en",		HNS3_CMDQ_INTR_EN_REG},
+	{"cmdq_intr_gen",		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"vector0_oter_en",		HNS3_VECTOR0_OTER_EN_REG},
+	{"misc_reset_sts",		HNS3_MISC_RESET_STS_REG},
+	{"vector0_other_int_sts",	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{"global_reset",		HNS3_GLOBAL_RESET_REG},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_vf_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry ring_reg_list[] = {
+	{"ring_rx_bd_num",		HNS3_RING_RX_BD_NUM_REG},
+	{"ring_rx_bd_len",		HNS3_RING_RX_BD_LEN_REG},
+	{"ring_rx_en",			HNS3_RING_RX_EN_REG},
+	{"ring_rx_merge_en",		HNS3_RING_RX_MERGE_EN_REG},
+	{"ring_rx_tail",		HNS3_RING_RX_TAIL_REG},
+	{"ring_rx_head",		HNS3_RING_RX_HEAD_REG},
+	{"ring_rx_fbdnum",		HNS3_RING_RX_FBDNUM_REG},
+	{"ring_rx_offset",		HNS3_RING_RX_OFFSET_REG},
+	{"ring_rx_fbd_offset",		HNS3_RING_RX_FBD_OFFSET_REG},
+	{"ring_rx_stash",		HNS3_RING_RX_STASH_REG},
+	{"ring_rx_bd_err",		HNS3_RING_RX_BD_ERR_REG},
+	{"ring_tx_bd_num",		HNS3_RING_TX_BD_NUM_REG},
+	{"ring_tx_en",			HNS3_RING_TX_EN_REG},
+	{"ring_tx_priority",		HNS3_RING_TX_PRIORITY_REG},
+	{"ring_tx_tc",			HNS3_RING_TX_TC_REG},
+	{"ring_tx_merge_en",		HNS3_RING_TX_MERGE_EN_REG},
+	{"ring_tx_tail",		HNS3_RING_TX_TAIL_REG},
+	{"ring_tx_head",		HNS3_RING_TX_HEAD_REG},
+	{"ring_tx_fbdnum",		HNS3_RING_TX_FBDNUM_REG},
+	{"ring_tx_offset",		HNS3_RING_TX_OFFSET_REG},
+	{"ring_tx_ebd_num",		HNS3_RING_TX_EBD_NUM_REG},
+	{"ring_tx_ebd_offset",		HNS3_RING_TX_EBD_OFFSET_REG},
+	{"ring_tx_bd_err",		HNS3_RING_TX_BD_ERR_REG},
+	{"ring_en",			HNS3_RING_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry tqp_intr_reg_list[] = {
+	{"tqp_intr_ctrl",		HNS3_TQP_INTR_CTRL_REG},
+	{"tqp_intr_gl0",		HNS3_TQP_INTR_GL0_REG},
+	{"tqp_intr_gl1",		HNS3_TQP_INTR_GL1_REG},
+	{"tqp_intr_gl2",		HNS3_TQP_INTR_GL2_REG},
+	{"tqp_intr_rl",			HNS3_TQP_INTR_RL_REG},
+};
+
+struct hns3_dfx_reg_entry {
+	/**
+	 * name_v1 -- default register name for all platforms (HIP08/HIP09/newer).
+	 * name_v2 -- register name different from the default for HIP09.
+	 * If there are more platform with different register name, name_vXX is extended.
+	 * If the platform is newer than HIP09, use default name.
+	 */
+	const char *name_v1;
+	const char *name_v2;
+};
+
+static struct hns3_dfx_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_dfx_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_dfx_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"btmp_ageing_st_b0"},
+	{"btmp_ageing_st_b1"},
+	{"btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"lo_pri_unicast_rlt_drop_num"},
+	{"hi_pri_multicast_rlt_drop_num"},
+
+	{"lo_pri_multicast_rlt_drop_num"},
+	{"ncsi_packet_curr_buffer_cnt"},
+	{"btmp_ageing_rls_cnt_bank0",		"dfx_ssu0_rsv5"},
+	{"btmp_ageing_rls_cnt_bank1",		"dfx_ssu0_rsv6"},
+	{"btmp_ageing_rls_cnt_bank2",		"dfx_ssu0_rsv7"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ncsi_rx_packet_in_cnt_l"},
+	{"ncsi_rx_packet_in_cnt_h"},
+	{"ncsi_tx_packet_out_cnt_l"},
+	{"ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"mb_uncopy_num"},
+	{"rx_oq_drop_pkt_cnt"},
+	{"tx_oq_drop_pkt_cnt"},
+	{"bank_unbalance_drop_cnt"},
+	{"bank_unbalance_rx_drop_cnt"},
+
+	{"nic_l2_eer_drop_pkt_cnt"},
+	{"roc_l2_eer_drop_pkt_cnt"},
+	{"nic_l2_eer_drop_pkt_cnt_rx"},
+	{"roc_l2_eer_drop_pkt_cnt_rx"},
+	{"rx_oq_glb_drop_pkt_cnt"},
+	{"dfx_ssu0_rsv8"},
+
+	{"lo_pri_unicast_cur_cnt"},
+	{"hi_pri_multicast_cur_cnt"},
+	{"lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"packet_tc_curr_buffer_cnt_0"},
+	{"packet_tc_curr_buffer_cnt_1"},
+	{"packet_tc_curr_buffer_cnt_2"},
+	{"packet_tc_curr_buffer_cnt_3"},
+	{"packet_tc_curr_buffer_cnt_4"},
+
+	{"packet_tc_curr_buffer_cnt_5"},
+	{"packet_tc_curr_buffer_cnt_6"},
+	{"packet_tc_curr_buffer_cnt_7"},
+	{"packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"rx_packet_in_cnt_l"},
+	{"rx_packet_in_cnt_h"},
+	{"rx_packet_out_cnt_l"},
+	{"rx_packet_out_cnt_h"},
+	{"tx_packet_in_cnt_l"},
+	{"tx_packet_in_cnt_h"},
+
+	{"tx_packet_out_cnt_l"},
+	{"tx_packet_out_cnt_h"},
+	{"roc_rx_packet_in_cnt_l"},
+	{"roc_rx_packet_in_cnt_h"},
+	{"roc_tx_packet_in_cnt_l"},
+	{"roc_tx_packet_in_cnt_h"},
+
+	{"rx_packet_tc_in_cnt_0_l"},
+	{"rx_packet_tc_in_cnt_0_h"},
+	{"rx_packet_tc_in_cnt_1_l"},
+	{"rx_packet_tc_in_cnt_1_h"},
+	{"rx_packet_tc_in_cnt_2_l"},
+	{"rx_packet_tc_in_cnt_2_h"},
+
+	{"rx_packet_tc_in_cnt_3_l"},
+	{"rx_packet_tc_in_cnt_3_h"},
+	{"rx_packet_tc_in_cnt_4_l"},
+	{"rx_packet_tc_in_cnt_4_h"},
+	{"rx_packet_tc_in_cnt_5_l"},
+	{"rx_packet_tc_in_cnt_5_h"},
+
+	{"rx_packet_tc_in_cnt_6_l"},
+	{"rx_packet_tc_in_cnt_6_h"},
+	{"rx_packet_tc_in_cnt_7_l"},
+	{"rx_packet_tc_in_cnt_7_h"},
+	{"rx_packet_tc_out_cnt_0_l"},
+	{"rx_packet_tc_out_cnt_0_h"},
+
+	{"rx_packet_tc_out_cnt_1_l"},
+	{"rx_packet_tc_out_cnt_1_h"},
+	{"rx_packet_tc_out_cnt_2_l"},
+	{"rx_packet_tc_out_cnt_2_h"},
+	{"rx_packet_tc_out_cnt_3_l"},
+	{"rx_packet_tc_out_cnt_3_h"},
+
+	{"rx_packet_tc_out_cnt_4_l"},
+	{"rx_packet_tc_out_cnt_4_h"},
+	{"rx_packet_tc_out_cnt_5_l"},
+	{"rx_packet_tc_out_cnt_5_h"},
+	{"rx_packet_tc_out_cnt_6_l"},
+	{"rx_packet_tc_out_cnt_6_h"},
+
+	{"rx_packet_tc_out_cnt_7_l"},
+	{"rx_packet_tc_out_cnt_7_h"},
+	{"tx_packet_tc_in_cnt_0_l"},
+	{"tx_packet_tc_in_cnt_0_h"},
+	{"tx_packet_tc_in_cnt_1_l"},
+	{"tx_packet_tc_in_cnt_1_h"},
+
+	{"tx_packet_tc_in_cnt_2_l"},
+	{"tx_packet_tc_in_cnt_2_h"},
+	{"tx_packet_tc_in_cnt_3_l"},
+	{"tx_packet_tc_in_cnt_3_h"},
+	{"tx_packet_tc_in_cnt_4_l"},
+	{"tx_packet_tc_in_cnt_4_h"},
+
+	{"tx_packet_tc_in_cnt_5_l"},
+	{"tx_packet_tc_in_cnt_5_h"},
+	{"tx_packet_tc_in_cnt_6_l"},
+	{"tx_packet_tc_in_cnt_6_h"},
+	{"tx_packet_tc_in_cnt_7_l"},
+	{"tx_packet_tc_in_cnt_7_h"},
+
+	{"tx_packet_tc_out_cnt_0_l"},
+	{"tx_packet_tc_out_cnt_0_h"},
+	{"tx_packet_tc_out_cnt_1_l"},
+	{"tx_packet_tc_out_cnt_1_h"},
+	{"tx_packet_tc_out_cnt_2_l"},
+	{"tx_packet_tc_out_cnt_2_h"},
+
+	{"tx_packet_tc_out_cnt_3_l"},
+	{"tx_packet_tc_out_cnt_3_h"},
+	{"tx_packet_tc_out_cnt_4_l"},
+	{"tx_packet_tc_out_cnt_4_h"},
+	{"tx_packet_tc_out_cnt_5_l"},
+	{"tx_packet_tc_out_cnt_5_h"},
+
+	{"tx_packet_tc_out_cnt_6_l"},
+	{"tx_packet_tc_out_cnt_6_h"},
+	{"tx_packet_tc_out_cnt_7_l"},
+	{"tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_rsv0",		"igu_egu_mul_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv1",		"igu_egu_mul_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv2",		"igu_egu_bro_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv3",		"igu_egu_bro_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv4",		"igu_egu_rsv0"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_tc_queue_num",		"rpu_currport_tnl_index"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rslt_descr_sts",		"ppp_rsv1"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_vmdq1_hit_cnt_l",	"ppp_um_tbl_snq_hit_cnt_l"},
+	{"ppp_um_tbl_vmdq1_hit_cnt_h",	"ppp_um_tbl_snq_hit_cnt_h"},
+	{"ppp_mta_tbl_hit_cnt_l",	"ppp_rsv5"},
+	{"ppp_mta_tbl_hit_cnt_h",	"ppp_rsv6"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_vlan_mirr_cnt_l",		"ppp_rsv7"},
+	{"ppp_vlan_mirr_cnt_h",		"ppp_rsv8"},
+
+	{"ppp_ig_mirr_cnt_l",		"ppp_rsv9"},
+	{"ppp_ig_mirr_cnt_h",		"ppp_rsv10"},
+	{"ppp_eg_mirr_cnt_l",		"ppp_rsv11"},
+	{"ppp_eg_mirr_cnt_h",		"ppp_rsv12"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_axi_rd_fbd_serr_cnt",	"rcb_rcb_tx_mem_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_dfx_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+enum hns3_reg_modules {
+	HNS3_BIOS_COMMON = 0,
+	HNS3_SSU_0,
+	HNS3_SSU_1,
+	HNS3_IGU_EGU,
+	HNS3_RPU_0,
+	HNS3_RPU_1,
+	HNS3_NCSI,
+	HNS3_RTC,
+	HNS3_PPP,
+	HNS3_RCB,
+	HNS3_TQP,
+	HNS3_SSU_2,
+
+	HNS3_CMDQ = 12,
+	HNS3_COMMON_PF,
+	HNS3_COMMON_VF,
+	HNS3_RING,
+	HNS3_TQP_INTR,
+
+	HNS3_32_BIT_DFX,
+	HNS3_64_BIT_DFX,
+};
+
+struct hns3_reg_list {
+	const void *reg_list;
+	uint32_t entry_num;
+};
+
+static struct hns3_reg_list hns3_reg_lists[] = {
+	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
+	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+
+	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
+	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
+	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
+	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
+	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
+
+	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
+	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
-	HNS3_OPC_DFX_BIOS_COMMON_REG,
-	HNS3_OPC_DFX_SSU_REG_0,
-	HNS3_OPC_DFX_SSU_REG_1,
-	HNS3_OPC_DFX_IGU_EGU_REG,
-	HNS3_OPC_DFX_RPU_REG_0,
-	HNS3_OPC_DFX_RPU_REG_1,
-	HNS3_OPC_DFX_NCSI_REG,
-	HNS3_OPC_DFX_RTC_REG,
-	HNS3_OPC_DFX_PPP_REG,
-	HNS3_OPC_DFX_RCB_REG,
-	HNS3_OPC_DFX_TQP_REG,
-	HNS3_OPC_DFX_SSU_REG_2
+	[HNS3_BIOS_COMMON]	=	HNS3_OPC_DFX_BIOS_COMMON_REG,
+	[HNS3_SSU_0]		=	HNS3_OPC_DFX_SSU_REG_0,
+	[HNS3_SSU_1]		=	HNS3_OPC_DFX_SSU_REG_1,
+	[HNS3_IGU_EGU]		=	HNS3_OPC_DFX_IGU_EGU_REG,
+	[HNS3_RPU_0]		=	HNS3_OPC_DFX_RPU_REG_0,
+	[HNS3_RPU_1]		=	HNS3_OPC_DFX_RPU_REG_1,
+	[HNS3_NCSI]		=	HNS3_OPC_DFX_NCSI_REG,
+	[HNS3_RTC]		=	HNS3_OPC_DFX_RTC_REG,
+	[HNS3_PPP]		=	HNS3_OPC_DFX_PPP_REG,
+	[HNS3_RCB]		=	HNS3_OPC_DFX_RCB_REG,
+	[HNS3_TQP]		=	HNS3_OPC_DFX_TQP_REG,
+	[HNS3_SSU_2]		=	HNS3_OPC_DFX_SSU_REG_2
 };
 
 static int
@@ -100,6 +856,11 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE != RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -161,6 +922,7 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
+	uint32_t reg_num;
 	int ret;
 	int i;
 
@@ -168,8 +930,14 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < opcode_num; i++) {
+		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+		if (reg_num != hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module!");
+			return -EINVAL;
+		}
+		*count += reg_num;
+	}
 
 	return 0;
 }
@@ -196,14 +964,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	int ret;
 
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = RTE_DIM(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
 
-	len = sizeof(cmdq_reg_addrs) + common_cnt +
-		sizeof(ring_reg_addrs) * hw->tqps_num +
-		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
-	len /= sizeof(uint32_t);
+	len = RTE_DIM(cmdq_reg_list) + common_cnt +
+		RTE_DIM(ring_reg_list) * hw->tqps_num +
+		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
@@ -219,13 +986,31 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	return 0;
 }
 
+static void
+hns3_fill_dfx_regs_name(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			const struct hns3_dfx_reg_entry *reg_list, uint32_t reg_num)
+{
+	uint32_t i, cnt = regs->length;
+	const char *name;
+
+	if (regs->names == NULL)
+		return;
+
+	for (i = 0; i < reg_num; i++) {
+		name = reg_list[i].name_v1;
+		if (hw->revision == PCI_REVISION_ID_HIP09_A && reg_list[i].name_v2 != NULL)
+			name = reg_list[i].name_v2;
+		snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, "%s", name);
+	}
+}
+
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint32_t *reg_val = data;
 	uint32_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -254,6 +1039,9 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_32_bit_list, regs_num);
+	reg_val += regs->length;
+	regs->length += regs_num;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = &desc[i].data[0];
@@ -265,7 +1053,6 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_32(*desc_data++);
-
 			regs_num--;
 			if (regs_num == 0)
 				break;
@@ -277,12 +1064,12 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 }
 
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint64_t *reg_val = data;
 	uint64_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -311,6 +1098,9 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_64_bit_list, regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE);
+	reg_val += regs->length;
+	regs->length += regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = (uint64_t *)(&desc[i].data[0]);
@@ -322,7 +1112,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_64(*desc_data++);
-
 			regs_num--;
 			if (!regs_num)
 				break;
@@ -333,47 +1122,80 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+static void
+hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			     enum hns3_reg_modules idx)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
-	size_t reg_num;
-	uint16_t j;
-	size_t i;
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint32_t *data = regs->data;
+	size_t reg_num, i, cnt;
+
+	data += regs->length;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	cnt = regs->length;
+	for (i = 0; i < reg_num; i++) {
+		*data++ = hns3_read_dev(hw, reg_list[i].addr);
+		if (regs->names != NULL)
+			snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE,
+				 "%s", reg_list[i].name);
+	}
 
-	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+	regs->length += reg_num;
+}
+
+static uint32_t
+hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
+{
+	if (idx == HNS3_RING)
+		return hns3_get_tqp_reg_offset(queue_id);
+	else if (idx == HNS3_TQP_INTR)
+		return hns3_get_tqp_intr_reg_offset(queue_id);
+
+	return 0;
+}
+
+static void
+hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+				 enum hns3_reg_modules idx)
+{
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint16_t tqp_num, reg_offset;
+	uint32_t *data = regs->data;
+	uint32_t reg_num, i, j;
+
+	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+		return;
+
+	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	data += regs->length;
+	for (i = 0; i < tqp_num; i++) {
+		reg_offset = hns3_get_module_tqp_reg_offset(idx, i);
+		for (j = 0; j < reg_num; j++) {
+			*data++ = hns3_read_dev(hw, reg_list[j].addr + reg_offset);
+			if (regs->names != NULL)
+				snprintf(regs->names[regs->length].name,
+					 RTE_ETH_REG_NAME_SIZE, "Q%u_%s", i, reg_list[j].name);
+			regs->length++;
+		}
+	}
+}
+
+static void
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->tqps_num; j++) {
-		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
-	}
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->intr_tqps_num; j++) {
-		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
-						reg_offset);
-	}
-	return data - origin_data_ptr;
+	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
 }
 
 static int
@@ -417,13 +1239,13 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t max_bd_num, bd_num, opcode;
+	uint32_t max_bd_num, bd_num, opcode, regs_num;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
+	uint32_t *data = regs->data;
 	int ret;
 	int i;
 
@@ -447,42 +1269,47 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+
+		data += regs->length;
+		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
+		regs->length += regs_num;
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
+	if (hns->is_vf)
+		return 0;
+
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 	if (ret) {
 		hns3_err(hw, "Get register number failed, ret = %d", ret);
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-	return hns3_get_dfx_regs(hw, (void **)&data);
+	return hns3_get_dfx_regs(hw, regs);
 }
 
 int
@@ -491,15 +1318,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -510,13 +1335,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
+	/* to count the number of filled registers */
+	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
-
-	if (hns->is_vf)
-		return 0;
+	hns3_direct_access_regs(hw, regs);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, data);
+	return  hns3_get_regs_from_firmware(hw, regs);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [RESEND v6 8/8] net/hns3: support filter registers by module names
  2024-09-05  6:26 ` [RESEND " Jie Hai
                     ` (6 preceding siblings ...)
  2024-09-05  6:26   ` [RESEND v6 7/8] net/hns3: support report names of registers Jie Hai
@ 2024-09-05  6:26   ` Jie Hai
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-05  6:26 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch support dumping registers which name contains the
`filter` string. The module names are in lower case and so is
the `filter`. Available module names are cmdq, common_pf,
common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
ssu, ppp, rpu, ncsi, rtc, rcb, etc.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 309 ++++++++++++++++++++---------------
 1 file changed, 180 insertions(+), 129 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 622d2e1c3d..265d9b4336 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,8 +12,6 @@
 
 #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
-
 struct hns3_dirt_reg_entry {
 	const char *name;
 	uint32_t addr;
@@ -795,33 +793,77 @@ enum hns3_reg_modules {
 	HNS3_64_BIT_DFX,
 };
 
+#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
+#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
+			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
+#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
+
 struct hns3_reg_list {
 	const void *reg_list;
 	uint32_t entry_num;
+	const char *module;
 };
 
 static struct hns3_reg_list hns3_reg_lists[] = {
-	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
-	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
-	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
-	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
-	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
-	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
-	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
-	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
-	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
-	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
-	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
-	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
-
-	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
-	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
-	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
-	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
-	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
-
-	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
-	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
+	[HNS3_BIOS_COMMON] = {
+		dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list),	"bios"
+	},
+	[HNS3_SSU_0] = {
+		dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list),		"ssu"
+	},
+	[HNS3_SSU_1] = {
+		dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list),		"ssu"
+	},
+	[HNS3_IGU_EGU] = {
+		dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list),		"igu_egu"
+	},
+	[HNS3_RPU_0] = {
+		dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list),		"rpu"
+	},
+	[HNS3_RPU_1] = {
+		dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list),		"rpu"
+	},
+	[HNS3_NCSI] = {
+		dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list),		"ncsi"
+	},
+	[HNS3_RTC] = {
+		dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list),		"rtc"
+	},
+	[HNS3_PPP] = {
+		dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list),		"ppp"
+	},
+	[HNS3_RCB] = {
+		dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list),		"rcb"
+	},
+	[HNS3_TQP] = {
+		dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list),		"tqp"
+	},
+	[HNS3_SSU_2] = {
+		dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list),		"ssu"
+	},
+
+	[HNS3_CMDQ] = {
+		cmdq_reg_list,			RTE_DIM(cmdq_reg_list),		"cmdq"
+	},
+	[HNS3_COMMON_PF] = {
+		common_reg_list,		RTE_DIM(common_reg_list),	"common_pf"
+	},
+	[HNS3_COMMON_VF] = {
+		common_vf_reg_list,		RTE_DIM(common_vf_reg_list),	"common_vf"
+	},
+	[HNS3_RING] = {
+		ring_reg_list,			RTE_DIM(ring_reg_list),		"ring"
+	},
+	[HNS3_TQP_INTR] = {
+		tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list),	"tqp_intr"
+	},
+
+	[HNS3_32_BIT_DFX] = {
+		regs_32_bit_list,		RTE_DIM(regs_32_bit_list),	"32_bit_dfx"
+	},
+	[HNS3_64_BIT_DFX] = {
+		regs_64_bit_list,		RTE_DIM(regs_64_bit_list),	"64_bit_dfx"
+	},
 };
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
@@ -865,21 +907,52 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
-static int
-hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+static bool
+hns3_check_module_match(const char *module, const char *filter)
 {
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	int ret;
+	if (filter != NULL && strcmp(filter, module) != 0)
+		return false;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "fail to get the number of registers, "
-			 "ret = %d.", ret);
-		return ret;
+	return true;
+}
+
+#define HNS3_MAX_MODULES_LEN 512
+static uint32_t
+hns3_check_module_names(const char *filter, char *names)
+{
+	uint32_t ret = 0, pos = 0;
+	size_t i;
+
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if (hns3_check_module_match(hns3_reg_lists[i].module, filter))
+			ret |= HNS3_MODULE_MASK(i);
+		if (HNS3_MAX_MODULES_LEN - pos <= strlen(hns3_reg_lists[i].module))
+			return -ENOMEM;
+		snprintf(&names[pos], HNS3_MAX_MODULES_LEN - pos, " %s", hns3_reg_lists[i].module);
+		pos += strlen(hns3_reg_lists[i].module) + 1;
 	}
+	return ret;
+}
 
-	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-	return 0;
+static uint32_t
+hns3_check_filter(struct hns3_hw *hw, const char *filter)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	char names[HNS3_MAX_MODULES_LEN + 1] = {0};
+	uint32_t modules = 0;
+
+	if (filter == NULL)
+		return (1 << RTE_DIM(hns3_reg_lists)) - 1;
+
+	modules = hns3_check_module_names(filter, names);
+	if (hns->is_vf)
+		modules &= HNS3_VF_MODULES;
+	else
+		modules &= ~HNS3_VF_ONLY_MODULES;
+	if (modules == 0)
+		hns3_err(hw, "mismatched module name! Available names are:\n%s.", names);
+
+	return modules;
 }
 
 static int
@@ -917,73 +990,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
 	return 0;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	uint32_t reg_num;
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++) {
-		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-		if (reg_num != hns3_reg_lists[i].entry_num) {
-			hns3_err(hw, "Query register number differ from the list for module!");
-			return -EINVAL;
-		}
-		*count += reg_num;
-	}
-
-	return 0;
-}
-
-static int
-hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int ret;
-
-	ret = hns3_get_32_64_regs_cnt(hw, count);
-	if (ret < 0)
-		return ret;
-
-	return hns3_get_dfx_reg_cnt(hw, count);
-}
-
-static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+static uint32_t
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t dfx_reg_cnt = 0;
-	uint32_t common_cnt;
-	uint32_t len;
-	int ret;
-
-	if (hns->is_vf)
-		common_cnt = RTE_DIM(common_vf_reg_list);
-	else
-		common_cnt = RTE_DIM(common_reg_list);
+	uint32_t reg_num = 0, length = 0;
+	uint32_t i;
 
-	len = RTE_DIM(cmdq_reg_list) + common_cnt +
-		RTE_DIM(ring_reg_list) * hw->tqps_num +
-		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if ((BIT(i) & modules) == 0)
+			continue;
+		reg_num = hns3_reg_lists[i].entry_num;
+		if (i == HNS3_RING)
+			reg_num *= hw->tqps_num;
+		else if (i == HNS3_TQP_INTR)
+			reg_num *= hw->intr_tqps_num;
 
-	if (!hns->is_vf) {
-		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of dfx registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		len += dfx_reg_cnt;
+		length += reg_num;
 	}
 
-	*length = len;
-	return 0;
+	return length;
 }
 
 static void
@@ -1124,12 +1149,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
 
 static void
 hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-			     enum hns3_reg_modules idx)
+			     uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint32_t *data = regs->data;
 	size_t reg_num, i, cnt;
 
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
+		return;
+
 	data += regs->length;
 	reg_num = hns3_reg_lists[idx].entry_num;
 	reg_list = hns3_reg_lists[idx].reg_list;
@@ -1157,14 +1185,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
 
 static void
 hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-				 enum hns3_reg_modules idx)
+				 uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint16_t tqp_num, reg_offset;
 	uint32_t *data = regs->data;
 	uint32_t reg_num, i, j;
 
-	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
 		return;
 
 	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
@@ -1184,18 +1212,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
 }
 
 static void
-hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-
-	if (hns->is_vf)
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
-	else
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
-
-	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
 }
 
 static int
@@ -1239,7 +1262,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode, regs_num;
@@ -1264,6 +1287,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 	for (i = 0; i < opcode_num; i++) {
 		opcode = hns3_dfx_reg_opcode_list[i];
 		bd_num = bd_num_list[i];
+		if ((modules & HNS3_MODULE_MASK(i)) == 0)
+			continue;
 		if (bd_num == 0)
 			continue;
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
@@ -1272,6 +1297,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 
 		data += regs->length;
 		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		if (regs_num !=  hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module %s!",
+				 hns3_reg_lists[i].module);
+			return -EINVAL;
+		}
 		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
 		regs->length += regs_num;
 	}
@@ -1281,14 +1311,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
-	if (hns->is_vf)
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
+	    (modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0)
 		return 0;
 
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -1297,19 +1327,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	return hns3_get_dfx_regs(hw, regs);
+	return 0;
+}
+
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	int ret;
+
+	if (hns->is_vf)
+		return 0;
+
+	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
+	if (ret != 0)
+		return ret;
+
+	return hns3_get_dfx_regs(hw, regs, modules);
 }
 
 int
@@ -1317,13 +1367,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	uint32_t modules = 0;
 	uint32_t length;
-	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
-	if (ret)
-		return ret;
+	modules = hns3_check_filter(hw, regs->filter);
+	if (modules == 0)
+		return -EINVAL;
 
+	length = hns3_get_regs_length(hw, modules);
 	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
@@ -1339,8 +1390,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	hns3_direct_access_regs(hw, regs);
+	hns3_direct_access_regs(hw, regs, modules);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, regs);
+	return  hns3_get_regs_from_firmware(hw, regs, modules);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 0/8] support dump reigser names and filter
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (6 preceding siblings ...)
  2024-09-05  6:26 ` [RESEND " Jie Hai
@ 2024-09-14  6:53 ` Jie Hai
  2024-09-14  7:13 ` Jie Hai
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-14  6:53 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient for
users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
to support the capability of exporting the name of the corresponding
register and filtering by module names.

--
v7: fix doc indention.
--
Jie Hai (8):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: remove some basic address dump
  net/hns3: fix dump counter of registers
  net/hns3: remove separators between register module
  net/hns3: refactor register dump
  net/hns3: support report names of registers
  net/hns3: support filter registers by module names

 doc/guides/rel_notes/release_24_11.rst |    9 +
 drivers/net/hns3/hns3_regs.c           | 1394 +++++++++++++++++++-----
 lib/ethdev/ethdev_trace.h              |    2 +
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  128 +++
 lib/ethdev/version.map                 |    3 +
 8 files changed, 1348 insertions(+), 266 deletions(-)
 mode change 100644 => 100755 doc/guides/rel_notes/release_24_11.rst

-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 0/8] support dump reigser names and filter
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (7 preceding siblings ...)
  2024-09-14  6:53 ` [PATCH v7 0/8] support dump reigser names and filter Jie Hai
@ 2024-09-14  7:13 ` Jie Hai
  2024-09-14  7:13   ` [PATCH v7 1/8] ethdev: support report register " Jie Hai
                     ` (9 more replies)
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
  10 siblings, 10 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient for
users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
to support the capability of exporting the name of the corresponding
register and filtering by module names.

--
v7: fix doc indention.
--
Jie Hai (8):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: remove some basic address dump
  net/hns3: fix dump counter of registers
  net/hns3: remove separators between register module
  net/hns3: refactor register dump
  net/hns3: support report names of registers
  net/hns3: support filter registers by module names

 doc/guides/rel_notes/release_24_11.rst |    9 +
 drivers/net/hns3/hns3_regs.c           | 1394 +++++++++++++++++++-----
 lib/ethdev/ethdev_trace.h              |    2 +
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  128 +++
 lib/ethdev/version.map                 |    3 +
 8 files changed, 1348 insertions(+), 266 deletions(-)
 mode change 100644 => 100755 doc/guides/rel_notes/release_24_11.rst

-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 1/8] ethdev: support report register names and filter
  2024-09-14  7:13 ` Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-22 21:26     ` Ferruh Yigit
  2024-09-14  7:13   ` [PATCH v7 2/8] ethdev: add telemetry cmd for registers Jie Hai
                     ` (8 subsequent siblings)
  9 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their module names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by modules. And the original API
rte_eth_dev_get_reg_info() does not use the names and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "index_XXX", which means the location in the register table.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 doc/guides/rel_notes/release_24_11.rst |  9 ++++++
 lib/ethdev/ethdev_trace.h              |  2 ++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
 lib/ethdev/version.map                 |  3 ++
 6 files changed, 92 insertions(+)
 mode change 100644 => 100755 doc/guides/rel_notes/release_24_11.rst

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
old mode 100644
new mode 100755
index 0ff70d90578e..d53ab8fa5bc7
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added support for dumping registers with names and filtering by modules.**
+
+  Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to filter the
+  registers by module names and get the information (names, values and other
+  attributes) of the filtered registers.
+
 
 Removed Items
 -------------
@@ -100,6 +106,9 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for filtering by modules and reporting names of registers.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 3bec87bfdb70..0c4780a09ef5 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -1152,6 +1152,8 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_u32(info->length);
 	rte_trace_point_emit_u32(info->width);
 	rte_trace_point_emit_u32(info->version);
+	rte_trace_point_emit_ptr(info->names);
+	rte_trace_point_emit_ptr(info->filter);
 	rte_trace_point_emit_int(ret);
 )
 
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..26b777f9836e 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 64
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Name of target module, filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..30ca4a0043c5 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 		return -EINVAL;
 	}
 
+	if (info->names != NULL && info->length != 0)
+		memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length);
+
 	if (*dev->dev_ops->get_reg == NULL)
 		return -ENOTSUP;
 	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) {
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"index_%u", info->offset + i);
+	}
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 548fada1c7ad..02cb3c07f742 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5071,6 +5071,35 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   - If info->filter is NULL, return info for all registers (seen as filter
+ *     none).
+ *   - If info->filter is not NULL, return error if the driver does not support
+ *     filter. Fill the length field with filtered register number.
+ *   - If info->data is NULL, the function fills in the width and length fields.
+ *   - If info->data is not NULL, ethdev considers there are enough spaces to
+ *     store the registers, and the values of registers with the filter string
+ *     as the module name are put into the buffer pointed at by info->data.
+ *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
+ *     with default names.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 1669055ca566..abc2ff5bb4d5 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,9 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+
+	# added in 24.07
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 2/8] ethdev: add telemetry cmd for registers
  2024-09-14  7:13 ` Jie Hai
  2024-09-14  7:13   ` [PATCH v7 1/8] ethdev: support report register " Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  8:20     ` fengchengwen
  2024-09-22 21:28     ` Ferruh Yigit
  2024-09-14  7:13   ` [PATCH v7 3/8] net/hns3: remove some basic address dump Jie Hai
                     ` (7 subsequent siblings)
  9 siblings, 2 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds a telemetry command for registers dump,
and supports obtaining the registers of a specified module.

In one way, the number of registers that can be exported
is limited by the number of elements carried by dict and
container. In another way, the length of the string
exported by telemetry is limited by MAX_OUTPUT_LEN.
Therefore, when the number of registers to be exported
exceeds, some information will be lost. Warn on the former
case.

An example usage is shown below:
--> /ethdev/regs,0,ring
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "Q0_ring_rx_bd_num": "0x0",
      "Q0_ring_rx_bd_len": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 128 ++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..1d59c693883e 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -1395,6 +1395,132 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static void
+eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
+		     uint32_t idx)
+{
+	if (reg_info->width == sizeof(uint32_t))
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint32_t *)reg_info->data + idx), 0);
+	else
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint64_t *)reg_info->data + idx), 0);
+}
+
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t i;
+	int ret;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	for (i = 0; i < reg_info->length; i++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
+			eth_dev_add_reg_data(group, reg_info, i);
+			continue;
+		}
+
+		group = rte_tel_data_alloc();
+		if (group == NULL) {
+			ret = -ENOMEM;
+			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
+			goto out;
+		}
+		groups[grp_num++] = group;
+		rte_tel_data_start_dict(group);
+		eth_dev_add_reg_data(group, reg_info, i);
+	}
+
+	for (i = 0; i < grp_num; i++) {
+		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
+		ret = rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
+		if (ret == -ENOSPC) {
+			RTE_ETHDEV_LOG_LINE(WARNING,
+				"Reduce register number to be displayed from %u to %u due to limited capacity of telemetry",
+				reg_info->length, i * RTE_TEL_MAX_DICT_ENTRIES);
+			break;
+		}
+	}
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Error getting device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (reg_info.data == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.data");
+		return -ENOMEM;
+	}
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (reg_info.names == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.names");
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Error getting regs from device: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter, *end_param;
+	uint16_t port_id;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1562,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 3/8] net/hns3: remove some basic address dump
  2024-09-14  7:13 ` Jie Hai
  2024-09-14  7:13   ` [PATCH v7 1/8] ethdev: support report register " Jie Hai
  2024-09-14  7:13   ` [PATCH v7 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  8:21     ` fengchengwen
  2024-09-14  7:13   ` [PATCH v7 4/8] net/hns3: fix dump counter of registers Jie Hai
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

For security reasons, some address registers are not suitable
to be exposed, remove them.

Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li<lihuisong@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..53d829a4fc68 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -17,13 +17,9 @@
 
 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
+static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
 					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
 					  HNS3_CMDQ_RX_DEPTH_REG,
 					  HNS3_CMDQ_RX_TAIL_REG,
 					  HNS3_CMDQ_RX_HEAD_REG,
@@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
 					       HNS3_FUN_RST_ING,
 					       HNS3_GRO_EN_REG};
 
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
+static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
 					  HNS3_RING_RX_BD_LEN_REG,
 					  HNS3_RING_RX_EN_REG,
 					  HNS3_RING_RX_MERGE_EN_REG,
@@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
 					  HNS3_RING_RX_FBD_OFFSET_REG,
 					  HNS3_RING_RX_STASH_REG,
 					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
 					  HNS3_RING_TX_BD_NUM_REG,
 					  HNS3_RING_TX_EN_REG,
 					  HNS3_RING_TX_PRIORITY_REG,
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 4/8] net/hns3: fix dump counter of registers
  2024-09-14  7:13 ` Jie Hai
                     ` (2 preceding siblings ...)
  2024-09-14  7:13   ` [PATCH v7 3/8] net/hns3: remove some basic address dump Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  7:13   ` [PATCH v7 5/8] net/hns3: remove separators between register module Jie Hai
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")
Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 53d829a4fc68..d9c546470dbe 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -127,7 +127,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 5/8] net/hns3: remove separators between register module
  2024-09-14  7:13 ` Jie Hai
                     ` (3 preceding siblings ...)
  2024-09-14  7:13   ` [PATCH v7 4/8] net/hns3: fix dump counter of registers Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  7:13   ` [PATCH v7 6/8] net/hns3: refactor register dump Jie Hai
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 68 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 50 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d9c546470dbe..c8e3fb118e4b 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
@@ -111,23 +108,21 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
+	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = sizeof(cmdq_reg_addrs) + common_cnt +
+		sizeof(ring_reg_addrs) * hw->tqps_num +
+		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
+	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -136,18 +131,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -268,18 +261,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -294,7 +275,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -305,7 +285,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -313,7 +292,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -322,7 +300,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -398,17 +375,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -416,11 +391,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -467,7 +439,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -512,16 +483,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 6/8] net/hns3: refactor register dump
  2024-09-14  7:13 ` Jie Hai
                     ` (4 preceding siblings ...)
  2024-09-14  7:13   ` [PATCH v7 5/8] net/hns3: remove separators between register module Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  8:26     ` fengchengwen
  2024-09-14  7:13   ` [PATCH v7 7/8] net/hns3: support report names of registers Jie Hai
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch refactors codes dumping registers from firmware.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++---------------
 1 file changed, 115 insertions(+), 88 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index c8e3fb118e4b..89858c2b1c09 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -104,12 +104,93 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static int
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
+			uint32_t list_size)
+{
+#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
+	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
+	uint32_t index, desc_index;
+	uint32_t bd_num;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	/* The last BD does not need a next flag */
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+
+	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
+	if (ret) {
+		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
+		return ret;
+	}
+
+	/* The first data in the first BD is a reserved field */
+	for (i = 1; i <= list_size; i++) {
+		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
+		index = i % HNS3_CMD_DESC_DATA_NUM;
+		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
+		bd_num_list[i - 1] = bd_num;
+	}
+
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num_list[opcode_num];
+	int ret;
+	int i;
+
+	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+
+	return 0;
+}
+
+static int
+hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int ret;
+
+	ret = hns3_get_32_64_regs_cnt(hw, count);
+	if (ret < 0)
+		return ret;
+
+	return hns3_get_dfx_reg_cnt(hw, count);
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_cnt;
+	uint32_t dfx_reg_cnt = 0;
 	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
@@ -125,16 +206,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -304,41 +376,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	return data - origin_data_ptr;
 }
 
-static int
-hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
-			uint32_t list_size)
-{
-#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
-	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
-	uint32_t index, desc_index;
-	uint32_t bd_num;
-	uint32_t i;
-	int ret;
-
-	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
-		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
-	}
-	/* The last BD does not need a next flag */
-	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-
-	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
-	if (ret) {
-		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
-		return ret;
-	}
-
-	/* The first data in the first BD is a reserved field */
-	for (i = 1; i <= list_size; i++) {
-		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
-		index = i % HNS3_CMD_DESC_DATA_NUM;
-		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
-		bd_num_list[i - 1] = bd_num;
-	}
-
-	return 0;
-}
-
 static int
 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
 			int bd_num, uint32_t opcode)
@@ -379,24 +416,6 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 	return reg_num;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-
-	return 0;
-}
-
 static int
 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 {
@@ -436,13 +455,41 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 	return ret;
 }
 
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+{
+	uint32_t regs_num_32_bit;
+	uint32_t regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "Get register number failed, ret = %d", ret);
+		return ret;
+	}
+
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_32_bit;
+
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+
+	return hns3_get_dfx_regs(hw, (void **)&data);
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
@@ -470,26 +517,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
 	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_32_bit;
-
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	return  hns3_get_regs_from_firmware(hw, data);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 7/8] net/hns3: support report names of registers
  2024-09-14  7:13 ` Jie Hai
                     ` (5 preceding siblings ...)
  2024-09-14  7:13   ` [PATCH v7 6/8] net/hns3: refactor register dump Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  8:27     ` fengchengwen
  2024-09-14  7:13   ` [PATCH v7 8/8] net/hns3: support filter registers by module names Jie Hai
                     ` (2 subsequent siblings)
  9 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds names for register lists, and support report
names of registers. Some registers has different names on
different platform, use names of HIP08 as default names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 1090 +++++++++++++++++++++++++++++-----
 1 file changed, 957 insertions(+), 133 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 89858c2b1c09..622d2e1c3d02 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,73 +14,829 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct hns3_dirt_reg_entry {
+	const char *name;
+	uint32_t addr;
+};
+
+static const struct hns3_dirt_reg_entry cmdq_reg_list[] = {
+	{"cmdq_tx_depth",		HNS3_CMDQ_TX_DEPTH_REG},
+	{"cmdq_tx_tail",		HNS3_CMDQ_TX_TAIL_REG},
+	{"cmdq_tx_head",		HNS3_CMDQ_TX_HEAD_REG},
+	{"cmdq_rx_depth",		HNS3_CMDQ_RX_DEPTH_REG},
+	{"cmdq_rx_tail",		HNS3_CMDQ_RX_TAIL_REG},
+	{"cmdq_rx_head",		HNS3_CMDQ_RX_HEAD_REG},
+	{"vector0_cmdq_src",		HNS3_VECTOR0_CMDQ_SRC_REG},
+	{"cmdq_intr_sts",		HNS3_CMDQ_INTR_STS_REG},
+	{"cmdq_intr_en",		HNS3_CMDQ_INTR_EN_REG},
+	{"cmdq_intr_gen",		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"vector0_oter_en",		HNS3_VECTOR0_OTER_EN_REG},
+	{"misc_reset_sts",		HNS3_MISC_RESET_STS_REG},
+	{"vector0_other_int_sts",	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{"global_reset",		HNS3_GLOBAL_RESET_REG},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_vf_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry ring_reg_list[] = {
+	{"ring_rx_bd_num",		HNS3_RING_RX_BD_NUM_REG},
+	{"ring_rx_bd_len",		HNS3_RING_RX_BD_LEN_REG},
+	{"ring_rx_en",			HNS3_RING_RX_EN_REG},
+	{"ring_rx_merge_en",		HNS3_RING_RX_MERGE_EN_REG},
+	{"ring_rx_tail",		HNS3_RING_RX_TAIL_REG},
+	{"ring_rx_head",		HNS3_RING_RX_HEAD_REG},
+	{"ring_rx_fbdnum",		HNS3_RING_RX_FBDNUM_REG},
+	{"ring_rx_offset",		HNS3_RING_RX_OFFSET_REG},
+	{"ring_rx_fbd_offset",		HNS3_RING_RX_FBD_OFFSET_REG},
+	{"ring_rx_stash",		HNS3_RING_RX_STASH_REG},
+	{"ring_rx_bd_err",		HNS3_RING_RX_BD_ERR_REG},
+	{"ring_tx_bd_num",		HNS3_RING_TX_BD_NUM_REG},
+	{"ring_tx_en",			HNS3_RING_TX_EN_REG},
+	{"ring_tx_priority",		HNS3_RING_TX_PRIORITY_REG},
+	{"ring_tx_tc",			HNS3_RING_TX_TC_REG},
+	{"ring_tx_merge_en",		HNS3_RING_TX_MERGE_EN_REG},
+	{"ring_tx_tail",		HNS3_RING_TX_TAIL_REG},
+	{"ring_tx_head",		HNS3_RING_TX_HEAD_REG},
+	{"ring_tx_fbdnum",		HNS3_RING_TX_FBDNUM_REG},
+	{"ring_tx_offset",		HNS3_RING_TX_OFFSET_REG},
+	{"ring_tx_ebd_num",		HNS3_RING_TX_EBD_NUM_REG},
+	{"ring_tx_ebd_offset",		HNS3_RING_TX_EBD_OFFSET_REG},
+	{"ring_tx_bd_err",		HNS3_RING_TX_BD_ERR_REG},
+	{"ring_en",			HNS3_RING_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry tqp_intr_reg_list[] = {
+	{"tqp_intr_ctrl",		HNS3_TQP_INTR_CTRL_REG},
+	{"tqp_intr_gl0",		HNS3_TQP_INTR_GL0_REG},
+	{"tqp_intr_gl1",		HNS3_TQP_INTR_GL1_REG},
+	{"tqp_intr_gl2",		HNS3_TQP_INTR_GL2_REG},
+	{"tqp_intr_rl",			HNS3_TQP_INTR_RL_REG},
+};
+
+struct hns3_dfx_reg_entry {
+	/**
+	 * name_v1 -- default register name for all platforms (HIP08/HIP09/newer).
+	 * name_v2 -- register name different from the default for HIP09.
+	 * If there are more platform with different register name, name_vXX is extended.
+	 * If the platform is newer than HIP09, use default name.
+	 */
+	const char *name_v1;
+	const char *name_v2;
+};
+
+static struct hns3_dfx_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_dfx_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_dfx_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"btmp_ageing_st_b0"},
+	{"btmp_ageing_st_b1"},
+	{"btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"lo_pri_unicast_rlt_drop_num"},
+	{"hi_pri_multicast_rlt_drop_num"},
+
+	{"lo_pri_multicast_rlt_drop_num"},
+	{"ncsi_packet_curr_buffer_cnt"},
+	{"btmp_ageing_rls_cnt_bank0",		"dfx_ssu0_rsv5"},
+	{"btmp_ageing_rls_cnt_bank1",		"dfx_ssu0_rsv6"},
+	{"btmp_ageing_rls_cnt_bank2",		"dfx_ssu0_rsv7"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ncsi_rx_packet_in_cnt_l"},
+	{"ncsi_rx_packet_in_cnt_h"},
+	{"ncsi_tx_packet_out_cnt_l"},
+	{"ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"mb_uncopy_num"},
+	{"rx_oq_drop_pkt_cnt"},
+	{"tx_oq_drop_pkt_cnt"},
+	{"bank_unbalance_drop_cnt"},
+	{"bank_unbalance_rx_drop_cnt"},
+
+	{"nic_l2_eer_drop_pkt_cnt"},
+	{"roc_l2_eer_drop_pkt_cnt"},
+	{"nic_l2_eer_drop_pkt_cnt_rx"},
+	{"roc_l2_eer_drop_pkt_cnt_rx"},
+	{"rx_oq_glb_drop_pkt_cnt"},
+	{"dfx_ssu0_rsv8"},
+
+	{"lo_pri_unicast_cur_cnt"},
+	{"hi_pri_multicast_cur_cnt"},
+	{"lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"packet_tc_curr_buffer_cnt_0"},
+	{"packet_tc_curr_buffer_cnt_1"},
+	{"packet_tc_curr_buffer_cnt_2"},
+	{"packet_tc_curr_buffer_cnt_3"},
+	{"packet_tc_curr_buffer_cnt_4"},
+
+	{"packet_tc_curr_buffer_cnt_5"},
+	{"packet_tc_curr_buffer_cnt_6"},
+	{"packet_tc_curr_buffer_cnt_7"},
+	{"packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"rx_packet_in_cnt_l"},
+	{"rx_packet_in_cnt_h"},
+	{"rx_packet_out_cnt_l"},
+	{"rx_packet_out_cnt_h"},
+	{"tx_packet_in_cnt_l"},
+	{"tx_packet_in_cnt_h"},
+
+	{"tx_packet_out_cnt_l"},
+	{"tx_packet_out_cnt_h"},
+	{"roc_rx_packet_in_cnt_l"},
+	{"roc_rx_packet_in_cnt_h"},
+	{"roc_tx_packet_in_cnt_l"},
+	{"roc_tx_packet_in_cnt_h"},
+
+	{"rx_packet_tc_in_cnt_0_l"},
+	{"rx_packet_tc_in_cnt_0_h"},
+	{"rx_packet_tc_in_cnt_1_l"},
+	{"rx_packet_tc_in_cnt_1_h"},
+	{"rx_packet_tc_in_cnt_2_l"},
+	{"rx_packet_tc_in_cnt_2_h"},
+
+	{"rx_packet_tc_in_cnt_3_l"},
+	{"rx_packet_tc_in_cnt_3_h"},
+	{"rx_packet_tc_in_cnt_4_l"},
+	{"rx_packet_tc_in_cnt_4_h"},
+	{"rx_packet_tc_in_cnt_5_l"},
+	{"rx_packet_tc_in_cnt_5_h"},
+
+	{"rx_packet_tc_in_cnt_6_l"},
+	{"rx_packet_tc_in_cnt_6_h"},
+	{"rx_packet_tc_in_cnt_7_l"},
+	{"rx_packet_tc_in_cnt_7_h"},
+	{"rx_packet_tc_out_cnt_0_l"},
+	{"rx_packet_tc_out_cnt_0_h"},
+
+	{"rx_packet_tc_out_cnt_1_l"},
+	{"rx_packet_tc_out_cnt_1_h"},
+	{"rx_packet_tc_out_cnt_2_l"},
+	{"rx_packet_tc_out_cnt_2_h"},
+	{"rx_packet_tc_out_cnt_3_l"},
+	{"rx_packet_tc_out_cnt_3_h"},
+
+	{"rx_packet_tc_out_cnt_4_l"},
+	{"rx_packet_tc_out_cnt_4_h"},
+	{"rx_packet_tc_out_cnt_5_l"},
+	{"rx_packet_tc_out_cnt_5_h"},
+	{"rx_packet_tc_out_cnt_6_l"},
+	{"rx_packet_tc_out_cnt_6_h"},
+
+	{"rx_packet_tc_out_cnt_7_l"},
+	{"rx_packet_tc_out_cnt_7_h"},
+	{"tx_packet_tc_in_cnt_0_l"},
+	{"tx_packet_tc_in_cnt_0_h"},
+	{"tx_packet_tc_in_cnt_1_l"},
+	{"tx_packet_tc_in_cnt_1_h"},
+
+	{"tx_packet_tc_in_cnt_2_l"},
+	{"tx_packet_tc_in_cnt_2_h"},
+	{"tx_packet_tc_in_cnt_3_l"},
+	{"tx_packet_tc_in_cnt_3_h"},
+	{"tx_packet_tc_in_cnt_4_l"},
+	{"tx_packet_tc_in_cnt_4_h"},
+
+	{"tx_packet_tc_in_cnt_5_l"},
+	{"tx_packet_tc_in_cnt_5_h"},
+	{"tx_packet_tc_in_cnt_6_l"},
+	{"tx_packet_tc_in_cnt_6_h"},
+	{"tx_packet_tc_in_cnt_7_l"},
+	{"tx_packet_tc_in_cnt_7_h"},
+
+	{"tx_packet_tc_out_cnt_0_l"},
+	{"tx_packet_tc_out_cnt_0_h"},
+	{"tx_packet_tc_out_cnt_1_l"},
+	{"tx_packet_tc_out_cnt_1_h"},
+	{"tx_packet_tc_out_cnt_2_l"},
+	{"tx_packet_tc_out_cnt_2_h"},
+
+	{"tx_packet_tc_out_cnt_3_l"},
+	{"tx_packet_tc_out_cnt_3_h"},
+	{"tx_packet_tc_out_cnt_4_l"},
+	{"tx_packet_tc_out_cnt_4_h"},
+	{"tx_packet_tc_out_cnt_5_l"},
+	{"tx_packet_tc_out_cnt_5_h"},
+
+	{"tx_packet_tc_out_cnt_6_l"},
+	{"tx_packet_tc_out_cnt_6_h"},
+	{"tx_packet_tc_out_cnt_7_l"},
+	{"tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_rsv0",		"igu_egu_mul_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv1",		"igu_egu_mul_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv2",		"igu_egu_bro_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv3",		"igu_egu_bro_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv4",		"igu_egu_rsv0"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_tc_queue_num",		"rpu_currport_tnl_index"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rslt_descr_sts",		"ppp_rsv1"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_vmdq1_hit_cnt_l",	"ppp_um_tbl_snq_hit_cnt_l"},
+	{"ppp_um_tbl_vmdq1_hit_cnt_h",	"ppp_um_tbl_snq_hit_cnt_h"},
+	{"ppp_mta_tbl_hit_cnt_l",	"ppp_rsv5"},
+	{"ppp_mta_tbl_hit_cnt_h",	"ppp_rsv6"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_vlan_mirr_cnt_l",		"ppp_rsv7"},
+	{"ppp_vlan_mirr_cnt_h",		"ppp_rsv8"},
+
+	{"ppp_ig_mirr_cnt_l",		"ppp_rsv9"},
+	{"ppp_ig_mirr_cnt_h",		"ppp_rsv10"},
+	{"ppp_eg_mirr_cnt_l",		"ppp_rsv11"},
+	{"ppp_eg_mirr_cnt_h",		"ppp_rsv12"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_axi_rd_fbd_serr_cnt",	"rcb_rcb_tx_mem_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_dfx_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+enum hns3_reg_modules {
+	HNS3_BIOS_COMMON = 0,
+	HNS3_SSU_0,
+	HNS3_SSU_1,
+	HNS3_IGU_EGU,
+	HNS3_RPU_0,
+	HNS3_RPU_1,
+	HNS3_NCSI,
+	HNS3_RTC,
+	HNS3_PPP,
+	HNS3_RCB,
+	HNS3_TQP,
+	HNS3_SSU_2,
+
+	HNS3_CMDQ = 12,
+	HNS3_COMMON_PF,
+	HNS3_COMMON_VF,
+	HNS3_RING,
+	HNS3_TQP_INTR,
+
+	HNS3_32_BIT_DFX,
+	HNS3_64_BIT_DFX,
+};
+
+struct hns3_reg_list {
+	const void *reg_list;
+	uint32_t entry_num;
+};
+
+static struct hns3_reg_list hns3_reg_lists[] = {
+	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
+	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
+	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
+	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
+	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
+	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
+	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
+	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
+	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
+	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
+	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
+	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
+
+	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
+	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
+	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
+	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
+	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
+
+	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
+	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
-	HNS3_OPC_DFX_BIOS_COMMON_REG,
-	HNS3_OPC_DFX_SSU_REG_0,
-	HNS3_OPC_DFX_SSU_REG_1,
-	HNS3_OPC_DFX_IGU_EGU_REG,
-	HNS3_OPC_DFX_RPU_REG_0,
-	HNS3_OPC_DFX_RPU_REG_1,
-	HNS3_OPC_DFX_NCSI_REG,
-	HNS3_OPC_DFX_RTC_REG,
-	HNS3_OPC_DFX_PPP_REG,
-	HNS3_OPC_DFX_RCB_REG,
-	HNS3_OPC_DFX_TQP_REG,
-	HNS3_OPC_DFX_SSU_REG_2
+	[HNS3_BIOS_COMMON]	=	HNS3_OPC_DFX_BIOS_COMMON_REG,
+	[HNS3_SSU_0]		=	HNS3_OPC_DFX_SSU_REG_0,
+	[HNS3_SSU_1]		=	HNS3_OPC_DFX_SSU_REG_1,
+	[HNS3_IGU_EGU]		=	HNS3_OPC_DFX_IGU_EGU_REG,
+	[HNS3_RPU_0]		=	HNS3_OPC_DFX_RPU_REG_0,
+	[HNS3_RPU_1]		=	HNS3_OPC_DFX_RPU_REG_1,
+	[HNS3_NCSI]		=	HNS3_OPC_DFX_NCSI_REG,
+	[HNS3_RTC]		=	HNS3_OPC_DFX_RTC_REG,
+	[HNS3_PPP]		=	HNS3_OPC_DFX_PPP_REG,
+	[HNS3_RCB]		=	HNS3_OPC_DFX_RCB_REG,
+	[HNS3_TQP]		=	HNS3_OPC_DFX_TQP_REG,
+	[HNS3_SSU_2]		=	HNS3_OPC_DFX_SSU_REG_2
 };
 
 static int
@@ -100,6 +856,11 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE != RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -161,6 +922,7 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
+	uint32_t reg_num;
 	int ret;
 	int i;
 
@@ -168,8 +930,14 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < opcode_num; i++) {
+		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+		if (reg_num != hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module!");
+			return -EINVAL;
+		}
+		*count += reg_num;
+	}
 
 	return 0;
 }
@@ -196,14 +964,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	int ret;
 
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = RTE_DIM(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
 
-	len = sizeof(cmdq_reg_addrs) + common_cnt +
-		sizeof(ring_reg_addrs) * hw->tqps_num +
-		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
-	len /= sizeof(uint32_t);
+	len = RTE_DIM(cmdq_reg_list) + common_cnt +
+		RTE_DIM(ring_reg_list) * hw->tqps_num +
+		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
@@ -219,13 +986,31 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	return 0;
 }
 
+static void
+hns3_fill_dfx_regs_name(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			const struct hns3_dfx_reg_entry *reg_list, uint32_t reg_num)
+{
+	uint32_t i, cnt = regs->length;
+	const char *name;
+
+	if (regs->names == NULL)
+		return;
+
+	for (i = 0; i < reg_num; i++) {
+		name = reg_list[i].name_v1;
+		if (hw->revision == PCI_REVISION_ID_HIP09_A && reg_list[i].name_v2 != NULL)
+			name = reg_list[i].name_v2;
+		snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, "%s", name);
+	}
+}
+
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint32_t *reg_val = data;
 	uint32_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -254,6 +1039,9 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_32_bit_list, regs_num);
+	reg_val += regs->length;
+	regs->length += regs_num;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = &desc[i].data[0];
@@ -265,7 +1053,6 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_32(*desc_data++);
-
 			regs_num--;
 			if (regs_num == 0)
 				break;
@@ -277,12 +1064,12 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 }
 
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint64_t *reg_val = data;
 	uint64_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -311,6 +1098,9 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_64_bit_list, regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE);
+	reg_val += regs->length;
+	regs->length += regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = (uint64_t *)(&desc[i].data[0]);
@@ -322,7 +1112,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_64(*desc_data++);
-
 			regs_num--;
 			if (!regs_num)
 				break;
@@ -333,47 +1122,80 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+static void
+hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			     enum hns3_reg_modules idx)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
-	size_t reg_num;
-	uint16_t j;
-	size_t i;
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint32_t *data = regs->data;
+	size_t reg_num, i, cnt;
+
+	data += regs->length;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	cnt = regs->length;
+	for (i = 0; i < reg_num; i++) {
+		*data++ = hns3_read_dev(hw, reg_list[i].addr);
+		if (regs->names != NULL)
+			snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE,
+				 "%s", reg_list[i].name);
+	}
 
-	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+	regs->length += reg_num;
+}
+
+static uint32_t
+hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
+{
+	if (idx == HNS3_RING)
+		return hns3_get_tqp_reg_offset(queue_id);
+	else if (idx == HNS3_TQP_INTR)
+		return hns3_get_tqp_intr_reg_offset(queue_id);
+
+	return 0;
+}
+
+static void
+hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+				 enum hns3_reg_modules idx)
+{
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint16_t tqp_num, reg_offset;
+	uint32_t *data = regs->data;
+	uint32_t reg_num, i, j;
+
+	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+		return;
+
+	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	data += regs->length;
+	for (i = 0; i < tqp_num; i++) {
+		reg_offset = hns3_get_module_tqp_reg_offset(idx, i);
+		for (j = 0; j < reg_num; j++) {
+			*data++ = hns3_read_dev(hw, reg_list[j].addr + reg_offset);
+			if (regs->names != NULL)
+				snprintf(regs->names[regs->length].name,
+					 RTE_ETH_REG_NAME_SIZE, "Q%u_%s", i, reg_list[j].name);
+			regs->length++;
+		}
+	}
+}
+
+static void
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->tqps_num; j++) {
-		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
-	}
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->intr_tqps_num; j++) {
-		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
-						reg_offset);
-	}
-	return data - origin_data_ptr;
+	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
 }
 
 static int
@@ -417,13 +1239,13 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t max_bd_num, bd_num, opcode;
+	uint32_t max_bd_num, bd_num, opcode, regs_num;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
+	uint32_t *data = regs->data;
 	int ret;
 	int i;
 
@@ -447,42 +1269,47 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+
+		data += regs->length;
+		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
+		regs->length += regs_num;
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
+	if (hns->is_vf)
+		return 0;
+
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 	if (ret) {
 		hns3_err(hw, "Get register number failed, ret = %d", ret);
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-	return hns3_get_dfx_regs(hw, (void **)&data);
+	return hns3_get_dfx_regs(hw, regs);
 }
 
 int
@@ -491,15 +1318,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -510,13 +1335,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
+	/* to count the number of filled registers */
+	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
-
-	if (hns->is_vf)
-		return 0;
+	hns3_direct_access_regs(hw, regs);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, data);
+	return  hns3_get_regs_from_firmware(hw, regs);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v7 8/8] net/hns3: support filter registers by module names
  2024-09-14  7:13 ` Jie Hai
                     ` (6 preceding siblings ...)
  2024-09-14  7:13   ` [PATCH v7 7/8] net/hns3: support report names of registers Jie Hai
@ 2024-09-14  7:13   ` Jie Hai
  2024-09-14  8:46     ` fengchengwen
  2024-09-14 15:00   ` [PATCH v7 0/8] support dump reigser names and filter Stephen Hemminger
  2024-09-22 21:31   ` Ferruh Yigit
  9 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-14  7:13 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch support dumping registers which name contains the
`filter` string. The module names are in lower case and so is
the `filter`. Available module names are cmdq, common_pf,
common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
ssu, ppp, rpu, ncsi, rtc, rcb, etc.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 309 ++++++++++++++++++++---------------
 1 file changed, 180 insertions(+), 129 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 622d2e1c3d02..265d9b433653 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,8 +12,6 @@
 
 #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
-
 struct hns3_dirt_reg_entry {
 	const char *name;
 	uint32_t addr;
@@ -795,33 +793,77 @@ enum hns3_reg_modules {
 	HNS3_64_BIT_DFX,
 };
 
+#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
+#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
+			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
+#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
+
 struct hns3_reg_list {
 	const void *reg_list;
 	uint32_t entry_num;
+	const char *module;
 };
 
 static struct hns3_reg_list hns3_reg_lists[] = {
-	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
-	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
-	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
-	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
-	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
-	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
-	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
-	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
-	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
-	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
-	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
-	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
-
-	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
-	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
-	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
-	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
-	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
-
-	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
-	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
+	[HNS3_BIOS_COMMON] = {
+		dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list),	"bios"
+	},
+	[HNS3_SSU_0] = {
+		dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list),		"ssu"
+	},
+	[HNS3_SSU_1] = {
+		dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list),		"ssu"
+	},
+	[HNS3_IGU_EGU] = {
+		dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list),		"igu_egu"
+	},
+	[HNS3_RPU_0] = {
+		dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list),		"rpu"
+	},
+	[HNS3_RPU_1] = {
+		dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list),		"rpu"
+	},
+	[HNS3_NCSI] = {
+		dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list),		"ncsi"
+	},
+	[HNS3_RTC] = {
+		dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list),		"rtc"
+	},
+	[HNS3_PPP] = {
+		dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list),		"ppp"
+	},
+	[HNS3_RCB] = {
+		dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list),		"rcb"
+	},
+	[HNS3_TQP] = {
+		dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list),		"tqp"
+	},
+	[HNS3_SSU_2] = {
+		dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list),		"ssu"
+	},
+
+	[HNS3_CMDQ] = {
+		cmdq_reg_list,			RTE_DIM(cmdq_reg_list),		"cmdq"
+	},
+	[HNS3_COMMON_PF] = {
+		common_reg_list,		RTE_DIM(common_reg_list),	"common_pf"
+	},
+	[HNS3_COMMON_VF] = {
+		common_vf_reg_list,		RTE_DIM(common_vf_reg_list),	"common_vf"
+	},
+	[HNS3_RING] = {
+		ring_reg_list,			RTE_DIM(ring_reg_list),		"ring"
+	},
+	[HNS3_TQP_INTR] = {
+		tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list),	"tqp_intr"
+	},
+
+	[HNS3_32_BIT_DFX] = {
+		regs_32_bit_list,		RTE_DIM(regs_32_bit_list),	"32_bit_dfx"
+	},
+	[HNS3_64_BIT_DFX] = {
+		regs_64_bit_list,		RTE_DIM(regs_64_bit_list),	"64_bit_dfx"
+	},
 };
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
@@ -865,21 +907,52 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
-static int
-hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+static bool
+hns3_check_module_match(const char *module, const char *filter)
 {
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	int ret;
+	if (filter != NULL && strcmp(filter, module) != 0)
+		return false;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "fail to get the number of registers, "
-			 "ret = %d.", ret);
-		return ret;
+	return true;
+}
+
+#define HNS3_MAX_MODULES_LEN 512
+static uint32_t
+hns3_check_module_names(const char *filter, char *names)
+{
+	uint32_t ret = 0, pos = 0;
+	size_t i;
+
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if (hns3_check_module_match(hns3_reg_lists[i].module, filter))
+			ret |= HNS3_MODULE_MASK(i);
+		if (HNS3_MAX_MODULES_LEN - pos <= strlen(hns3_reg_lists[i].module))
+			return -ENOMEM;
+		snprintf(&names[pos], HNS3_MAX_MODULES_LEN - pos, " %s", hns3_reg_lists[i].module);
+		pos += strlen(hns3_reg_lists[i].module) + 1;
 	}
+	return ret;
+}
 
-	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-	return 0;
+static uint32_t
+hns3_check_filter(struct hns3_hw *hw, const char *filter)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	char names[HNS3_MAX_MODULES_LEN + 1] = {0};
+	uint32_t modules = 0;
+
+	if (filter == NULL)
+		return (1 << RTE_DIM(hns3_reg_lists)) - 1;
+
+	modules = hns3_check_module_names(filter, names);
+	if (hns->is_vf)
+		modules &= HNS3_VF_MODULES;
+	else
+		modules &= ~HNS3_VF_ONLY_MODULES;
+	if (modules == 0)
+		hns3_err(hw, "mismatched module name! Available names are:\n%s.", names);
+
+	return modules;
 }
 
 static int
@@ -917,73 +990,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
 	return 0;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	uint32_t reg_num;
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++) {
-		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-		if (reg_num != hns3_reg_lists[i].entry_num) {
-			hns3_err(hw, "Query register number differ from the list for module!");
-			return -EINVAL;
-		}
-		*count += reg_num;
-	}
-
-	return 0;
-}
-
-static int
-hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int ret;
-
-	ret = hns3_get_32_64_regs_cnt(hw, count);
-	if (ret < 0)
-		return ret;
-
-	return hns3_get_dfx_reg_cnt(hw, count);
-}
-
-static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+static uint32_t
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t dfx_reg_cnt = 0;
-	uint32_t common_cnt;
-	uint32_t len;
-	int ret;
-
-	if (hns->is_vf)
-		common_cnt = RTE_DIM(common_vf_reg_list);
-	else
-		common_cnt = RTE_DIM(common_reg_list);
+	uint32_t reg_num = 0, length = 0;
+	uint32_t i;
 
-	len = RTE_DIM(cmdq_reg_list) + common_cnt +
-		RTE_DIM(ring_reg_list) * hw->tqps_num +
-		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if ((BIT(i) & modules) == 0)
+			continue;
+		reg_num = hns3_reg_lists[i].entry_num;
+		if (i == HNS3_RING)
+			reg_num *= hw->tqps_num;
+		else if (i == HNS3_TQP_INTR)
+			reg_num *= hw->intr_tqps_num;
 
-	if (!hns->is_vf) {
-		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of dfx registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		len += dfx_reg_cnt;
+		length += reg_num;
 	}
 
-	*length = len;
-	return 0;
+	return length;
 }
 
 static void
@@ -1124,12 +1149,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
 
 static void
 hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-			     enum hns3_reg_modules idx)
+			     uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint32_t *data = regs->data;
 	size_t reg_num, i, cnt;
 
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
+		return;
+
 	data += regs->length;
 	reg_num = hns3_reg_lists[idx].entry_num;
 	reg_list = hns3_reg_lists[idx].reg_list;
@@ -1157,14 +1185,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
 
 static void
 hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-				 enum hns3_reg_modules idx)
+				 uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint16_t tqp_num, reg_offset;
 	uint32_t *data = regs->data;
 	uint32_t reg_num, i, j;
 
-	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
 		return;
 
 	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
@@ -1184,18 +1212,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
 }
 
 static void
-hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-
-	if (hns->is_vf)
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
-	else
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
-
-	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
 }
 
 static int
@@ -1239,7 +1262,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode, regs_num;
@@ -1264,6 +1287,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 	for (i = 0; i < opcode_num; i++) {
 		opcode = hns3_dfx_reg_opcode_list[i];
 		bd_num = bd_num_list[i];
+		if ((modules & HNS3_MODULE_MASK(i)) == 0)
+			continue;
 		if (bd_num == 0)
 			continue;
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
@@ -1272,6 +1297,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 
 		data += regs->length;
 		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		if (regs_num !=  hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module %s!",
+				 hns3_reg_lists[i].module);
+			return -EINVAL;
+		}
 		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
 		regs->length += regs_num;
 	}
@@ -1281,14 +1311,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
-	if (hns->is_vf)
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
+	    (modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0)
 		return 0;
 
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -1297,19 +1327,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	return hns3_get_dfx_regs(hw, regs);
+	return 0;
+}
+
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	int ret;
+
+	if (hns->is_vf)
+		return 0;
+
+	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
+	if (ret != 0)
+		return ret;
+
+	return hns3_get_dfx_regs(hw, regs, modules);
 }
 
 int
@@ -1317,13 +1367,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	uint32_t modules = 0;
 	uint32_t length;
-	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
-	if (ret)
-		return ret;
+	modules = hns3_check_filter(hw, regs->filter);
+	if (modules == 0)
+		return -EINVAL;
 
+	length = hns3_get_regs_length(hw, modules);
 	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
@@ -1339,8 +1390,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	hns3_direct_access_regs(hw, regs);
+	hns3_direct_access_regs(hw, regs, modules);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, regs);
+	return  hns3_get_regs_from_firmware(hw, regs, modules);
 }
-- 
2.22.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 2/8] ethdev: add telemetry cmd for registers
  2024-09-14  7:13   ` [PATCH v7 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-09-14  8:20     ` fengchengwen
  2024-09-23  2:41       ` Jie Hai
  2024-09-22 21:28     ` Ferruh Yigit
  1 sibling, 1 reply; 134+ messages in thread
From: fengchengwen @ 2024-09-14  8:20 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

On 2024/9/14 15:13, Jie Hai wrote:
> This patch adds a telemetry command for registers dump,
> and supports obtaining the registers of a specified module.
> 
> In one way, the number of registers that can be exported
> is limited by the number of elements carried by dict and
> container. In another way, the length of the string
> exported by telemetry is limited by MAX_OUTPUT_LEN.
> Therefore, when the number of registers to be exported
> exceeds, some information will be lost. Warn on the former
> case.
> 
> An example usage is shown below:
> --> /ethdev/regs,0,ring
> {
>   "/ethdev/regs": {
>     "registers_length": 318,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "group_0": {
>       "Q0_ring_rx_bd_num": "0x0",
>       "Q0_ring_rx_bd_len": "0x0",
>       ...
>       },
>     "group_1": {
>         ...
>     },
>     ...
> }
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  lib/ethdev/rte_ethdev_telemetry.c | 128 ++++++++++++++++++++++++++++++
>  1 file changed, 128 insertions(+)
> 
> diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
> index 6b873e7abe68..1d59c693883e 100644
> --- a/lib/ethdev/rte_ethdev_telemetry.c
> +++ b/lib/ethdev/rte_ethdev_telemetry.c
> @@ -1395,6 +1395,132 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
>  	return ret;
>  }
>  
> +static void
> +eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
> +		     uint32_t idx)
> +{
> +	if (reg_info->width == sizeof(uint32_t))
> +		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
> +			*((uint32_t *)reg_info->data + idx), 0);
> +	else
> +		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
> +			*((uint64_t *)reg_info->data + idx), 0);
> +}
> +
> +static int
> +eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
> +{
> +	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
> +	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
> +	struct rte_tel_data *group = NULL;
> +	uint32_t grp_num = 0;
> +	uint32_t i;
> +	int ret;
> +
> +	rte_tel_data_start_dict(d);
> +	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
> +	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
> +	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
> +	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
> +
> +	for (i = 0; i < reg_info->length; i++) {
> +		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
> +			eth_dev_add_reg_data(group, reg_info, i);
> +			continue;
> +		}
> +
> +		group = rte_tel_data_alloc();
> +		if (group == NULL) {
> +			ret = -ENOMEM;
> +			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
> +			goto out;
> +		}
> +		groups[grp_num++] = group;

Although the probability is very small, the groups array may overflow if the length is very large.

Suggest add judgement at the begin of this function:

uint32_t max_cap = (RTE_TEL_MAX_DICT_ENTRIES - 4) * RTE_TEL_MAX_DICT_ENTRIES;   // it will be 65000+ register
if (reg_info->length > max_cap) {
    // just output error and exit
}

> +		rte_tel_data_start_dict(group);
> +		eth_dev_add_reg_data(group, reg_info, i);
> +	}
> +
> +	for (i = 0; i < grp_num; i++) {
> +		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
> +		ret = rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
> +		if (ret == -ENOSPC) {
> +			RTE_ETHDEV_LOG_LINE(WARNING,
> +				"Reduce register number to be displayed from %u to %u due to limited capacity of telemetry",
> +				reg_info->length, i * RTE_TEL_MAX_DICT_ENTRIES);
> +			break;
> +		}

It may lead to memory leak when break. If we add such judgement before, there is no need to add such judgement here.

> +	}
> +	return 0;
> +out:
> +	for (i = 0; i < grp_num; i++)
> +		rte_tel_data_free(groups[i]);
> +
> +	return ret;
> +}
> +
> +static int
> +eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
> +{
> +	struct rte_dev_reg_info reg_info;
> +	int ret;
> +
> +	memset(&reg_info, 0, sizeof(reg_info));
> +	reg_info.filter = filter;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Error getting device reg info: %d", ret);

how about "Failed to get device reg info, ret = %d"

> +		return ret;
> +	}
> +
> +	reg_info.data = calloc(reg_info.length, reg_info.width);
> +	if (reg_info.data == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.data");
> +		return -ENOMEM;
> +	}
> +
> +	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
> +	if (reg_info.names == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.names");
> +		free(reg_info.data);
> +		return -ENOMEM;
> +	}
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Error getting regs from device: %d", ret);

It seemed the ret is device id, how about "Failed to get device reg info, ret = %d"

> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	ret = eth_dev_store_regs(d, &reg_info);
> +out:
> +	free(reg_info.data);
> +	free(reg_info.names);
> +
> +	return ret;
> +}
> +
> +static int
> +eth_dev_handle_port_regs(const char *cmd __rte_unused,
> +		const char *params,
> +		struct rte_tel_data *d)
> +{
> +	char *filter, *end_param;
> +	uint16_t port_id;
> +	int ret;
> +
> +	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
> +	if (ret != 0)
> +		return ret;
> +
> +	filter = strtok(end_param, ",");
> +	if (filter != NULL && strlen(filter) == 0)
> +		filter = NULL;
> +
> +	return eth_dev_get_port_regs(port_id, d, filter);
> +}
> +
>  RTE_INIT(ethdev_init_telemetry)
>  {
>  	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
> @@ -1436,4 +1562,6 @@ RTE_INIT(ethdev_init_telemetry)
>  			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
>  	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
>  			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
> +	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
> +			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
>  }


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 3/8] net/hns3: remove some basic address dump
  2024-09-14  7:13   ` [PATCH v7 3/8] net/hns3: remove some basic address dump Jie Hai
@ 2024-09-14  8:21     ` fengchengwen
  0 siblings, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-09-14  8:21 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Acked-by: Chengwen Feng <fengchengwen@huawei.com>

On 2024/9/14 15:13, Jie Hai wrote:
> For security reasons, some address registers are not suitable
> to be exposed, remove them.
> 
> Cc: stable@dpdk.org
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> Acked-by: Huisong Li<lihuisong@huawei.com>
> ---
>  drivers/net/hns3/hns3_regs.c | 12 ++----------
>  1 file changed, 2 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index be1be6a89c94..53d829a4fc68 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -17,13 +17,9 @@
>  
>  static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
>  
> -static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
> -					  HNS3_CMDQ_TX_ADDR_H_REG,
> -					  HNS3_CMDQ_TX_DEPTH_REG,
> +static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
>  					  HNS3_CMDQ_TX_TAIL_REG,
>  					  HNS3_CMDQ_TX_HEAD_REG,
> -					  HNS3_CMDQ_RX_ADDR_L_REG,
> -					  HNS3_CMDQ_RX_ADDR_H_REG,
>  					  HNS3_CMDQ_RX_DEPTH_REG,
>  					  HNS3_CMDQ_RX_TAIL_REG,
>  					  HNS3_CMDQ_RX_HEAD_REG,
> @@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
>  					       HNS3_FUN_RST_ING,
>  					       HNS3_GRO_EN_REG};
>  
> -static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
> -					  HNS3_RING_RX_BASEADDR_H_REG,
> -					  HNS3_RING_RX_BD_NUM_REG,
> +static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
>  					  HNS3_RING_RX_BD_LEN_REG,
>  					  HNS3_RING_RX_EN_REG,
>  					  HNS3_RING_RX_MERGE_EN_REG,
> @@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
>  					  HNS3_RING_RX_FBD_OFFSET_REG,
>  					  HNS3_RING_RX_STASH_REG,
>  					  HNS3_RING_RX_BD_ERR_REG,
> -					  HNS3_RING_TX_BASEADDR_L_REG,
> -					  HNS3_RING_TX_BASEADDR_H_REG,
>  					  HNS3_RING_TX_BD_NUM_REG,
>  					  HNS3_RING_TX_EN_REG,
>  					  HNS3_RING_TX_PRIORITY_REG,


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 6/8] net/hns3: refactor register dump
  2024-09-14  7:13   ` [PATCH v7 6/8] net/hns3: refactor register dump Jie Hai
@ 2024-09-14  8:26     ` fengchengwen
  0 siblings, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-09-14  8:26 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Acked-by: Chengwen Feng <fengchengwen@huawei.com>

On 2024/9/14 15:13, Jie Hai wrote:
> This patch refactors codes dumping registers from firmware.
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++---------------
>  1 file changed, 115 insertions(+), 88 deletions(-)
> 

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 7/8] net/hns3: support report names of registers
  2024-09-14  7:13   ` [PATCH v7 7/8] net/hns3: support report names of registers Jie Hai
@ 2024-09-14  8:27     ` fengchengwen
  0 siblings, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-09-14  8:27 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Acked-by: Chengwen Feng <fengchengwen@huawei.com>

On 2024/9/14 15:13, Jie Hai wrote:
> This patch adds names for register lists, and support report
> names of registers. Some registers has different names on
> different platform, use names of HIP08 as default names.
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 8/8] net/hns3: support filter registers by module names
  2024-09-14  7:13   ` [PATCH v7 8/8] net/hns3: support filter registers by module names Jie Hai
@ 2024-09-14  8:46     ` fengchengwen
  0 siblings, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-09-14  8:46 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

On 2024/9/14 15:13, Jie Hai wrote:
> This patch support dumping registers which name contains the
> `filter` string. The module names are in lower case and so is
> the `filter`. Available module names are cmdq, common_pf,
> common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
> ssu, ppp, rpu, ncsi, rtc, rcb, etc.
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  drivers/net/hns3/hns3_regs.c | 309 ++++++++++++++++++++---------------
>  1 file changed, 180 insertions(+), 129 deletions(-)
> 
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index 622d2e1c3d02..265d9b433653 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -12,8 +12,6 @@
>  
>  #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
>  
> -static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
> -
>  struct hns3_dirt_reg_entry {
>  	const char *name;
>  	uint32_t addr;
> @@ -795,33 +793,77 @@ enum hns3_reg_modules {
>  	HNS3_64_BIT_DFX,
>  };
>  
> +#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
> +#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
> +			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
> +#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
> +
>  struct hns3_reg_list {
>  	const void *reg_list;
>  	uint32_t entry_num;
> +	const char *module;
>  };
>  
>  static struct hns3_reg_list hns3_reg_lists[] = {
> -	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list)},
> -	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list)},
> -	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list)},
> -	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list)},
> -	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list)},
> -	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list)},
> -	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list)},
> -	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list)},
> -	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list)},
> -	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list)},
> -	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list)},
> -	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list)},
> -
> -	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list)},
> -	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list)},
> -	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list)},
> -	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list)},
> -	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list)},
> -
> -	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list)},
> -	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list)},
> +	[HNS3_BIOS_COMMON] = {
> +		dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list),	"bios"
> +	},
> +	[HNS3_SSU_0] = {
> +		dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list),		"ssu"
> +	},
> +	[HNS3_SSU_1] = {
> +		dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list),		"ssu"
> +	},
> +	[HNS3_IGU_EGU] = {
> +		dfx_igu_egu_reg_list,		RTE_DIM(dfx_igu_egu_reg_list),		"igu_egu"
> +	},
> +	[HNS3_RPU_0] = {
> +		dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list),		"rpu"
> +	},
> +	[HNS3_RPU_1] = {
> +		dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list),		"rpu"
> +	},
> +	[HNS3_NCSI] = {
> +		dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list),		"ncsi"
> +	},
> +	[HNS3_RTC] = {
> +		dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list),		"rtc"
> +	},
> +	[HNS3_PPP] = {
> +		dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list),		"ppp"
> +	},
> +	[HNS3_RCB] = {
> +		dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list),		"rcb"
> +	},
> +	[HNS3_TQP] = {
> +		dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list),		"tqp"
> +	},
> +	[HNS3_SSU_2] = {
> +		dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list),		"ssu"
> +	},
> +
> +	[HNS3_CMDQ] = {
> +		cmdq_reg_list,			RTE_DIM(cmdq_reg_list),		"cmdq"
> +	},
> +	[HNS3_COMMON_PF] = {
> +		common_reg_list,		RTE_DIM(common_reg_list),	"common_pf"
> +	},
> +	[HNS3_COMMON_VF] = {
> +		common_vf_reg_list,		RTE_DIM(common_vf_reg_list),	"common_vf"
> +	},
> +	[HNS3_RING] = {
> +		ring_reg_list,			RTE_DIM(ring_reg_list),		"ring"
> +	},
> +	[HNS3_TQP_INTR] = {
> +		tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list),	"tqp_intr"
> +	},
> +
> +	[HNS3_32_BIT_DFX] = {
> +		regs_32_bit_list,		RTE_DIM(regs_32_bit_list),	"32_bit_dfx"
> +	},
> +	[HNS3_64_BIT_DFX] = {
> +		regs_64_bit_list,		RTE_DIM(regs_64_bit_list),	"64_bit_dfx"
> +	},
>  };
>  
>  static const uint32_t hns3_dfx_reg_opcode_list[] = {
> @@ -865,21 +907,52 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>  	return 0;
>  }
>  
> -static int
> -hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
> +static bool
> +hns3_check_module_match(const char *module, const char *filter)
>  {
> -	uint32_t regs_num_32_bit, regs_num_64_bit;
> -	int ret;
> +	if (filter != NULL && strcmp(filter, module) != 0)
> +		return false;
>  
> -	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
> -	if (ret) {
> -		hns3_err(hw, "fail to get the number of registers, "
> -			 "ret = %d.", ret);
> -		return ret;
> +	return true;
> +}
> +
> +#define HNS3_MAX_MODULES_LEN 512
> +static uint32_t
> +hns3_check_module_names(const char *filter, char *names)
> +{
> +	uint32_t ret = 0, pos = 0;
> +	size_t i;
> +
> +	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
> +		if (hns3_check_module_match(hns3_reg_lists[i].module, filter))
> +			ret |= HNS3_MODULE_MASK(i);
> +		if (HNS3_MAX_MODULES_LEN - pos <= strlen(hns3_reg_lists[i].module))
> +			return -ENOMEM;

I can't understand it, could you explain it.

> +		snprintf(&names[pos], HNS3_MAX_MODULES_LEN - pos, " %s", hns3_reg_lists[i].module);

Suggest add a new function which format all filter's name, e.g. hns3_format_reg_module_name()?

> +		pos += strlen(hns3_reg_lists[i].module) + 1;
>  	}
> +	return ret;
> +}
>  
> -	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
> -	return 0;
> +static uint32_t
> +hns3_check_filter(struct hns3_hw *hw, const char *filter)
> +{
> +	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> +	char names[HNS3_MAX_MODULES_LEN + 1] = {0};
> +	uint32_t modules = 0;
> +
> +	if (filter == NULL)
> +		return (1 << RTE_DIM(hns3_reg_lists)) - 1;

The returned bitmask should remove the difference of PF and VF.

> +
> +	modules = hns3_check_module_names(filter, names);
> +	if (hns->is_vf)
> +		modules &= HNS3_VF_MODULES;
> +	else
> +		modules &= ~HNS3_VF_ONLY_MODULES;
> +	if (modules == 0)
> +		hns3_err(hw, "mismatched module name! Available names are:\n%s.", names);

Except the error should this, how about add the modules info in driver's rst?

> +
> +	return modules;
>  }
>  
>  static int
> @@ -917,73 +990,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
>  	return 0;
>  }
>  
> -static int
> -hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
> -{
> -	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
> -	uint32_t bd_num_list[opcode_num];
> -	uint32_t reg_num;
> -	int ret;
> -	int i;
> -
> -	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
> -	if (ret)
> -		return ret;
> -
> -	for (i = 0; i < opcode_num; i++) {
> -		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
> -		if (reg_num != hns3_reg_lists[i].entry_num) {
> -			hns3_err(hw, "Query register number differ from the list for module!");
> -			return -EINVAL;
> -		}
> -		*count += reg_num;
> -	}
> -
> -	return 0;
> -}
> -
> -static int
> -hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
> -{
> -	int ret;
> -
> -	ret = hns3_get_32_64_regs_cnt(hw, count);
> -	if (ret < 0)
> -		return ret;
> -
> -	return hns3_get_dfx_reg_cnt(hw, count);
> -}
> -
> -static int
> -hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
> +static uint32_t
> +hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
>  {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> -	uint32_t dfx_reg_cnt = 0;
> -	uint32_t common_cnt;
> -	uint32_t len;
> -	int ret;
> -
> -	if (hns->is_vf)
> -		common_cnt = RTE_DIM(common_vf_reg_list);
> -	else
> -		common_cnt = RTE_DIM(common_reg_list);
> +	uint32_t reg_num = 0, length = 0;
> +	uint32_t i;
>  
> -	len = RTE_DIM(cmdq_reg_list) + common_cnt +
> -		RTE_DIM(ring_reg_list) * hw->tqps_num +
> -		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
> +	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
> +		if ((BIT(i) & modules) == 0)

Please use RTE_BIT32, so that it consistent with "#define HNS3_MODULE_MASK(x) RTE_BIT32(x)"

> +			continue;
> +		reg_num = hns3_reg_lists[i].entry_num;
> +		if (i == HNS3_RING)
> +			reg_num *= hw->tqps_num;
> +		else if (i == HNS3_TQP_INTR)
> +			reg_num *= hw->intr_tqps_num;
>  
> -	if (!hns->is_vf) {
> -		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
> -		if (ret) {
> -			hns3_err(hw, "fail to get the number of dfx registers, "
> -				 "ret = %d.", ret);
> -			return ret;
> -		}
> -		len += dfx_reg_cnt;
> +		length += reg_num;
>  	}
>  
> -	*length = len;
> -	return 0;
> +	return length;
>  }
>  
>  static void
> @@ -1124,12 +1149,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
>  
>  static void
>  hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
> -			     enum hns3_reg_modules idx)
> +			     uint32_t modules, enum hns3_reg_modules idx)
>  {
>  	const struct hns3_dirt_reg_entry *reg_list;
>  	uint32_t *data = regs->data;
>  	size_t reg_num, i, cnt;
>  
> +	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
> +		return;
> +
>  	data += regs->length;
>  	reg_num = hns3_reg_lists[idx].entry_num;
>  	reg_list = hns3_reg_lists[idx].reg_list;
> @@ -1157,14 +1185,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
>  
>  static void
>  hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
> -				 enum hns3_reg_modules idx)
> +				 uint32_t modules, enum hns3_reg_modules idx)
>  {
>  	const struct hns3_dirt_reg_entry *reg_list;
>  	uint16_t tqp_num, reg_offset;
>  	uint32_t *data = regs->data;
>  	uint32_t reg_num, i, j;
>  
> -	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
> +	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
>  		return;
>  
>  	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
> @@ -1184,18 +1212,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
>  }
>  
>  static void
> -hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
> +hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
>  {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> -
> -	if (hns->is_vf)
> -		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
> -	else
> -		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
> -
> -	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
> -	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
> -	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
> +	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
> +	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
> +	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
> +	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
> +	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
>  }
>  
>  static int
> @@ -1239,7 +1262,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
>  }
>  
>  static int
> -hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
> +hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
>  {
>  	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
>  	uint32_t max_bd_num, bd_num, opcode, regs_num;
> @@ -1264,6 +1287,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  	for (i = 0; i < opcode_num; i++) {
>  		opcode = hns3_dfx_reg_opcode_list[i];
>  		bd_num = bd_num_list[i];
> +		if ((modules & HNS3_MODULE_MASK(i)) == 0)
> +			continue;
>  		if (bd_num == 0)
>  			continue;
>  		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
> @@ -1272,6 +1297,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  
>  		data += regs->length;
>  		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
> +		if (regs_num !=  hns3_reg_lists[i].entry_num) {
> +			hns3_err(hw, "Query register number differ from the list for module %s!",
> +				 hns3_reg_lists[i].module);
> +			return -EINVAL;
> +		}
>  		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
>  		regs->length += regs_num;
>  	}
> @@ -1281,14 +1311,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  }
>  
>  static int
> -hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
> +hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
>  {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
>  	uint32_t regs_num_32_bit;
>  	uint32_t regs_num_64_bit;
>  	int ret;
>  
> -	if (hns->is_vf)
> +	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
> +	    (modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0)
>  		return 0;
>  
>  	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
> @@ -1297,19 +1327,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  		return ret;
>  	}
>  
> -	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
> -	if (ret) {
> -		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
> -		return ret;
> +	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
> +		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
> +		if (ret) {
> +			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
> +			return ret;
> +		}
>  	}
>  
> -	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
> -	if (ret) {
> -		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
> -		return ret;
> +	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
> +		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
> +		if (ret) {
> +			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
> +			return ret;
> +		}
>  	}
>  
> -	return hns3_get_dfx_regs(hw, regs);
> +	return 0;
> +}
> +
> +static int
> +hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
> +{
> +	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> +	int ret;
> +
> +	if (hns->is_vf)
> +		return 0;
> +
> +	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
> +	if (ret != 0)
> +		return ret;
> +
> +	return hns3_get_dfx_regs(hw, regs, modules);
>  }
>  
>  int
> @@ -1317,13 +1367,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>  {
>  	struct hns3_adapter *hns = eth_dev->data->dev_private;
>  	struct hns3_hw *hw = &hns->hw;
> +	uint32_t modules = 0;

No need to initilize zero.

>  	uint32_t length;
> -	int ret;
>  
> -	ret = hns3_get_regs_length(hw, &length);
> -	if (ret)
> -		return ret;
> +	modules = hns3_check_filter(hw, regs->filter);

How about rename hns3_check_filter with hns3_parse_modules_by_filter()?

> +	if (modules == 0)
> +		return -EINVAL;
>  
> +	length = hns3_get_regs_length(hw, modules);
>  	if (regs->data == NULL) {
>  		regs->length = length;
>  		regs->width = sizeof(uint32_t);
> @@ -1339,8 +1390,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>  	regs->length = 0;
>  
>  	/* fetching per-PF registers values from PF PCIe register space */
> -	hns3_direct_access_regs(hw, regs);
> +	hns3_direct_access_regs(hw, regs, modules);
>  
>  	/* fetching PF common registers values from firmware */
> -	return  hns3_get_regs_from_firmware(hw, regs);
> +	return  hns3_get_regs_from_firmware(hw, regs, modules);
>  }


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 0/8] support dump reigser names and filter
  2024-09-14  7:13 ` Jie Hai
                     ` (7 preceding siblings ...)
  2024-09-14  7:13   ` [PATCH v7 8/8] net/hns3: support filter registers by module names Jie Hai
@ 2024-09-14 15:00   ` Stephen Hemminger
  2024-09-23  2:41     ` Jie Hai
  2024-09-22 21:31   ` Ferruh Yigit
  9 siblings, 1 reply; 134+ messages in thread
From: Stephen Hemminger @ 2024-09-14 15:00 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, thomas, ferruh.yigit, andrew.rybchenko, lihuisong, fengchengwen

On Sat, 14 Sep 2024 15:13:12 +0800
Jie Hai <haijie1@huawei.com> wrote:

> The registers can be dumped through the API rte_eth_dev_get_reg_info.
> However, only register values are exported, which is inconvenient for
> users to interpret. Therefore, an extension of the structure
> "rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
> to support the capability of exporting the name of the corresponding
> register and filtering by module names.

The subject has a typo. Which would end up as typo in the commit log.

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 1/8] ethdev: support report register names and filter
  2024-09-14  7:13   ` [PATCH v7 1/8] ethdev: support report register " Jie Hai
@ 2024-09-22 21:26     ` Ferruh Yigit
  0 siblings, 0 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-09-22 21:26 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, andrew.rybchenko; +Cc: lihuisong, fengchengwen

On 9/14/2024 8:13 AM, Jie Hai wrote:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their module names.
> 
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by modules. And the original API
> rte_eth_dev_get_reg_info() does not use the names and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "index_XXX", which means the location in the register table.
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> Acked-by: Huisong Li <lihuisong@huawei.com>
> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
>

Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 2/8] ethdev: add telemetry cmd for registers
  2024-09-14  7:13   ` [PATCH v7 2/8] ethdev: add telemetry cmd for registers Jie Hai
  2024-09-14  8:20     ` fengchengwen
@ 2024-09-22 21:28     ` Ferruh Yigit
  1 sibling, 0 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-09-22 21:28 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, andrew.rybchenko; +Cc: lihuisong, fengchengwen

On 9/14/2024 8:13 AM, Jie Hai wrote:
> This patch adds a telemetry command for registers dump,
> and supports obtaining the registers of a specified module.
> 
> In one way, the number of registers that can be exported
> is limited by the number of elements carried by dict and
> container. In another way, the length of the string
> exported by telemetry is limited by MAX_OUTPUT_LEN.
> Therefore, when the number of registers to be exported
> exceeds, some information will be lost. Warn on the former
> case.
> 
> An example usage is shown below:
> --> /ethdev/regs,0,ring
> {
>   "/ethdev/regs": {
>     "registers_length": 318,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "group_0": {
>       "Q0_ring_rx_bd_num": "0x0",
>       "Q0_ring_rx_bd_len": "0x0",
>       ...
>       },
>     "group_1": {
>         ...
>     },
>     ...
> }
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
>

Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 0/8] support dump reigser names and filter
  2024-09-14  7:13 ` Jie Hai
                     ` (8 preceding siblings ...)
  2024-09-14 15:00   ` [PATCH v7 0/8] support dump reigser names and filter Stephen Hemminger
@ 2024-09-22 21:31   ` Ferruh Yigit
  9 siblings, 0 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-09-22 21:31 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, andrew.rybchenko; +Cc: lihuisong, fengchengwen

On 9/14/2024 8:13 AM, Jie Hai wrote:
> The registers can be dumped through the API rte_eth_dev_get_reg_info.
> However, only register values are exported, which is inconvenient for
> users to interpret. Therefore, an extension of the structure
> "rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
> to support the capability of exporting the name of the corresponding
> register and filtering by module names.
> 
> --
> v7: fix doc indention.
> --
> Jie Hai (8):
>   ethdev: support report register names and filter
>   ethdev: add telemetry cmd for registers
>   net/hns3: remove some basic address dump
>   net/hns3: fix dump counter of registers
>   net/hns3: remove separators between register module
>   net/hns3: refactor register dump
>   net/hns3: support report names of registers
>   net/hns3: support filter registers by module names
>

Hi Jie,

ethdev changes looks good to me, I can see there are some comments so I
assume there will be new version, if there is no major changes please
feel free to keep the review tags.

After new version I will wait for a few more days to give chance to
others for final review, and will merge later.

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 0/8] support dump reigser names and filter
  2024-09-14 15:00   ` [PATCH v7 0/8] support dump reigser names and filter Stephen Hemminger
@ 2024-09-23  2:41     ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-23  2:41 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, thomas, ferruh.yigit, andrew.rybchenko, lihuisong, fengchengwen

Hi,  Stephen Hemminger
On 2024/9/14 23:00, Stephen Hemminger wrote:
> On Sat, 14 Sep 2024 15:13:12 +0800
> Jie Hai <haijie1@huawei.com> wrote:
> 
>> The registers can be dumped through the API rte_eth_dev_get_reg_info.
>> However, only register values are exported, which is inconvenient for
>> users to interpret. Therefore, an extension of the structure
>> "rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
>> to support the capability of exporting the name of the corresponding
>> register and filtering by module names.
> 
> The subject has a typo. Which would end up as typo in the commit log
> .

Thanks for your review.
Will correct in the next version.

Best regards,
Jie Hai


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v7 2/8] ethdev: add telemetry cmd for registers
  2024-09-14  8:20     ` fengchengwen
@ 2024-09-23  2:41       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-23  2:41 UTC (permalink / raw)
  To: fengchengwen, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Hi, fengchengwen,

Thanks for your review, all will change in next version.

Thanks,
Jie Hai
On 2024/9/14 16:20, fengchengwen wrote:
> On 2024/9/14 15:13, Jie Hai wrote:
>> This patch adds a telemetry command for registers dump,
>> and supports obtaining the registers of a specified module.
>>
>> In one way, the number of registers that can be exported
>> is limited by the number of elements carried by dict and
>> container. In another way, the length of the string
>> exported by telemetry is limited by MAX_OUTPUT_LEN.
>> Therefore, when the number of registers to be exported
>> exceeds, some information will be lost. Warn on the former
>> case.
>>
>> An example usage is shown below:
>> --> /ethdev/regs,0,ring
>> {
>>    "/ethdev/regs": {
>>      "registers_length": 318,
>>      "registers_width": 4,
>>      "register_offset": "0x0",
>>      "version": "0x1140011",
>>      "group_0": {
>>        "Q0_ring_rx_bd_num": "0x0",
>>        "Q0_ring_rx_bd_len": "0x0",
>>        ...
>>        },
>>      "group_1": {
>>          ...
>>      },
>>      ...
>> }
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   lib/ethdev/rte_ethdev_telemetry.c | 128 ++++++++++++++++++++++++++++++
>>   1 file changed, 128 insertions(+)
>>
>> diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
>> index 6b873e7abe68..1d59c693883e 100644
>> --- a/lib/ethdev/rte_ethdev_telemetry.c
>> +++ b/lib/ethdev/rte_ethdev_telemetry.c
>> @@ -1395,6 +1395,132 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
>>   	return ret;
>>   }
>>   
>> +static void
>> +eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
>> +		     uint32_t idx)
>> +{
>> +	if (reg_info->width == sizeof(uint32_t))
>> +		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
>> +			*((uint32_t *)reg_info->data + idx), 0);
>> +	else
>> +		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
>> +			*((uint64_t *)reg_info->data + idx), 0);
>> +}
>> +
>> +static int
>> +eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
>> +{
>> +	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
>> +	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
>> +	struct rte_tel_data *group = NULL;
>> +	uint32_t grp_num = 0;
>> +	uint32_t i;
>> +	int ret;
>> +
>> +	rte_tel_data_start_dict(d);
>> +	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
>> +	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
>> +	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
>> +	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
>> +
>> +	for (i = 0; i < reg_info->length; i++) {
>> +		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
>> +			eth_dev_add_reg_data(group, reg_info, i);
>> +			continue;
>> +		}
>> +
>> +		group = rte_tel_data_alloc();
>> +		if (group == NULL) {
>> +			ret = -ENOMEM;
>> +			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
>> +			goto out;
>> +		}
>> +		groups[grp_num++] = group;
> 
> Although the probability is very small, the groups array may overflow if the length is very large.
> 
> Suggest add judgement at the begin of this function:
> 
> uint32_t max_cap = (RTE_TEL_MAX_DICT_ENTRIES - 4) * RTE_TEL_MAX_DICT_ENTRIES;   // it will be 65000+ register
> if (reg_info->length > max_cap) {
>      // just output error and exit
> }
> 
>> +		rte_tel_data_start_dict(group);
>> +		eth_dev_add_reg_data(group, reg_info, i);
>> +	}
>> +
>> +	for (i = 0; i < grp_num; i++) {
>> +		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
>> +		ret = rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
>> +		if (ret == -ENOSPC) {
>> +			RTE_ETHDEV_LOG_LINE(WARNING,
>> +				"Reduce register number to be displayed from %u to %u due to limited capacity of telemetry",
>> +				reg_info->length, i * RTE_TEL_MAX_DICT_ENTRIES);
>> +			break;
>> +		}
> 
> It may lead to memory leak when break. If we add such judgement before, there is no need to add such judgement here.
> 
>> +	}
>> +	return 0;
>> +out:
>> +	for (i = 0; i < grp_num; i++)
>> +		rte_tel_data_free(groups[i]);
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
>> +{
>> +	struct rte_dev_reg_info reg_info;
>> +	int ret;
>> +
>> +	memset(&reg_info, 0, sizeof(reg_info));
>> +	reg_info.filter = filter;
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0) {
>> +		RTE_ETHDEV_LOG_LINE(ERR, "Error getting device reg info: %d", ret);
> 
> how about "Failed to get device reg info, ret = %d"
> 
>> +		return ret;
>> +	}
>> +
>> +	reg_info.data = calloc(reg_info.length, reg_info.width);
>> +	if (reg_info.data == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.data");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
>> +	if (reg_info.names == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR, "Fail to allocate memory for reg_info.names");
>> +		free(reg_info.data);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0) {
>> +		RTE_ETHDEV_LOG_LINE(ERR, "Error getting regs from device: %d", ret);
> 
> It seemed the ret is device id, how about "Failed to get device reg info, ret = %d"
> 
>> +		ret = -EINVAL;
>> +		goto out;
>> +	}
>> +
>> +	ret = eth_dev_store_regs(d, &reg_info);
>> +out:
>> +	free(reg_info.data);
>> +	free(reg_info.names);
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +eth_dev_handle_port_regs(const char *cmd __rte_unused,
>> +		const char *params,
>> +		struct rte_tel_data *d)
>> +{
>> +	char *filter, *end_param;
>> +	uint16_t port_id;
>> +	int ret;
>> +
>> +	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	filter = strtok(end_param, ",");
>> +	if (filter != NULL && strlen(filter) == 0)
>> +		filter = NULL;
>> +
>> +	return eth_dev_get_port_regs(port_id, d, filter);
>> +}
>> +
>>   RTE_INIT(ethdev_init_telemetry)
>>   {
>>   	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
>> @@ -1436,4 +1562,6 @@ RTE_INIT(ethdev_init_telemetry)
>>   			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
>>   	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
>>   			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
>> +	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
>> +			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
>>   }
> 
> .

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 0/8] support dump register names and filter
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (8 preceding siblings ...)
  2024-09-14  7:13 ` Jie Hai
@ 2024-09-25  6:40 ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 1/8] ethdev: support report " Jie Hai
                     ` (7 more replies)
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
  10 siblings, 8 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient for
users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
to support the capability of exporting the name of the corresponding
register and filtering by module names.

--
v8:
1. fix typo on patch[0/8].
2. add Reviewed-bys and Acked-bys.
3. fix potentital memory leak and error information on telemetry.
4. fix on reviews about hns3 driver.

v7: fix doc indention.
--

Jie Hai (8):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: remove some basic address dump
  net/hns3: fix dump counter of registers
  net/hns3: remove separators between register module
  net/hns3: refactor register dump
  net/hns3: support report names of registers
  net/hns3: support filter registers by module names

 doc/guides/nics/hns3.rst               |    7 +
 doc/guides/rel_notes/release_24_11.rst |    8 +
 drivers/net/hns3/hns3_regs.c           | 1384 +++++++++++++++++++-----
 lib/ethdev/ethdev_trace.h              |    2 +
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  130 +++
 lib/ethdev/version.map                 |    1 +
 9 files changed, 1344 insertions(+), 266 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 1/8] ethdev: support report register names and filter
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 2/8] ethdev: add telemetry cmd for registers Jie Hai
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their module names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by modules. And the original API
rte_eth_dev_get_reg_info() does not use the names and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "index_XXX", which means the location in the register table.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
---
 doc/guides/rel_notes/release_24_11.rst |  8 ++++++
 lib/ethdev/ethdev_trace.h              |  2 ++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 6 files changed, 89 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index 5dd575fb39df..85960e71d0ca 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -60,6 +60,11 @@ New Features
   * Added SR-IOV VF support.
   * Added recent 1400/14000 and 15000 models to the supported list.
 
+* **Added support for dumping registers with names and filtering by modules.**
+
+  Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to filter the
+  registers by module names and get the information (names, values and other
+  attributes) of the filtered registers.
 
 Removed Items
 -------------
@@ -108,6 +113,9 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for filtering by modules and reporting names of registers.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 3bec87bfdb70..0c4780a09ef5 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -1152,6 +1152,8 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_u32(info->length);
 	rte_trace_point_emit_u32(info->width);
 	rte_trace_point_emit_u32(info->version);
+	rte_trace_point_emit_ptr(info->names);
+	rte_trace_point_emit_ptr(info->filter);
 	rte_trace_point_emit_int(ret);
 )
 
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..26b777f9836e 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 64
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Name of target module, filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..30ca4a0043c5 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 		return -EINVAL;
 	}
 
+	if (info->names != NULL && info->length != 0)
+		memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length);
+
 	if (*dev->dev_ops->get_reg == NULL)
 		return -ENOTSUP;
 	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) {
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"index_%u", info->offset + i);
+	}
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index eef254c46330..96b117899ae9 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5071,6 +5071,35 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   - If info->filter is NULL, return info for all registers (seen as filter
+ *     none).
+ *   - If info->filter is not NULL, return error if the driver does not support
+ *     filter. Fill the length field with filtered register number.
+ *   - If info->data is NULL, the function fills in the width and length fields.
+ *   - If info->data is not NULL, ethdev considers there are enough spaces to
+ *     store the registers, and the values of registers with the filter string
+ *     as the module name are put into the buffer pointed at by info->data.
+ *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
+ *     with default names.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index f6aca9506984..6bcfe073a818 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -330,6 +330,7 @@ EXPERIMENTAL {
 	__rte_ethdev_trace_rx_burst_nonempty;
 	__rte_eth_trace_call_rx_callbacks_empty;
 	__rte_eth_trace_call_rx_callbacks_nonempty;
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 2/8] ethdev: add telemetry cmd for registers
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
  2024-09-25  6:40   ` [PATCH v8 1/8] ethdev: support report " Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-26  1:22     ` fengchengwen
  2024-09-25  6:40   ` [PATCH v8 3/8] net/hns3: remove some basic address dump Jie Hai
                     ` (5 subsequent siblings)
  7 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds a telemetry command for registers dump,
and supports obtaining the registers of a specified module.

In one way, the number of registers that can be exported
is limited by the number of elements carried by dict and
container. In another way, the length of the string
exported by telemetry is limited by MAX_OUTPUT_LEN.
Therefore, when the number of registers to be exported
exceeds, some information will be lost. Warn on the former
case.

An example usage is shown below:
--> /ethdev/regs,0,ring
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "Q0_ring_rx_bd_num": "0x0",
      "Q0_ring_rx_bd_len": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 130 ++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..181390691099 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -1395,6 +1395,134 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static void
+eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
+		     uint32_t idx)
+{
+	if (reg_info->width == sizeof(uint32_t))
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint32_t *)reg_info->data + idx), 0);
+	else
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint64_t *)reg_info->data + idx), 0);
+}
+
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t i, max_cap;
+	int ret;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	max_cap = (RTE_TEL_MAX_DICT_ENTRIES - 4) * RTE_TEL_MAX_DICT_ENTRIES;
+	if (reg_info->length > max_cap) {
+		RTE_ETHDEV_LOG_LINE(WARNING,
+			"Registers to be displayed are reduced from %u to %u due to limited capacity",
+			reg_info->length, max_cap);
+		reg_info->length = max_cap;
+	}
+
+	for (i = 0; i < reg_info->length; i++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
+			eth_dev_add_reg_data(group, reg_info, i);
+			continue;
+		}
+
+		group = rte_tel_data_alloc();
+		if (group == NULL) {
+			ret = -ENOMEM;
+			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
+			goto out;
+		}
+		groups[grp_num++] = group;
+		rte_tel_data_start_dict(group);
+		eth_dev_add_reg_data(group, reg_info, i);
+	}
+
+	for (i = 0; i < grp_num; i++) {
+		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
+		rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
+	}
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to get device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (reg_info.data == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to allocate memory for reg_info.data");
+		return -ENOMEM;
+	}
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (reg_info.names == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to allocate memory for reg_info.names");
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to get device reg info: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter, *end_param;
+	uint16_t port_id;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1564,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 3/8] net/hns3: remove some basic address dump
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
  2024-09-25  6:40   ` [PATCH v8 1/8] ethdev: support report " Jie Hai
  2024-09-25  6:40   ` [PATCH v8 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 4/8] net/hns3: fix dump counter of registers Jie Hai
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

For security reasons, some address registers are not suitable
to be exposed, remove them.

Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li<lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..53d829a4fc68 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -17,13 +17,9 @@
 
 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
+static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
 					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
 					  HNS3_CMDQ_RX_DEPTH_REG,
 					  HNS3_CMDQ_RX_TAIL_REG,
 					  HNS3_CMDQ_RX_HEAD_REG,
@@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
 					       HNS3_FUN_RST_ING,
 					       HNS3_GRO_EN_REG};
 
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
+static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
 					  HNS3_RING_RX_BD_LEN_REG,
 					  HNS3_RING_RX_EN_REG,
 					  HNS3_RING_RX_MERGE_EN_REG,
@@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
 					  HNS3_RING_RX_FBD_OFFSET_REG,
 					  HNS3_RING_RX_STASH_REG,
 					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
 					  HNS3_RING_TX_BD_NUM_REG,
 					  HNS3_RING_TX_EN_REG,
 					  HNS3_RING_TX_PRIORITY_REG,
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 4/8] net/hns3: fix dump counter of registers
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
                     ` (2 preceding siblings ...)
  2024-09-25  6:40   ` [PATCH v8 3/8] net/hns3: remove some basic address dump Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 5/8] net/hns3: remove separators between register module Jie Hai
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")
Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 53d829a4fc68..d9c546470dbe 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -127,7 +127,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 5/8] net/hns3: remove separators between register module
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
                     ` (3 preceding siblings ...)
  2024-09-25  6:40   ` [PATCH v8 4/8] net/hns3: fix dump counter of registers Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 6/8] net/hns3: refactor register dump Jie Hai
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 68 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 50 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d9c546470dbe..c8e3fb118e4b 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
@@ -111,23 +108,21 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
+	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = sizeof(cmdq_reg_addrs) + common_cnt +
+		sizeof(ring_reg_addrs) * hw->tqps_num +
+		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
+	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -136,18 +131,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -268,18 +261,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -294,7 +275,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -305,7 +285,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -313,7 +292,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -322,7 +300,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -398,17 +375,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -416,11 +391,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -467,7 +439,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -512,16 +483,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 6/8] net/hns3: refactor register dump
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
                     ` (4 preceding siblings ...)
  2024-09-25  6:40   ` [PATCH v8 5/8] net/hns3: remove separators between register module Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 7/8] net/hns3: support report names of registers Jie Hai
  2024-09-25  6:40   ` [PATCH v8 8/8] net/hns3: support filter registers by module names Jie Hai
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch refactors codes dumping registers from firmware.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++---------------
 1 file changed, 115 insertions(+), 88 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index c8e3fb118e4b..89858c2b1c09 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -104,12 +104,93 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static int
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
+			uint32_t list_size)
+{
+#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
+	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
+	uint32_t index, desc_index;
+	uint32_t bd_num;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	/* The last BD does not need a next flag */
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+
+	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
+	if (ret) {
+		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
+		return ret;
+	}
+
+	/* The first data in the first BD is a reserved field */
+	for (i = 1; i <= list_size; i++) {
+		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
+		index = i % HNS3_CMD_DESC_DATA_NUM;
+		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
+		bd_num_list[i - 1] = bd_num;
+	}
+
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num_list[opcode_num];
+	int ret;
+	int i;
+
+	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+
+	return 0;
+}
+
+static int
+hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int ret;
+
+	ret = hns3_get_32_64_regs_cnt(hw, count);
+	if (ret < 0)
+		return ret;
+
+	return hns3_get_dfx_reg_cnt(hw, count);
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_cnt;
+	uint32_t dfx_reg_cnt = 0;
 	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
@@ -125,16 +206,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -304,41 +376,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	return data - origin_data_ptr;
 }
 
-static int
-hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
-			uint32_t list_size)
-{
-#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
-	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
-	uint32_t index, desc_index;
-	uint32_t bd_num;
-	uint32_t i;
-	int ret;
-
-	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
-		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
-	}
-	/* The last BD does not need a next flag */
-	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-
-	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
-	if (ret) {
-		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
-		return ret;
-	}
-
-	/* The first data in the first BD is a reserved field */
-	for (i = 1; i <= list_size; i++) {
-		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
-		index = i % HNS3_CMD_DESC_DATA_NUM;
-		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
-		bd_num_list[i - 1] = bd_num;
-	}
-
-	return 0;
-}
-
 static int
 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
 			int bd_num, uint32_t opcode)
@@ -379,24 +416,6 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 	return reg_num;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-
-	return 0;
-}
-
 static int
 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 {
@@ -436,13 +455,41 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 	return ret;
 }
 
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+{
+	uint32_t regs_num_32_bit;
+	uint32_t regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "Get register number failed, ret = %d", ret);
+		return ret;
+	}
+
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_32_bit;
+
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+
+	return hns3_get_dfx_regs(hw, (void **)&data);
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
@@ -470,26 +517,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
 	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_32_bit;
-
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	return  hns3_get_regs_from_firmware(hw, data);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 7/8] net/hns3: support report names of registers
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
                     ` (5 preceding siblings ...)
  2024-09-25  6:40   ` [PATCH v8 6/8] net/hns3: refactor register dump Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-25  6:40   ` [PATCH v8 8/8] net/hns3: support filter registers by module names Jie Hai
  7 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds names for register lists, and support report
names of registers. Some registers has different names on
different platform, use names of HIP08 as default names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 1088 +++++++++++++++++++++++++++++-----
 1 file changed, 955 insertions(+), 133 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 89858c2b1c09..a0d130302839 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,73 +14,827 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct hns3_dirt_reg_entry {
+	const char *name;
+	uint32_t addr;
+};
+
+static const struct hns3_dirt_reg_entry cmdq_reg_list[] = {
+	{"cmdq_tx_depth",		HNS3_CMDQ_TX_DEPTH_REG},
+	{"cmdq_tx_tail",		HNS3_CMDQ_TX_TAIL_REG},
+	{"cmdq_tx_head",		HNS3_CMDQ_TX_HEAD_REG},
+	{"cmdq_rx_depth",		HNS3_CMDQ_RX_DEPTH_REG},
+	{"cmdq_rx_tail",		HNS3_CMDQ_RX_TAIL_REG},
+	{"cmdq_rx_head",		HNS3_CMDQ_RX_HEAD_REG},
+	{"vector0_cmdq_src",		HNS3_VECTOR0_CMDQ_SRC_REG},
+	{"cmdq_intr_sts",		HNS3_CMDQ_INTR_STS_REG},
+	{"cmdq_intr_en",		HNS3_CMDQ_INTR_EN_REG},
+	{"cmdq_intr_gen",		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"vector0_oter_en",		HNS3_VECTOR0_OTER_EN_REG},
+	{"misc_reset_sts",		HNS3_MISC_RESET_STS_REG},
+	{"vector0_other_int_sts",	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{"global_reset",		HNS3_GLOBAL_RESET_REG},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_vf_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry ring_reg_list[] = {
+	{"ring_rx_bd_num",		HNS3_RING_RX_BD_NUM_REG},
+	{"ring_rx_bd_len",		HNS3_RING_RX_BD_LEN_REG},
+	{"ring_rx_en",			HNS3_RING_RX_EN_REG},
+	{"ring_rx_merge_en",		HNS3_RING_RX_MERGE_EN_REG},
+	{"ring_rx_tail",		HNS3_RING_RX_TAIL_REG},
+	{"ring_rx_head",		HNS3_RING_RX_HEAD_REG},
+	{"ring_rx_fbdnum",		HNS3_RING_RX_FBDNUM_REG},
+	{"ring_rx_offset",		HNS3_RING_RX_OFFSET_REG},
+	{"ring_rx_fbd_offset",		HNS3_RING_RX_FBD_OFFSET_REG},
+	{"ring_rx_stash",		HNS3_RING_RX_STASH_REG},
+	{"ring_rx_bd_err",		HNS3_RING_RX_BD_ERR_REG},
+	{"ring_tx_bd_num",		HNS3_RING_TX_BD_NUM_REG},
+	{"ring_tx_en",			HNS3_RING_TX_EN_REG},
+	{"ring_tx_priority",		HNS3_RING_TX_PRIORITY_REG},
+	{"ring_tx_tc",			HNS3_RING_TX_TC_REG},
+	{"ring_tx_merge_en",		HNS3_RING_TX_MERGE_EN_REG},
+	{"ring_tx_tail",		HNS3_RING_TX_TAIL_REG},
+	{"ring_tx_head",		HNS3_RING_TX_HEAD_REG},
+	{"ring_tx_fbdnum",		HNS3_RING_TX_FBDNUM_REG},
+	{"ring_tx_offset",		HNS3_RING_TX_OFFSET_REG},
+	{"ring_tx_ebd_num",		HNS3_RING_TX_EBD_NUM_REG},
+	{"ring_tx_ebd_offset",		HNS3_RING_TX_EBD_OFFSET_REG},
+	{"ring_tx_bd_err",		HNS3_RING_TX_BD_ERR_REG},
+	{"ring_en",			HNS3_RING_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry tqp_intr_reg_list[] = {
+	{"tqp_intr_ctrl",		HNS3_TQP_INTR_CTRL_REG},
+	{"tqp_intr_gl0",		HNS3_TQP_INTR_GL0_REG},
+	{"tqp_intr_gl1",		HNS3_TQP_INTR_GL1_REG},
+	{"tqp_intr_gl2",		HNS3_TQP_INTR_GL2_REG},
+	{"tqp_intr_rl",			HNS3_TQP_INTR_RL_REG},
+};
+
+struct hns3_dfx_reg_entry {
+	/**
+	 * name_v1 -- default register name for all platforms (HIP08/HIP09/newer).
+	 * name_v2 -- register name different from the default for HIP09.
+	 * If there are more platform with different register name, name_vXX is extended.
+	 * If the platform is newer than HIP09, use default name.
+	 */
+	const char *name_v1;
+	const char *name_v2;
+};
+
+static struct hns3_dfx_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_dfx_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_dfx_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"btmp_ageing_st_b0"},
+	{"btmp_ageing_st_b1"},
+	{"btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"lo_pri_unicast_rlt_drop_num"},
+	{"hi_pri_multicast_rlt_drop_num"},
+
+	{"lo_pri_multicast_rlt_drop_num"},
+	{"ncsi_packet_curr_buffer_cnt"},
+	{"btmp_ageing_rls_cnt_bank0",		"dfx_ssu0_rsv5"},
+	{"btmp_ageing_rls_cnt_bank1",		"dfx_ssu0_rsv6"},
+	{"btmp_ageing_rls_cnt_bank2",		"dfx_ssu0_rsv7"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ncsi_rx_packet_in_cnt_l"},
+	{"ncsi_rx_packet_in_cnt_h"},
+	{"ncsi_tx_packet_out_cnt_l"},
+	{"ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"mb_uncopy_num"},
+	{"rx_oq_drop_pkt_cnt"},
+	{"tx_oq_drop_pkt_cnt"},
+	{"bank_unbalance_drop_cnt"},
+	{"bank_unbalance_rx_drop_cnt"},
+
+	{"nic_l2_eer_drop_pkt_cnt"},
+	{"roc_l2_eer_drop_pkt_cnt"},
+	{"nic_l2_eer_drop_pkt_cnt_rx"},
+	{"roc_l2_eer_drop_pkt_cnt_rx"},
+	{"rx_oq_glb_drop_pkt_cnt"},
+	{"dfx_ssu0_rsv8"},
+
+	{"lo_pri_unicast_cur_cnt"},
+	{"hi_pri_multicast_cur_cnt"},
+	{"lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"packet_tc_curr_buffer_cnt_0"},
+	{"packet_tc_curr_buffer_cnt_1"},
+	{"packet_tc_curr_buffer_cnt_2"},
+	{"packet_tc_curr_buffer_cnt_3"},
+	{"packet_tc_curr_buffer_cnt_4"},
+
+	{"packet_tc_curr_buffer_cnt_5"},
+	{"packet_tc_curr_buffer_cnt_6"},
+	{"packet_tc_curr_buffer_cnt_7"},
+	{"packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"rx_packet_in_cnt_l"},
+	{"rx_packet_in_cnt_h"},
+	{"rx_packet_out_cnt_l"},
+	{"rx_packet_out_cnt_h"},
+	{"tx_packet_in_cnt_l"},
+	{"tx_packet_in_cnt_h"},
+
+	{"tx_packet_out_cnt_l"},
+	{"tx_packet_out_cnt_h"},
+	{"roc_rx_packet_in_cnt_l"},
+	{"roc_rx_packet_in_cnt_h"},
+	{"roc_tx_packet_in_cnt_l"},
+	{"roc_tx_packet_in_cnt_h"},
+
+	{"rx_packet_tc_in_cnt_0_l"},
+	{"rx_packet_tc_in_cnt_0_h"},
+	{"rx_packet_tc_in_cnt_1_l"},
+	{"rx_packet_tc_in_cnt_1_h"},
+	{"rx_packet_tc_in_cnt_2_l"},
+	{"rx_packet_tc_in_cnt_2_h"},
+
+	{"rx_packet_tc_in_cnt_3_l"},
+	{"rx_packet_tc_in_cnt_3_h"},
+	{"rx_packet_tc_in_cnt_4_l"},
+	{"rx_packet_tc_in_cnt_4_h"},
+	{"rx_packet_tc_in_cnt_5_l"},
+	{"rx_packet_tc_in_cnt_5_h"},
+
+	{"rx_packet_tc_in_cnt_6_l"},
+	{"rx_packet_tc_in_cnt_6_h"},
+	{"rx_packet_tc_in_cnt_7_l"},
+	{"rx_packet_tc_in_cnt_7_h"},
+	{"rx_packet_tc_out_cnt_0_l"},
+	{"rx_packet_tc_out_cnt_0_h"},
+
+	{"rx_packet_tc_out_cnt_1_l"},
+	{"rx_packet_tc_out_cnt_1_h"},
+	{"rx_packet_tc_out_cnt_2_l"},
+	{"rx_packet_tc_out_cnt_2_h"},
+	{"rx_packet_tc_out_cnt_3_l"},
+	{"rx_packet_tc_out_cnt_3_h"},
+
+	{"rx_packet_tc_out_cnt_4_l"},
+	{"rx_packet_tc_out_cnt_4_h"},
+	{"rx_packet_tc_out_cnt_5_l"},
+	{"rx_packet_tc_out_cnt_5_h"},
+	{"rx_packet_tc_out_cnt_6_l"},
+	{"rx_packet_tc_out_cnt_6_h"},
+
+	{"rx_packet_tc_out_cnt_7_l"},
+	{"rx_packet_tc_out_cnt_7_h"},
+	{"tx_packet_tc_in_cnt_0_l"},
+	{"tx_packet_tc_in_cnt_0_h"},
+	{"tx_packet_tc_in_cnt_1_l"},
+	{"tx_packet_tc_in_cnt_1_h"},
+
+	{"tx_packet_tc_in_cnt_2_l"},
+	{"tx_packet_tc_in_cnt_2_h"},
+	{"tx_packet_tc_in_cnt_3_l"},
+	{"tx_packet_tc_in_cnt_3_h"},
+	{"tx_packet_tc_in_cnt_4_l"},
+	{"tx_packet_tc_in_cnt_4_h"},
+
+	{"tx_packet_tc_in_cnt_5_l"},
+	{"tx_packet_tc_in_cnt_5_h"},
+	{"tx_packet_tc_in_cnt_6_l"},
+	{"tx_packet_tc_in_cnt_6_h"},
+	{"tx_packet_tc_in_cnt_7_l"},
+	{"tx_packet_tc_in_cnt_7_h"},
+
+	{"tx_packet_tc_out_cnt_0_l"},
+	{"tx_packet_tc_out_cnt_0_h"},
+	{"tx_packet_tc_out_cnt_1_l"},
+	{"tx_packet_tc_out_cnt_1_h"},
+	{"tx_packet_tc_out_cnt_2_l"},
+	{"tx_packet_tc_out_cnt_2_h"},
+
+	{"tx_packet_tc_out_cnt_3_l"},
+	{"tx_packet_tc_out_cnt_3_h"},
+	{"tx_packet_tc_out_cnt_4_l"},
+	{"tx_packet_tc_out_cnt_4_h"},
+	{"tx_packet_tc_out_cnt_5_l"},
+	{"tx_packet_tc_out_cnt_5_h"},
+
+	{"tx_packet_tc_out_cnt_6_l"},
+	{"tx_packet_tc_out_cnt_6_h"},
+	{"tx_packet_tc_out_cnt_7_l"},
+	{"tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_rsv0",		"igu_egu_mul_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv1",		"igu_egu_mul_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv2",		"igu_egu_bro_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv3",		"igu_egu_bro_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv4",		"igu_egu_rsv0"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_tc_queue_num",		"rpu_currport_tnl_index"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rslt_descr_sts",		"ppp_rsv1"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_vmdq1_hit_cnt_l",	"ppp_um_tbl_snq_hit_cnt_l"},
+	{"ppp_um_tbl_vmdq1_hit_cnt_h",	"ppp_um_tbl_snq_hit_cnt_h"},
+	{"ppp_mta_tbl_hit_cnt_l",	"ppp_rsv5"},
+	{"ppp_mta_tbl_hit_cnt_h",	"ppp_rsv6"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_vlan_mirr_cnt_l",		"ppp_rsv7"},
+	{"ppp_vlan_mirr_cnt_h",		"ppp_rsv8"},
+
+	{"ppp_ig_mirr_cnt_l",		"ppp_rsv9"},
+	{"ppp_ig_mirr_cnt_h",		"ppp_rsv10"},
+	{"ppp_eg_mirr_cnt_l",		"ppp_rsv11"},
+	{"ppp_eg_mirr_cnt_h",		"ppp_rsv12"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_axi_rd_fbd_serr_cnt",	"rcb_rcb_tx_mem_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_dfx_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+enum hns3_reg_modules {
+	HNS3_BIOS_COMMON = 0,
+	HNS3_SSU_0,
+	HNS3_SSU_1,
+	HNS3_IGU_EGU,
+	HNS3_RPU_0,
+	HNS3_RPU_1,
+	HNS3_NCSI,
+	HNS3_RTC,
+	HNS3_PPP,
+	HNS3_RCB,
+	HNS3_TQP,
+	HNS3_SSU_2,
+
+	HNS3_CMDQ = 12,
+	HNS3_COMMON_PF,
+	HNS3_COMMON_VF,
+	HNS3_RING,
+	HNS3_TQP_INTR,
+
+	HNS3_32_BIT_DFX,
+	HNS3_64_BIT_DFX,
+};
+
+struct hns3_reg_list {
+	const void *reg_list;
+	uint32_t entry_num;
+};
+
+static struct hns3_reg_list hns3_reg_lists[] = {
+	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list) },
+	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list) },
+	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list) },
+	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list) },
+	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list) },
+	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list) },
+	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list) },
+	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list) },
+	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list) },
+	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list) },
+	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list) },
+	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list) },
+	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list) },
+	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list) },
+	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list) },
+	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list) },
+	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list) },
+	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list) },
+	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list) },
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
-	HNS3_OPC_DFX_BIOS_COMMON_REG,
-	HNS3_OPC_DFX_SSU_REG_0,
-	HNS3_OPC_DFX_SSU_REG_1,
-	HNS3_OPC_DFX_IGU_EGU_REG,
-	HNS3_OPC_DFX_RPU_REG_0,
-	HNS3_OPC_DFX_RPU_REG_1,
-	HNS3_OPC_DFX_NCSI_REG,
-	HNS3_OPC_DFX_RTC_REG,
-	HNS3_OPC_DFX_PPP_REG,
-	HNS3_OPC_DFX_RCB_REG,
-	HNS3_OPC_DFX_TQP_REG,
-	HNS3_OPC_DFX_SSU_REG_2
+	[HNS3_BIOS_COMMON]	=	HNS3_OPC_DFX_BIOS_COMMON_REG,
+	[HNS3_SSU_0]		=	HNS3_OPC_DFX_SSU_REG_0,
+	[HNS3_SSU_1]		=	HNS3_OPC_DFX_SSU_REG_1,
+	[HNS3_IGU_EGU]		=	HNS3_OPC_DFX_IGU_EGU_REG,
+	[HNS3_RPU_0]		=	HNS3_OPC_DFX_RPU_REG_0,
+	[HNS3_RPU_1]		=	HNS3_OPC_DFX_RPU_REG_1,
+	[HNS3_NCSI]		=	HNS3_OPC_DFX_NCSI_REG,
+	[HNS3_RTC]		=	HNS3_OPC_DFX_RTC_REG,
+	[HNS3_PPP]		=	HNS3_OPC_DFX_PPP_REG,
+	[HNS3_RCB]		=	HNS3_OPC_DFX_RCB_REG,
+	[HNS3_TQP]		=	HNS3_OPC_DFX_TQP_REG,
+	[HNS3_SSU_2]		=	HNS3_OPC_DFX_SSU_REG_2
 };
 
 static int
@@ -100,6 +854,11 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE != RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -161,6 +920,7 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
+	uint32_t reg_num;
 	int ret;
 	int i;
 
@@ -168,8 +928,14 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < opcode_num; i++) {
+		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+		if (reg_num != hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list!");
+			return -EINVAL;
+		}
+		*count += reg_num;
+	}
 
 	return 0;
 }
@@ -196,14 +962,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	int ret;
 
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = RTE_DIM(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
 
-	len = sizeof(cmdq_reg_addrs) + common_cnt +
-		sizeof(ring_reg_addrs) * hw->tqps_num +
-		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
-	len /= sizeof(uint32_t);
+	len = RTE_DIM(cmdq_reg_list) + common_cnt +
+		RTE_DIM(ring_reg_list) * hw->tqps_num +
+		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
@@ -219,13 +984,31 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	return 0;
 }
 
+static void
+hns3_fill_dfx_regs_name(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			const struct hns3_dfx_reg_entry *reg_list, uint32_t reg_num)
+{
+	uint32_t i, cnt = regs->length;
+	const char *name;
+
+	if (regs->names == NULL)
+		return;
+
+	for (i = 0; i < reg_num; i++) {
+		name = reg_list[i].name_v1;
+		if (hw->revision == PCI_REVISION_ID_HIP09_A && reg_list[i].name_v2 != NULL)
+			name = reg_list[i].name_v2;
+		snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, "%s", name);
+	}
+}
+
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint32_t *reg_val = data;
 	uint32_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -254,6 +1037,9 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_32_bit_list, regs_num);
+	reg_val += regs->length;
+	regs->length += regs_num;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = &desc[i].data[0];
@@ -265,7 +1051,6 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_32(*desc_data++);
-
 			regs_num--;
 			if (regs_num == 0)
 				break;
@@ -277,12 +1062,12 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 }
 
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint64_t *reg_val = data;
 	uint64_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -311,6 +1096,9 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_64_bit_list, regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE);
+	reg_val += regs->length;
+	regs->length += regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = (uint64_t *)(&desc[i].data[0]);
@@ -322,7 +1110,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_64(*desc_data++);
-
 			regs_num--;
 			if (!regs_num)
 				break;
@@ -333,47 +1120,80 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+static void
+hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			     enum hns3_reg_modules idx)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
-	size_t reg_num;
-	uint16_t j;
-	size_t i;
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint32_t *data = regs->data;
+	size_t reg_num, i, cnt;
+
+	data += regs->length;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	cnt = regs->length;
+	for (i = 0; i < reg_num; i++) {
+		*data++ = hns3_read_dev(hw, reg_list[i].addr);
+		if (regs->names != NULL)
+			snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE,
+				 "%s", reg_list[i].name);
+	}
 
-	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+	regs->length += reg_num;
+}
+
+static uint32_t
+hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
+{
+	if (idx == HNS3_RING)
+		return hns3_get_tqp_reg_offset(queue_id);
+	else if (idx == HNS3_TQP_INTR)
+		return hns3_get_tqp_intr_reg_offset(queue_id);
+
+	return 0;
+}
+
+static void
+hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+				 enum hns3_reg_modules idx)
+{
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint16_t tqp_num, reg_offset;
+	uint32_t *data = regs->data;
+	uint32_t reg_num, i, j;
+
+	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+		return;
+
+	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	data += regs->length;
+	for (i = 0; i < tqp_num; i++) {
+		reg_offset = hns3_get_module_tqp_reg_offset(idx, i);
+		for (j = 0; j < reg_num; j++) {
+			*data++ = hns3_read_dev(hw, reg_list[j].addr + reg_offset);
+			if (regs->names != NULL)
+				snprintf(regs->names[regs->length].name,
+					 RTE_ETH_REG_NAME_SIZE, "Q%u_%s", i, reg_list[j].name);
+			regs->length++;
+		}
+	}
+}
+
+static void
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->tqps_num; j++) {
-		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
-	}
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->intr_tqps_num; j++) {
-		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
-						reg_offset);
-	}
-	return data - origin_data_ptr;
+	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
 }
 
 static int
@@ -417,13 +1237,13 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t max_bd_num, bd_num, opcode;
+	uint32_t max_bd_num, bd_num, opcode, regs_num;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
+	uint32_t *data = regs->data;
 	int ret;
 	int i;
 
@@ -447,42 +1267,47 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+
+		data += regs->length;
+		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
+		regs->length += regs_num;
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
+	if (hns->is_vf)
+		return 0;
+
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 	if (ret) {
 		hns3_err(hw, "Get register number failed, ret = %d", ret);
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-	return hns3_get_dfx_regs(hw, (void **)&data);
+	return hns3_get_dfx_regs(hw, regs);
 }
 
 int
@@ -491,15 +1316,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -510,13 +1333,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
+	/* to count the number of filled registers */
+	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
-
-	if (hns->is_vf)
-		return 0;
+	hns3_direct_access_regs(hw, regs);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, data);
+	return  hns3_get_regs_from_firmware(hw, regs);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v8 8/8] net/hns3: support filter registers by module names
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
                     ` (6 preceding siblings ...)
  2024-09-25  6:40   ` [PATCH v8 7/8] net/hns3: support report names of registers Jie Hai
@ 2024-09-25  6:40   ` Jie Hai
  2024-09-26  1:46     ` fengchengwen
  7 siblings, 1 reply; 134+ messages in thread
From: Jie Hai @ 2024-09-25  6:40 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch support dumping registers which module name is the
`filter` string. The module names are in lower case and so is
the `filter`. Available module names are cmdq, common_pf,
common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
ssu, ppp, rpu, ncsi, rtc, rcb, etc.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/nics/hns3.rst     |   7 +
 drivers/net/hns3/hns3_regs.c | 257 ++++++++++++++++++++---------------
 2 files changed, 157 insertions(+), 107 deletions(-)

diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 97b4686bfabe..20765bd7d145 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -407,6 +407,13 @@ be provided to avoid scheduling the CPU core used by DPDK application threads fo
 other tasks. Before starting the Linux OS, add the kernel isolation boot parameter.
 For example, "isolcpus=1-18 nohz_full=1-18 rcu_nocbs=1-18".
 
+Dump registers
+--------------
+HNS3 supports dumping registers values with their names, and suppotrt filtering
+by module names. The available modules are ``bios``, ``ssu``, ``igu_egu``,
+``rpu``, ``ncsi``, ``rtc``, ``ppp``, ``rcb``, ``tqp``, ``rtc``, ``cmdq``,
+``common_pf``, ``common_vf``, ``ring``, ``tqp_intr``, ``32_bit_dfx``,
+``64_bit_dfx``, etc.
 
 Limitations or Known issues
 ---------------------------
diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index a0d130302839..2e19add21265 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,7 +12,7 @@
 
 #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
+#define HNS3_MAX_MODULES_LEN 512
 
 struct hns3_dirt_reg_entry {
 	const char *name;
@@ -795,11 +795,39 @@ enum hns3_reg_modules {
 	HNS3_64_BIT_DFX,
 };
 
+#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
+#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
+			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
+#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
+
 struct hns3_reg_list {
 	const void *reg_list;
 	uint32_t entry_num;
 };
 
+struct {
+	const char *name;
+	uint32_t module;
+} hns3_module_name_map[] = {
+	{ "bios",	HNS3_MODULE_MASK(HNS3_BIOS_COMMON) },
+	{ "ssu",	HNS3_MODULE_MASK(HNS3_SSU_0) | HNS3_MODULE_MASK(HNS3_SSU_1) |
+			HNS3_MODULE_MASK(HNS3_SSU_2) },
+	{ "igu_egu",	HNS3_MODULE_MASK(HNS3_IGU_EGU) },
+	{ "rpu",	HNS3_MODULE_MASK(HNS3_RPU_0) | HNS3_MODULE_MASK(HNS3_RPU_1) },
+	{ "ncsi",	HNS3_MODULE_MASK(HNS3_NCSI) },
+	{ "rtc",	HNS3_MODULE_MASK(HNS3_RTC) },
+	{ "ppp",	HNS3_MODULE_MASK(HNS3_PPP) },
+	{ "rcb",	HNS3_MODULE_MASK(HNS3_RCB) },
+	{ "tqp",	HNS3_MODULE_MASK(HNS3_TQP) },
+	{ "cmdq",	HNS3_MODULE_MASK(HNS3_CMDQ) },
+	{ "common_pf",	HNS3_MODULE_MASK(HNS3_COMMON_PF) },
+	{ "common_vf",	HNS3_MODULE_MASK(HNS3_COMMON_VF) },
+	{ "ring",	HNS3_MODULE_MASK(HNS3_RING) },
+	{ "tqp_intr",	HNS3_MODULE_MASK(HNS3_TQP_INTR) },
+	{ "32_bit_dfx",	HNS3_MODULE_MASK(HNS3_32_BIT_DFX) },
+	{ "64_bit_dfx",	HNS3_MODULE_MASK(HNS3_64_BIT_DFX) },
+};
+
 static struct hns3_reg_list hns3_reg_lists[] = {
 	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list) },
 	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list) },
@@ -863,21 +891,58 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
-static int
-hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+static const char *
+hns3_get_name_by_module(enum hns3_reg_modules module)
 {
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	int ret;
+	size_t i;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "fail to get the number of registers, "
-			 "ret = %d.", ret);
-		return ret;
+	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
+		if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0)
+			return hns3_module_name_map[i].name;
 	}
+	return "unknown";
+}
 
-	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-	return 0;
+static void
+hns3_get_module_names(char *names, uint32_t len)
+{
+	size_t i;
+
+	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
+		strlcat(names, " ", len);
+		strlcat(names, hns3_module_name_map[i].name, len);
+	}
+}
+
+static uint32_t
+hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	char names[HNS3_MAX_MODULES_LEN] = {0};
+	uint32_t modules = 0;
+	size_t i;
+
+	if (filter == NULL) {
+		modules = (1 << RTE_DIM(hns3_reg_lists)) - 1;
+	} else {
+		for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
+			if (strcmp(filter, hns3_module_name_map[i].name) == 0) {
+				modules |= hns3_module_name_map[i].module;
+				break;
+			}
+		}
+	}
+
+	if (hns->is_vf)
+		modules &= HNS3_VF_MODULES;
+	else
+		modules &= ~HNS3_VF_ONLY_MODULES;
+	if (modules == 0) {
+		hns3_get_module_names(names, HNS3_MAX_MODULES_LEN);
+		hns3_err(hw, "mismatched module name! Available names are:\n%s.",
+			 names);
+	}
+	return modules;
 }
 
 static int
@@ -915,73 +980,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
 	return 0;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	uint32_t reg_num;
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++) {
-		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-		if (reg_num != hns3_reg_lists[i].entry_num) {
-			hns3_err(hw, "Query register number differ from the list!");
-			return -EINVAL;
-		}
-		*count += reg_num;
-	}
-
-	return 0;
-}
-
-static int
-hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int ret;
-
-	ret = hns3_get_32_64_regs_cnt(hw, count);
-	if (ret < 0)
-		return ret;
-
-	return hns3_get_dfx_reg_cnt(hw, count);
-}
-
-static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+static uint32_t
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t dfx_reg_cnt = 0;
-	uint32_t common_cnt;
-	uint32_t len;
-	int ret;
-
-	if (hns->is_vf)
-		common_cnt = RTE_DIM(common_vf_reg_list);
-	else
-		common_cnt = RTE_DIM(common_reg_list);
+	uint32_t reg_num = 0, length = 0;
+	uint32_t i;
 
-	len = RTE_DIM(cmdq_reg_list) + common_cnt +
-		RTE_DIM(ring_reg_list) * hw->tqps_num +
-		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if ((RTE_BIT32(i) & modules) == 0)
+			continue;
+		reg_num = hns3_reg_lists[i].entry_num;
+		if (i == HNS3_RING)
+			reg_num *= hw->tqps_num;
+		else if (i == HNS3_TQP_INTR)
+			reg_num *= hw->intr_tqps_num;
 
-	if (!hns->is_vf) {
-		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of dfx registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		len += dfx_reg_cnt;
+		length += reg_num;
 	}
 
-	*length = len;
-	return 0;
+	return length;
 }
 
 static void
@@ -1122,12 +1139,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
 
 static void
 hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-			     enum hns3_reg_modules idx)
+			     uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint32_t *data = regs->data;
 	size_t reg_num, i, cnt;
 
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
+		return;
+
 	data += regs->length;
 	reg_num = hns3_reg_lists[idx].entry_num;
 	reg_list = hns3_reg_lists[idx].reg_list;
@@ -1155,14 +1175,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
 
 static void
 hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-				 enum hns3_reg_modules idx)
+				 uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint16_t tqp_num, reg_offset;
 	uint32_t *data = regs->data;
 	uint32_t reg_num, i, j;
 
-	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
 		return;
 
 	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
@@ -1182,18 +1202,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
 }
 
 static void
-hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-
-	if (hns->is_vf)
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
-	else
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
-
-	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
 }
 
 static int
@@ -1237,7 +1252,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode, regs_num;
@@ -1262,6 +1277,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 	for (i = 0; i < opcode_num; i++) {
 		opcode = hns3_dfx_reg_opcode_list[i];
 		bd_num = bd_num_list[i];
+		if ((modules & HNS3_MODULE_MASK(i)) == 0)
+			continue;
 		if (bd_num == 0)
 			continue;
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
@@ -1270,6 +1287,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 
 		data += regs->length;
 		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		if (regs_num !=  hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module %s!",
+				 hns3_get_name_by_module(i));
+			return -EINVAL;
+		}
 		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
 		regs->length += regs_num;
 	}
@@ -1279,14 +1301,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
-	if (hns->is_vf)
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
+	    (modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) == 0)
 		return 0;
 
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -1295,19 +1317,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) != 0) {
+		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	return hns3_get_dfx_regs(hw, regs);
+	return 0;
+}
+
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	int ret;
+
+	if (hns->is_vf)
+		return 0;
+
+	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
+	if (ret != 0)
+		return ret;
+
+	return hns3_get_dfx_regs(hw, regs, modules);
 }
 
 int
@@ -1315,13 +1357,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	uint32_t modules;
 	uint32_t length;
-	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
-	if (ret)
-		return ret;
+	modules = hns3_parse_modules_by_filter(hw, regs->filter);
+	if (modules == 0)
+		return -EINVAL;
 
+	length = hns3_get_regs_length(hw, modules);
 	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
@@ -1337,8 +1380,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	hns3_direct_access_regs(hw, regs);
+	hns3_direct_access_regs(hw, regs, modules);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, regs);
+	return  hns3_get_regs_from_firmware(hw, regs, modules);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v8 2/8] ethdev: add telemetry cmd for registers
  2024-09-25  6:40   ` [PATCH v8 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-09-26  1:22     ` fengchengwen
  0 siblings, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-09-26  1:22 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Acked-by: Chengwen Feng <fengchengwen@huawei.com>

On 2024/9/25 14:40, Jie Hai wrote:
> This patch adds a telemetry command for registers dump,
> and supports obtaining the registers of a specified module.
> 
> In one way, the number of registers that can be exported
> is limited by the number of elements carried by dict and
> container. In another way, the length of the string
> exported by telemetry is limited by MAX_OUTPUT_LEN.
> Therefore, when the number of registers to be exported
> exceeds, some information will be lost. Warn on the former
> case.
> 
> An example usage is shown below:
> --> /ethdev/regs,0,ring
> {
>   "/ethdev/regs": {
>     "registers_length": 318,
>     "registers_width": 4,
>     "register_offset": "0x0",
>     "version": "0x1140011",
>     "group_0": {
>       "Q0_ring_rx_bd_num": "0x0",
>       "Q0_ring_rx_bd_len": "0x0",
>       ...
>       },
>     "group_1": {
>         ...
>     },
>     ...
> }
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v8 8/8] net/hns3: support filter registers by module names
  2024-09-25  6:40   ` [PATCH v8 8/8] net/hns3: support filter registers by module names Jie Hai
@ 2024-09-26  1:46     ` fengchengwen
  2024-09-26 12:37       ` Jie Hai
  0 siblings, 1 reply; 134+ messages in thread
From: fengchengwen @ 2024-09-26  1:46 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

On 2024/9/25 14:40, Jie Hai wrote:
> This patch support dumping registers which module name is the
> `filter` string. The module names are in lower case and so is
> the `filter`. Available module names are cmdq, common_pf,
> common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
> ssu, ppp, rpu, ncsi, rtc, rcb, etc.
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  doc/guides/nics/hns3.rst     |   7 +
>  drivers/net/hns3/hns3_regs.c | 257 ++++++++++++++++++++---------------
>  2 files changed, 157 insertions(+), 107 deletions(-)
> 
> diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
> index 97b4686bfabe..20765bd7d145 100644
> --- a/doc/guides/nics/hns3.rst
> +++ b/doc/guides/nics/hns3.rst
> @@ -407,6 +407,13 @@ be provided to avoid scheduling the CPU core used by DPDK application threads fo
>  other tasks. Before starting the Linux OS, add the kernel isolation boot parameter.
>  For example, "isolcpus=1-18 nohz_full=1-18 rcu_nocbs=1-18".
>  
> +Dump registers
> +--------------
> +HNS3 supports dumping registers values with their names, and suppotrt filtering

typo of suppotrt

> +by module names. The available modules are ``bios``, ``ssu``, ``igu_egu``,

The available modules names?

> +``rpu``, ``ncsi``, ``rtc``, ``ppp``, ``rcb``, ``tqp``, ``rtc``, ``cmdq``,
> +``common_pf``, ``common_vf``, ``ring``, ``tqp_intr``, ``32_bit_dfx``,
> +``64_bit_dfx``, etc.

etc means there are more which don't list above, please don't add it because the doc should contain all modules names.

>  
>  Limitations or Known issues
>  ---------------------------
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index a0d130302839..2e19add21265 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c
> @@ -12,7 +12,7 @@
>  
>  #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
>  
> -static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
> +#define HNS3_MAX_MODULES_LEN 512
>  
>  struct hns3_dirt_reg_entry {
>  	const char *name;
> @@ -795,11 +795,39 @@ enum hns3_reg_modules {
>  	HNS3_64_BIT_DFX,
>  };
>  
> +#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
> +#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
> +			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
> +#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
> +
>  struct hns3_reg_list {
>  	const void *reg_list;
>  	uint32_t entry_num;
>  };
>  
> +struct {
> +	const char *name;
> +	uint32_t module;
> +} hns3_module_name_map[] = {
> +	{ "bios",	HNS3_MODULE_MASK(HNS3_BIOS_COMMON) },
> +	{ "ssu",	HNS3_MODULE_MASK(HNS3_SSU_0) | HNS3_MODULE_MASK(HNS3_SSU_1) |
> +			HNS3_MODULE_MASK(HNS3_SSU_2) },
> +	{ "igu_egu",	HNS3_MODULE_MASK(HNS3_IGU_EGU) },
> +	{ "rpu",	HNS3_MODULE_MASK(HNS3_RPU_0) | HNS3_MODULE_MASK(HNS3_RPU_1) },
> +	{ "ncsi",	HNS3_MODULE_MASK(HNS3_NCSI) },
> +	{ "rtc",	HNS3_MODULE_MASK(HNS3_RTC) },
> +	{ "ppp",	HNS3_MODULE_MASK(HNS3_PPP) },
> +	{ "rcb",	HNS3_MODULE_MASK(HNS3_RCB) },
> +	{ "tqp",	HNS3_MODULE_MASK(HNS3_TQP) },
> +	{ "cmdq",	HNS3_MODULE_MASK(HNS3_CMDQ) },
> +	{ "common_pf",	HNS3_MODULE_MASK(HNS3_COMMON_PF) },
> +	{ "common_vf",	HNS3_MODULE_MASK(HNS3_COMMON_VF) },
> +	{ "ring",	HNS3_MODULE_MASK(HNS3_RING) },
> +	{ "tqp_intr",	HNS3_MODULE_MASK(HNS3_TQP_INTR) },
> +	{ "32_bit_dfx",	HNS3_MODULE_MASK(HNS3_32_BIT_DFX) },
> +	{ "64_bit_dfx",	HNS3_MODULE_MASK(HNS3_64_BIT_DFX) },
> +};
> +
>  static struct hns3_reg_list hns3_reg_lists[] = {
>  	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list) },
>  	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list) },
> @@ -863,21 +891,58 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>  	return 0;
>  }
>  
> -static int
> -hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
> +static const char *
> +hns3_get_name_by_module(enum hns3_reg_modules module)
>  {
> -	uint32_t regs_num_32_bit, regs_num_64_bit;
> -	int ret;
> +	size_t i;
>  
> -	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
> -	if (ret) {
> -		hns3_err(hw, "fail to get the number of registers, "
> -			 "ret = %d.", ret);
> -		return ret;
> +	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
> +		if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0)
> +			return hns3_module_name_map[i].name;
>  	}
> +	return "unknown";
> +}
>  
> -	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
> -	return 0;
> +static void
> +hns3_get_module_names(char *names, uint32_t len)
> +{
> +	size_t i;
> +
> +	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
> +		strlcat(names, " ", len);
> +		strlcat(names, hns3_module_name_map[i].name, len);
> +	}
> +}
> +
> +static uint32_t
> +hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter)
> +{
> +	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> +	char names[HNS3_MAX_MODULES_LEN] = {0};
> +	uint32_t modules = 0;
> +	size_t i;
> +
> +	if (filter == NULL) {
> +		modules = (1 << RTE_DIM(hns3_reg_lists)) - 1;
> +	} else {
> +		for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
> +			if (strcmp(filter, hns3_module_name_map[i].name) == 0) {
> +				modules |= hns3_module_name_map[i].module;
> +				break;
> +			}
> +		}
> +	}
> +
> +	if (hns->is_vf)
> +		modules &= HNS3_VF_MODULES;
> +	else
> +		modules &= ~HNS3_VF_ONLY_MODULES;
> +	if (modules == 0) {
> +		hns3_get_module_names(names, HNS3_MAX_MODULES_LEN);

the name is NULL.

> +		hns3_err(hw, "mismatched module name! Available names are:\n%s.",

hns3_err already contain \n, please remove this.

> +			 names);
> +	}
> +	return modules;
>  }
>  
>  static int
> @@ -915,73 +980,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
>  	return 0;
>  }
>  
> -static int
> -hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
> -{
> -	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
> -	uint32_t bd_num_list[opcode_num];
> -	uint32_t reg_num;
> -	int ret;
> -	int i;
> -
> -	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
> -	if (ret)
> -		return ret;
> -
> -	for (i = 0; i < opcode_num; i++) {
> -		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
> -		if (reg_num != hns3_reg_lists[i].entry_num) {
> -			hns3_err(hw, "Query register number differ from the list!");
> -			return -EINVAL;
> -		}
> -		*count += reg_num;
> -	}
> -
> -	return 0;
> -}
> -
> -static int
> -hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
> -{
> -	int ret;
> -
> -	ret = hns3_get_32_64_regs_cnt(hw, count);
> -	if (ret < 0)
> -		return ret;
> -
> -	return hns3_get_dfx_reg_cnt(hw, count);
> -}
> -
> -static int
> -hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
> +static uint32_t
> +hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
>  {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> -	uint32_t dfx_reg_cnt = 0;
> -	uint32_t common_cnt;
> -	uint32_t len;
> -	int ret;
> -
> -	if (hns->is_vf)
> -		common_cnt = RTE_DIM(common_vf_reg_list);
> -	else
> -		common_cnt = RTE_DIM(common_reg_list);
> +	uint32_t reg_num = 0, length = 0;
> +	uint32_t i;
>  
> -	len = RTE_DIM(cmdq_reg_list) + common_cnt +
> -		RTE_DIM(ring_reg_list) * hw->tqps_num +
> -		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
> +	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
> +		if ((RTE_BIT32(i) & modules) == 0)
> +			continue;
> +		reg_num = hns3_reg_lists[i].entry_num;
> +		if (i == HNS3_RING)
> +			reg_num *= hw->tqps_num;
> +		else if (i == HNS3_TQP_INTR)
> +			reg_num *= hw->intr_tqps_num;
>  
> -	if (!hns->is_vf) {
> -		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
> -		if (ret) {
> -			hns3_err(hw, "fail to get the number of dfx registers, "
> -				 "ret = %d.", ret);
> -			return ret;
> -		}
> -		len += dfx_reg_cnt;
> +		length += reg_num;
>  	}
>  
> -	*length = len;
> -	return 0;
> +	return length;
>  }
>  
>  static void
> @@ -1122,12 +1139,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
>  
>  static void
>  hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
> -			     enum hns3_reg_modules idx)
> +			     uint32_t modules, enum hns3_reg_modules idx)
>  {
>  	const struct hns3_dirt_reg_entry *reg_list;
>  	uint32_t *data = regs->data;
>  	size_t reg_num, i, cnt;
>  
> +	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
> +		return;
> +
>  	data += regs->length;
>  	reg_num = hns3_reg_lists[idx].entry_num;
>  	reg_list = hns3_reg_lists[idx].reg_list;
> @@ -1155,14 +1175,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
>  
>  static void
>  hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
> -				 enum hns3_reg_modules idx)
> +				 uint32_t modules, enum hns3_reg_modules idx)
>  {
>  	const struct hns3_dirt_reg_entry *reg_list;
>  	uint16_t tqp_num, reg_offset;
>  	uint32_t *data = regs->data;
>  	uint32_t reg_num, i, j;
>  
> -	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
> +	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
>  		return;
>  
>  	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
> @@ -1182,18 +1202,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
>  }
>  
>  static void
> -hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
> +hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
>  {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> -
> -	if (hns->is_vf)
> -		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
> -	else
> -		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
> -
> -	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
> -	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
> -	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
> +	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
> +	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
> +	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
> +	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
> +	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
>  }
>  
>  static int
> @@ -1237,7 +1252,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
>  }
>  
>  static int
> -hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
> +hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
>  {
>  	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
>  	uint32_t max_bd_num, bd_num, opcode, regs_num;
> @@ -1262,6 +1277,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  	for (i = 0; i < opcode_num; i++) {
>  		opcode = hns3_dfx_reg_opcode_list[i];
>  		bd_num = bd_num_list[i];
> +		if ((modules & HNS3_MODULE_MASK(i)) == 0)
> +			continue;
>  		if (bd_num == 0)
>  			continue;
>  		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
> @@ -1270,6 +1287,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  
>  		data += regs->length;
>  		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
> +		if (regs_num !=  hns3_reg_lists[i].entry_num) {
> +			hns3_err(hw, "Query register number differ from the list for module %s!",
> +				 hns3_get_name_by_module(i));
> +			return -EINVAL;
> +		}
>  		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
>  		regs->length += regs_num;
>  	}
> @@ -1279,14 +1301,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  }
>  
>  static int
> -hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
> +hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
>  {
> -	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
>  	uint32_t regs_num_32_bit;
>  	uint32_t regs_num_64_bit;
>  	int ret;
>  
> -	if (hns->is_vf)
> +	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
> +	    (modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) == 0)
>  		return 0;
>  
>  	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
> @@ -1295,19 +1317,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
>  		return ret;
>  	}
>  
> -	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
> -	if (ret) {
> -		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
> -		return ret;
> +	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
> +		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
> +		if (ret) {
> +			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
> +			return ret;
> +		}
>  	}
>  
> -	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
> -	if (ret) {
> -		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
> -		return ret;
> +	if ((modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) != 0) {
> +		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
> +		if (ret) {
> +			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
> +			return ret;
> +		}
>  	}
>  
> -	return hns3_get_dfx_regs(hw, regs);
> +	return 0;
> +}
> +
> +static int
> +hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
> +{
> +	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> +	int ret;
> +
> +	if (hns->is_vf)
> +		return 0;
> +
> +	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
> +	if (ret != 0)
> +		return ret;
> +
> +	return hns3_get_dfx_regs(hw, regs, modules);
>  }
>  
>  int
> @@ -1315,13 +1357,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>  {
>  	struct hns3_adapter *hns = eth_dev->data->dev_private;
>  	struct hns3_hw *hw = &hns->hw;
> +	uint32_t modules;
>  	uint32_t length;
> -	int ret;
>  
> -	ret = hns3_get_regs_length(hw, &length);
> -	if (ret)
> -		return ret;
> +	modules = hns3_parse_modules_by_filter(hw, regs->filter);
> +	if (modules == 0)
> +		return -EINVAL;
>  
> +	length = hns3_get_regs_length(hw, modules);
>  	if (regs->data == NULL) {
>  		regs->length = length;
>  		regs->width = sizeof(uint32_t);
> @@ -1337,8 +1380,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
>  	regs->length = 0;
>  
>  	/* fetching per-PF registers values from PF PCIe register space */
> -	hns3_direct_access_regs(hw, regs);
> +	hns3_direct_access_regs(hw, regs, modules);
>  
>  	/* fetching PF common registers values from firmware */
> -	return  hns3_get_regs_from_firmware(hw, regs);
> +	return  hns3_get_regs_from_firmware(hw, regs, modules);
>  }


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v8 8/8] net/hns3: support filter registers by module names
  2024-09-26  1:46     ` fengchengwen
@ 2024-09-26 12:37       ` Jie Hai
  0 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:37 UTC (permalink / raw)
  To: fengchengwen, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Hi, fengchengwen,

Thanks for your review.

On 2024/9/26 9:46, fengchengwen wrote:
> On 2024/9/25 14:40, Jie Hai wrote:
>> This patch support dumping registers which module name is the
>> `filter` string. The module names are in lower case and so is
>> the `filter`. Available module names are cmdq, common_pf,
>> common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
>> ssu, ppp, rpu, ncsi, rtc, rcb, etc.
>>
>> Signed-off-by: Jie Hai<haijie1@huawei.com>
>> ---
>>   doc/guides/nics/hns3.rst     |   7 +
>>   drivers/net/hns3/hns3_regs.c | 257 ++++++++++++++++++++---------------
>>   2 files changed, 157 insertions(+), 107 deletions(-)
>>
>> diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
>> index 97b4686bfabe..20765bd7d145 100644
>> --- a/doc/guides/nics/hns3.rst
>> +++ b/doc/guides/nics/hns3.rst
>> @@ -407,6 +407,13 @@ be provided to avoid scheduling the CPU core used by DPDK application threads fo
>>   other tasks. Before starting the Linux OS, add the kernel isolation boot parameter.
>>   For example, "isolcpus=1-18 nohz_full=1-18 rcu_nocbs=1-18".
>>   
>> +Dump registers
>> +--------------
>> +HNS3 supports dumping registers values with their names, and suppotrt filtering
> typo of suppotrt
> 
Will correct in V9.
>> +by module names. The available modules are ``bios``, ``ssu``, ``igu_egu``,
> The available modules names?
> 
>> +``rpu``, ``ncsi``, ``rtc``, ``ppp``, ``rcb``, ``tqp``, ``rtc``, ``cmdq``,
>> +``common_pf``, ``common_vf``, ``ring``, ``tqp_intr``, ``32_bit_dfx``,
>> +``64_bit_dfx``, etc.
> etc means there are more which don't list above, please don't add it because the doc should contain all modules names.
> 
Will remove 'etc' in V9.
>>   
>>   Limitations or Known issues
>>   ---------------------------

>> +static void
>> +hns3_get_module_names(char *names, uint32_t len)
>> +{
>> +	size_t i;
>> +
>> +	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
>> +		strlcat(names, " ", len);
>> +		strlcat(names, hns3_module_name_map[i].name, len);
>> +	}
>> +}
>> +
>> +static uint32_t
>> +hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter)
>> +{
>> +	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
>> +	char names[HNS3_MAX_MODULES_LEN] = {0};
>> +	uint32_t modules = 0;
>> +	size_t i;
>> +
>> +	if (filter == NULL) {
>> +		modules = (1 << RTE_DIM(hns3_reg_lists)) - 1;
>> +	} else {
>> +		for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
>> +			if (strcmp(filter, hns3_module_name_map[i].name) == 0) {
>> +				modules |= hns3_module_name_map[i].module;
>> +				break;
>> +			}
>> +		}
>> +	}
>> +
>> +	if (hns->is_vf)
>> +		modules &= HNS3_VF_MODULES;
>> +	else
>> +		modules &= ~HNS3_VF_ONLY_MODULES;
>> +	if (modules == 0) {
>> +		hns3_get_module_names(names, HNS3_MAX_MODULES_LEN);
> the name is NULL.
> 
I am not sure what problem it is.
You mean the parameter names of hns3_get_module_names?
It is an array and not null for sure. And it is used for the names of 
all modules.
>> +		hns3_err(hw, "mismatched module name! Available names are:\n%s.",
> hns3_err already contain \n, please remove this.
This is a new line between the above expression and the name list
to prevent the overall output from being too long.
Not the last of the expression.
> 
>> +			 names);
>> +	}
>> +	return modules;
>>   }
>>   

^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 0/8] support dump reigster names and filter
  2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
                   ` (9 preceding siblings ...)
  2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
@ 2024-09-26 12:42 ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 1/8] ethdev: support report register " Jie Hai
                     ` (8 more replies)
  10 siblings, 9 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

The registers can be dumped through the API rte_eth_dev_get_reg_info.
However, only register values are exported, which is inconvenient for
users to interpret. Therefore, an extension of the structure
"rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
to support the capability of exporting the name of the corresponding
register and filtering by module names.

--
v9:
1. add Acked-by.
2. fix typo and inaccurate expression of hns3.rst.

v8:
1. fix typo on patch[0/8].
2. add Reviewed-bys and Acked-bys.
3. fix potentital memory leak and error information on telemetry.
4. fix on reviews about hns3 driver.

v7: fix doc indention.
--

Jie Hai (8):
  ethdev: support report register names and filter
  ethdev: add telemetry cmd for registers
  net/hns3: remove some basic address dump
  net/hns3: fix dump counter of registers
  net/hns3: remove separators between register module
  net/hns3: refactor register dump
  net/hns3: support report names of registers
  net/hns3: support filter registers by module names

 doc/guides/nics/hns3.rst               |    7 +
 doc/guides/rel_notes/release_24_11.rst |    8 +
 drivers/net/hns3/hns3_regs.c           | 1384 +++++++++++++++++++-----
 lib/ethdev/ethdev_trace.h              |    2 +
 lib/ethdev/rte_dev_info.h              |   11 +
 lib/ethdev/rte_ethdev.c                |   38 +
 lib/ethdev/rte_ethdev.h                |   29 +
 lib/ethdev/rte_ethdev_telemetry.c      |  130 +++
 lib/ethdev/version.map                 |    1 +
 9 files changed, 1344 insertions(+), 266 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 1/8] ethdev: support report register names and filter
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 2/8] ethdev: add telemetry cmd for registers Jie Hai
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their module names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by modules. And the original API
rte_eth_dev_get_reg_info() does not use the names and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "index_XXX", which means the location in the register table.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
---
 doc/guides/rel_notes/release_24_11.rst |  8 ++++++
 lib/ethdev/ethdev_trace.h              |  2 ++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 38 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 29 ++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 6 files changed, 89 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index 5dd575fb39df..85960e71d0ca 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -60,6 +60,11 @@ New Features
   * Added SR-IOV VF support.
   * Added recent 1400/14000 and 15000 models to the supported list.
 
+* **Added support for dumping registers with names and filtering by modules.**
+
+  Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to filter the
+  registers by module names and get the information (names, values and other
+  attributes) of the filtered registers.
 
 Removed Items
 -------------
@@ -108,6 +113,9 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for filtering by modules and reporting names of registers.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 3bec87bfdb70..0c4780a09ef5 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -1152,6 +1152,8 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_u32(info->length);
 	rte_trace_point_emit_u32(info->width);
 	rte_trace_point_emit_u32(info->version);
+	rte_trace_point_emit_ptr(info->names);
+	rte_trace_point_emit_ptr(info->filter);
 	rte_trace_point_emit_int(ret);
 )
 
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..26b777f9836e 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 64
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Name of target module, filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..30ca4a0043c5 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 		return -EINVAL;
 	}
 
+	if (info->names != NULL && info->length != 0)
+		memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length);
+
 	if (*dev->dev_ops->get_reg == NULL)
 		return -ENOTSUP;
 	ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) {
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"index_%u", info->offset + i);
+	}
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index eef254c46330..96b117899ae9 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5071,6 +5071,35 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   - If info->filter is NULL, return info for all registers (seen as filter
+ *     none).
+ *   - If info->filter is not NULL, return error if the driver does not support
+ *     filter. Fill the length field with filtered register number.
+ *   - If info->data is NULL, the function fills in the width and length fields.
+ *   - If info->data is not NULL, ethdev considers there are enough spaces to
+ *     store the registers, and the values of registers with the filter string
+ *     as the module name are put into the buffer pointed at by info->data.
+ *   - If info->names is not NULL, drivers should fill it or the ethdev fills it
+ *     with default names.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index f6aca9506984..6bcfe073a818 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -330,6 +330,7 @@ EXPERIMENTAL {
 	__rte_ethdev_trace_rx_burst_nonempty;
 	__rte_eth_trace_call_rx_callbacks_empty;
 	__rte_eth_trace_call_rx_callbacks_nonempty;
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 2/8] ethdev: add telemetry cmd for registers
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
  2024-09-26 12:42   ` [PATCH v9 1/8] ethdev: support report register " Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 3/8] net/hns3: remove some basic address dump Jie Hai
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds a telemetry command for registers dump,
and supports obtaining the registers of a specified module.

In one way, the number of registers that can be exported
is limited by the number of elements carried by dict and
container. In another way, the length of the string
exported by telemetry is limited by MAX_OUTPUT_LEN.
Therefore, when the number of registers to be exported
exceeds, some information will be lost. Warn on the former
case.

An example usage is shown below:
--> /ethdev/regs,0,ring
{
  "/ethdev/regs": {
    "registers_length": 318,
    "registers_width": 4,
    "register_offset": "0x0",
    "version": "0x1140011",
    "group_0": {
      "Q0_ring_rx_bd_num": "0x0",
      "Q0_ring_rx_bd_len": "0x0",
      ...
      },
    "group_1": {
        ...
    },
    ...
}

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 lib/ethdev/rte_ethdev_telemetry.c | 130 ++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c
index 6b873e7abe68..181390691099 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -1395,6 +1395,134 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused,
 	return ret;
 }
 
+static void
+eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info,
+		     uint32_t idx)
+{
+	if (reg_info->width == sizeof(uint32_t))
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint32_t *)reg_info->data + idx), 0);
+	else
+		rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name,
+			*((uint64_t *)reg_info->data + idx), 0);
+}
+
+static int
+eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info)
+{
+	struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES];
+	char group_name[RTE_TEL_MAX_STRING_LEN] = {0};
+	struct rte_tel_data *group = NULL;
+	uint32_t grp_num = 0;
+	uint32_t i, max_cap;
+	int ret;
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_uint(d, "register_length", reg_info->length);
+	rte_tel_data_add_dict_uint(d, "register_width", reg_info->width);
+	rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0);
+	rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0);
+
+	max_cap = (RTE_TEL_MAX_DICT_ENTRIES - 4) * RTE_TEL_MAX_DICT_ENTRIES;
+	if (reg_info->length > max_cap) {
+		RTE_ETHDEV_LOG_LINE(WARNING,
+			"Registers to be displayed are reduced from %u to %u due to limited capacity",
+			reg_info->length, max_cap);
+		reg_info->length = max_cap;
+	}
+
+	for (i = 0; i < reg_info->length; i++) {
+		if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) {
+			eth_dev_add_reg_data(group, reg_info, i);
+			continue;
+		}
+
+		group = rte_tel_data_alloc();
+		if (group == NULL) {
+			ret = -ENOMEM;
+			RTE_ETHDEV_LOG_LINE(WARNING, "No enough memory for group data");
+			goto out;
+		}
+		groups[grp_num++] = group;
+		rte_tel_data_start_dict(group);
+		eth_dev_add_reg_data(group, reg_info, i);
+	}
+
+	for (i = 0; i < grp_num; i++) {
+		snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i);
+		rte_tel_data_add_dict_container(d, group_name, groups[i], 0);
+	}
+	return 0;
+out:
+	for (i = 0; i < grp_num; i++)
+		rte_tel_data_free(groups[i]);
+
+	return ret;
+}
+
+static int
+eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	memset(&reg_info, 0, sizeof(reg_info));
+	reg_info.filter = filter;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to get device reg info: %d", ret);
+		return ret;
+	}
+
+	reg_info.data = calloc(reg_info.length, reg_info.width);
+	if (reg_info.data == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to allocate memory for reg_info.data");
+		return -ENOMEM;
+	}
+
+	reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name));
+	if (reg_info.names == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to allocate memory for reg_info.names");
+		free(reg_info.data);
+		return -ENOMEM;
+	}
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Failed to get device reg info: %d", ret);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = eth_dev_store_regs(d, &reg_info);
+out:
+	free(reg_info.data);
+	free(reg_info.names);
+
+	return ret;
+}
+
+static int
+eth_dev_handle_port_regs(const char *cmd __rte_unused,
+		const char *params,
+		struct rte_tel_data *d)
+{
+	char *filter, *end_param;
+	uint16_t port_id;
+	int ret;
+
+	ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
+	if (ret != 0)
+		return ret;
+
+	filter = strtok(end_param, ",");
+	if (filter != NULL && strlen(filter) == 0)
+		filter = NULL;
+
+	return eth_dev_get_port_regs(port_id, d, filter);
+}
+
 RTE_INIT(ethdev_init_telemetry)
 {
 	rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list,
@@ -1436,4 +1564,6 @@ RTE_INIT(ethdev_init_telemetry)
 			"Returns TM Level Capabilities info for a port. Parameters: int port_id, int level_id (see tm_capability for the max)");
 	rte_telemetry_register_cmd("/ethdev/tm_node_capability", eth_dev_handle_port_tm_node_caps,
 			"Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)");
+	rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs,
+			"Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)");
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 3/8] net/hns3: remove some basic address dump
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
  2024-09-26 12:42   ` [PATCH v9 1/8] ethdev: support report register " Jie Hai
  2024-09-26 12:42   ` [PATCH v9 2/8] ethdev: add telemetry cmd for registers Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 4/8] net/hns3: fix dump counter of registers Jie Hai
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

For security reasons, some address registers are not suitable
to be exposed, remove them.

Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li<lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index be1be6a89c94..53d829a4fc68 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -17,13 +17,9 @@
 
 static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG,
-					  HNS3_CMDQ_TX_ADDR_H_REG,
-					  HNS3_CMDQ_TX_DEPTH_REG,
+static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
 					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_ADDR_L_REG,
-					  HNS3_CMDQ_RX_ADDR_H_REG,
 					  HNS3_CMDQ_RX_DEPTH_REG,
 					  HNS3_CMDQ_RX_TAIL_REG,
 					  HNS3_CMDQ_RX_HEAD_REG,
@@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
 					       HNS3_FUN_RST_ING,
 					       HNS3_GRO_EN_REG};
 
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
-					  HNS3_RING_RX_BASEADDR_H_REG,
-					  HNS3_RING_RX_BD_NUM_REG,
+static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
 					  HNS3_RING_RX_BD_LEN_REG,
 					  HNS3_RING_RX_EN_REG,
 					  HNS3_RING_RX_MERGE_EN_REG,
@@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG,
 					  HNS3_RING_RX_FBD_OFFSET_REG,
 					  HNS3_RING_RX_STASH_REG,
 					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BASEADDR_L_REG,
-					  HNS3_RING_TX_BASEADDR_H_REG,
 					  HNS3_RING_TX_BD_NUM_REG,
 					  HNS3_RING_TX_EN_REG,
 					  HNS3_RING_TX_PRIORITY_REG,
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 4/8] net/hns3: fix dump counter of registers
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
                     ` (2 preceding siblings ...)
  2024-09-26 12:42   ` [PATCH v9 3/8] net/hns3: remove some basic address dump Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 5/8] net/hns3: remove separators between register module Jie Hai
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver dumps the queue interrupt registers according
to the intr_tqps_num, the counter should be the same.

Fixes: acb3260fac5c ("net/hns3: fix dump register out of range")
Fixes: 936eda25e8da ("net/hns3: support dump register")
Cc: stable@dpdk.org

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 53d829a4fc68..d9c546470dbe 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -127,7 +127,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
 
 	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE;
+	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 5/8] net/hns3: remove separators between register module
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
                     ` (3 preceding siblings ...)
  2024-09-26 12:42   ` [PATCH v9 4/8] net/hns3: fix dump counter of registers Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 6/8] net/hns3: refactor register dump Jie Hai
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

Since the driver is going to support reporting names of
all registers, remove the counter and insert of separators
between different register modules.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Reviewed-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 68 ++++++++++--------------------------
 1 file changed, 18 insertions(+), 50 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index d9c546470dbe..c8e3fb118e4b 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -10,12 +10,9 @@
 #include "hns3_rxtx.h"
 #include "hns3_regs.h"
 
-#define MAX_SEPARATE_NUM	4
-#define SEPARATOR_VALUE		0xFFFFFFFF
-#define REG_NUM_PER_LINE	4
-#define REG_LEN_PER_LINE	(REG_NUM_PER_LINE * sizeof(uint32_t))
+#define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines);
+static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
 static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
 					  HNS3_CMDQ_TX_TAIL_REG,
@@ -111,23 +108,21 @@ static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines;
 	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_lines;
+	uint32_t dfx_reg_cnt;
+	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
 
-	cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1;
 	if (hns->is_vf)
-		common_lines =
-			sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_vf_reg_addrs);
 	else
-		common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1;
-	ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1;
-	tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1;
+		common_cnt = sizeof(common_reg_addrs);
 
-	len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num +
-	      tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE;
+	len = sizeof(cmdq_reg_addrs) + common_cnt +
+		sizeof(ring_reg_addrs) * hw->tqps_num +
+		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
+	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
 		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -136,18 +131,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 				 "ret = %d.", ret);
 			return ret;
 		}
-		dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) /
-					REG_LEN_PER_LINE + 1;
-		dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) /
-					REG_LEN_PER_LINE + 1;
+		dfx_reg_cnt = regs_num_32_bit +
+			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-		ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines);
+		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
 			return ret;
 		}
-		len += dfx_reg_lines * REG_NUM_PER_LINE;
+		len += dfx_reg_cnt;
 	}
 
 	*length = len;
@@ -268,18 +261,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_insert_reg_separator(int reg_num, uint32_t *data)
-{
-	int separator_num;
-	int i;
-
-	separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE;
-	for (i = 0; i < separator_num; i++)
-		*data++ = SEPARATOR_VALUE;
-	return separator_num;
-}
-
 static int
 hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 {
@@ -294,7 +275,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
 	for (i = 0; i < reg_num; i++)
 		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	if (hns->is_vf)
 		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
@@ -305,7 +285,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
 		else
 			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-	data += hns3_insert_reg_separator(reg_num, data);
 
 	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
 	for (j = 0; j < hw->tqps_num; j++) {
@@ -313,7 +292,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw,
 						ring_reg_addrs[i] + reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 
 	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
@@ -322,7 +300,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 		for (i = 0; i < reg_num; i++)
 			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
 						reg_offset);
-		data += hns3_insert_reg_separator(reg_num, data);
 	}
 	return data - origin_data_ptr;
 }
@@ -398,17 +375,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 		index = i % HNS3_CMD_DESC_DATA_NUM;
 		*reg++ = desc[desc_index].data[index];
 	}
-	reg_num += hns3_insert_reg_separator(reg_num, reg);
 
 	return reg_num;
 }
 
 static int
-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
-	uint32_t bd_num, data_len;
 	int ret;
 	int i;
 
@@ -416,11 +391,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++) {
-		bd_num = bd_num_list[i];
-		data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t);
-		*lines += data_len / REG_LEN_PER_LINE + 1;
-	}
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
 
 	return 0;
 }
@@ -467,7 +439,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t regs_num_32_bit;
@@ -512,16 +483,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 	data += regs_num_32_bit;
-	data += hns3_insert_reg_separator(regs_num_32_bit, data);
 
 	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE;
-	data += hns3_insert_reg_separator(regs_num_64_bit *
-					  HNS3_64_BIT_REG_SIZE, data);
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
 	return  hns3_get_dfx_regs(hw, (void **)&data);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 6/8] net/hns3: refactor register dump
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
                     ` (4 preceding siblings ...)
  2024-09-26 12:42   ` [PATCH v9 5/8] net/hns3: remove separators between register module Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 7/8] net/hns3: support report names of registers Jie Hai
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch refactors codes dumping registers from firmware.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++---------------
 1 file changed, 115 insertions(+), 88 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index c8e3fb118e4b..89858c2b1c09 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -104,12 +104,93 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
+static int
+hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	uint32_t regs_num_32_bit, regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "fail to get the number of registers, "
+			 "ret = %d.", ret);
+		return ret;
+	}
+
+	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
+			uint32_t list_size)
+{
+#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
+	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
+	uint32_t index, desc_index;
+	uint32_t bd_num;
+	uint32_t i;
+	int ret;
+
+	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	/* The last BD does not need a next flag */
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
+
+	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
+	if (ret) {
+		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
+		return ret;
+	}
+
+	/* The first data in the first BD is a reserved field */
+	for (i = 1; i <= list_size; i++) {
+		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
+		index = i % HNS3_CMD_DESC_DATA_NUM;
+		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
+		bd_num_list[i - 1] = bd_num;
+	}
+
+	return 0;
+}
+
+static int
+hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
+	uint32_t bd_num_list[opcode_num];
+	int ret;
+	int i;
+
+	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < opcode_num; i++)
+		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+
+	return 0;
+}
+
+static int
+hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
+{
+	int ret;
+
+	ret = hns3_get_32_64_regs_cnt(hw, count);
+	if (ret < 0)
+		return ret;
+
+	return hns3_get_dfx_reg_cnt(hw, count);
+}
+
 static int
 hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	uint32_t dfx_reg_cnt;
+	uint32_t dfx_reg_cnt = 0;
 	uint32_t common_cnt;
 	uint32_t len;
 	int ret;
@@ -125,16 +206,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	len /= sizeof(uint32_t);
 
 	if (!hns->is_vf) {
-		ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		dfx_reg_cnt = regs_num_32_bit +
-			      regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-		ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt);
+		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
 		if (ret) {
 			hns3_err(hw, "fail to get the number of dfx registers, "
 				 "ret = %d.", ret);
@@ -304,41 +376,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 	return data - origin_data_ptr;
 }
 
-static int
-hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
-			uint32_t list_size)
-{
-#define HNS3_GET_DFX_REG_BD_NUM_SIZE	4
-	struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE];
-	uint32_t index, desc_index;
-	uint32_t bd_num;
-	uint32_t i;
-	int ret;
-
-	for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) {
-		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
-	}
-	/* The last BD does not need a next flag */
-	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true);
-
-	ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE);
-	if (ret) {
-		hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret);
-		return ret;
-	}
-
-	/* The first data in the first BD is a reserved field */
-	for (i = 1; i <= list_size; i++) {
-		desc_index = i / HNS3_CMD_DESC_DATA_NUM;
-		index = i % HNS3_CMD_DESC_DATA_NUM;
-		bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]);
-		bd_num_list[i - 1] = bd_num;
-	}
-
-	return 0;
-}
-
 static int
 hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
 			int bd_num, uint32_t opcode)
@@ -379,24 +416,6 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 	return reg_num;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-
-	return 0;
-}
-
 static int
 hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 {
@@ -436,13 +455,41 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 	return ret;
 }
 
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+{
+	uint32_t regs_num_32_bit;
+	uint32_t regs_num_64_bit;
+	int ret;
+
+	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
+	if (ret) {
+		hns3_err(hw, "Get register number failed, ret = %d", ret);
+		return ret;
+	}
+
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_32_bit;
+
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	if (ret) {
+		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+		return ret;
+	}
+	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
+
+	return hns3_get_dfx_regs(hw, (void **)&data);
+}
+
 int
 hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	uint32_t regs_num_32_bit;
-	uint32_t regs_num_64_bit;
 	uint32_t length;
 	uint32_t *data;
 	int ret;
@@ -470,26 +517,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	if (hns->is_vf)
 		return 0;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "Get register number failed, ret = %d", ret);
-		return ret;
-	}
-
 	/* fetching PF common registers values from firmware */
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_32_bit;
-
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
-	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-
-	return  hns3_get_dfx_regs(hw, (void **)&data);
+	return  hns3_get_regs_from_firmware(hw, data);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 7/8] net/hns3: support report names of registers
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
                     ` (5 preceding siblings ...)
  2024-09-26 12:42   ` [PATCH v9 6/8] net/hns3: refactor register dump Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-26 12:42   ` [PATCH v9 8/8] net/hns3: support filter registers by module names Jie Hai
  2024-09-27 21:38   ` [PATCH v9 0/8] support dump reigster names and filter Ferruh Yigit
  8 siblings, 0 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch adds names for register lists, and support report
names of registers. Some registers has different names on
different platform, use names of HIP08 as default names.

Signed-off-by: Jie Hai <haijie1@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_regs.c | 1088 +++++++++++++++++++++++++++++-----
 1 file changed, 955 insertions(+), 133 deletions(-)

diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index 89858c2b1c09..a0d130302839 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -14,73 +14,827 @@
 
 static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
 
-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG,
-					  HNS3_CMDQ_TX_TAIL_REG,
-					  HNS3_CMDQ_TX_HEAD_REG,
-					  HNS3_CMDQ_RX_DEPTH_REG,
-					  HNS3_CMDQ_RX_TAIL_REG,
-					  HNS3_CMDQ_RX_HEAD_REG,
-					  HNS3_VECTOR0_CMDQ_SRC_REG,
-					  HNS3_CMDQ_INTR_STS_REG,
-					  HNS3_CMDQ_INTR_EN_REG,
-					  HNS3_CMDQ_INTR_GEN_REG};
-
-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					    HNS3_VECTOR0_OTER_EN_REG,
-					    HNS3_MISC_RESET_STS_REG,
-					    HNS3_VECTOR0_OTHER_INT_STS_REG,
-					    HNS3_GLOBAL_RESET_REG,
-					    HNS3_FUN_RST_ING,
-					    HNS3_GRO_EN_REG};
-
-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE,
-					       HNS3_FUN_RST_ING,
-					       HNS3_GRO_EN_REG};
-
-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG,
-					  HNS3_RING_RX_BD_LEN_REG,
-					  HNS3_RING_RX_EN_REG,
-					  HNS3_RING_RX_MERGE_EN_REG,
-					  HNS3_RING_RX_TAIL_REG,
-					  HNS3_RING_RX_HEAD_REG,
-					  HNS3_RING_RX_FBDNUM_REG,
-					  HNS3_RING_RX_OFFSET_REG,
-					  HNS3_RING_RX_FBD_OFFSET_REG,
-					  HNS3_RING_RX_STASH_REG,
-					  HNS3_RING_RX_BD_ERR_REG,
-					  HNS3_RING_TX_BD_NUM_REG,
-					  HNS3_RING_TX_EN_REG,
-					  HNS3_RING_TX_PRIORITY_REG,
-					  HNS3_RING_TX_TC_REG,
-					  HNS3_RING_TX_MERGE_EN_REG,
-					  HNS3_RING_TX_TAIL_REG,
-					  HNS3_RING_TX_HEAD_REG,
-					  HNS3_RING_TX_FBDNUM_REG,
-					  HNS3_RING_TX_OFFSET_REG,
-					  HNS3_RING_TX_EBD_NUM_REG,
-					  HNS3_RING_TX_EBD_OFFSET_REG,
-					  HNS3_RING_TX_BD_ERR_REG,
-					  HNS3_RING_EN_REG};
-
-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG,
-					      HNS3_TQP_INTR_GL0_REG,
-					      HNS3_TQP_INTR_GL1_REG,
-					      HNS3_TQP_INTR_GL2_REG,
-					      HNS3_TQP_INTR_RL_REG};
+struct hns3_dirt_reg_entry {
+	const char *name;
+	uint32_t addr;
+};
+
+static const struct hns3_dirt_reg_entry cmdq_reg_list[] = {
+	{"cmdq_tx_depth",		HNS3_CMDQ_TX_DEPTH_REG},
+	{"cmdq_tx_tail",		HNS3_CMDQ_TX_TAIL_REG},
+	{"cmdq_tx_head",		HNS3_CMDQ_TX_HEAD_REG},
+	{"cmdq_rx_depth",		HNS3_CMDQ_RX_DEPTH_REG},
+	{"cmdq_rx_tail",		HNS3_CMDQ_RX_TAIL_REG},
+	{"cmdq_rx_head",		HNS3_CMDQ_RX_HEAD_REG},
+	{"vector0_cmdq_src",		HNS3_VECTOR0_CMDQ_SRC_REG},
+	{"cmdq_intr_sts",		HNS3_CMDQ_INTR_STS_REG},
+	{"cmdq_intr_en",		HNS3_CMDQ_INTR_EN_REG},
+	{"cmdq_intr_gen",		HNS3_CMDQ_INTR_GEN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"vector0_oter_en",		HNS3_VECTOR0_OTER_EN_REG},
+	{"misc_reset_sts",		HNS3_MISC_RESET_STS_REG},
+	{"vector0_other_int_sts",	HNS3_VECTOR0_OTHER_INT_STS_REG},
+	{"global_reset",		HNS3_GLOBAL_RESET_REG},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry common_vf_reg_list[] = {
+	{"misc_vector_reg_base",	HNS3_MISC_VECTOR_REG_BASE},
+	{"fun_rst_ing",			HNS3_FUN_RST_ING},
+	{"gro_en",			HNS3_GRO_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry ring_reg_list[] = {
+	{"ring_rx_bd_num",		HNS3_RING_RX_BD_NUM_REG},
+	{"ring_rx_bd_len",		HNS3_RING_RX_BD_LEN_REG},
+	{"ring_rx_en",			HNS3_RING_RX_EN_REG},
+	{"ring_rx_merge_en",		HNS3_RING_RX_MERGE_EN_REG},
+	{"ring_rx_tail",		HNS3_RING_RX_TAIL_REG},
+	{"ring_rx_head",		HNS3_RING_RX_HEAD_REG},
+	{"ring_rx_fbdnum",		HNS3_RING_RX_FBDNUM_REG},
+	{"ring_rx_offset",		HNS3_RING_RX_OFFSET_REG},
+	{"ring_rx_fbd_offset",		HNS3_RING_RX_FBD_OFFSET_REG},
+	{"ring_rx_stash",		HNS3_RING_RX_STASH_REG},
+	{"ring_rx_bd_err",		HNS3_RING_RX_BD_ERR_REG},
+	{"ring_tx_bd_num",		HNS3_RING_TX_BD_NUM_REG},
+	{"ring_tx_en",			HNS3_RING_TX_EN_REG},
+	{"ring_tx_priority",		HNS3_RING_TX_PRIORITY_REG},
+	{"ring_tx_tc",			HNS3_RING_TX_TC_REG},
+	{"ring_tx_merge_en",		HNS3_RING_TX_MERGE_EN_REG},
+	{"ring_tx_tail",		HNS3_RING_TX_TAIL_REG},
+	{"ring_tx_head",		HNS3_RING_TX_HEAD_REG},
+	{"ring_tx_fbdnum",		HNS3_RING_TX_FBDNUM_REG},
+	{"ring_tx_offset",		HNS3_RING_TX_OFFSET_REG},
+	{"ring_tx_ebd_num",		HNS3_RING_TX_EBD_NUM_REG},
+	{"ring_tx_ebd_offset",		HNS3_RING_TX_EBD_OFFSET_REG},
+	{"ring_tx_bd_err",		HNS3_RING_TX_BD_ERR_REG},
+	{"ring_en",			HNS3_RING_EN_REG},
+};
+
+static const struct hns3_dirt_reg_entry tqp_intr_reg_list[] = {
+	{"tqp_intr_ctrl",		HNS3_TQP_INTR_CTRL_REG},
+	{"tqp_intr_gl0",		HNS3_TQP_INTR_GL0_REG},
+	{"tqp_intr_gl1",		HNS3_TQP_INTR_GL1_REG},
+	{"tqp_intr_gl2",		HNS3_TQP_INTR_GL2_REG},
+	{"tqp_intr_rl",			HNS3_TQP_INTR_RL_REG},
+};
+
+struct hns3_dfx_reg_entry {
+	/**
+	 * name_v1 -- default register name for all platforms (HIP08/HIP09/newer).
+	 * name_v2 -- register name different from the default for HIP09.
+	 * If there are more platform with different register name, name_vXX is extended.
+	 * If the platform is newer than HIP09, use default name.
+	 */
+	const char *name_v1;
+	const char *name_v2;
+};
+
+static struct hns3_dfx_reg_entry regs_32_bit_list[] = {
+	{"ssu_common_err_int"},
+	{"ssu_port_based_err_int"},
+	{"ssu_fifo_overflow_int"},
+	{"ssu_ets_tcg_int"},
+	{"ssu_bp_status_0"},
+	{"ssu_bp_status_1"},
+
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+	{"ssu_mac_rx_pfc_ind"},
+
+	{"ssu_rx_oq_drop_pkt_cnt"},
+	{"ssu_tx_oq_drop_pkt_cnt"},
+};
+
+static struct hns3_dfx_reg_entry regs_64_bit_list[] = {
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+};
+
+static struct hns3_dfx_reg_entry dfx_bios_common_reg_list[] = {
+	{"bios_rsv0"},
+	{"bp_cpu_state"},
+	{"dfx_msix_info_nic_0"},
+	{"dfx_msix_info_nic_1"},
+	{"dfx_msix_info_nic_2"},
+	{"dfx_msix_info_nic_3"},
+
+	{"dfx_msix_info_roce_0"},
+	{"dfx_msix_info_roce_1"},
+	{"dfx_msix_info_roce_2"},
+	{"dfx_msix_info_roce_3"},
+	{"bios_rsv1"},
+	{"bios_rsv2"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_0_list[] = {
+	{"dfx_ssu0_rsv0"},
+	{"ssu_ets_port_status"},
+	{"ssu_ets_tcg_status"},
+	{"dfx_ssu0_rsv1"},
+	{"dfx_ssu0_rsv2"},
+	{"ssu_bp_status_0"},
+
+	{"ssu_bp_status_1"},
+	{"ssu_bp_status_2"},
+	{"ssu_bp_status_3"},
+	{"ssu_bp_status_4"},
+	{"ssu_bp_status_5"},
+	{"ssu_mac_tx_pfc_ind"},
+
+	{"mac_ssu_rx_pfc_ind"},
+	{"btmp_ageing_st_b0"},
+	{"btmp_ageing_st_b1"},
+	{"btmp_ageing_st_b2"},
+	{"dfx_ssu0_rsv3"},
+	{"dfx_ssu0_rsv4"},
+
+	{"ssu_full_drop_num"},
+	{"ssu_part_drop_num"},
+	{"ppp_key_drop_num"},
+	{"ppp_rlt_drop_num"},
+	{"lo_pri_unicast_rlt_drop_num"},
+	{"hi_pri_multicast_rlt_drop_num"},
+
+	{"lo_pri_multicast_rlt_drop_num"},
+	{"ncsi_packet_curr_buffer_cnt"},
+	{"btmp_ageing_rls_cnt_bank0",		"dfx_ssu0_rsv5"},
+	{"btmp_ageing_rls_cnt_bank1",		"dfx_ssu0_rsv6"},
+	{"btmp_ageing_rls_cnt_bank2",		"dfx_ssu0_rsv7"},
+	{"ssu_mb_rd_rlt_drop_cnt"},
+
+	{"ssu_ppp_mac_key_num_l"},
+	{"ssu_ppp_mac_key_num_h"},
+	{"ssu_ppp_host_key_num_l"},
+	{"ssu_ppp_host_key_num_h"},
+	{"ppp_ssu_mac_rlt_num_l"},
+	{"ppp_ssu_mac_rlt_num_h"},
+
+	{"ppp_ssu_host_rlt_num_l"},
+	{"ppp_ssu_host_rlt_num_h"},
+	{"ncsi_rx_packet_in_cnt_l"},
+	{"ncsi_rx_packet_in_cnt_h"},
+	{"ncsi_tx_packet_out_cnt_l"},
+	{"ncsi_tx_packet_out_cnt_h"},
+
+	{"ssu_key_drop_num"},
+	{"mb_uncopy_num"},
+	{"rx_oq_drop_pkt_cnt"},
+	{"tx_oq_drop_pkt_cnt"},
+	{"bank_unbalance_drop_cnt"},
+	{"bank_unbalance_rx_drop_cnt"},
+
+	{"nic_l2_eer_drop_pkt_cnt"},
+	{"roc_l2_eer_drop_pkt_cnt"},
+	{"nic_l2_eer_drop_pkt_cnt_rx"},
+	{"roc_l2_eer_drop_pkt_cnt_rx"},
+	{"rx_oq_glb_drop_pkt_cnt"},
+	{"dfx_ssu0_rsv8"},
+
+	{"lo_pri_unicast_cur_cnt"},
+	{"hi_pri_multicast_cur_cnt"},
+	{"lo_pri_multicast_cur_cnt"},
+	{"dfx_ssu0_rsv9"},
+	{"dfx_ssu0_rsv10"},
+	{"dfx_ssu0_rsv11"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_1_list[] = {
+	{"dfx_ssu1_prt_id"},
+	{"packet_tc_curr_buffer_cnt_0"},
+	{"packet_tc_curr_buffer_cnt_1"},
+	{"packet_tc_curr_buffer_cnt_2"},
+	{"packet_tc_curr_buffer_cnt_3"},
+	{"packet_tc_curr_buffer_cnt_4"},
+
+	{"packet_tc_curr_buffer_cnt_5"},
+	{"packet_tc_curr_buffer_cnt_6"},
+	{"packet_tc_curr_buffer_cnt_7"},
+	{"packet_curr_buffer_cnt"},
+	{"dfx_ssu1_rsv0"},
+	{"dfx_ssu1_rsv1"},
+
+	{"rx_packet_in_cnt_l"},
+	{"rx_packet_in_cnt_h"},
+	{"rx_packet_out_cnt_l"},
+	{"rx_packet_out_cnt_h"},
+	{"tx_packet_in_cnt_l"},
+	{"tx_packet_in_cnt_h"},
+
+	{"tx_packet_out_cnt_l"},
+	{"tx_packet_out_cnt_h"},
+	{"roc_rx_packet_in_cnt_l"},
+	{"roc_rx_packet_in_cnt_h"},
+	{"roc_tx_packet_in_cnt_l"},
+	{"roc_tx_packet_in_cnt_h"},
+
+	{"rx_packet_tc_in_cnt_0_l"},
+	{"rx_packet_tc_in_cnt_0_h"},
+	{"rx_packet_tc_in_cnt_1_l"},
+	{"rx_packet_tc_in_cnt_1_h"},
+	{"rx_packet_tc_in_cnt_2_l"},
+	{"rx_packet_tc_in_cnt_2_h"},
+
+	{"rx_packet_tc_in_cnt_3_l"},
+	{"rx_packet_tc_in_cnt_3_h"},
+	{"rx_packet_tc_in_cnt_4_l"},
+	{"rx_packet_tc_in_cnt_4_h"},
+	{"rx_packet_tc_in_cnt_5_l"},
+	{"rx_packet_tc_in_cnt_5_h"},
+
+	{"rx_packet_tc_in_cnt_6_l"},
+	{"rx_packet_tc_in_cnt_6_h"},
+	{"rx_packet_tc_in_cnt_7_l"},
+	{"rx_packet_tc_in_cnt_7_h"},
+	{"rx_packet_tc_out_cnt_0_l"},
+	{"rx_packet_tc_out_cnt_0_h"},
+
+	{"rx_packet_tc_out_cnt_1_l"},
+	{"rx_packet_tc_out_cnt_1_h"},
+	{"rx_packet_tc_out_cnt_2_l"},
+	{"rx_packet_tc_out_cnt_2_h"},
+	{"rx_packet_tc_out_cnt_3_l"},
+	{"rx_packet_tc_out_cnt_3_h"},
+
+	{"rx_packet_tc_out_cnt_4_l"},
+	{"rx_packet_tc_out_cnt_4_h"},
+	{"rx_packet_tc_out_cnt_5_l"},
+	{"rx_packet_tc_out_cnt_5_h"},
+	{"rx_packet_tc_out_cnt_6_l"},
+	{"rx_packet_tc_out_cnt_6_h"},
+
+	{"rx_packet_tc_out_cnt_7_l"},
+	{"rx_packet_tc_out_cnt_7_h"},
+	{"tx_packet_tc_in_cnt_0_l"},
+	{"tx_packet_tc_in_cnt_0_h"},
+	{"tx_packet_tc_in_cnt_1_l"},
+	{"tx_packet_tc_in_cnt_1_h"},
+
+	{"tx_packet_tc_in_cnt_2_l"},
+	{"tx_packet_tc_in_cnt_2_h"},
+	{"tx_packet_tc_in_cnt_3_l"},
+	{"tx_packet_tc_in_cnt_3_h"},
+	{"tx_packet_tc_in_cnt_4_l"},
+	{"tx_packet_tc_in_cnt_4_h"},
+
+	{"tx_packet_tc_in_cnt_5_l"},
+	{"tx_packet_tc_in_cnt_5_h"},
+	{"tx_packet_tc_in_cnt_6_l"},
+	{"tx_packet_tc_in_cnt_6_h"},
+	{"tx_packet_tc_in_cnt_7_l"},
+	{"tx_packet_tc_in_cnt_7_h"},
+
+	{"tx_packet_tc_out_cnt_0_l"},
+	{"tx_packet_tc_out_cnt_0_h"},
+	{"tx_packet_tc_out_cnt_1_l"},
+	{"tx_packet_tc_out_cnt_1_h"},
+	{"tx_packet_tc_out_cnt_2_l"},
+	{"tx_packet_tc_out_cnt_2_h"},
+
+	{"tx_packet_tc_out_cnt_3_l"},
+	{"tx_packet_tc_out_cnt_3_h"},
+	{"tx_packet_tc_out_cnt_4_l"},
+	{"tx_packet_tc_out_cnt_4_h"},
+	{"tx_packet_tc_out_cnt_5_l"},
+	{"tx_packet_tc_out_cnt_5_h"},
+
+	{"tx_packet_tc_out_cnt_6_l"},
+	{"tx_packet_tc_out_cnt_6_h"},
+	{"tx_packet_tc_out_cnt_7_l"},
+	{"tx_packet_tc_out_cnt_7_h"},
+	{"dfx_ssu1_rsv2"},
+	{"dfx_ssu1_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_igu_egu_reg_list[] = {
+	{"igu_egu_prt_id"},
+	{"igu_rx_err_pkt"},
+	{"igu_rx_no_sof_pkt"},
+	{"egu_tx_1588_short_pkt"},
+	{"egu_tx_1588_pkt"},
+	{"egu_tx_1588_err_pkt"},
+
+	{"igu_rx_out_l2_pkt"},
+	{"igu_rx_out_l3_pkt"},
+	{"igu_rx_out_l4_pkt"},
+	{"igu_rx_in_l2_pkt"},
+	{"igu_rx_in_l3_pkt"},
+	{"igu_rx_in_l4_pkt"},
+
+	{"igu_rx_el3e_pkt"},
+	{"igu_rx_el4e_pkt"},
+	{"igu_rx_l3e_pkt"},
+	{"igu_rx_l4e_pkt"},
+	{"igu_rx_rocee_pkt"},
+	{"igu_rx_out_udp0_pkt"},
+
+	{"igu_rx_in_udp0_pkt"},
+	{"igu_egu_rsv0",		"igu_egu_mul_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv1",		"igu_egu_mul_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv2",		"igu_egu_bro_car_drop_pkt_cnt_l"},
+	{"igu_egu_rsv3",		"igu_egu_bro_car_drop_pkt_cnt_h"},
+	{"igu_egu_rsv4",		"igu_egu_rsv0"},
+
+	{"igu_rx_oversize_pkt_l"},
+	{"igu_rx_oversize_pkt_h"},
+	{"igu_rx_undersize_pkt_l"},
+	{"igu_rx_undersize_pkt_h"},
+	{"igu_rx_out_all_pkt_l"},
+	{"igu_rx_out_all_pkt_h"},
+
+	{"igu_tx_out_all_pkt_l"},
+	{"igu_tx_out_all_pkt_h"},
+	{"igu_rx_uni_pkt_l"},
+	{"igu_rx_uni_pkt_h"},
+	{"igu_rx_multi_pkt_l"},
+	{"igu_rx_multi_pkt_h"},
+
+	{"igu_rx_broad_pkt_l"},
+	{"igu_rx_broad_pkt_h"},
+	{"egu_tx_out_all_pkt_l"},
+	{"egu_tx_out_all_pkt_h"},
+	{"egu_tx_uni_pkt_l"},
+	{"egu_tx_uni_pkt_h"},
+
+	{"egu_tx_multi_pkt_l"},
+	{"egu_tx_multi_pkt_h"},
+	{"egu_tx_broad_pkt_l"},
+	{"egu_tx_broad_pkt_h"},
+	{"igu_tx_key_num_l"},
+	{"igu_tx_key_num_h"},
+
+	{"igu_rx_non_tun_pkt_l"},
+	{"igu_rx_non_tun_pkt_h"},
+	{"igu_rx_tun_pkt_l"},
+	{"igu_rx_tun_pkt_h"},
+	{"igu_egu_rsv5"},
+	{"igu_egu_rsv6"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_0_list[] = {
+	{"rpu_tc_queue_num",		"rpu_currport_tnl_index"},
+	{"rpu_fsm_dfx_st0"},
+	{"rpu_fsm_dfx_st1"},
+	{"rpu_rpu_rx_pkt_drop_cnt"},
+	{"rpu_buf_wait_timeout"},
+	{"rpu_buf_wait_timeout_qid"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rpu_reg_1_list[] = {
+	{"rpu_rsv0"},
+	{"rpu_fifo_dfx_st0"},
+	{"rpu_fifo_dfx_st1"},
+	{"rpu_fifo_dfx_st2"},
+	{"rpu_fifo_dfx_st3"},
+	{"rpu_fifo_dfx_st4"},
+
+	{"rpu_fifo_dfx_st5"},
+	{"rpu_rsv1"},
+	{"rpu_rsv2"},
+	{"rpu_rsv3"},
+	{"rpu_rsv4"},
+	{"rpu_rsv5"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ncsi_reg_list[] = {
+	{"ncsi_rsv0"},
+	{"ncsi_egu_tx_fifo_sts"},
+	{"ncsi_pause_status"},
+	{"ncsi_rx_ctrl_dmac_err_cnt"},
+	{"ncsi_rx_ctrl_smac_err_cnt"},
+	{"ncsi_rx_ctrl_cks_err_cnt"},
+
+	{"ncsi_rx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_pt_dmac_err_cnt"},
+	{"ncsi_rx_pt_smac_err_cnt"},
+	{"ncsi_rx_pt_pkt_cnt"},
+	{"ncsi_rx_fcs_err_cnt"},
+	{"ncsi_tx_ctrl_dmac_err_cnt"},
+
+	{"ncsi_tx_ctrl_smac_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_cnt"},
+	{"ncsi_tx_pt_dmac_err_cnt"},
+	{"ncsi_tx_pt_smac_err_cnt"},
+	{"ncsi_tx_pt_pkt_cnt"},
+	{"ncsi_tx_pt_pkt_trun_cnt"},
+
+	{"ncsi_tx_pt_pkt_err_cnt"},
+	{"ncsi_tx_ctrl_pkt_err_cnt"},
+	{"ncsi_rx_ctrl_pkt_trun_cnt"},
+	{"ncsi_rx_ctrl_pkt_cflit_cnt"},
+	{"ncsi_rsv1"},
+	{"ncsi_rsv2"},
+
+	{"ncsi_mac_rx_octets_ok"},
+	{"ncsi_mac_rx_octets_bad"},
+	{"ncsi_mac_rx_uc_pkts"},
+	{"ncsi_mac_rx_mc_pkts"},
+	{"ncsi_mac_rx_bc_pkts"},
+	{"ncsi_mac_rx_pkts_64octets"},
+
+	{"ncsi_mac_rx_pkts_64to127_octets"},
+	{"ncsi_mac_rx_pkts_128to255_octets"},
+	{"ncsi_mac_rx_pkts_256to511_octets"},
+	{"ncsi_mac_rx_pkts_512to1023_octets"},
+	{"ncsi_mac_rx_pkts_1024to1518_octets"},
+	{"ncsi_mac_rx_pkts_1519tomax_octets"},
+
+	{"ncsi_mac_rx_fcs_errors"},
+	{"ncsi_mac_rx_long_errors"},
+	{"ncsi_mac_rx_jabber_errors"},
+	{"ncsi_mac_rx_runt_err_cnt"},
+	{"ncsi_mac_rx_short_err_cnt"},
+	{"ncsi_mac_rx_filt_pkt_cnt"},
+
+	{"ncsi_mac_rx_octets_total_filt"},
+	{"ncsi_mac_tx_octets_ok"},
+	{"ncsi_mac_tx_octets_bad"},
+	{"ncsi_mac_tx_uc_pkts"},
+	{"ncsi_mac_tx_mc_pkts"},
+	{"ncsi_mac_tx_bc_pkts"},
+
+	{"ncsi_mac_tx_pkts_64octets"},
+	{"ncsi_mac_tx_pkts_64to127_octets"},
+	{"ncsi_mac_tx_pkts_128to255_octets"},
+	{"ncsi_mac_tx_pkts_256to511_octets"},
+	{"ncsi_mac_tx_pkts_512to1023_octets"},
+	{"ncsi_mac_tx_pkts_1024to1518_octets"},
+
+	{"ncsi_mac_tx_pkts_1519tomax_octets"},
+	{"ncsi_mac_tx_underrun"},
+	{"ncsi_mac_tx_crc_error"},
+	{"ncsi_mac_tx_pause_frames"},
+	{"ncsi_mac_rx_pad_pkts"},
+	{"ncsi_mac_rx_pause_frames"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rtc_reg_list[] = {
+	{"rtc_rsv0"},
+	{"lge_igu_afifo_dfx_0"},
+	{"lge_igu_afifo_dfx_1"},
+	{"lge_igu_afifo_dfx_2"},
+	{"lge_igu_afifo_dfx_3"},
+	{"lge_igu_afifo_dfx_4"},
+
+	{"lge_igu_afifo_dfx_5"},
+	{"lge_igu_afifo_dfx_6"},
+	{"lge_igu_afifo_dfx_7"},
+	{"lge_egu_afifo_dfx_0"},
+	{"lge_egu_afifo_dfx_1"},
+	{"lge_egu_afifo_dfx_2"},
+
+	{"lge_egu_afifo_dfx_3"},
+	{"lge_egu_afifo_dfx_4"},
+	{"lge_egu_afifo_dfx_5"},
+	{"lge_egu_afifo_dfx_6"},
+	{"lge_egu_afifo_dfx_7"},
+	{"cge_igu_afifo_dfx_0"},
+
+	{"cge_igu_afifo_dfx_1"},
+	{"cge_egu_afifo_dfx_0"},
+	{"cge_egu_afifo_dfx_i"},
+	{"rtc_rsv1"},
+	{"rtc_rsv2"},
+	{"rtc_rsv3"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ppp_reg_list[] = {
+	{"ppp_rsv0"},
+	{"ppp_drop_from_prt_pkt_cnt"},
+	{"ppp_drop_from_host_pkt_cnt"},
+	{"ppp_drop_tx_vlan_proc_cnt"},
+	{"ppp_drop_mng_cnt"},
+	{"ppp_drop_fd_cnt"},
+
+	{"ppp_drop_no_dst_cnt"},
+	{"ppp_drop_mc_mbid_full_cnt"},
+	{"ppp_drop_sc_filtered"},
+	{"ppp_ppp_mc_drop_pkt_cnt"},
+	{"ppp_drop_pt_cnt"},
+	{"ppp_drop_mac_anti_spoof_cnt"},
+
+	{"ppp_drop_ig_vfv_cnt"},
+	{"ppp_drop_ig_prtv_cnt"},
+	{"ppp_drop_cnm_pfc_pause_cnt"},
+	{"ppp_drop_torus_tc_cnt"},
+	{"ppp_drop_torus_lpbk_cnt"},
+	{"ppp_ppp_hfs_sts"},
+
+	{"ppp_mc_rslt_sts"},
+	{"ppp_p3u_sts"},
+	{"ppp_rslt_descr_sts",		"ppp_rsv1"},
+	{"ppp_umv_sts_0"},
+	{"ppp_umv_sts_1"},
+	{"ppp_vfv_sts"},
+
+	{"ppp_gro_key_cnt"},
+	{"ppp_gro_info_cnt"},
+	{"ppp_gro_drop_cnt"},
+	{"ppp_gro_out_cnt"},
+	{"ppp_gro_key_match_data_cnt"},
+	{"ppp_gro_key_match_tcam_cnt"},
+
+	{"ppp_gro_info_match_cnt"},
+	{"ppp_gro_free_entry_cnt"},
+	{"ppp_gro_inner_dfx_signal"},
+	{"ppp_rsv2"},
+	{"ppp_rsv3"},
+	{"ppp_rsv4"},
+
+	{"ppp_get_rx_pkt_cnt_l"},
+	{"ppp_get_rx_pkt_cnt_h"},
+	{"ppp_get_tx_pkt_cnt_l"},
+	{"ppp_get_tx_pkt_cnt_h"},
+	{"ppp_send_uc_prt2host_pkt_cnt_l"},
+	{"ppp_send_uc_prt2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2prt_pkt_cnt_l"},
+	{"ppp_send_uc_prt2prt_pkt_cnt_h"},
+	{"ppp_send_uc_host2host_pkt_cnt_l"},
+	{"ppp_send_uc_host2host_pkt_cnt_h"},
+	{"ppp_send_uc_host2prt_pkt_cnt_l"},
+	{"ppp_send_uc_host2prt_pkt_cnt_h"},
+
+	{"ppp_send_mc_from_prt_cnt_l"},
+	{"ppp_send_mc_from_prt_cnt_h"},
+	{"ppp_send_mc_from_host_cnt_l"},
+	{"ppp_send_mc_from_host_cnt_h"},
+	{"ppp_ssu_mc_rd_cnt_l"},
+	{"ppp_ssu_mc_rd_cnt_h"},
+
+	{"ppp_ssu_mc_drop_cnt_l"},
+	{"ppp_ssu_mc_drop_cnt_h"},
+	{"ppp_ssu_mc_rd_pkt_cnt_l"},
+	{"ppp_ssu_mc_rd_pkt_cnt_h"},
+	{"ppp_mc_2host_pkt_cnt_l"},
+	{"ppp_mc_2host_pkt_cnt_h"},
+
+	{"ppp_mc_2prt_pkt_cnt_l"},
+	{"ppp_mc_2prt_pkt_cnt_h"},
+	{"ppp_ntsnos_pkt_cnt_l"},
+	{"ppp_ntsnos_pkt_cnt_h"},
+	{"ppp_ntup_pkt_cnt_l"},
+	{"ppp_ntup_pkt_cnt_h"},
+
+	{"ppp_ntlcl_pkt_cnt_l"},
+	{"ppp_ntlcl_pkt_cnt_h"},
+	{"ppp_nttgt_pkt_cnt_l"},
+	{"ppp_nttgt_pkt_cnt_h"},
+	{"ppp_rtns_pkt_cnt_l"},
+	{"ppp_rtns_pkt_cnt_h"},
+
+	{"ppp_rtlpbk_pkt_cnt_l"},
+	{"ppp_rtlpbk_pkt_cnt_h"},
+	{"ppp_nr_pkt_cnt_l"},
+	{"ppp_nr_pkt_cnt_h"},
+	{"ppp_rr_pkt_cnt_l"},
+	{"ppp_rr_pkt_cnt_h"},
+
+	{"ppp_mng_tbl_hit_cnt_l"},
+	{"ppp_mng_tbl_hit_cnt_h"},
+	{"ppp_fd_tbl_hit_cnt_l"},
+	{"ppp_fd_tbl_hit_cnt_h"},
+	{"ppp_fd_lkup_cnt_l"},
+	{"ppp_fd_lkup_cnt_h"},
+
+	{"ppp_bc_hit_cnt"},
+	{"ppp_bc_hit_cnt_h"},
+	{"ppp_um_tbl_uc_hit_cnt"},
+	{"ppp_um_tbl_uc_hit_cnt_h"},
+	{"ppp_um_tbl_mc_hit_cnt"},
+	{"ppp_um_tbl_mc_hit_cnt_h"},
+
+	{"ppp_um_tbl_vmdq1_hit_cnt_l",	"ppp_um_tbl_snq_hit_cnt_l"},
+	{"ppp_um_tbl_vmdq1_hit_cnt_h",	"ppp_um_tbl_snq_hit_cnt_h"},
+	{"ppp_mta_tbl_hit_cnt_l",	"ppp_rsv5"},
+	{"ppp_mta_tbl_hit_cnt_h",	"ppp_rsv6"},
+	{"ppp_fwd_bonding_hit_cnt_l"},
+	{"ppp_fwd_bonding_hit_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_cnt_l"},
+	{"ppp_promisc_tbl_hit_cnt_h"},
+	{"ppp_get_tunl_pkt_cnt_l"},
+	{"ppp_get_tunl_pkt_cnt_h"},
+	{"ppp_get_bmc_pkt_cnt_l"},
+	{"ppp_get_bmc_pkt_cnt_h"},
+
+	{"ppp_send_uc_prt2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_prt2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_l"},
+	{"ppp_send_uc_host2bmc_pkt_cnt_h"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2host_pkt_cnt_h"},
+
+	{"ppp_send_uc_bmc2prt_pkt_cnt_l"},
+	{"ppp_send_uc_bmc2prt_pkt_cnt_h"},
+	{"ppp_mc_2bmc_pkt_cnt_l"},
+	{"ppp_mc_2bmc_pkt_cnt_h"},
+	{"ppp_vlan_mirr_cnt_l",		"ppp_rsv7"},
+	{"ppp_vlan_mirr_cnt_h",		"ppp_rsv8"},
+
+	{"ppp_ig_mirr_cnt_l",		"ppp_rsv9"},
+	{"ppp_ig_mirr_cnt_h",		"ppp_rsv10"},
+	{"ppp_eg_mirr_cnt_l",		"ppp_rsv11"},
+	{"ppp_eg_mirr_cnt_h",		"ppp_rsv12"},
+	{"ppp_rx_default_host_hit_cnt_l"},
+	{"ppp_rx_default_host_hit_cnt_h"},
+
+	{"ppp_lan_pair_cnt_l"},
+	{"ppp_lan_pair_cnt_h"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_l"},
+	{"ppp_um_tbl_mc_hit_pkt_cnt_h"},
+	{"ppp_mta_tbl_hit_pkt_cnt_l"},
+	{"ppp_mta_tbl_hit_pkt_cnt_h"},
+
+	{"ppp_promisc_tbl_hit_pkt_cnt_l"},
+	{"ppp_promisc_tbl_hit_pkt_cnt_h"},
+	{"ppp_rsv13"},
+	{"ppp_rsv14"},
+	{"ppp_rsv15"},
+	{"ppp_rsv16"},
+};
+
+static struct hns3_dfx_reg_entry dfx_rcb_reg_list[] = {
+	{"rcb_rsv0"},
+	{"rcb_fsm_dfx_st0"},
+	{"rcb_fsm_dfx_st1"},
+	{"rcb_fsm_dfx_st2"},
+	{"rcb_fifo_dfx_st0"},
+	{"rcb_fifo_dfx_st1"},
+
+	{"rcb_fifo_dfx_st2"},
+	{"rcb_fifo_dfx_st3"},
+	{"rcb_fifo_dfx_st4"},
+	{"rcb_fifo_dfx_st5"},
+	{"rcb_fifo_dfx_st6"},
+	{"rcb_fifo_dfx_st7"},
+
+	{"rcb_fifo_dfx_st8"},
+	{"rcb_fifo_dfx_st9"},
+	{"rcb_fifo_dfx_st10"},
+	{"rcb_fifo_dfx_st11"},
+	{"rcb_q_credit_vld_0"},
+	{"rcb_q_credit_vld_1"},
+
+	{"rcb_q_credit_vld_2"},
+	{"rcb_q_credit_vld_3"},
+	{"rcb_q_credit_vld_4"},
+	{"rcb_q_credit_vld_5"},
+	{"rcb_q_credit_vld_6"},
+	{"rcb_q_credit_vld_7"},
+
+	{"rcb_q_credit_vld_8"},
+	{"rcb_q_credit_vld_9"},
+	{"rcb_q_credit_vld_10"},
+	{"rcb_q_credit_vld_11"},
+	{"rcb_q_credit_vld_12"},
+	{"rcb_q_credit_vld_13"},
+
+	{"rcb_q_credit_vld_14"},
+	{"rcb_q_credit_vld_15"},
+	{"rcb_q_credit_vld_16"},
+	{"rcb_q_credit_vld_17"},
+	{"rcb_q_credit_vld_18"},
+	{"rcb_q_credit_vld_19"},
+
+	{"rcb_q_credit_vld_20"},
+	{"rcb_q_credit_vld_21"},
+	{"rcb_q_credit_vld_22"},
+	{"rcb_q_credit_vld_23"},
+	{"rcb_q_credit_vld_24"},
+	{"rcb_q_credit_vld_25"},
+
+	{"rcb_q_credit_vld_26"},
+	{"rcb_q_credit_vld_27"},
+	{"rcb_q_credit_vld_28"},
+	{"rcb_q_credit_vld_29"},
+	{"rcb_q_credit_vld_30"},
+	{"rcb_q_credit_vld_31"},
+
+	{"rcb_gro_bd_serr_cnt"},
+	{"rcb_gro_context_serr_cnt"},
+	{"rcb_rx_stash_cfg_serr_cnt"},
+	{"rcb_axi_rd_fbd_serr_cnt",	"rcb_rcb_tx_mem_serr_cnt"},
+	{"rcb_gro_bd_merr_cnt"},
+	{"rcb_gro_context_merr_cnt"},
+
+	{"rcb_rx_stash_cfg_merr_cnt"},
+	{"rcb_axi_rd_fbd_merr_cnt"},
+	{"rcb_rsv1"},
+	{"rcb_rsv2"},
+	{"rcb_rsv3"},
+	{"rcb_rsv4"},
+};
+
+static struct hns3_dfx_reg_entry dfx_tqp_reg_list[] = {
+	{"dfx_tqp_q_num"},
+	{"rcb_cfg_rx_ring_tail"},
+	{"rcb_cfg_rx_ring_head"},
+	{"rcb_cfg_rx_ring_fbdnum"},
+	{"rcb_cfg_rx_ring_offset"},
+	{"rcb_cfg_rx_ring_fbdoffset"},
+
+	{"rcb_cfg_rx_ring_pktnum_record"},
+	{"rcb_cfg_tx_ring_tail"},
+	{"rcb_cfg_tx_ring_head"},
+	{"rcb_cfg_tx_ring_fbdnum"},
+	{"rcb_cfg_tx_ring_offset"},
+	{"rcb_cfg_tx_ring_ebdnum"},
+};
+
+static struct hns3_dfx_reg_entry dfx_ssu_reg_2_list[] = {
+	{"dfx_ssu2_oq_index"},
+	{"dfx_ssu2_queue_cnt"},
+	{"dfx_ssu2_rsv0"},
+	{"dfx_ssu2_rsv1"},
+	{"dfx_ssu2_rsv2"},
+	{"dfx_ssu2_rsv3"},
+};
+
+enum hns3_reg_modules {
+	HNS3_BIOS_COMMON = 0,
+	HNS3_SSU_0,
+	HNS3_SSU_1,
+	HNS3_IGU_EGU,
+	HNS3_RPU_0,
+	HNS3_RPU_1,
+	HNS3_NCSI,
+	HNS3_RTC,
+	HNS3_PPP,
+	HNS3_RCB,
+	HNS3_TQP,
+	HNS3_SSU_2,
+
+	HNS3_CMDQ = 12,
+	HNS3_COMMON_PF,
+	HNS3_COMMON_VF,
+	HNS3_RING,
+	HNS3_TQP_INTR,
+
+	HNS3_32_BIT_DFX,
+	HNS3_64_BIT_DFX,
+};
+
+struct hns3_reg_list {
+	const void *reg_list;
+	uint32_t entry_num;
+};
+
+static struct hns3_reg_list hns3_reg_lists[] = {
+	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list) },
+	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list) },
+	[HNS3_SSU_1]		= { dfx_ssu_reg_1_list,		RTE_DIM(dfx_ssu_reg_1_list) },
+	[HNS3_IGU_EGU]		= { dfx_igu_egu_reg_list,	RTE_DIM(dfx_igu_egu_reg_list) },
+	[HNS3_RPU_0]		= { dfx_rpu_reg_0_list,		RTE_DIM(dfx_rpu_reg_0_list) },
+	[HNS3_RPU_1]		= { dfx_rpu_reg_1_list,		RTE_DIM(dfx_rpu_reg_1_list) },
+	[HNS3_NCSI]		= { dfx_ncsi_reg_list,		RTE_DIM(dfx_ncsi_reg_list) },
+	[HNS3_RTC]		= { dfx_rtc_reg_list,		RTE_DIM(dfx_rtc_reg_list) },
+	[HNS3_PPP]		= { dfx_ppp_reg_list,		RTE_DIM(dfx_ppp_reg_list) },
+	[HNS3_RCB]		= { dfx_rcb_reg_list,		RTE_DIM(dfx_rcb_reg_list) },
+	[HNS3_TQP]		= { dfx_tqp_reg_list,		RTE_DIM(dfx_tqp_reg_list) },
+	[HNS3_SSU_2]		= { dfx_ssu_reg_2_list,		RTE_DIM(dfx_ssu_reg_2_list) },
+	[HNS3_CMDQ]		= { cmdq_reg_list,		RTE_DIM(cmdq_reg_list) },
+	[HNS3_COMMON_PF]	= { common_reg_list,		RTE_DIM(common_reg_list) },
+	[HNS3_COMMON_VF]	= { common_vf_reg_list,		RTE_DIM(common_vf_reg_list) },
+	[HNS3_RING]		= { ring_reg_list,		RTE_DIM(ring_reg_list) },
+	[HNS3_TQP_INTR]		= { tqp_intr_reg_list,		RTE_DIM(tqp_intr_reg_list) },
+	[HNS3_32_BIT_DFX]	= { regs_32_bit_list,		RTE_DIM(regs_32_bit_list) },
+	[HNS3_64_BIT_DFX]	= { regs_64_bit_list,		RTE_DIM(regs_64_bit_list) },
+};
 
 static const uint32_t hns3_dfx_reg_opcode_list[] = {
-	HNS3_OPC_DFX_BIOS_COMMON_REG,
-	HNS3_OPC_DFX_SSU_REG_0,
-	HNS3_OPC_DFX_SSU_REG_1,
-	HNS3_OPC_DFX_IGU_EGU_REG,
-	HNS3_OPC_DFX_RPU_REG_0,
-	HNS3_OPC_DFX_RPU_REG_1,
-	HNS3_OPC_DFX_NCSI_REG,
-	HNS3_OPC_DFX_RTC_REG,
-	HNS3_OPC_DFX_PPP_REG,
-	HNS3_OPC_DFX_RCB_REG,
-	HNS3_OPC_DFX_TQP_REG,
-	HNS3_OPC_DFX_SSU_REG_2
+	[HNS3_BIOS_COMMON]	=	HNS3_OPC_DFX_BIOS_COMMON_REG,
+	[HNS3_SSU_0]		=	HNS3_OPC_DFX_SSU_REG_0,
+	[HNS3_SSU_1]		=	HNS3_OPC_DFX_SSU_REG_1,
+	[HNS3_IGU_EGU]		=	HNS3_OPC_DFX_IGU_EGU_REG,
+	[HNS3_RPU_0]		=	HNS3_OPC_DFX_RPU_REG_0,
+	[HNS3_RPU_1]		=	HNS3_OPC_DFX_RPU_REG_1,
+	[HNS3_NCSI]		=	HNS3_OPC_DFX_NCSI_REG,
+	[HNS3_RTC]		=	HNS3_OPC_DFX_RTC_REG,
+	[HNS3_PPP]		=	HNS3_OPC_DFX_PPP_REG,
+	[HNS3_RCB]		=	HNS3_OPC_DFX_RCB_REG,
+	[HNS3_TQP]		=	HNS3_OPC_DFX_TQP_REG,
+	[HNS3_SSU_2]		=	HNS3_OPC_DFX_SSU_REG_2
 };
 
 static int
@@ -100,6 +854,11 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 
 	*regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]);
 	*regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]);
+	if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) ||
+	    *regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE != RTE_DIM(regs_64_bit_list)) {
+		hns3_err(hw, "Query register number differ from the list!");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -161,6 +920,7 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t bd_num_list[opcode_num];
+	uint32_t reg_num;
 	int ret;
 	int i;
 
@@ -168,8 +928,14 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < opcode_num; i++)
-		*count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+	for (i = 0; i < opcode_num; i++) {
+		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
+		if (reg_num != hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list!");
+			return -EINVAL;
+		}
+		*count += reg_num;
+	}
 
 	return 0;
 }
@@ -196,14 +962,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	int ret;
 
 	if (hns->is_vf)
-		common_cnt = sizeof(common_vf_reg_addrs);
+		common_cnt = RTE_DIM(common_vf_reg_list);
 	else
-		common_cnt = sizeof(common_reg_addrs);
+		common_cnt = RTE_DIM(common_reg_list);
 
-	len = sizeof(cmdq_reg_addrs) + common_cnt +
-		sizeof(ring_reg_addrs) * hw->tqps_num +
-		sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num;
-	len /= sizeof(uint32_t);
+	len = RTE_DIM(cmdq_reg_list) + common_cnt +
+		RTE_DIM(ring_reg_list) * hw->tqps_num +
+		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
 
 	if (!hns->is_vf) {
 		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
@@ -219,13 +984,31 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
 	return 0;
 }
 
+static void
+hns3_fill_dfx_regs_name(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			const struct hns3_dfx_reg_entry *reg_list, uint32_t reg_num)
+{
+	uint32_t i, cnt = regs->length;
+	const char *name;
+
+	if (regs->names == NULL)
+		return;
+
+	for (i = 0; i < reg_num; i++) {
+		name = reg_list[i].name_v1;
+		if (hw->revision == PCI_REVISION_ID_HIP09_A && reg_list[i].name_v2 != NULL)
+			name = reg_list[i].name_v2;
+		snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, "%s", name);
+	}
+}
+
 static int
-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_32_BIT_REG_RTN_DATANUM 8
 #define HNS3_32_BIT_DESC_NODATA_LEN 2
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint32_t *reg_val = data;
 	uint32_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -254,6 +1037,9 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_32_bit_list, regs_num);
+	reg_val += regs->length;
+	regs->length += regs_num;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = &desc[i].data[0];
@@ -265,7 +1051,6 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_32(*desc_data++);
-
 			regs_num--;
 			if (regs_num == 0)
 				break;
@@ -277,12 +1062,12 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 }
 
 static int
-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
+hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs)
 {
 #define HNS3_64_BIT_REG_RTN_DATANUM 4
 #define HNS3_64_BIT_DESC_NODATA_LEN 1
+	uint32_t *reg_val = regs->data;
 	struct hns3_cmd_desc *desc;
-	uint64_t *reg_val = data;
 	uint64_t *desc_data;
 	int cmd_num;
 	int i, k, n;
@@ -311,6 +1096,9 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		return ret;
 	}
 
+	hns3_fill_dfx_regs_name(hw, regs, regs_64_bit_list, regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE);
+	reg_val += regs->length;
+	regs->length += regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE;
 	for (i = 0; i < cmd_num; i++) {
 		if (i == 0) {
 			desc_data = (uint64_t *)(&desc[i].data[0]);
@@ -322,7 +1110,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 		}
 		for (k = 0; k < n; k++) {
 			*reg_val++ = rte_le_to_cpu_64(*desc_data++);
-
 			regs_num--;
 			if (!regs_num)
 				break;
@@ -333,47 +1120,80 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data)
 	return 0;
 }
 
-static int
-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
+static void
+hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+			     enum hns3_reg_modules idx)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t *origin_data_ptr = data;
-	uint32_t reg_offset;
-	size_t reg_num;
-	uint16_t j;
-	size_t i;
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint32_t *data = regs->data;
+	size_t reg_num, i, cnt;
+
+	data += regs->length;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	cnt = regs->length;
+	for (i = 0; i < reg_num; i++) {
+		*data++ = hns3_read_dev(hw, reg_list[i].addr);
+		if (regs->names != NULL)
+			snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE,
+				 "%s", reg_list[i].name);
+	}
 
-	/* fetching per-PF registers values from PF PCIe register space */
-	reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		*data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]);
+	regs->length += reg_num;
+}
+
+static uint32_t
+hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
+{
+	if (idx == HNS3_RING)
+		return hns3_get_tqp_reg_offset(queue_id);
+	else if (idx == HNS3_TQP_INTR)
+		return hns3_get_tqp_intr_reg_offset(queue_id);
+
+	return 0;
+}
+
+static void
+hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
+				 enum hns3_reg_modules idx)
+{
+	const struct hns3_dirt_reg_entry *reg_list;
+	uint16_t tqp_num, reg_offset;
+	uint32_t *data = regs->data;
+	uint32_t reg_num, i, j;
+
+	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+		return;
+
+	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
+	reg_list = hns3_reg_lists[idx].reg_list;
+	reg_num = hns3_reg_lists[idx].entry_num;
+	data += regs->length;
+	for (i = 0; i < tqp_num; i++) {
+		reg_offset = hns3_get_module_tqp_reg_offset(idx, i);
+		for (j = 0; j < reg_num; j++) {
+			*data++ = hns3_read_dev(hw, reg_list[j].addr + reg_offset);
+			if (regs->names != NULL)
+				snprintf(regs->names[regs->length].name,
+					 RTE_ETH_REG_NAME_SIZE, "Q%u_%s", i, reg_list[j].name);
+			regs->length++;
+		}
+	}
+}
+
+static void
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 
 	if (hns->is_vf)
-		reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t);
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
 	else
-		reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t);
-	for (i = 0; i < reg_num; i++)
-		if (hns->is_vf)
-			*data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]);
-		else
-			*data++ = hns3_read_dev(hw, common_reg_addrs[i]);
-
-	reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->tqps_num; j++) {
-		reg_offset = hns3_get_tqp_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw,
-						ring_reg_addrs[i] + reg_offset);
-	}
+		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
 
-	reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
-	for (j = 0; j < hw->intr_tqps_num; j++) {
-		reg_offset = hns3_get_tqp_intr_reg_offset(j);
-		for (i = 0; i < reg_num; i++)
-			*data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
-						reg_offset);
-	}
-	return data - origin_data_ptr;
+	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
 }
 
 static int
@@ -417,13 +1237,13 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t max_bd_num, bd_num, opcode;
+	uint32_t max_bd_num, bd_num, opcode, regs_num;
 	uint32_t bd_num_list[opcode_num];
 	struct hns3_cmd_desc *cmd_descs;
-	uint32_t *reg_val = (uint32_t *)*data;
+	uint32_t *data = regs->data;
 	int ret;
 	int i;
 
@@ -447,42 +1267,47 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data)
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
 		if (ret)
 			break;
-		reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val);
+
+		data += regs->length;
+		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
+		regs->length += regs_num;
 	}
 	rte_free(cmd_descs);
-	*data = (void *)reg_val;
 
 	return ret;
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data)
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
+	if (hns->is_vf)
+		return 0;
+
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
 	if (ret) {
 		hns3_err(hw, "Get register number failed, ret = %d", ret);
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data);
+	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_32_bit;
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data);
+	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
 	if (ret) {
 		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
 		return ret;
 	}
-	data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
 
-	return hns3_get_dfx_regs(hw, (void **)&data);
+	return hns3_get_dfx_regs(hw, regs);
 }
 
 int
@@ -491,15 +1316,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
 	uint32_t length;
-	uint32_t *data;
 	int ret;
 
 	ret = hns3_get_regs_length(hw, &length);
 	if (ret)
 		return ret;
 
-	data = regs->data;
-	if (data == NULL) {
+	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
 		return 0;
@@ -510,13 +1333,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 		return -ENOTSUP;
 
 	regs->version = hw->fw_version;
+	/* to count the number of filled registers */
+	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	data += hns3_direct_access_regs(hw, data);
-
-	if (hns->is_vf)
-		return 0;
+	hns3_direct_access_regs(hw, regs);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, data);
+	return  hns3_get_regs_from_firmware(hw, regs);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* [PATCH v9 8/8] net/hns3: support filter registers by module names
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
                     ` (6 preceding siblings ...)
  2024-09-26 12:42   ` [PATCH v9 7/8] net/hns3: support report names of registers Jie Hai
@ 2024-09-26 12:42   ` Jie Hai
  2024-09-27  1:37     ` fengchengwen
  2024-10-04 13:59     ` David Marchand
  2024-09-27 21:38   ` [PATCH v9 0/8] support dump reigster names and filter Ferruh Yigit
  8 siblings, 2 replies; 134+ messages in thread
From: Jie Hai @ 2024-09-26 12:42 UTC (permalink / raw)
  To: dev, thomas, ferruh.yigit, andrew.rybchenko
  Cc: lihuisong, fengchengwen, haijie1

This patch support dumping registers which module name is the
`filter` string. The module names are in lower case and so is
the `filter`. Available module names are cmdq, common_pf,
common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
ssu, ppp, rpu, ncsi, rtc, rcb, etc.

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/nics/hns3.rst     |   7 +
 drivers/net/hns3/hns3_regs.c | 257 ++++++++++++++++++++---------------
 2 files changed, 157 insertions(+), 107 deletions(-)

diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 97b4686bfabe..9a2e33ce6954 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -407,6 +407,13 @@ be provided to avoid scheduling the CPU core used by DPDK application threads fo
 other tasks. Before starting the Linux OS, add the kernel isolation boot parameter.
 For example, "isolcpus=1-18 nohz_full=1-18 rcu_nocbs=1-18".
 
+Dump registers
+--------------
+HNS3 supports dumping registers values with their names, and supports filtering
+by module names. The available module names are ``bios``, ``ssu``, ``igu_egu``,
+``rpu``, ``ncsi``, ``rtc``, ``ppp``, ``rcb``, ``tqp``, ``rtc``, ``cmdq``,
+``common_pf``, ``common_vf``, ``ring``, ``tqp_intr``, ``32_bit_dfx``,
+``64_bit_dfx``.
 
 Limitations or Known issues
 ---------------------------
diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
index a0d130302839..2e19add21265 100644
--- a/drivers/net/hns3/hns3_regs.c
+++ b/drivers/net/hns3/hns3_regs.c
@@ -12,7 +12,7 @@
 
 #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t))
 
-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count);
+#define HNS3_MAX_MODULES_LEN 512
 
 struct hns3_dirt_reg_entry {
 	const char *name;
@@ -795,11 +795,39 @@ enum hns3_reg_modules {
 	HNS3_64_BIT_DFX,
 };
 
+#define HNS3_MODULE_MASK(x) RTE_BIT32(x)
+#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \
+			 HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR))
+#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF)
+
 struct hns3_reg_list {
 	const void *reg_list;
 	uint32_t entry_num;
 };
 
+struct {
+	const char *name;
+	uint32_t module;
+} hns3_module_name_map[] = {
+	{ "bios",	HNS3_MODULE_MASK(HNS3_BIOS_COMMON) },
+	{ "ssu",	HNS3_MODULE_MASK(HNS3_SSU_0) | HNS3_MODULE_MASK(HNS3_SSU_1) |
+			HNS3_MODULE_MASK(HNS3_SSU_2) },
+	{ "igu_egu",	HNS3_MODULE_MASK(HNS3_IGU_EGU) },
+	{ "rpu",	HNS3_MODULE_MASK(HNS3_RPU_0) | HNS3_MODULE_MASK(HNS3_RPU_1) },
+	{ "ncsi",	HNS3_MODULE_MASK(HNS3_NCSI) },
+	{ "rtc",	HNS3_MODULE_MASK(HNS3_RTC) },
+	{ "ppp",	HNS3_MODULE_MASK(HNS3_PPP) },
+	{ "rcb",	HNS3_MODULE_MASK(HNS3_RCB) },
+	{ "tqp",	HNS3_MODULE_MASK(HNS3_TQP) },
+	{ "cmdq",	HNS3_MODULE_MASK(HNS3_CMDQ) },
+	{ "common_pf",	HNS3_MODULE_MASK(HNS3_COMMON_PF) },
+	{ "common_vf",	HNS3_MODULE_MASK(HNS3_COMMON_VF) },
+	{ "ring",	HNS3_MODULE_MASK(HNS3_RING) },
+	{ "tqp_intr",	HNS3_MODULE_MASK(HNS3_TQP_INTR) },
+	{ "32_bit_dfx",	HNS3_MODULE_MASK(HNS3_32_BIT_DFX) },
+	{ "64_bit_dfx",	HNS3_MODULE_MASK(HNS3_64_BIT_DFX) },
+};
+
 static struct hns3_reg_list hns3_reg_lists[] = {
 	[HNS3_BIOS_COMMON]	= { dfx_bios_common_reg_list,	RTE_DIM(dfx_bios_common_reg_list) },
 	[HNS3_SSU_0]		= { dfx_ssu_reg_0_list,		RTE_DIM(dfx_ssu_reg_0_list) },
@@ -863,21 +891,58 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
 	return 0;
 }
 
-static int
-hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
+static const char *
+hns3_get_name_by_module(enum hns3_reg_modules module)
 {
-	uint32_t regs_num_32_bit, regs_num_64_bit;
-	int ret;
+	size_t i;
 
-	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
-	if (ret) {
-		hns3_err(hw, "fail to get the number of registers, "
-			 "ret = %d.", ret);
-		return ret;
+	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
+		if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0)
+			return hns3_module_name_map[i].name;
 	}
+	return "unknown";
+}
 
-	*count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
-	return 0;
+static void
+hns3_get_module_names(char *names, uint32_t len)
+{
+	size_t i;
+
+	for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
+		strlcat(names, " ", len);
+		strlcat(names, hns3_module_name_map[i].name, len);
+	}
+}
+
+static uint32_t
+hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	char names[HNS3_MAX_MODULES_LEN] = {0};
+	uint32_t modules = 0;
+	size_t i;
+
+	if (filter == NULL) {
+		modules = (1 << RTE_DIM(hns3_reg_lists)) - 1;
+	} else {
+		for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
+			if (strcmp(filter, hns3_module_name_map[i].name) == 0) {
+				modules |= hns3_module_name_map[i].module;
+				break;
+			}
+		}
+	}
+
+	if (hns->is_vf)
+		modules &= HNS3_VF_MODULES;
+	else
+		modules &= ~HNS3_VF_ONLY_MODULES;
+	if (modules == 0) {
+		hns3_get_module_names(names, HNS3_MAX_MODULES_LEN);
+		hns3_err(hw, "mismatched module name! Available names are:\n%s.",
+			 names);
+	}
+	return modules;
 }
 
 static int
@@ -915,73 +980,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list,
 	return 0;
 }
 
-static int
-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
-	uint32_t bd_num_list[opcode_num];
-	uint32_t reg_num;
-	int ret;
-	int i;
-
-	ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < opcode_num; i++) {
-		reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM;
-		if (reg_num != hns3_reg_lists[i].entry_num) {
-			hns3_err(hw, "Query register number differ from the list!");
-			return -EINVAL;
-		}
-		*count += reg_num;
-	}
-
-	return 0;
-}
-
-static int
-hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count)
-{
-	int ret;
-
-	ret = hns3_get_32_64_regs_cnt(hw, count);
-	if (ret < 0)
-		return ret;
-
-	return hns3_get_dfx_reg_cnt(hw, count);
-}
-
-static int
-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length)
+static uint32_t
+hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-	uint32_t dfx_reg_cnt = 0;
-	uint32_t common_cnt;
-	uint32_t len;
-	int ret;
-
-	if (hns->is_vf)
-		common_cnt = RTE_DIM(common_vf_reg_list);
-	else
-		common_cnt = RTE_DIM(common_reg_list);
+	uint32_t reg_num = 0, length = 0;
+	uint32_t i;
 
-	len = RTE_DIM(cmdq_reg_list) + common_cnt +
-		RTE_DIM(ring_reg_list) * hw->tqps_num +
-		RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num;
+	for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) {
+		if ((RTE_BIT32(i) & modules) == 0)
+			continue;
+		reg_num = hns3_reg_lists[i].entry_num;
+		if (i == HNS3_RING)
+			reg_num *= hw->tqps_num;
+		else if (i == HNS3_TQP_INTR)
+			reg_num *= hw->intr_tqps_num;
 
-	if (!hns->is_vf) {
-		ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt);
-		if (ret) {
-			hns3_err(hw, "fail to get the number of dfx registers, "
-				 "ret = %d.", ret);
-			return ret;
-		}
-		len += dfx_reg_cnt;
+		length += reg_num;
 	}
 
-	*length = len;
-	return 0;
+	return length;
 }
 
 static void
@@ -1122,12 +1139,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i
 
 static void
 hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-			     enum hns3_reg_modules idx)
+			     uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint32_t *data = regs->data;
 	size_t reg_num, i, cnt;
 
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
+		return;
+
 	data += regs->length;
 	reg_num = hns3_reg_lists[idx].entry_num;
 	reg_list = hns3_reg_lists[idx].reg_list;
@@ -1155,14 +1175,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id)
 
 static void
 hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs,
-				 enum hns3_reg_modules idx)
+				 uint32_t modules, enum hns3_reg_modules idx)
 {
 	const struct hns3_dirt_reg_entry *reg_list;
 	uint16_t tqp_num, reg_offset;
 	uint32_t *data = regs->data;
 	uint32_t reg_num, i, j;
 
-	if (idx != HNS3_RING && idx != HNS3_TQP_INTR)
+	if ((modules & HNS3_MODULE_MASK(idx)) == 0)
 		return;
 
 	tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num;
@@ -1182,18 +1202,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re
 }
 
 static void
-hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-
-	if (hns->is_vf)
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF);
-	else
-		hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF);
-
-	hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING);
-	hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF);
+	hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING);
+	hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR);
 }
 
 static int
@@ -1237,7 +1252,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg)
 }
 
 static int
-hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
 	int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list);
 	uint32_t max_bd_num, bd_num, opcode, regs_num;
@@ -1262,6 +1277,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 	for (i = 0; i < opcode_num; i++) {
 		opcode = hns3_dfx_reg_opcode_list[i];
 		bd_num = bd_num_list[i];
+		if ((modules & HNS3_MODULE_MASK(i)) == 0)
+			continue;
 		if (bd_num == 0)
 			continue;
 		ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode);
@@ -1270,6 +1287,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 
 		data += regs->length;
 		regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data);
+		if (regs_num !=  hns3_reg_lists[i].entry_num) {
+			hns3_err(hw, "Query register number differ from the list for module %s!",
+				 hns3_get_name_by_module(i));
+			return -EINVAL;
+		}
 		hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num);
 		regs->length += regs_num;
 	}
@@ -1279,14 +1301,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 }
 
 static int
-hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
+hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
 {
-	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t regs_num_32_bit;
 	uint32_t regs_num_64_bit;
 	int ret;
 
-	if (hns->is_vf)
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 &&
+	    (modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) == 0)
 		return 0;
 
 	ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
@@ -1295,19 +1317,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs)
 		return ret;
 	}
 
-	ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) {
+		ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 32 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
-	if (ret) {
-		hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
-		return ret;
+	if ((modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) != 0) {
+		ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs);
+		if (ret) {
+			hns3_err(hw, "Get 64 bit register failed, ret = %d", ret);
+			return ret;
+		}
 	}
 
-	return hns3_get_dfx_regs(hw, regs);
+	return 0;
+}
+
+static int
+hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	int ret;
+
+	if (hns->is_vf)
+		return 0;
+
+	ret = hns3_get_32_b4_bit_regs(hw, regs, modules);
+	if (ret != 0)
+		return ret;
+
+	return hns3_get_dfx_regs(hw, regs, modules);
 }
 
 int
@@ -1315,13 +1357,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 {
 	struct hns3_adapter *hns = eth_dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
+	uint32_t modules;
 	uint32_t length;
-	int ret;
 
-	ret = hns3_get_regs_length(hw, &length);
-	if (ret)
-		return ret;
+	modules = hns3_parse_modules_by_filter(hw, regs->filter);
+	if (modules == 0)
+		return -EINVAL;
 
+	length = hns3_get_regs_length(hw, modules);
 	if (regs->data == NULL) {
 		regs->length = length;
 		regs->width = sizeof(uint32_t);
@@ -1337,8 +1380,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 	regs->length = 0;
 
 	/* fetching per-PF registers values from PF PCIe register space */
-	hns3_direct_access_regs(hw, regs);
+	hns3_direct_access_regs(hw, regs, modules);
 
 	/* fetching PF common registers values from firmware */
-	return  hns3_get_regs_from_firmware(hw, regs);
+	return  hns3_get_regs_from_firmware(hw, regs, modules);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v9 8/8] net/hns3: support filter registers by module names
  2024-09-26 12:42   ` [PATCH v9 8/8] net/hns3: support filter registers by module names Jie Hai
@ 2024-09-27  1:37     ` fengchengwen
  2024-10-04 13:59     ` David Marchand
  1 sibling, 0 replies; 134+ messages in thread
From: fengchengwen @ 2024-09-27  1:37 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, ferruh.yigit, andrew.rybchenko; +Cc: lihuisong

Acked-by: Chengwen Feng <fengchengwen@huawei.com>

On 2024/9/26 20:42, Jie Hai wrote:
> This patch support dumping registers which module name is the
> `filter` string. The module names are in lower case and so is
> the `filter`. Available module names are cmdq, common_pf,
> common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu,
> ssu, ppp, rpu, ncsi, rtc, rcb, etc.
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v9 0/8] support dump reigster names and filter
  2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
                     ` (7 preceding siblings ...)
  2024-09-26 12:42   ` [PATCH v9 8/8] net/hns3: support filter registers by module names Jie Hai
@ 2024-09-27 21:38   ` Ferruh Yigit
  8 siblings, 0 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-09-27 21:38 UTC (permalink / raw)
  To: Jie Hai, dev, thomas, andrew.rybchenko; +Cc: lihuisong, fengchengwen

On 9/26/2024 1:42 PM, Jie Hai wrote:
> The registers can be dumped through the API rte_eth_dev_get_reg_info.
> However, only register values are exported, which is inconvenient for
> users to interpret. Therefore, an extension of the structure
> "rte_dev_reg_info" and a new API rte_eth_dev_get_reg_info_ext is added
> to support the capability of exporting the name of the corresponding
> register and filtering by module names.
> 
> --
> v9:
> 1. add Acked-by.
> 2. fix typo and inaccurate expression of hns3.rst.
> 
> v8:
> 1. fix typo on patch[0/8].
> 2. add Reviewed-bys and Acked-bys.
> 3. fix potentital memory leak and error information on telemetry.
> 4. fix on reviews about hns3 driver.
> 
> v7: fix doc indention.
> --
> 
> Jie Hai (8):
>   ethdev: support report register names and filter
>   ethdev: add telemetry cmd for registers
>   net/hns3: remove some basic address dump
>   net/hns3: fix dump counter of registers
>   net/hns3: remove separators between register module
>   net/hns3: refactor register dump
>   net/hns3: support report names of registers
>   net/hns3: support filter registers by module names
>

Series applied to dpdk-next-net/main, thanks.

^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v9 8/8] net/hns3: support filter registers by module names
  2024-09-26 12:42   ` [PATCH v9 8/8] net/hns3: support filter registers by module names Jie Hai
  2024-09-27  1:37     ` fengchengwen
@ 2024-10-04 13:59     ` David Marchand
  2024-10-07  3:01       ` Ferruh Yigit
  1 sibling, 1 reply; 134+ messages in thread
From: David Marchand @ 2024-10-04 13:59 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, thomas, ferruh.yigit, andrew.rybchenko, lihuisong, fengchengwen

On Thu, Sep 26, 2024 at 2:44 PM Jie Hai <haijie1@huawei.com> wrote:
> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
> index a0d130302839..2e19add21265 100644
> --- a/drivers/net/hns3/hns3_regs.c
> +++ b/drivers/net/hns3/hns3_regs.c

[snip]

> @@ -863,21 +891,58 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>         return 0;
>  }
>
> -static int
> -hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
> +static const char *
> +hns3_get_name_by_module(enum hns3_reg_modules module)
>  {
> -       uint32_t regs_num_32_bit, regs_num_64_bit;
> -       int ret;
> +       size_t i;
>
> -       ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
> -       if (ret) {
> -               hns3_err(hw, "fail to get the number of registers, "
> -                        "ret = %d.", ret);
> -               return ret;
> +       for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
> +               if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0)
> +                       return hns3_module_name_map[i].name;
>         }
> +       return "unknown";
> +}
>
> -       *count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
> -       return 0;
> +static void
> +hns3_get_module_names(char *names, uint32_t len)
> +{
> +       size_t i;
> +
> +       for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
> +               strlcat(names, " ", len);
> +               strlcat(names, hns3_module_name_map[i].name, len);
> +       }
> +}
> +
> +static uint32_t
> +hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter)
> +{
> +       struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
> +       char names[HNS3_MAX_MODULES_LEN] = {0};
> +       uint32_t modules = 0;
> +       size_t i;
> +
> +       if (filter == NULL) {
> +               modules = (1 << RTE_DIM(hns3_reg_lists)) - 1;
> +       } else {
> +               for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
> +                       if (strcmp(filter, hns3_module_name_map[i].name) == 0) {
> +                               modules |= hns3_module_name_map[i].module;
> +                               break;
> +                       }
> +               }
> +       }
> +
> +       if (hns->is_vf)
> +               modules &= HNS3_VF_MODULES;
> +       else
> +               modules &= ~HNS3_VF_ONLY_MODULES;
> +       if (modules == 0) {
> +               hns3_get_module_names(names, HNS3_MAX_MODULES_LEN);
> +               hns3_err(hw, "mismatched module name! Available names are:\n%s.",
> +                        names);

No need for \n.
Please send a fix against next-net.


> +       }
> +       return modules;
>  }
>
>  static int


-- 
David Marchand


^ permalink raw reply	[flat|nested] 134+ messages in thread

* Re: [PATCH v9 8/8] net/hns3: support filter registers by module names
  2024-10-04 13:59     ` David Marchand
@ 2024-10-07  3:01       ` Ferruh Yigit
  0 siblings, 0 replies; 134+ messages in thread
From: Ferruh Yigit @ 2024-10-07  3:01 UTC (permalink / raw)
  To: David Marchand, Jie Hai
  Cc: dev, thomas, andrew.rybchenko, lihuisong, fengchengwen

On 10/4/2024 2:59 PM, David Marchand wrote:
> On Thu, Sep 26, 2024 at 2:44 PM Jie Hai <haijie1@huawei.com> wrote:
>> diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c
>> index a0d130302839..2e19add21265 100644
>> --- a/drivers/net/hns3/hns3_regs.c
>> +++ b/drivers/net/hns3/hns3_regs.c
> 
> [snip]
> 
>> @@ -863,21 +891,58 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit,
>>         return 0;
>>  }
>>
>> -static int
>> -hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count)
>> +static const char *
>> +hns3_get_name_by_module(enum hns3_reg_modules module)
>>  {
>> -       uint32_t regs_num_32_bit, regs_num_64_bit;
>> -       int ret;
>> +       size_t i;
>>
>> -       ret = hns3_get_regs_num(hw, &regs_num_32_bit, &regs_num_64_bit);
>> -       if (ret) {
>> -               hns3_err(hw, "fail to get the number of registers, "
>> -                        "ret = %d.", ret);
>> -               return ret;
>> +       for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
>> +               if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0)
>> +                       return hns3_module_name_map[i].name;
>>         }
>> +       return "unknown";
>> +}
>>
>> -       *count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE;
>> -       return 0;
>> +static void
>> +hns3_get_module_names(char *names, uint32_t len)
>> +{
>> +       size_t i;
>> +
>> +       for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
>> +               strlcat(names, " ", len);
>> +               strlcat(names, hns3_module_name_map[i].name, len);
>> +       }
>> +}
>> +
>> +static uint32_t
>> +hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter)
>> +{
>> +       struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
>> +       char names[HNS3_MAX_MODULES_LEN] = {0};
>> +       uint32_t modules = 0;
>> +       size_t i;
>> +
>> +       if (filter == NULL) {
>> +               modules = (1 << RTE_DIM(hns3_reg_lists)) - 1;
>> +       } else {
>> +               for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) {
>> +                       if (strcmp(filter, hns3_module_name_map[i].name) == 0) {
>> +                               modules |= hns3_module_name_map[i].module;
>> +                               break;
>> +                       }
>> +               }
>> +       }
>> +
>> +       if (hns->is_vf)
>> +               modules &= HNS3_VF_MODULES;
>> +       else
>> +               modules &= ~HNS3_VF_ONLY_MODULES;
>> +       if (modules == 0) {
>> +               hns3_get_module_names(names, HNS3_MAX_MODULES_LEN);
>> +               hns3_err(hw, "mismatched module name! Available names are:\n%s.",
>> +                        names);
> 
> No need for \n.
> Please send a fix against next-net.
> 

Fixed while rebasing next-net to main.


^ permalink raw reply	[flat|nested] 134+ messages in thread

end of thread, other threads:[~2024-10-07  3:01 UTC | newest]

Thread overview: 134+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-14  1:56 [PATCH] ethdev: add dump regs for telemetry Jie Hai
2023-12-14 12:49 ` Ferruh Yigit
2024-01-09  2:19   ` Jie Hai
2024-01-09  2:41     ` Jie Hai
2024-01-09 18:06     ` Ferruh Yigit
2024-01-10  1:38       ` fengchengwen
2024-01-10 12:15         ` Ferruh Yigit
2024-01-10 14:09           ` Thomas Monjalon
2024-01-10 15:48             ` Ferruh Yigit
2024-01-11  1:55           ` fengchengwen
2024-01-11 11:11             ` Ferruh Yigit
2024-01-11 12:43               ` fengchengwen
2024-02-05 10:51 ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
2024-02-05 10:51   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
2024-02-07 17:00     ` Ferruh Yigit
2024-02-20  8:43       ` Jie Hai
2024-02-05 10:51   ` [PATCH v2 2/7] ethdev: add telemetry cmd for registers Jie Hai
2024-02-07 17:03     ` Ferruh Yigit
2024-02-22  9:01       ` Jie Hai
2024-02-05 10:51   ` [PATCH v2 3/7] net/hns3: fix dump counter of registers Jie Hai
2024-02-05 10:51   ` [PATCH v2 4/7] net/hns3: remove dump format " Jie Hai
2024-02-05 10:51   ` [PATCH v2 5/7] net/hns3: add names for registers Jie Hai
2024-02-05 10:51   ` [PATCH v2 6/7] net/hns3: support filter directly accessed registers Jie Hai
2024-02-05 10:51   ` [PATCH v2 7/7] net/hns3: support filter dump of registers Jie Hai
2024-02-20 10:58 ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
2024-02-20 10:58   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
2024-02-20 15:09     ` Stephen Hemminger
2024-02-26  2:33       ` Jie Hai
2024-02-20 15:13     ` Stephen Hemminger
2024-02-26  2:41       ` Jie Hai
2024-02-20 15:14     ` Stephen Hemminger
2024-02-26  2:57       ` Jie Hai
2024-02-20 15:14     ` Stephen Hemminger
2024-02-26  2:33       ` Jie Hai
2024-02-20 10:58   ` [PATCH v3 2/7] ethdev: add telemetry cmd for registers Jie Hai
2024-02-20 10:58   ` [PATCH v3 3/7] net/hns3: fix dump counter of registers Jie Hai
2024-02-20 10:58   ` [PATCH v3 4/7] net/hns3: remove dump format " Jie Hai
2024-02-20 10:58   ` [PATCH v3 5/7] net/hns3: add names for registers Jie Hai
2024-02-20 10:58   ` [PATCH v3 6/7] net/hns3: support filter directly accessed registers Jie Hai
2024-02-20 10:58   ` [PATCH v3 7/7] net/hns3: support filter dump of registers Jie Hai
2024-02-26  3:07 ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
2024-02-26  3:07   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
2024-02-26  8:01     ` fengchengwen
2024-03-06  7:22       ` Jie Hai
2024-02-29  9:52     ` Thomas Monjalon
2024-03-05  7:45       ` Jie Hai
2024-02-26  3:07   ` [PATCH v4 2/7] ethdev: add telemetry cmd for registers Jie Hai
2024-02-26  9:09     ` fengchengwen
2024-03-06  7:18       ` Jie Hai
2024-02-26  3:07   ` [PATCH v4 3/7] net/hns3: fix dump counter of registers Jie Hai
2024-02-26  3:07   ` [PATCH v4 4/7] net/hns3: remove dump format " Jie Hai
2024-02-26  3:07   ` [PATCH v4 5/7] net/hns3: add names for registers Jie Hai
2024-02-26  3:07   ` [PATCH v4 6/7] net/hns3: support filter directly accessed registers Jie Hai
2024-02-26  3:07   ` [PATCH v4 7/7] net/hns3: support filter dump of registers Jie Hai
2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
2024-03-07  3:02   ` [PATCH v5 1/7] ethdev: support report register names and filter Jie Hai
2024-03-08  8:09     ` lihuisong (C)
2024-03-07  3:02   ` [PATCH v5 2/7] ethdev: add telemetry cmd for registers Jie Hai
2024-03-08  8:48     ` lihuisong (C)
2024-03-07  3:02   ` [PATCH v5 3/7] net/hns3: fix dump counter of registers Jie Hai
2024-03-08  8:49     ` lihuisong (C)
2024-03-07  3:02   ` [PATCH v5 4/7] net/hns3: remove dump format " Jie Hai
2024-03-08  9:17     ` lihuisong (C)
2024-03-07  3:02   ` [PATCH v5 5/7] net/hns3: add names for registers Jie Hai
2024-03-08  9:41     ` lihuisong (C)
2024-03-08 10:24     ` lihuisong (C)
2024-03-07  3:02   ` [PATCH v5 6/7] net/hns3: support filter directly accessed registers Jie Hai
2024-03-08  9:41     ` lihuisong (C)
2024-03-07  3:02   ` [PATCH v5 7/7] net/hns3: support filter dump of registers Jie Hai
2024-07-22  6:58 ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
2024-07-22  6:58   ` [PATCH v6 1/8] ethdev: support report register " Jie Hai
2024-07-22  6:58   ` [PATCH v6 2/8] ethdev: add telemetry cmd for registers Jie Hai
2024-07-22  6:58   ` [PATCH v6 3/8] net/hns3: remove some basic address dump Jie Hai
2024-07-22  6:58   ` [PATCH v6 4/8] net/hns3: fix dump counter of registers Jie Hai
2024-07-22  6:58   ` [PATCH v6 5/8] net/hns3: remove separators between register module Jie Hai
2024-07-22  6:58   ` [PATCH v6 6/8] net/hns3: refactor register dump Jie Hai
2024-07-22  6:58   ` [PATCH v6 7/8] net/hns3: support report names of registers Jie Hai
2024-07-22  6:58   ` [PATCH v6 8/8] net/hns3: support filter registers by module names Jie Hai
2024-08-09  9:22   ` [PATCH v6 0/8] support dump reigser names and filter Jie Hai
2024-09-05  6:26 ` [RESEND " Jie Hai
2024-09-05  6:26   ` [RESEND v6 1/8] ethdev: support report register " Jie Hai
2024-09-05  6:26   ` [RESEND v6 2/8] ethdev: add telemetry cmd for registers Jie Hai
2024-09-05  6:26   ` [RESEND v6 3/8] net/hns3: remove some basic address dump Jie Hai
2024-09-05  6:26   ` [RESEND v6 4/8] net/hns3: fix dump counter of registers Jie Hai
2024-09-05  6:26   ` [RESEND v6 5/8] net/hns3: remove separators between register module Jie Hai
2024-09-05  6:26   ` [RESEND v6 6/8] net/hns3: refactor register dump Jie Hai
2024-09-05  6:26   ` [RESEND v6 7/8] net/hns3: support report names of registers Jie Hai
2024-09-05  6:26   ` [RESEND v6 8/8] net/hns3: support filter registers by module names Jie Hai
2024-09-14  6:53 ` [PATCH v7 0/8] support dump reigser names and filter Jie Hai
2024-09-14  7:13 ` Jie Hai
2024-09-14  7:13   ` [PATCH v7 1/8] ethdev: support report register " Jie Hai
2024-09-22 21:26     ` Ferruh Yigit
2024-09-14  7:13   ` [PATCH v7 2/8] ethdev: add telemetry cmd for registers Jie Hai
2024-09-14  8:20     ` fengchengwen
2024-09-23  2:41       ` Jie Hai
2024-09-22 21:28     ` Ferruh Yigit
2024-09-14  7:13   ` [PATCH v7 3/8] net/hns3: remove some basic address dump Jie Hai
2024-09-14  8:21     ` fengchengwen
2024-09-14  7:13   ` [PATCH v7 4/8] net/hns3: fix dump counter of registers Jie Hai
2024-09-14  7:13   ` [PATCH v7 5/8] net/hns3: remove separators between register module Jie Hai
2024-09-14  7:13   ` [PATCH v7 6/8] net/hns3: refactor register dump Jie Hai
2024-09-14  8:26     ` fengchengwen
2024-09-14  7:13   ` [PATCH v7 7/8] net/hns3: support report names of registers Jie Hai
2024-09-14  8:27     ` fengchengwen
2024-09-14  7:13   ` [PATCH v7 8/8] net/hns3: support filter registers by module names Jie Hai
2024-09-14  8:46     ` fengchengwen
2024-09-14 15:00   ` [PATCH v7 0/8] support dump reigser names and filter Stephen Hemminger
2024-09-23  2:41     ` Jie Hai
2024-09-22 21:31   ` Ferruh Yigit
2024-09-25  6:40 ` [PATCH v8 0/8] support dump register " Jie Hai
2024-09-25  6:40   ` [PATCH v8 1/8] ethdev: support report " Jie Hai
2024-09-25  6:40   ` [PATCH v8 2/8] ethdev: add telemetry cmd for registers Jie Hai
2024-09-26  1:22     ` fengchengwen
2024-09-25  6:40   ` [PATCH v8 3/8] net/hns3: remove some basic address dump Jie Hai
2024-09-25  6:40   ` [PATCH v8 4/8] net/hns3: fix dump counter of registers Jie Hai
2024-09-25  6:40   ` [PATCH v8 5/8] net/hns3: remove separators between register module Jie Hai
2024-09-25  6:40   ` [PATCH v8 6/8] net/hns3: refactor register dump Jie Hai
2024-09-25  6:40   ` [PATCH v8 7/8] net/hns3: support report names of registers Jie Hai
2024-09-25  6:40   ` [PATCH v8 8/8] net/hns3: support filter registers by module names Jie Hai
2024-09-26  1:46     ` fengchengwen
2024-09-26 12:37       ` Jie Hai
2024-09-26 12:42 ` [PATCH v9 0/8] support dump reigster names and filter Jie Hai
2024-09-26 12:42   ` [PATCH v9 1/8] ethdev: support report register " Jie Hai
2024-09-26 12:42   ` [PATCH v9 2/8] ethdev: add telemetry cmd for registers Jie Hai
2024-09-26 12:42   ` [PATCH v9 3/8] net/hns3: remove some basic address dump Jie Hai
2024-09-26 12:42   ` [PATCH v9 4/8] net/hns3: fix dump counter of registers Jie Hai
2024-09-26 12:42   ` [PATCH v9 5/8] net/hns3: remove separators between register module Jie Hai
2024-09-26 12:42   ` [PATCH v9 6/8] net/hns3: refactor register dump Jie Hai
2024-09-26 12:42   ` [PATCH v9 7/8] net/hns3: support report names of registers Jie Hai
2024-09-26 12:42   ` [PATCH v9 8/8] net/hns3: support filter registers by module names Jie Hai
2024-09-27  1:37     ` fengchengwen
2024-10-04 13:59     ` David Marchand
2024-10-07  3:01       ` Ferruh Yigit
2024-09-27 21:38   ` [PATCH v9 0/8] support dump reigster names and filter Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).