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
                   ` (4 more replies)
  0 siblings, 5 replies; 69+ 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] 69+ 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
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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
                   ` (2 subsequent siblings)
  4 siblings, 7 replies; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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
  2024-03-07  3:02 ` [PATCH v5 0/7] support dump reigser names and filter them Jie Hai
  4 siblings, 7 replies; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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
  4 siblings, 7 replies; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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)
  4 siblings, 7 replies; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ 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; 69+ 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] 69+ messages in thread

end of thread, other threads:[~2024-03-08 10:24 UTC | newest]

Thread overview: 69+ 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

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).