From e782454207ceb4189feb6a4d8652a38f899c377c Mon Sep 17 00:00:00 2001 From: Dengdui Huang Date: Mon, 11 Nov 2024 18:33:26 +0800 Subject: [PATCH] sync some patchs from upstreaming Sync some patchs from upstreaming, includind some bugfixes, hns3 pmd flow rule priority feature, hns3 pmd outer VLAN flow match feature, and support dump reigser names and filter. This patch set is modified as follows: - net/hns3: fix cannot fully use hardware flow director table - net/hns3: fix error code for repeatedly create counter - net/hns3: support flow rule priority - common/nfp: use new kvargs process API - net/tap: use new kvargs process API - net/sfc: use new kvargs process API - kvargs: rework process API - net/hns3: fix variable type - net/hns3: fix pointer offset - net/hns3: fix error log - net/hns3: support filtering registers by module names - net/hns3: support reporting names of registers - net/hns3: refactor register dump - net/hns3: remove separators between register module - net/hns3: fix dump counter of registers - net/hns3: remove some basic address dump - telemetry: register command with private argument - ethdev: fix race on ports in telemetry endpoints - ethdev: add telemetry command for registers - ethdev: add report of register names and filter - net/hns3: support outer VLAN flow match - net/hns3: register VLAN flow match mode parameter - net/hns3: support general tunnel flow match - net/hns3: restrict tunnel flow rule to one header - net/hns3: remove ROH devices - net/hns3: dump queue head and tail pointer info - dmadev: fix potential null pointer access - net/hns3: verify reset type from firmware - ethdev: verify queue ID in Tx done cleanup Signed-off-by: Dengdui Huang (cherry picked from commit a1c828e1eb9cf716187d2a7656023e95bdce9b55) --- ...v-verify-queue-ID-in-Tx-done-cleanup.patch | 38 + ...hns3-verify-reset-type-from-firmware.patch | 38 + ...ev-fix-potential-null-pointer-access.patch | 35 + ...ump-queue-head-and-tail-pointer-info.patch | 104 ++ 0051-net-hns3-remove-ROH-devices.patch | 66 + ...trict-tunnel-flow-rule-to-one-header.patch | 39 + ...s3-support-general-tunnel-flow-match.patch | 155 ++ ...ister-VLAN-flow-match-mode-parameter.patch | 63 + ...t-hns3-support-outer-VLAN-flow-match.patch | 497 +++++++ ...gister-command-with-private-argument.patch | 208 +++ ...race-on-ports-in-telemetry-endpoints.patch | 130 ++ ...-report-of-register-names-and-filter.patch | 191 +++ ...-add-telemetry-command-for-registers.patch | 193 +++ ...-hns3-remove-some-basic-address-dump.patch | 61 + ...t-hns3-fix-dump-counter-of-registers.patch | 37 + ...e-separators-between-register-module.patch | 205 +++ 0063-net-hns3-refactor-register-dump.patch | 275 ++++ ...support-reporting-names-of-registers.patch | 1283 +++++++++++++++++ ...-filtering-registers-by-module-names.patch | 440 ++++++ 0066-net-hns3-fix-error-log.patch | 34 + ...ns3-fix-pointer-offset-for-registers.patch | 53 + 0068-net-hns3-fix-integer-type.patch | 38 + 0069-kvargs-rework-process-API.patch | 167 +++ 0070-net-sfc-use-new-kvargs-process-API.patch | 116 ++ 0071-net-tap-use-new-kvargs-process-API.patch | 47 + ...ommon-nfp-use-new-kvargs-process-API.patch | 37 + ...-net-hns3-support-flow-rule-priority.patch | 380 +++++ ...r-code-for-repeatedly-create-counter.patch | 36 + ...lly-use-hardware-flow-director-table.patch | 40 + dpdk.spec | 66 +- 30 files changed, 5071 insertions(+), 1 deletion(-) create mode 100644 0047-ethdev-verify-queue-ID-in-Tx-done-cleanup.patch create mode 100644 0048-net-hns3-verify-reset-type-from-firmware.patch create mode 100644 0049-dmadev-fix-potential-null-pointer-access.patch create mode 100644 0050-net-hns3-dump-queue-head-and-tail-pointer-info.patch create mode 100644 0051-net-hns3-remove-ROH-devices.patch create mode 100644 0052-net-hns3-restrict-tunnel-flow-rule-to-one-header.patch create mode 100644 0053-net-hns3-support-general-tunnel-flow-match.patch create mode 100644 0054-net-hns3-register-VLAN-flow-match-mode-parameter.patch create mode 100644 0055-net-hns3-support-outer-VLAN-flow-match.patch create mode 100644 0056-telemetry-register-command-with-private-argument.patch create mode 100644 0057-ethdev-fix-race-on-ports-in-telemetry-endpoints.patch create mode 100644 0058-ethdev-add-report-of-register-names-and-filter.patch create mode 100644 0059-ethdev-add-telemetry-command-for-registers.patch create mode 100644 0060-net-hns3-remove-some-basic-address-dump.patch create mode 100644 0061-net-hns3-fix-dump-counter-of-registers.patch create mode 100644 0062-net-hns3-remove-separators-between-register-module.patch create mode 100644 0063-net-hns3-refactor-register-dump.patch create mode 100644 0064-net-hns3-support-reporting-names-of-registers.patch create mode 100644 0065-net-hns3-support-filtering-registers-by-module-names.patch create mode 100644 0066-net-hns3-fix-error-log.patch create mode 100644 0067-net-hns3-fix-pointer-offset-for-registers.patch create mode 100644 0068-net-hns3-fix-integer-type.patch create mode 100644 0069-kvargs-rework-process-API.patch create mode 100644 0070-net-sfc-use-new-kvargs-process-API.patch create mode 100644 0071-net-tap-use-new-kvargs-process-API.patch create mode 100644 0072-common-nfp-use-new-kvargs-process-API.patch create mode 100644 0073-net-hns3-support-flow-rule-priority.patch create mode 100644 0074-net-hns3-fix-error-code-for-repeatedly-create-counter.patch create mode 100644 0075-net-hns3-fix-fully-use-hardware-flow-director-table.patch diff --git a/0047-ethdev-verify-queue-ID-in-Tx-done-cleanup.patch b/0047-ethdev-verify-queue-ID-in-Tx-done-cleanup.patch new file mode 100644 index 0000000..b2c02a0 --- /dev/null +++ b/0047-ethdev-verify-queue-ID-in-Tx-done-cleanup.patch @@ -0,0 +1,38 @@ +From 528e7939a75f2eb6416162e5b77a23300dcc820f Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 12 Oct 2024 17:14:37 +0800 +Subject: [PATCH] ethdev: verify queue ID in Tx done cleanup + +[ upstream commit 707f50cef003a89f8fc5170c2ca5aea808cf4297 ] + +Verify queue_id for rte_eth_tx_done_cleanup API. + +Fixes: 44a718c457b5 ("ethdev: add API to free consumed buffers in Tx ring") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Reviewed-by: Ferruh Yigit +--- + lib/ethdev/rte_ethdev.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c +index c0398d9..8438f2a 100644 +--- a/lib/ethdev/rte_ethdev.c ++++ b/lib/ethdev/rte_ethdev.c +@@ -2823,6 +2823,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt) + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + ++#ifdef RTE_ETHDEV_DEBUG_TX ++ ret = eth_dev_validate_tx_queue(dev, queue_id); ++ if (ret != 0) ++ return ret; ++#endif ++ + if (*dev->dev_ops->tx_done_cleanup == NULL) + return -ENOTSUP; + +-- +2.33.0 + diff --git a/0048-net-hns3-verify-reset-type-from-firmware.patch b/0048-net-hns3-verify-reset-type-from-firmware.patch new file mode 100644 index 0000000..6a6ccf2 --- /dev/null +++ b/0048-net-hns3-verify-reset-type-from-firmware.patch @@ -0,0 +1,38 @@ +From e089c8f6266a0c65600be8b32c14ffc014c2b506 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 12 Oct 2024 17:14:57 +0800 +Subject: [PATCH] net/hns3: verify reset type from firmware + +[ upstream commit 3db846003734d38d59950ebe024ad6d61afe08f0 ] + +Verify reset-type which get from firmware. + +Fixes: 1c1eb759e9d7 ("net/hns3: support RAS process in Kunpeng 930") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Acked-by: Jie Hai +--- + drivers/net/hns3/hns3_intr.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c +index 916bf30..d37c7eb 100644 +--- a/drivers/net/hns3/hns3_intr.c ++++ b/drivers/net/hns3/hns3_intr.c +@@ -2252,6 +2252,12 @@ hns3_handle_module_error_data(struct hns3_hw *hw, uint32_t *buf, + sum_err_info = (struct hns3_sum_err_info *)&buf[offset++]; + mod_num = sum_err_info->mod_num; + reset_type = sum_err_info->reset_type; ++ ++ if (reset_type >= HNS3_MAX_RESET) { ++ hns3_err(hw, "invalid reset type = %u", reset_type); ++ return; ++ } ++ + if (reset_type && reset_type != HNS3_NONE_RESET) + hns3_atomic_set_bit(reset_type, &hw->reset.request); + +-- +2.33.0 + diff --git a/0049-dmadev-fix-potential-null-pointer-access.patch b/0049-dmadev-fix-potential-null-pointer-access.patch new file mode 100644 index 0000000..58aceb7 --- /dev/null +++ b/0049-dmadev-fix-potential-null-pointer-access.patch @@ -0,0 +1,35 @@ +From 6963b0641d446209018f0fdc6cd773c92b3f4612 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Sat, 12 Oct 2024 17:17:34 +0800 +Subject: [PATCH] dmadev: fix potential null pointer access + +[ upstream commit e5389d427ec43ab805d0a1caed89b63656fd7fde ] + +When rte_dma_vchan_status(dev_id, vchan, NULL) is called, a null pointer +access is triggered. +This patch adds the null pointer checker. + +Fixes: 5e0f85912754 ("dmadev: add channel status check for testing use") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +--- + lib/dmadev/rte_dmadev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/dmadev/rte_dmadev.c b/lib/dmadev/rte_dmadev.c +index 7729519..8a010c4 100644 +--- a/lib/dmadev/rte_dmadev.c ++++ b/lib/dmadev/rte_dmadev.c +@@ -722,7 +722,7 @@ rte_dma_vchan_status(int16_t dev_id, uint16_t vchan, enum rte_dma_vchan_status * + { + struct rte_dma_dev *dev = &rte_dma_devices[dev_id]; + +- if (!rte_dma_is_valid(dev_id)) ++ if (!rte_dma_is_valid(dev_id) || status == NULL) + return -EINVAL; + + if (vchan >= dev->data->dev_conf.nb_vchans) { +-- +2.33.0 + diff --git a/0050-net-hns3-dump-queue-head-and-tail-pointer-info.patch b/0050-net-hns3-dump-queue-head-and-tail-pointer-info.patch new file mode 100644 index 0000000..e01f88c --- /dev/null +++ b/0050-net-hns3-dump-queue-head-and-tail-pointer-info.patch @@ -0,0 +1,104 @@ +From 839eb2318fe2353e6a602ca5398969b501e9cc90 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Thu, 5 Sep 2024 14:48:03 +0800 +Subject: [PATCH] net/hns3: dump queue head and tail pointer info + +[ upstream commit 364a31b7628536ad7c5fb68603e11c5b166df248 ] + +Add dump the head and tail pointer of RxTx queue. +-- Rx queue head and tail info: + qid sw_head sw_hold hw_head hw_tail + 0 288 32 256 320 + 1 248 56 192 280 + 2 264 72 192 296 + 3 256 64 192 292 +-- Tx queue head and tail info: + qid sw_head sw_tail hw_head hw_tail + 0 0 92 84 92 + 1 32 131 128 139 + 2 32 128 120 128 + 3 96 184 176 184 + +Signed-off-by: Dengdui Huang +--- + drivers/net/hns3/hns3_dump.c | 57 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 57 insertions(+) + +diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c +index cb369be..5fee082 100644 +--- a/drivers/net/hns3/hns3_dump.c ++++ b/drivers/net/hns3/hns3_dump.c +@@ -436,6 +436,62 @@ hns3_get_rxtx_queue_enable_state(FILE *file, struct rte_eth_dev *dev) + rte_free(tx_queue_state); + } + ++static void ++hns3_get_rxtx_queue_head_tail_pointer(FILE *file, struct rte_eth_dev *dev) ++{ ++ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); ++ uint32_t reg_offset, queue_id; ++ void **rx_queues, **tx_queues; ++ struct hns3_rx_queue *rxq; ++ struct hns3_tx_queue *txq; ++ uint16_t sw_hold; ++ ++ rx_queues = dev->data->rx_queues; ++ if (rx_queues == NULL) ++ return; ++ tx_queues = dev->data->tx_queues; ++ if (tx_queues == NULL) ++ return; ++ ++ fprintf(file, "\t -- Rx queue head and tail info:\n"); ++ fprintf(file, "\t qid sw_head sw_hold hw_head hw_tail\n"); ++ for (queue_id = 0; queue_id < dev->data->nb_rx_queues; queue_id++) { ++ if (rx_queues[queue_id] == NULL) ++ continue; ++ rxq = (struct hns3_rx_queue *)rx_queues[queue_id]; ++ if (rxq->rx_deferred_start) ++ continue; ++ ++ if (dev->rx_pkt_burst == hns3_recv_pkts_vec || ++ dev->rx_pkt_burst == hns3_recv_pkts_vec_sve) ++ sw_hold = rxq->rx_rearm_nb; ++ else ++ sw_hold = rxq->rx_free_hold; ++ ++ reg_offset = hns3_get_tqp_reg_offset(queue_id); ++ fprintf(file, "\t %-5u%-9u%-9u%-9u%u\n", queue_id, ++ rxq->next_to_use, sw_hold, ++ hns3_read_dev(hw, HNS3_RING_RX_HEAD_REG + reg_offset), ++ hns3_read_dev(hw, HNS3_RING_RX_TAIL_REG + reg_offset)); ++ } ++ ++ fprintf(file, "\t -- Tx queue head and tail info:\n"); ++ fprintf(file, "\t qid sw_head sw_tail hw_head hw_tail\n"); ++ for (queue_id = 0; queue_id < dev->data->nb_tx_queues; queue_id++) { ++ if (tx_queues[queue_id] == NULL) ++ continue; ++ txq = (struct hns3_tx_queue *)tx_queues[queue_id]; ++ if (txq->tx_deferred_start) ++ continue; ++ ++ reg_offset = hns3_get_tqp_reg_offset(queue_id); ++ fprintf(file, "\t %-5u%-9u%-9u%-9u%u\n", queue_id, ++ txq->next_to_clean, txq->next_to_use, ++ hns3_read_dev(hw, HNS3_RING_TX_HEAD_REG + reg_offset), ++ hns3_read_dev(hw, HNS3_RING_TX_TAIL_REG + reg_offset)); ++ } ++} ++ + static void + hns3_get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev) + { +@@ -460,6 +516,7 @@ hns3_get_rxtx_queue_info(FILE *file, struct rte_eth_dev *dev) + + hns3_get_rxtx_fake_queue_info(file, dev); + hns3_get_rxtx_queue_enable_state(file, dev); ++ hns3_get_rxtx_queue_head_tail_pointer(file, dev); + } + + static int +-- +2.33.0 + diff --git a/0051-net-hns3-remove-ROH-devices.patch b/0051-net-hns3-remove-ROH-devices.patch new file mode 100644 index 0000000..d0ea2aa --- /dev/null +++ b/0051-net-hns3-remove-ROH-devices.patch @@ -0,0 +1,66 @@ +From e09cc47f4eb826f3bfbc93c579d891cf18310d81 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Sat, 26 Oct 2024 14:38:35 +0800 +Subject: [PATCH] net/hns3: remove ROH devices + +[ upstream commit feb4548ffd80bf249239d99bf9053ecf78f815d1 ] + +The devices added in commit 3f1436d7006c ("net/hns3: support new device") +is no longer available, so revert it. + +Fixes: 3f1436d7006c ("net/hns3: support new device") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +Acked-by: Jie Hai +--- + drivers/net/hns3/hns3_cmd.c | 4 +--- + drivers/net/hns3/hns3_ethdev.c | 2 -- + drivers/net/hns3/hns3_ethdev.h | 2 -- + 3 files changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c +index 001ff49..2c16644 100644 +--- a/drivers/net/hns3/hns3_cmd.c ++++ b/drivers/net/hns3/hns3_cmd.c +@@ -545,9 +545,7 @@ hns3_set_dcb_capability(struct hns3_hw *hw) + if (device_id == HNS3_DEV_ID_25GE_RDMA || + device_id == HNS3_DEV_ID_50GE_RDMA || + device_id == HNS3_DEV_ID_100G_RDMA_MACSEC || +- device_id == HNS3_DEV_ID_200G_RDMA || +- device_id == HNS3_DEV_ID_100G_ROH || +- device_id == HNS3_DEV_ID_200G_ROH) ++ device_id == HNS3_DEV_ID_200G_RDMA) + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1); + } + +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 2340fb2..cc2edb3 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6651,8 +6651,6 @@ static const struct rte_pci_id pci_id_hns3_map[] = { + { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_50GE_RDMA) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_100G_RDMA_MACSEC) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_200G_RDMA) }, +- { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_100G_ROH) }, +- { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_200G_ROH) }, + { .vendor_id = 0, }, /* sentinel */ + }; + +diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h +index c190d51..00d226d 100644 +--- a/drivers/net/hns3/hns3_ethdev.h ++++ b/drivers/net/hns3/hns3_ethdev.h +@@ -28,9 +28,7 @@ + #define HNS3_DEV_ID_25GE_RDMA 0xA222 + #define HNS3_DEV_ID_50GE_RDMA 0xA224 + #define HNS3_DEV_ID_100G_RDMA_MACSEC 0xA226 +-#define HNS3_DEV_ID_100G_ROH 0xA227 + #define HNS3_DEV_ID_200G_RDMA 0xA228 +-#define HNS3_DEV_ID_200G_ROH 0xA22C + #define HNS3_DEV_ID_100G_VF 0xA22E + #define HNS3_DEV_ID_100G_RDMA_PFC_VF 0xA22F + +-- +2.33.0 + diff --git a/0052-net-hns3-restrict-tunnel-flow-rule-to-one-header.patch b/0052-net-hns3-restrict-tunnel-flow-rule-to-one-header.patch new file mode 100644 index 0000000..5645f40 --- /dev/null +++ b/0052-net-hns3-restrict-tunnel-flow-rule-to-one-header.patch @@ -0,0 +1,39 @@ +From 0448f90a404a332052aacd45e8445c9fd22cfc61 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 18 Oct 2024 14:19:38 +0800 +Subject: [PATCH] net/hns3: restrict tunnel flow rule to one header + +[ upstream commit 8887c207b9373a1875031c5346706f698322d66d ] + +The device's flow director supports a maximum of one tunnel header, if +passed more than one tunnel header from rte-flow API, the driver should +return error. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Jie Hai +--- + drivers/net/hns3/hns3_flow.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 37eb2b4..e287420 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -1221,6 +1221,11 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + "Tunnel packets must configure " + "with mask"); + ++ if (rule->key_conf.spec.tunnel_type != 0) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ item, "Too many tunnel headers!"); ++ + switch (item->type) { + case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: +-- +2.33.0 + diff --git a/0053-net-hns3-support-general-tunnel-flow-match.patch b/0053-net-hns3-support-general-tunnel-flow-match.patch new file mode 100644 index 0000000..04a1a7b --- /dev/null +++ b/0053-net-hns3-support-general-tunnel-flow-match.patch @@ -0,0 +1,155 @@ +From 969605f0cc24c8917317fe83462c3165e4901771 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 18 Oct 2024 14:19:39 +0800 +Subject: [PATCH] net/hns3: support general tunnel flow match + +[ upstream commit 90294fa5bc3ab8d0592bbde190dcc8b614850aad ] + +In the current driver implementation, if you want to configure the same +action for all tunnel packets, you need to configure a rule for each +specific tunnel packet. e.g: + + flow create 0 ingress pattern ipv4 / udp / vxlan / end actions ... + flow create 0 ingress pattern ipv4 / udp / vxlan-gpe / end actions ... + flow create 0 ingress pattern ipv4 / udp / geneve / end actions ... + flow create 0 ingress pattern ipv4 / nvgre / end actions ... + flow create 0 ingress pattern ipv6 / udp / vxlan / end actions ... + flow create 0 ingress pattern ipv6 / udp / vxlan-gpe / end actions ... + flow create 0 ingress pattern ipv6 / udp / geneve / end actions ... + flow create 0 ingress pattern ipv6 / nvgre / end actions ... + +It occupies entry rule resources and is inconvenient to use. + +The hardware supports 'tunnel packet' meta-data bit, this bit was set +when the hardware detects any type of supported tunnel packets. + +This commit supports general tunnel match by identify +RTE_FLOW_ITEM_TYPE_PTYPE, and only support PTYPE_TUNNEL (0xf000). We +will treat it (0xf000) as a general tunnel, all tunnel types that +hardware recognized will match it. + +After this commit, we could just create one rule per case: + + case1: match all tunnel packets + rule1: flow create 0 ingress pattern ptype packet_type is 0xf000 / + end actions ... + + case2: match all ipv4 tunnel packets + rule2: flow create 0 ingress pattern ipv4 ptype packet_type is 0xf000 + / end actions ... + + case3: match all ipv6 tunnel packets + rule3: flow create 0 ingress pattern ipv6 ptype packet_type is 0xf000 + / end actions ... + +Signed-off-by: Chengwen Feng +Signed-off-by: Jie Hai +--- + doc/guides/nics/features/hns3.ini | 1 + + drivers/net/hns3/hns3_flow.c | 45 ++++++++++++++++++++++++++++--- + 2 files changed, 42 insertions(+), 4 deletions(-) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index 338b4e6..a9480d6 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -57,6 +57,7 @@ icmp = Y + ipv4 = Y + ipv6 = Y + nvgre = Y ++ptype = P + sctp = Y + tcp = Y + udp = Y +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index e287420..89ee2c6 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -155,13 +155,15 @@ static enum rte_flow_item_type first_items[] = { + RTE_FLOW_ITEM_TYPE_NVGRE, + RTE_FLOW_ITEM_TYPE_VXLAN, + RTE_FLOW_ITEM_TYPE_GENEVE, +- RTE_FLOW_ITEM_TYPE_VXLAN_GPE ++ RTE_FLOW_ITEM_TYPE_VXLAN_GPE, ++ RTE_FLOW_ITEM_TYPE_PTYPE + }; + + static enum rte_flow_item_type L2_next_items[] = { + RTE_FLOW_ITEM_TYPE_VLAN, + RTE_FLOW_ITEM_TYPE_IPV4, +- RTE_FLOW_ITEM_TYPE_IPV6 ++ RTE_FLOW_ITEM_TYPE_IPV6, ++ RTE_FLOW_ITEM_TYPE_PTYPE + }; + + static enum rte_flow_item_type L3_next_items[] = { +@@ -169,7 +171,8 @@ static enum rte_flow_item_type L3_next_items[] = { + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_SCTP, + RTE_FLOW_ITEM_TYPE_NVGRE, +- RTE_FLOW_ITEM_TYPE_ICMP ++ RTE_FLOW_ITEM_TYPE_ICMP, ++ RTE_FLOW_ITEM_TYPE_PTYPE + }; + + static enum rte_flow_item_type L4_next_items[] = { +@@ -1204,6 +1207,32 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + return 0; + } + ++static int ++hns3_parse_ptype(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, ++ struct rte_flow_error *error) ++{ ++ const struct rte_flow_item_ptype *spec = item->spec; ++ const struct rte_flow_item_ptype *mask = item->mask; ++ ++ if (spec == NULL || mask == NULL) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, item, ++ "PTYPE must set spec and mask at the same time!"); ++ ++ if (spec->packet_type != RTE_PTYPE_TUNNEL_MASK || ++ (mask->packet_type & RTE_PTYPE_TUNNEL_MASK) != RTE_PTYPE_TUNNEL_MASK) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, ++ "PTYPE only support general tunnel!"); ++ ++ /* ++ * Set tunnel_type to non-zero, so that meta-data's tunnel packet bit ++ * will be set, then hardware will match tunnel packet. ++ */ ++ rule->key_conf.spec.tunnel_type = 1; ++ return 0; ++} ++ + static int + hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + struct rte_flow_error *error) +@@ -1237,6 +1266,9 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + case RTE_FLOW_ITEM_TYPE_GENEVE: + ret = hns3_parse_geneve(item, rule, error); + break; ++ case RTE_FLOW_ITEM_TYPE_PTYPE: ++ ret = hns3_parse_ptype(item, rule, error); ++ break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, +@@ -1336,7 +1368,12 @@ is_tunnel_packet(enum rte_flow_item_type type) + if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || + type == RTE_FLOW_ITEM_TYPE_VXLAN || + type == RTE_FLOW_ITEM_TYPE_NVGRE || +- type == RTE_FLOW_ITEM_TYPE_GENEVE) ++ type == RTE_FLOW_ITEM_TYPE_GENEVE || ++ /* ++ * Here treat PTYPE as tunnel type because driver only support PTYPE_TUNNEL, ++ * other PTYPE will return error in hns3_parse_ptype() later. ++ */ ++ type == RTE_FLOW_ITEM_TYPE_PTYPE) + return true; + return false; + } +-- +2.33.0 + diff --git a/0054-net-hns3-register-VLAN-flow-match-mode-parameter.patch b/0054-net-hns3-register-VLAN-flow-match-mode-parameter.patch new file mode 100644 index 0000000..390c242 --- /dev/null +++ b/0054-net-hns3-register-VLAN-flow-match-mode-parameter.patch @@ -0,0 +1,63 @@ +From 4b176ac13dbd408624d083f55a4892282791133b Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 18 Oct 2024 14:19:40 +0800 +Subject: [PATCH] net/hns3: register VLAN flow match mode parameter + +[ upstream commit bf16032eb1e62338e02b1278e10033366448c5bc ] + +This commit adds fdir_vlan_match_mode in RTE_PMD_REGISTER_PARAM_STRING. + +Fixes: 06b9ee343940 ("net/hns3: add VLAN match mode runtime config") +Cc: stable@dpdk.org + +Signed-off-by: Chengwen Feng +Signed-off-by: Jie Hai +--- + drivers/net/hns3/hns3_common.c | 2 +- + drivers/net/hns3/hns3_common.h | 2 +- + drivers/net/hns3/hns3_ethdev.c | 3 ++- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c +index 5e6cdfd..7a36673 100644 +--- a/drivers/net/hns3/hns3_common.c ++++ b/drivers/net/hns3/hns3_common.c +@@ -308,7 +308,7 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + &hns3_parse_mbx_time_limit, &mbx_time_limit_ms); + if (!hns->is_vf) + (void)rte_kvargs_process(kvlist, +- HNS3_DEVARG_FDIR_VALN_MATCH_MODE, ++ HNS3_DEVARG_FDIR_VLAN_MATCH_MODE, + &hns3_parse_vlan_match_mode, + &hns->pf.fdir.vlan_match_mode); + +diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h +index cf9593b..1668520 100644 +--- a/drivers/net/hns3/hns3_common.h ++++ b/drivers/net/hns3/hns3_common.h +@@ -27,7 +27,7 @@ enum { + + #define HNS3_DEVARG_MBX_TIME_LIMIT_MS "mbx_time_limit_ms" + +-#define HNS3_DEVARG_FDIR_VALN_MATCH_MODE "fdir_vlan_match_mode" ++#define HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "fdir_vlan_match_mode" + + #define MSEC_PER_SEC 1000L + #define USEC_PER_MSEC 1000L +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index cc2edb3..23a1fca 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6668,7 +6668,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_hns3, + HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common " + HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common " + HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> " +- HNS3_DEVARG_MBX_TIME_LIMIT_MS "= "); ++ HNS3_DEVARG_MBX_TIME_LIMIT_MS "= " ++ HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "=strict|nostrict " + RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE); + RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE); + #ifdef RTE_ETHDEV_DEBUG_RX +-- +2.33.0 + diff --git a/0055-net-hns3-support-outer-VLAN-flow-match.patch b/0055-net-hns3-support-outer-VLAN-flow-match.patch new file mode 100644 index 0000000..553b2fb --- /dev/null +++ b/0055-net-hns3-support-outer-VLAN-flow-match.patch @@ -0,0 +1,497 @@ +From 40a389f8a82d04698fb59742ea8987d1025c32ea Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Fri, 18 Oct 2024 14:19:41 +0800 +Subject: [PATCH] net/hns3: support outer VLAN flow match + +[ upstream commit a47328471c9a297dbe6caddf9db867cddc902f6d ] + +The hardware FDIR supports many tuples match (including outer vlan), +however, the width of hardware entries is limited, therefore, only +part of tuples are enabled, unfortunately, outer vlan is not enabled. + +This commit supports outer vlan match, to avoid affecting the current +use, use runtime config 'fdir_tuple_config' to enable this feature, the +options are as follows: +1. +outvlan-insmac: means disable inner src mac tuple, + and enable outer vlan tuple. +2. +outvlan-indmac: means disable inner dst mac tuple, + and enable outer vlan tuple. +3. +outvlan-insip: means disable inner src ip tuple, + and enable outer vlan tuple. +4. +outvlan-indip: means disable inner dst ip tuple, + and enable outer vlan tuple. +5. +outvlan-sctptag: means disable sctp tag tuple, + and enable outer vlan tuple. +6. +outvlan-tunvni: means disable tunnel vni tuple, + and enable outer vlan tuple. + +Signed-off-by: Chengwen Feng +Signed-off-by: Jie Hai +--- + doc/guides/nics/features/hns3.ini | 2 +- + doc/guides/nics/hns3.rst | 10 +++ + drivers/net/hns3/hns3_common.c | 25 +++++++- + drivers/net/hns3/hns3_common.h | 1 + + drivers/net/hns3/hns3_dump.c | 4 +- + drivers/net/hns3/hns3_ethdev.c | 3 + + drivers/net/hns3/hns3_fdir.c | 103 ++++++++++++++++++++++++++++++ + drivers/net/hns3/hns3_fdir.h | 51 +++++++++++++++ + drivers/net/hns3/hns3_flow.c | 79 +++++++++++++++++++++-- + 9 files changed, 269 insertions(+), 9 deletions(-) + +diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini +index a9480d6..6ac55f7 100644 +--- a/doc/guides/nics/features/hns3.ini ++++ b/doc/guides/nics/features/hns3.ini +@@ -61,7 +61,7 @@ ptype = P + sctp = Y + tcp = Y + udp = Y +-vlan = P ++vlan = Y + vxlan = Y + vxlan_gpe = Y + +diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst +index 97b4686..4f0bc42 100644 +--- a/doc/guides/nics/hns3.rst ++++ b/doc/guides/nics/hns3.rst +@@ -183,6 +183,16 @@ Runtime Configuration + + -a 0000:7d:00.0,fdir_vlan_match_mode=nostrict + ++- ``fdir_tuple_config`` (default ``none``) ++ ++ Used to customize the flow director tuples. Current supported options are follows: ++ ``+outvlan-insmac``: means disable inner src mac tuple, and enable outer vlan tuple. ++ ``+outvlan-indmac``: means disable inner dst mac tuple, and enable outer vlan tuple. ++ ``+outvlan-insip``: means disable inner src ip tuple, and enable outer vlan tuple. ++ ``+outvlan-indip``: means disable inner dst ip tuple, and enable outer vlan tuple. ++ ``+outvlan-sctptag``: means disable sctp tag tuple, and enable outer vlan tuple. ++ ``+outvlan-tunvni``: means disable tunnel vni tuple, and enable outer vlan tuple. ++ + Driver compilation and testing + ------------------------------ + +diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c +index 7a36673..99a1d59 100644 +--- a/drivers/net/hns3/hns3_common.c ++++ b/drivers/net/hns3/hns3_common.c +@@ -272,6 +272,24 @@ hns3_parse_vlan_match_mode(const char *key, const char *value, void *args) + return 0; + } + ++static int ++hns3_parse_fdir_tuple_config(const char *key, const char *value, void *args) ++{ ++ enum hns3_fdir_tuple_config tuple_cfg; ++ ++ tuple_cfg = hns3_parse_tuple_config(value); ++ if (tuple_cfg == HNS3_FDIR_TUPLE_CONFIG_DEFAULT || ++ tuple_cfg == HNS3_FDIR_TUPLE_CONFIG_BUTT) { ++ PMD_INIT_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\"", ++ value, key); ++ return -1; ++ } ++ ++ *(enum hns3_fdir_tuple_config *)args = tuple_cfg; ++ ++ return 0; ++} ++ + void + hns3_parse_devargs(struct rte_eth_dev *dev) + { +@@ -306,11 +324,16 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + &hns3_parse_dev_caps_mask, &dev_caps_mask); + (void)rte_kvargs_process(kvlist, HNS3_DEVARG_MBX_TIME_LIMIT_MS, + &hns3_parse_mbx_time_limit, &mbx_time_limit_ms); +- if (!hns->is_vf) ++ if (!hns->is_vf) { + (void)rte_kvargs_process(kvlist, + HNS3_DEVARG_FDIR_VLAN_MATCH_MODE, + &hns3_parse_vlan_match_mode, + &hns->pf.fdir.vlan_match_mode); ++ (void)rte_kvargs_process(kvlist, ++ HNS3_DEVARG_FDIR_TUPLE_CONFIG, ++ &hns3_parse_fdir_tuple_config, ++ &hns->pf.fdir.tuple_cfg); ++ } + + rte_kvargs_free(kvlist); + +diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h +index 1668520..ca90936 100644 +--- a/drivers/net/hns3/hns3_common.h ++++ b/drivers/net/hns3/hns3_common.h +@@ -28,6 +28,7 @@ enum { + #define HNS3_DEVARG_MBX_TIME_LIMIT_MS "mbx_time_limit_ms" + + #define HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "fdir_vlan_match_mode" ++#define HNS3_DEVARG_FDIR_TUPLE_CONFIG "fdir_tuple_config" + + #define MSEC_PER_SEC 1000L + #define USEC_PER_MSEC 1000L +diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c +index 5fee082..fbe3716 100644 +--- a/drivers/net/hns3/hns3_dump.c ++++ b/drivers/net/hns3/hns3_dump.c +@@ -169,6 +169,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf) + "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n" + "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n" + "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n" ++ "\t -- tuple_config: %s\n" + "\t -- active_tuples:\n", + fdcfg->fd_mode, fdcfg->max_key_length, + fdcfg->rule_num[HNS3_FD_STAGE_1], +@@ -179,7 +180,8 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf) + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_sipv6_word_en, + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en, + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en, +- fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en); ++ fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en, ++ hns3_tuple_config_name(pf->fdir.tuple_cfg)); + + for (i = 0; i < MAX_TUPLE; i++) { + if (!(fdcfg->key_cfg[HNS3_FD_STAGE_1].tuple_active & BIT(i))) +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 23a1fca..30b7aaa 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6670,6 +6670,9 @@ RTE_PMD_REGISTER_PARAM_STRING(net_hns3, + HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> " + HNS3_DEVARG_MBX_TIME_LIMIT_MS "= " + HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "=strict|nostrict " ++ HNS3_DEVARG_FDIR_TUPLE_CONFIG "=+outvlan-insmac|+outvlan-indmac|" ++ "+outvlan-insip|+outvlan-indip" ++ "+outvlan-sctptag|+outvlan-tunvni "); + RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE); + RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE); + #ifdef RTE_ETHDEV_DEBUG_RX +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index d100e58..389dec2 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -300,6 +300,58 @@ static int hns3_set_fd_key_config(struct hns3_adapter *hns) + return ret; + } + ++static void hns3_set_tuple_config(struct hns3_adapter *hns, ++ struct hns3_fd_key_cfg *key_cfg) ++{ ++ enum hns3_fdir_tuple_config tuple_cfg = hns->pf.fdir.tuple_cfg; ++ ++ if (tuple_cfg == HNS3_FDIR_TUPLE_CONFIG_DEFAULT) ++ return; ++ ++ if (hns->pf.fdir.fd_cfg.max_key_length != MAX_KEY_LENGTH) { ++ hns3_warn(&hns->hw, "fdir tuple config only valid with 400bit key!"); ++ return; ++ } ++ ++ switch (tuple_cfg) { ++ case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSMAC: ++ key_cfg->tuple_active &= ~BIT(INNER_SRC_MAC); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); ++ break; ++ case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDMAC: ++ key_cfg->tuple_active &= ~BIT(INNER_DST_MAC); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); ++ break; ++ case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSIP: ++ key_cfg->tuple_active &= ~BIT(INNER_SRC_IP); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); ++ break; ++ case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDIP: ++ key_cfg->tuple_active &= ~BIT(INNER_DST_IP); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); ++ break; ++ case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_SCTPTAG: ++ key_cfg->tuple_active &= ~BIT(INNER_SCTP_TAG); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); ++ break; ++ case HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_TUNVNI: ++ key_cfg->tuple_active &= ~BIT(OUTER_TUN_VNI); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_FST); ++ key_cfg->tuple_active |= BIT(OUTER_VLAN_TAG_SEC); ++ break; ++ default: ++ hns3_err(&hns->hw, "invalid fdir tuple config %u!", tuple_cfg); ++ return; ++ } ++ ++ hns3_info(&hns->hw, "fdir tuple config %s!", hns3_tuple_config_name(tuple_cfg)); ++} ++ + int hns3_init_fd_config(struct hns3_adapter *hns) + { + struct hns3_pf *pf = &hns->pf; +@@ -352,6 +404,8 @@ int hns3_init_fd_config(struct hns3_adapter *hns) + "l4_src_port l4_dst_port tun_vni tun_flow_id>"); + } + ++ hns3_set_tuple_config(hns, key_cfg); ++ + /* roce_type is used to filter roce frames + * dst_vport is used to specify the rule + */ +@@ -500,6 +554,14 @@ static void hns3_fd_convert_int16(uint32_t tuple, struct hns3_fdir_rule *rule, + uint16_t key; + + switch (tuple) { ++ case OUTER_VLAN_TAG_FST: ++ key = rule->key_conf.spec.outer_vlan_tag1; ++ mask = rule->key_conf.mask.outer_vlan_tag1; ++ break; ++ case OUTER_VLAN_TAG_SEC: ++ key = rule->key_conf.spec.outer_vlan_tag2; ++ mask = rule->key_conf.mask.outer_vlan_tag2; ++ break; + case OUTER_SRC_PORT: + key = rule->key_conf.spec.outer_src_port; + mask = rule->key_conf.mask.outer_src_port; +@@ -575,6 +637,8 @@ static bool hns3_fd_convert_tuple(struct hns3_hw *hw, + hns3_fd_convert_mac(key_conf->spec.src_mac, + key_conf->mask.src_mac, key_x, key_y); + break; ++ case OUTER_VLAN_TAG_FST: ++ case OUTER_VLAN_TAG_SEC: + case OUTER_SRC_PORT: + case OUTER_DST_PORT: + case OUTER_ETH_TYPE: +@@ -1128,3 +1192,42 @@ int hns3_fd_get_count(struct hns3_hw *hw, uint32_t id, uint64_t *value) + + return ret; + } ++ ++static struct { ++ enum hns3_fdir_tuple_config tuple_cfg; ++ const char *name; ++} tuple_config_map[] = { ++ { HNS3_FDIR_TUPLE_CONFIG_DEFAULT, "default" }, ++ { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSMAC, "+outvlan-insmac" }, ++ { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDMAC, "+outvlan-indmac" }, ++ { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSIP, "+outvlan-insip" }, ++ { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDIP, "+outvlan-indip" }, ++ { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_SCTPTAG, "+outvlan-sctptag" }, ++ { HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_TUNVNI, "+outvlan-tunvni" } ++}; ++ ++enum hns3_fdir_tuple_config ++hns3_parse_tuple_config(const char *name) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < RTE_DIM(tuple_config_map); i++) { ++ if (!strcmp(name, tuple_config_map[i].name)) ++ return tuple_config_map[i].tuple_cfg; ++ } ++ ++ return HNS3_FDIR_TUPLE_CONFIG_BUTT; ++} ++ ++const char * ++hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < RTE_DIM(tuple_config_map); i++) { ++ if (tuple_cfg == tuple_config_map[i].tuple_cfg) ++ return tuple_config_map[i].name; ++ } ++ ++ return "unknown"; ++} +diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h +index 6ccd90a..2d0c9bf 100644 +--- a/drivers/net/hns3/hns3_fdir.h ++++ b/drivers/net/hns3/hns3_fdir.h +@@ -97,6 +97,8 @@ struct hns3_fd_rule_tuples { + uint32_t sctp_tag; + uint16_t outer_src_port; + uint16_t tunnel_type; ++ uint16_t outer_vlan_tag1; ++ uint16_t outer_vlan_tag2; + uint16_t outer_ether_type; + uint8_t outer_proto; + uint8_t outer_tun_vni[VNI_OR_TNI_LEN]; +@@ -181,6 +183,51 @@ TAILQ_HEAD(hns3_fdir_rule_list, hns3_fdir_rule_ele); + #define HNS3_FDIR_VLAN_STRICT_MATCH 1 + #define HNS3_FDIR_VLAN_NOSTRICT_MATCH 0 + ++/* ++ * The hardware supports many tuples match (see @enum HNS3_FD_TUPLE), ++ * however, the width of hardware entries is limited, therefore, only part ++ * of tuples are enabled (see as @hns3_init_fd_config). ++ * ++ * We should replace the existing tuples if we want to enable other tuples ++ * because the width capacity is insufficient. ++ */ ++enum hns3_fdir_tuple_config { ++ /* Default tuple config (see as @hns3_init_fd_config). */ ++ HNS3_FDIR_TUPLE_CONFIG_DEFAULT, ++ /* ++ * Based on the default tuple config, disable the inner src-mac tuple, ++ * and enable the outer VLAN tuple. ++ */ ++ HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSMAC, ++ /* ++ * Based on the default tuple config, disable the inner dst-mac tuple, ++ * and enable the outer VLAN tuple. ++ */ ++ HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDMAC, ++ /* ++ * Based on the default tuple config, disable the inner src-ip tuple, ++ * and enable the outer VLAN tuple. ++ */ ++ HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INSIP, ++ /* ++ * Based on the default tuple config, disable the inner dst-ip tuple, ++ * and enable the outer VLAN tuple. ++ */ ++ HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_INDIP, ++ /* ++ * Based on the default tuple config, disable the sctp-tag tuple, ++ * and enable the outer VLAN tuple. ++ */ ++ HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_SCTPTAG, ++ /* ++ * Based on the default tuple config, disable the tunnel vni tuple, ++ * and enable the outer VLAN tuple. ++ */ ++ HNS3_FDIR_TUPLE_OUTVLAN_REPLACE_TUNVNI, ++ ++ HNS3_FDIR_TUPLE_CONFIG_BUTT ++}; ++ + /* + * A structure used to define fields of a FDIR related info. + */ +@@ -190,6 +237,7 @@ struct hns3_fdir_info { + struct rte_hash *hash_handle; + struct hns3_fd_cfg fd_cfg; + uint8_t vlan_match_mode; ++ enum hns3_fdir_tuple_config tuple_cfg; + }; + + struct hns3_adapter; +@@ -204,4 +252,7 @@ int hns3_clear_all_fdir_filter(struct hns3_adapter *hns); + int hns3_fd_get_count(struct hns3_hw *hw, uint32_t id, uint64_t *value); + int hns3_restore_all_fdir_filter(struct hns3_adapter *hns); + ++enum hns3_fdir_tuple_config hns3_parse_tuple_config(const char *name); ++const char *hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg); ++ + #endif /* HNS3_FDIR_H */ +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 89ee2c6..4674f74 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -608,6 +608,59 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) + return 0; + } + ++static int ++hns3_check_tuple(const struct rte_eth_dev *dev, const struct hns3_fdir_rule *rule, ++ struct rte_flow_error *error) ++{ ++ const char * const err_msg[] = { ++ "Not support outer dst mac", ++ "Not support outer src mac", ++ "Not support outer vlan1 tag", ++ "Not support outer vlan2 tag", ++ "Not support outer eth type", ++ "Not support outer l2 rsv", ++ "Not support outer ip tos", ++ "Not support outer ip proto", ++ "Not support outer src ip", ++ "Not support outer dst ip", ++ "Not support outer l3 rsv", ++ "Not support outer src port", ++ "Not support outer dst port", ++ "Not support outer l4 rsv", ++ "Not support outer tun vni", ++ "Not support outer tun flow id", ++ "Not support inner dst mac", ++ "Not support inner src mac", ++ "Not support inner vlan tag1", ++ "Not support inner vlan tag2", ++ "Not support inner eth type", ++ "Not support inner l2 rsv", ++ "Not support inner ip tos", ++ "Not support inner ip proto", ++ "Not support inner src ip", ++ "Not support inner dst ip", ++ "Not support inner l3 rsv", ++ "Not support inner src port", ++ "Not support inner dst port", ++ "Not support inner sctp tag", ++ }; ++ struct hns3_adapter *hns = dev->data->dev_private; ++ uint32_t tuple_active = hns->pf.fdir.fd_cfg.key_cfg[HNS3_FD_STAGE_1].tuple_active; ++ uint32_t i; ++ ++ for (i = 0; i < MAX_TUPLE; i++) { ++ if ((rule->input_set & BIT(i)) == 0) ++ continue; ++ if (tuple_active & BIT(i)) ++ continue; ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ NULL, err_msg[i]); ++ } ++ ++ return 0; ++} ++ + static int + hns3_parse_eth(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + struct rte_flow_error *error __rte_unused) +@@ -1029,12 +1082,22 @@ hns3_handle_tunnel(const struct rte_flow_item *item, + rule->key_conf.mask.ether_type = 0; + } + +- /* check vlan config */ +- if (rule->input_set & (BIT(INNER_VLAN_TAG1) | BIT(INNER_VLAN_TAG2))) +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ITEM, +- item, +- "Outer vlan tags is unsupported"); ++ if (rule->input_set & BIT(INNER_VLAN_TAG1)) { ++ hns3_set_bit(rule->input_set, OUTER_VLAN_TAG_FST, 1); ++ hns3_set_bit(rule->input_set, INNER_VLAN_TAG1, 0); ++ rule->key_conf.spec.outer_vlan_tag1 = rule->key_conf.spec.vlan_tag1; ++ rule->key_conf.mask.outer_vlan_tag1 = rule->key_conf.mask.vlan_tag1; ++ rule->key_conf.spec.vlan_tag1 = 0; ++ rule->key_conf.mask.vlan_tag1 = 0; ++ } ++ if (rule->input_set & BIT(INNER_VLAN_TAG2)) { ++ hns3_set_bit(rule->input_set, OUTER_VLAN_TAG_SEC, 1); ++ hns3_set_bit(rule->input_set, INNER_VLAN_TAG2, 0); ++ rule->key_conf.spec.outer_vlan_tag2 = rule->key_conf.spec.vlan_tag2; ++ rule->key_conf.mask.outer_vlan_tag2 = rule->key_conf.mask.vlan_tag2; ++ rule->key_conf.spec.vlan_tag2 = 0; ++ rule->key_conf.mask.vlan_tag2 = 0; ++ } + + /* clear vlan_num for inner vlan select */ + rule->key_conf.outer_vlan_num = rule->key_conf.vlan_num; +@@ -1444,6 +1507,10 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + } + } + ++ ret = hns3_check_tuple(dev, rule, error); ++ if (ret) ++ return ret; ++ + return hns3_handle_actions(dev, actions, rule, error); + } + +-- +2.33.0 + diff --git a/0056-telemetry-register-command-with-private-argument.patch b/0056-telemetry-register-command-with-private-argument.patch new file mode 100644 index 0000000..36bab3d --- /dev/null +++ b/0056-telemetry-register-command-with-private-argument.patch @@ -0,0 +1,208 @@ +From f04a80934422279e4459869d17d5118ee1dc3efe Mon Sep 17 00:00:00 2001 +From: Robin Jarry +Date: Mon, 14 Oct 2024 21:32:36 +0200 +Subject: telemetry: register command with private argument + +[ upstream commit ceb5914cd1e153b01bedd9f14a8119355114a21f ] + +Add a new rte_telemetry_register_cmd_arg public function to register +a telemetry endpoint with a callback that takes an additional private +argument. + +This will be used in the next commit to protect ethdev endpoints with +a lock. + +Update perform_command() to take a struct callback object copied from +the list of callbacks and invoke the correct function pointer. + +Signed-off-by: Robin Jarry +Acked-by: Bruce Richardson +--- + lib/telemetry/rte_telemetry.h | 46 +++++++++++++++++++++++++++++++++++ + lib/telemetry/telemetry.c | 38 +++++++++++++++++++++++------ + lib/telemetry/version.map | 3 +++ + 3 files changed, 79 insertions(+), 8 deletions(-) + +diff --git a/lib/telemetry/rte_telemetry.h b/lib/telemetry/rte_telemetry.h +index cab9daa6fe..b7143e63fe 100644 +--- a/lib/telemetry/rte_telemetry.h ++++ b/lib/telemetry/rte_telemetry.h +@@ -336,6 +336,30 @@ rte_tel_data_add_dict_uint_hex(struct rte_tel_data *d, const char *name, + typedef int (*telemetry_cb)(const char *cmd, const char *params, + struct rte_tel_data *info); + ++/** ++ * This telemetry callback is used when registering a telemetry command with ++ * rte_telemetry_register_cmd_arg(). ++ * ++ * It handles getting and formatting information to be returned to telemetry ++ * when requested. ++ * ++ * @param cmd ++ * The cmd that was requested by the client. ++ * @param params ++ * Contains data required by the callback function. ++ * @param arg ++ * The opaque value that was passed to rte_telemetry_register_cmd_arg(). ++ * @param info ++ * The information to be returned to the caller. ++ * ++ * @return ++ * Length of buffer used on success. ++ * @return ++ * Negative integer on error. ++ */ ++typedef int (*telemetry_arg_cb)(const char *cmd, const char *params, void *arg, ++ struct rte_tel_data *info); ++ + /** + * Used for handling data received over a telemetry socket. + * +@@ -367,6 +391,28 @@ typedef void * (*handler)(void *sock_id); + int + rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help); + ++/** ++ * Used when registering a command and callback function with telemetry. ++ * ++ * @param cmd ++ * The command to register with telemetry. ++ * @param fn ++ * Callback function to be called when the command is requested. ++ * @param arg ++ * An opaque value that will be passed to the callback function. ++ * @param help ++ * Help text for the command. ++ * ++ * @return ++ * 0 on success. ++ * @return ++ * -EINVAL for invalid parameters failure. ++ * @return ++ * -ENOMEM for mem allocation failure. ++ */ ++__rte_experimental ++int ++rte_telemetry_register_cmd_arg(const char *cmd, telemetry_arg_cb fn, void *arg, const char *help); + + /** + * Get a pointer to a container with memory allocated. The container is to be +diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c +index 92982842a8..8345991706 100644 +--- a/lib/telemetry/telemetry.c ++++ b/lib/telemetry/telemetry.c +@@ -37,6 +37,8 @@ client_handler(void *socket); + struct cmd_callback { + char cmd[MAX_CMD_LEN]; + telemetry_cb fn; ++ telemetry_arg_cb fn_arg; ++ void *arg; + char help[RTE_TEL_MAX_STRING_LEN]; + }; + +@@ -67,14 +69,15 @@ static rte_spinlock_t callback_sl = RTE_SPINLOCK_INITIALIZER; + static RTE_ATOMIC(uint16_t) v2_clients; + #endif /* !RTE_EXEC_ENV_WINDOWS */ + +-int +-rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) ++static int ++register_cmd(const char *cmd, const char *help, ++ telemetry_cb fn, telemetry_arg_cb fn_arg, void *arg) + { + struct cmd_callback *new_callbacks; + const char *cmdp = cmd; + int i = 0; + +- if (strlen(cmd) >= MAX_CMD_LEN || fn == NULL || cmd[0] != '/' ++ if (strlen(cmd) >= MAX_CMD_LEN || (fn == NULL && fn_arg == NULL) || cmd[0] != '/' + || strlen(help) >= RTE_TEL_MAX_STRING_LEN) + return -EINVAL; + +@@ -101,6 +104,8 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) + + strlcpy(callbacks[i].cmd, cmd, MAX_CMD_LEN); + callbacks[i].fn = fn; ++ callbacks[i].fn_arg = fn_arg; ++ callbacks[i].arg = arg; + strlcpy(callbacks[i].help, help, RTE_TEL_MAX_STRING_LEN); + num_callbacks++; + rte_spinlock_unlock(&callback_sl); +@@ -108,6 +113,18 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) + return 0; + } + ++int ++rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) ++{ ++ return register_cmd(cmd, help, fn, NULL, NULL); ++} ++ ++int ++rte_telemetry_register_cmd_arg(const char *cmd, telemetry_arg_cb fn, void *arg, const char *help) ++{ ++ return register_cmd(cmd, help, NULL, fn, arg); ++} ++ + #ifndef RTE_EXEC_ENV_WINDOWS + + static int +@@ -344,11 +361,16 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) + } + + static void +-perform_command(telemetry_cb fn, const char *cmd, const char *param, int s) ++perform_command(const struct cmd_callback *cb, const char *cmd, const char *param, int s) + { + struct rte_tel_data data = {0}; ++ int ret; ++ ++ if (cb->fn_arg != NULL) ++ ret = cb->fn_arg(cmd, param, cb->arg, &data); ++ else ++ ret = cb->fn(cmd, param, &data); + +- int ret = fn(cmd, param, &data); + if (ret < 0) { + char out_buf[MAX_CMD_LEN + 10]; + int used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":null}", +@@ -387,19 +409,19 @@ client_handler(void *sock_id) + buffer[bytes] = 0; + const char *cmd = strtok(buffer, ","); + const char *param = strtok(NULL, "\0"); +- telemetry_cb fn = unknown_command; ++ struct cmd_callback cb = {.fn = unknown_command}; + int i; + + if (cmd && strlen(cmd) < MAX_CMD_LEN) { + rte_spinlock_lock(&callback_sl); + for (i = 0; i < num_callbacks; i++) + if (strcmp(cmd, callbacks[i].cmd) == 0) { +- fn = callbacks[i].fn; ++ cb = callbacks[i]; + break; + } + rte_spinlock_unlock(&callback_sl); + } +- perform_command(fn, cmd, param, s); ++ perform_command(&cb, cmd, param, s); + + bytes = read(s, buffer, sizeof(buffer) - 1); + } +diff --git a/lib/telemetry/version.map b/lib/telemetry/version.map +index 7d12c92905..74acbf3f0d 100644 +--- a/lib/telemetry/version.map ++++ b/lib/telemetry/version.map +@@ -28,6 +28,9 @@ EXPERIMENTAL { + rte_tel_data_add_array_uint_hex; + rte_tel_data_add_dict_uint_hex; + ++ # added in 24.11 ++ rte_telemetry_register_cmd_arg; ++ + local: *; + }; + +-- +2.20.1.windows.1 + diff --git a/0057-ethdev-fix-race-on-ports-in-telemetry-endpoints.patch b/0057-ethdev-fix-race-on-ports-in-telemetry-endpoints.patch new file mode 100644 index 0000000..510d609 --- /dev/null +++ b/0057-ethdev-fix-race-on-ports-in-telemetry-endpoints.patch @@ -0,0 +1,130 @@ +From b4003561f3345fd745a6636cfa4b89711338e3f1 Mon Sep 17 00:00:00 2001 +From: Robin Jarry +Date: Mon, 14 Oct 2024 21:32:37 +0200 +Subject: ethdev: fix race on ports in telemetry endpoints + +[ upstream commit 6f96937dada54d5cfc8def0955b0807759b45ac4 ] + +While invoking telemetry commands (which may happen at any time, out of +control of the application), an application thread may concurrently +add/remove ports. The telemetry callbacks may then access partially +initialized/uninitialised ethdev data. + +Reuse the ethdev lock that protects port allocation/destruction and the +new telemetry callback register api that takes an additional private +argument. Pass eth_dev_telemetry_do as the main callback and the actual +endpoint callbacks as private argument. + +Fixes: c190daedb9b1 ("ethdev: add telemetry callbacks") +Cc: stable@dpdk.org + +Signed-off-by: Robin Jarry +Acked-by: Bruce Richardson +Acked-by: Stephen Hemminger +--- + lib/ethdev/rte_ethdev_telemetry.c | 69 ++++++++++++++++++++++--------- + 1 file changed, 50 insertions(+), 19 deletions(-) + +diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c +index b01028ce9b..128c8e0012 100644 +--- a/lib/ethdev/rte_ethdev_telemetry.c ++++ b/lib/ethdev/rte_ethdev_telemetry.c +@@ -1395,45 +1395,76 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused, + return ret; + } + ++static int eth_dev_telemetry_do(const char *cmd, const char *params, void *arg, ++ struct rte_tel_data *d) ++{ ++ telemetry_cb fn = arg; ++ int ret; ++ ++ /* Protect against port removal while invoking callback, calling ethdev API. */ ++ rte_spinlock_lock(rte_mcfg_ethdev_get_lock()); ++ ret = fn(cmd, params, d); ++ rte_spinlock_unlock(rte_mcfg_ethdev_get_lock()); ++ ++ return ret; ++} ++ + RTE_INIT(ethdev_init_telemetry) + { +- rte_telemetry_register_cmd("/ethdev/list", eth_dev_handle_port_list, ++ rte_telemetry_register_cmd_arg("/ethdev/list", ++ eth_dev_telemetry_do, eth_dev_handle_port_list, + "Returns list of available ethdev ports. Takes no parameters"); +- rte_telemetry_register_cmd("/ethdev/stats", eth_dev_handle_port_stats, ++ rte_telemetry_register_cmd_arg("/ethdev/stats", ++ eth_dev_telemetry_do, eth_dev_handle_port_stats, + "Returns the common stats for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/xstats", eth_dev_handle_port_xstats, ++ rte_telemetry_register_cmd_arg("/ethdev/xstats", ++ eth_dev_telemetry_do, eth_dev_handle_port_xstats, + "Returns the extended stats for a port. Parameters: int port_id,hide_zero=true|false(Optional for indicates hide zero xstats)"); + #ifndef RTE_EXEC_ENV_WINDOWS +- rte_telemetry_register_cmd("/ethdev/dump_priv", eth_dev_handle_port_dump_priv, ++ rte_telemetry_register_cmd_arg("/ethdev/dump_priv", ++ eth_dev_telemetry_do, eth_dev_handle_port_dump_priv, + "Returns dump private information for a port. Parameters: int port_id"); + #endif +- rte_telemetry_register_cmd("/ethdev/link_status", +- eth_dev_handle_port_link_status, ++ rte_telemetry_register_cmd_arg("/ethdev/link_status", ++ eth_dev_telemetry_do, eth_dev_handle_port_link_status, + "Returns the link status for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/info", eth_dev_handle_port_info, ++ rte_telemetry_register_cmd_arg("/ethdev/info", ++ eth_dev_telemetry_do, eth_dev_handle_port_info, + "Returns the device info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/module_eeprom", eth_dev_handle_port_module_eeprom, ++ rte_telemetry_register_cmd_arg("/ethdev/module_eeprom", ++ eth_dev_telemetry_do, eth_dev_handle_port_module_eeprom, + "Returns module EEPROM info with SFF specs. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/macs", eth_dev_handle_port_macs, ++ rte_telemetry_register_cmd_arg("/ethdev/macs", ++ eth_dev_telemetry_do, eth_dev_handle_port_macs, + "Returns the MAC addresses for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/flow_ctrl", eth_dev_handle_port_flow_ctrl, ++ rte_telemetry_register_cmd_arg("/ethdev/flow_ctrl", ++ eth_dev_telemetry_do, eth_dev_handle_port_flow_ctrl, + "Returns flow ctrl info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/rx_queue", eth_dev_handle_port_rxq, ++ rte_telemetry_register_cmd_arg("/ethdev/rx_queue", ++ eth_dev_telemetry_do, eth_dev_handle_port_rxq, + "Returns Rx queue info for a port. Parameters: int port_id, int queue_id (Optional if only one queue)"); +- rte_telemetry_register_cmd("/ethdev/tx_queue", eth_dev_handle_port_txq, ++ rte_telemetry_register_cmd_arg("/ethdev/tx_queue", ++ eth_dev_telemetry_do, eth_dev_handle_port_txq, + "Returns Tx queue info for a port. Parameters: int port_id, int queue_id (Optional if only one queue)"); +- rte_telemetry_register_cmd("/ethdev/dcb", eth_dev_handle_port_dcb, ++ rte_telemetry_register_cmd_arg("/ethdev/dcb", ++ eth_dev_telemetry_do, eth_dev_handle_port_dcb, + "Returns DCB info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/rss_info", eth_dev_handle_port_rss_info, ++ rte_telemetry_register_cmd_arg("/ethdev/rss_info", ++ eth_dev_telemetry_do, eth_dev_handle_port_rss_info, + "Returns RSS info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/fec", eth_dev_handle_port_fec, ++ rte_telemetry_register_cmd_arg("/ethdev/fec", ++ eth_dev_telemetry_do, eth_dev_handle_port_fec, + "Returns FEC info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/vlan", eth_dev_handle_port_vlan, ++ rte_telemetry_register_cmd_arg("/ethdev/vlan", ++ eth_dev_telemetry_do, eth_dev_handle_port_vlan, + "Returns VLAN info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/tm_capability", eth_dev_handle_port_tm_caps, ++ rte_telemetry_register_cmd_arg("/ethdev/tm_capability", ++ eth_dev_telemetry_do, eth_dev_handle_port_tm_caps, + "Returns TM Capabilities info for a port. Parameters: int port_id"); +- rte_telemetry_register_cmd("/ethdev/tm_level_capability", eth_dev_handle_port_tm_level_caps, ++ rte_telemetry_register_cmd_arg("/ethdev/tm_level_capability", ++ eth_dev_telemetry_do, eth_dev_handle_port_tm_level_caps, + "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, ++ rte_telemetry_register_cmd_arg("/ethdev/tm_node_capability", ++ eth_dev_telemetry_do, 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)"); + } +-- +2.20.1.windows.1 + diff --git a/0058-ethdev-add-report-of-register-names-and-filter.patch b/0058-ethdev-add-report-of-register-names-and-filter.patch new file mode 100644 index 0000000..16c714c --- /dev/null +++ b/0058-ethdev-add-report-of-register-names-and-filter.patch @@ -0,0 +1,191 @@ +From cdb9ef406cbbb4abf95667b9e616ae2309b90aa9 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:42 +0800 +Subject: ethdev: add report of register names and filter + +[ upstream commit 083db2ed9e9ea321f37fb49a9ea118446c04a782 ] + +This patch adds "filter" and "names" fields to "rte_dev_reg_info" +structure. Names of registers in data fields can be reported and +the registers can be filtered by their module names. + +The new API rte_eth_dev_get_reg_info_ext() is added to support +reporting names and filtering by modules. And the original API +rte_eth_dev_get_reg_info() does not use the names and filter fields. +A local variable is used in rte_eth_dev_get_reg_info for +compatibility. If the drivers does not report the names, set them +to "index_XXX", which means the location in the register table. + +Signed-off-by: Jie Hai +Acked-by: Huisong Li +Acked-by: Chengwen Feng +Reviewed-by: Ferruh Yigit +--- + lib/ethdev/ethdev_trace.h | 2 ++ + lib/ethdev/rte_dev_info.h | 11 +++++++++++ + lib/ethdev/rte_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++ + lib/ethdev/rte_ethdev.h | 29 +++++++++++++++++++++++++++++ + lib/ethdev/version.map | 1 + + 5 files changed, 81 insertions(+) + +diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h +index 1b1ae0cfe8..c327f97763 100644 +--- a/lib/ethdev/ethdev_trace.h ++++ b/lib/ethdev/ethdev_trace.h +@@ -1152,6 +1152,8 @@ RTE_TRACE_POINT( + rte_trace_point_emit_u32(info->length); + rte_trace_point_emit_u32(info->width); + rte_trace_point_emit_u32(info->version); ++ rte_trace_point_emit_ptr(info->names); ++ rte_trace_point_emit_ptr(info->filter); + rte_trace_point_emit_int(ret); + ) + +diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h +index 67cf0ae526..26b777f983 100644 +--- a/lib/ethdev/rte_dev_info.h ++++ b/lib/ethdev/rte_dev_info.h +@@ -11,6 +11,11 @@ extern "C" { + + #include + ++#define RTE_ETH_REG_NAME_SIZE 64 ++struct rte_eth_reg_name { ++ char name[RTE_ETH_REG_NAME_SIZE]; ++}; ++ + /* + * Placeholder for accessing device registers + */ +@@ -20,6 +25,12 @@ struct rte_dev_reg_info { + uint32_t length; /**< Number of registers to fetch */ + uint32_t width; /**< Size of device register */ + uint32_t version; /**< Device version */ ++ /** ++ * Name of target module, filter for target subset of registers. ++ * This field could affects register selection for data/length/names. ++ */ ++ const char *filter; ++ struct rte_eth_reg_name *names; /**< Registers name saver */ + }; + + /* +diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c +index 8438f2a776..cfb4cfbb8b 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(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, ®_info); ++ if (ret != 0) ++ return ret; ++ ++ info->length = reg_info.length; ++ info->width = reg_info.width; ++ info->version = reg_info.version; ++ info->offset = reg_info.offset; ++ ++ return 0; ++} ++ ++int ++rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info) + { + struct rte_eth_dev *dev; ++ uint32_t i; + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); +@@ -6402,12 +6431,21 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) + return -EINVAL; + } + ++ if (info->names != NULL && info->length != 0) ++ memset(info->names, 0, sizeof(struct rte_eth_reg_name) * info->length); ++ + if (*dev->dev_ops->get_reg == NULL) + return -ENOTSUP; + ret = eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info)); + + rte_ethdev_trace_get_reg_info(port_id, info, ret); + ++ /* Report the default names if drivers not report. */ ++ if (ret == 0 && info->names != NULL && strlen(info->names[0].name) == 0) { ++ for (i = 0; i < info->length; i++) ++ snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE, ++ "index_%u", info->offset + i); ++ } + return ret; + } + +diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h +index b95ae691ce..480a04b668 100644 +--- a/lib/ethdev/rte_ethdev.h ++++ b/lib/ethdev/rte_ethdev.h +@@ -5057,6 +5057,35 @@ __rte_experimental + int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id, + struct rte_power_monitor_cond *pmc); + ++/** ++ * Retrieve the filtered device registers (values and names) and ++ * register attributes (number of registers and register size) ++ * ++ * @param port_id ++ * The port identifier of the Ethernet device. ++ * @param info ++ * Pointer to rte_dev_reg_info structure to fill in. ++ * - If info->filter is NULL, return info for all registers (seen as filter ++ * none). ++ * - If info->filter is not NULL, return error if the driver does not support ++ * filter. Fill the length field with filtered register number. ++ * - If info->data is NULL, the function fills in the width and length fields. ++ * - If info->data is not NULL, ethdev considers there are enough spaces to ++ * store the registers, and the values of registers with the filter string ++ * as the module name are put into the buffer pointed at by info->data. ++ * - If info->names is not NULL, drivers should fill it or the ethdev fills it ++ * with default names. ++ * @return ++ * - (0) if successful. ++ * - (-ENOTSUP) if hardware doesn't support. ++ * - (-EINVAL) if bad parameter. ++ * - (-ENODEV) if *port_id* invalid. ++ * - (-EIO) if device is removed. ++ * - others depends on the specific operations implementation. ++ */ ++__rte_experimental ++int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info); ++ + /** + * Retrieve device registers and register attributes (number of registers and + * register size) +diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map +index a050baab0f..60f787bbb9 100644 +--- a/lib/ethdev/version.map ++++ b/lib/ethdev/version.map +@@ -319,6 +319,7 @@ EXPERIMENTAL { + + # added in 24.03 + rte_eth_find_rss_algo; ++ rte_eth_dev_get_reg_info_ext; + }; + + INTERNAL { +-- +2.20.1.windows.1 + diff --git a/0059-ethdev-add-telemetry-command-for-registers.patch b/0059-ethdev-add-telemetry-command-for-registers.patch new file mode 100644 index 0000000..708402d --- /dev/null +++ b/0059-ethdev-add-telemetry-command-for-registers.patch @@ -0,0 +1,193 @@ +From 3f85d1cd33b037b73ac6b5a9746cb8e01c52dfb7 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:43 +0800 +Subject: ethdev: add telemetry command for registers + +[ upstream commit d916d27e3dca9d2e19e411fff9208929a7c7cbdf ] + +This patch adds a telemetry command for registers dump, +and supports obtaining the registers of a specified module. + +In one way, the number of registers that can be exported +is limited by the number of elements carried by dict and +container. In another way, the length of the string +exported by telemetry is limited by MAX_OUTPUT_LEN. +Therefore, when the number of registers to be exported +exceeds, some information will be lost. Warn on the former +case. + +An example usage is shown below: +--> /ethdev/regs,0,ring +{ + "/ethdev/regs": { + "registers_length": 318, + "registers_width": 4, + "register_offset": "0x0", + "version": "0x1140011", + "group_0": { + "Q0_ring_rx_bd_num": "0x0", + "Q0_ring_rx_bd_len": "0x0", + ... + }, + "group_1": { + ... + }, + ... +} + +Signed-off-by: Jie Hai +Reviewed-by: Ferruh Yigit +Acked-by: Chengwen Feng +--- + lib/ethdev/rte_ethdev_telemetry.c | 130 ++++++++++++++++++++++++++++++ + 1 file changed, 130 insertions(+) + +diff --git a/lib/ethdev/rte_ethdev_telemetry.c b/lib/ethdev/rte_ethdev_telemetry.c +index 128c8e0012..343f1817c7 100644 +--- a/lib/ethdev/rte_ethdev_telemetry.c ++++ b/lib/ethdev/rte_ethdev_telemetry.c +@@ -1395,6 +1395,134 @@ eth_dev_handle_port_tm_node_caps(const char *cmd __rte_unused, + return ret; + } + ++static void ++eth_dev_add_reg_data(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info, ++ uint32_t idx) ++{ ++ if (reg_info->width == sizeof(uint32_t)) ++ rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name, ++ *((uint32_t *)reg_info->data + idx), 0); ++ else ++ rte_tel_data_add_dict_uint_hex(d, reg_info->names[idx].name, ++ *((uint64_t *)reg_info->data + idx), 0); ++} ++ ++static int ++eth_dev_store_regs(struct rte_tel_data *d, struct rte_dev_reg_info *reg_info) ++{ ++ struct rte_tel_data *groups[RTE_TEL_MAX_DICT_ENTRIES]; ++ char group_name[RTE_TEL_MAX_STRING_LEN] = {0}; ++ struct rte_tel_data *group = NULL; ++ uint32_t grp_num = 0; ++ uint32_t i, max_cap; ++ int ret; ++ ++ rte_tel_data_start_dict(d); ++ rte_tel_data_add_dict_uint(d, "register_length", reg_info->length); ++ rte_tel_data_add_dict_uint(d, "register_width", reg_info->width); ++ rte_tel_data_add_dict_uint_hex(d, "register_offset", reg_info->offset, 0); ++ rte_tel_data_add_dict_uint_hex(d, "version", reg_info->version, 0); ++ ++ max_cap = (RTE_TEL_MAX_DICT_ENTRIES - 4) * RTE_TEL_MAX_DICT_ENTRIES; ++ if (reg_info->length > max_cap) { ++ RTE_ETHDEV_LOG(WARNING, ++ "Registers to be displayed are reduced from %u to %u due to limited capacity", ++ reg_info->length, max_cap); ++ reg_info->length = max_cap; ++ } ++ ++ for (i = 0; i < reg_info->length; i++) { ++ if (i % RTE_TEL_MAX_DICT_ENTRIES != 0) { ++ eth_dev_add_reg_data(group, reg_info, i); ++ continue; ++ } ++ ++ group = rte_tel_data_alloc(); ++ if (group == NULL) { ++ ret = -ENOMEM; ++ RTE_ETHDEV_LOG(WARNING, "No enough memory for group data"); ++ goto out; ++ } ++ groups[grp_num++] = group; ++ rte_tel_data_start_dict(group); ++ eth_dev_add_reg_data(group, reg_info, i); ++ } ++ ++ for (i = 0; i < grp_num; i++) { ++ snprintf(group_name, RTE_TEL_MAX_STRING_LEN, "group_%u", i); ++ rte_tel_data_add_dict_container(d, group_name, groups[i], 0); ++ } ++ return 0; ++out: ++ for (i = 0; i < grp_num; i++) ++ rte_tel_data_free(groups[i]); ++ ++ return ret; ++} ++ ++static int ++eth_dev_get_port_regs(int port_id, struct rte_tel_data *d, char *filter) ++{ ++ struct rte_dev_reg_info reg_info; ++ int ret; ++ ++ memset(®_info, 0, sizeof(reg_info)); ++ reg_info.filter = filter; ++ ++ ret = rte_eth_dev_get_reg_info_ext(port_id, ®_info); ++ if (ret != 0) { ++ RTE_ETHDEV_LOG(ERR, "Failed to get device reg info: %d", ret); ++ return ret; ++ } ++ ++ reg_info.data = calloc(reg_info.length, reg_info.width); ++ if (reg_info.data == NULL) { ++ RTE_ETHDEV_LOG(ERR, "Failed to allocate memory for reg_info.data"); ++ return -ENOMEM; ++ } ++ ++ reg_info.names = calloc(reg_info.length, sizeof(struct rte_eth_reg_name)); ++ if (reg_info.names == NULL) { ++ RTE_ETHDEV_LOG(ERR, "Failed to allocate memory for reg_info.names"); ++ free(reg_info.data); ++ return -ENOMEM; ++ } ++ ++ ret = rte_eth_dev_get_reg_info_ext(port_id, ®_info); ++ if (ret != 0) { ++ RTE_ETHDEV_LOG(ERR, "Failed to get device reg info: %d", ret); ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ ret = eth_dev_store_regs(d, ®_info); ++out: ++ free(reg_info.data); ++ free(reg_info.names); ++ ++ return ret; ++} ++ ++static int ++eth_dev_handle_port_regs(const char *cmd __rte_unused, ++ const char *params, ++ struct rte_tel_data *d) ++{ ++ char *filter, *end_param; ++ uint16_t port_id; ++ int ret; ++ ++ ret = eth_dev_parse_port_params(params, &port_id, &end_param, true); ++ if (ret != 0) ++ return ret; ++ ++ filter = strtok(end_param, ","); ++ if (filter != NULL && strlen(filter) == 0) ++ filter = NULL; ++ ++ return eth_dev_get_port_regs(port_id, d, filter); ++} ++ + static int eth_dev_telemetry_do(const char *cmd, const char *params, void *arg, + struct rte_tel_data *d) + { +@@ -1467,4 +1595,6 @@ RTE_INIT(ethdev_init_telemetry) + rte_telemetry_register_cmd_arg("/ethdev/tm_node_capability", + eth_dev_telemetry_do, eth_dev_handle_port_tm_node_caps, + "Returns TM Node Capabilities info for a port. Parameters: int port_id, int node_id (see tm_capability for the max)"); ++ rte_telemetry_register_cmd("/ethdev/regs", eth_dev_handle_port_regs, ++ "Returns all or filtered registers info for a port. Parameters: int port_id, string module_name (Optional if show all)"); + } +-- +2.20.1.windows.1 + diff --git a/0060-net-hns3-remove-some-basic-address-dump.patch b/0060-net-hns3-remove-some-basic-address-dump.patch new file mode 100644 index 0000000..8c68b23 --- /dev/null +++ b/0060-net-hns3-remove-some-basic-address-dump.patch @@ -0,0 +1,61 @@ +From ed9695ba9502b33f2f62b48beecfce1c4e70ad66 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:44 +0800 +Subject: [PATCH] net/hns3: remove some basic address dump + +[ upstream commit c8b7bec0ef23f53303c9cf03cfea44f1eb208738 ] + +For security reasons, some address registers are not suitable +to be exposed, remove them. + +Cc: stable@dpdk.org + +Signed-off-by: Jie Hai +Acked-by: Huisong Li +Acked-by: Chengwen Feng +--- + drivers/net/hns3/hns3_regs.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index be1be6a..53d829a 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -17,13 +17,9 @@ + + static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines); + +-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_ADDR_L_REG, +- HNS3_CMDQ_TX_ADDR_H_REG, +- HNS3_CMDQ_TX_DEPTH_REG, ++static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG, + HNS3_CMDQ_TX_TAIL_REG, + HNS3_CMDQ_TX_HEAD_REG, +- HNS3_CMDQ_RX_ADDR_L_REG, +- HNS3_CMDQ_RX_ADDR_H_REG, + HNS3_CMDQ_RX_DEPTH_REG, + HNS3_CMDQ_RX_TAIL_REG, + HNS3_CMDQ_RX_HEAD_REG, +@@ -44,9 +40,7 @@ static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE, + HNS3_FUN_RST_ING, + HNS3_GRO_EN_REG}; + +-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG, +- HNS3_RING_RX_BASEADDR_H_REG, +- HNS3_RING_RX_BD_NUM_REG, ++static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG, + HNS3_RING_RX_BD_LEN_REG, + HNS3_RING_RX_EN_REG, + HNS3_RING_RX_MERGE_EN_REG, +@@ -57,8 +51,6 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG, + HNS3_RING_RX_FBD_OFFSET_REG, + HNS3_RING_RX_STASH_REG, + HNS3_RING_RX_BD_ERR_REG, +- HNS3_RING_TX_BASEADDR_L_REG, +- HNS3_RING_TX_BASEADDR_H_REG, + HNS3_RING_TX_BD_NUM_REG, + HNS3_RING_TX_EN_REG, + HNS3_RING_TX_PRIORITY_REG, +-- +2.33.0 + diff --git a/0061-net-hns3-fix-dump-counter-of-registers.patch b/0061-net-hns3-fix-dump-counter-of-registers.patch new file mode 100644 index 0000000..297488d --- /dev/null +++ b/0061-net-hns3-fix-dump-counter-of-registers.patch @@ -0,0 +1,37 @@ +From 1c230057a50db378f46e86e6f7fbcf8266e62fba Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:45 +0800 +Subject: [PATCH] net/hns3: fix dump counter of registers + +[ upstream commit e9b82b4d54c019973ffcb5f404ba920494f70513 ] + +Since the driver dumps the queue interrupt registers according +to the intr_tqps_num, the counter should be the same. + +Fixes: acb3260fac5c ("net/hns3: fix dump register out of range") +Fixes: 936eda25e8da ("net/hns3: support dump register") +Cc: stable@dpdk.org + +Signed-off-by: Jie Hai +Acked-by: Huisong Li +Acked-by: Chengwen Feng +--- + 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 53d829a..d9c5464 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -127,7 +127,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1; + + len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num + +- tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE; ++ tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE; + + if (!hns->is_vf) { + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +-- +2.33.0 + diff --git a/0062-net-hns3-remove-separators-between-register-module.patch b/0062-net-hns3-remove-separators-between-register-module.patch new file mode 100644 index 0000000..5f309b0 --- /dev/null +++ b/0062-net-hns3-remove-separators-between-register-module.patch @@ -0,0 +1,205 @@ +From 6fb80992bb7e4bebad3890a73ad33bf1a511a545 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:46 +0800 +Subject: [PATCH] net/hns3: remove separators between register module + +[ upstream commit 7fddd3cac6a3730fc016480418ce693b4a491cb5 ] + +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 +Reviewed-by: Huisong Li +Acked-by: Chengwen Feng +--- + drivers/net/hns3/hns3_regs.c | 68 ++++++++++-------------------------- + 1 file changed, 18 insertions(+), 50 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index d9c5464..c8e3fb1 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -10,12 +10,9 @@ + #include "hns3_rxtx.h" + #include "hns3_regs.h" + +-#define MAX_SEPARATE_NUM 4 +-#define SEPARATOR_VALUE 0xFFFFFFFF +-#define REG_NUM_PER_LINE 4 +-#define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(uint32_t)) ++#define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t)) + +-static int hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines); ++static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count); + + static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG, + HNS3_CMDQ_TX_TAIL_REG, +@@ -111,23 +108,21 @@ static int + hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +- uint32_t cmdq_lines, common_lines, ring_lines, tqp_intr_lines; + uint32_t regs_num_32_bit, regs_num_64_bit; +- uint32_t dfx_reg_lines; ++ uint32_t dfx_reg_cnt; ++ uint32_t common_cnt; + uint32_t len; + int ret; + +- cmdq_lines = sizeof(cmdq_reg_addrs) / REG_LEN_PER_LINE + 1; + if (hns->is_vf) +- common_lines = +- sizeof(common_vf_reg_addrs) / REG_LEN_PER_LINE + 1; ++ common_cnt = sizeof(common_vf_reg_addrs); + else +- common_lines = sizeof(common_reg_addrs) / REG_LEN_PER_LINE + 1; +- ring_lines = sizeof(ring_reg_addrs) / REG_LEN_PER_LINE + 1; +- tqp_intr_lines = sizeof(tqp_intr_reg_addrs) / REG_LEN_PER_LINE + 1; ++ common_cnt = sizeof(common_reg_addrs); + +- len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num + +- tqp_intr_lines * hw->intr_tqps_num) * REG_NUM_PER_LINE; ++ len = sizeof(cmdq_reg_addrs) + common_cnt + ++ sizeof(ring_reg_addrs) * hw->tqps_num + ++ sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num; ++ len /= sizeof(uint32_t); + + if (!hns->is_vf) { + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +@@ -136,18 +131,16 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + "ret = %d.", ret); + return ret; + } +- dfx_reg_lines = regs_num_32_bit * sizeof(uint32_t) / +- REG_LEN_PER_LINE + 1; +- dfx_reg_lines += regs_num_64_bit * sizeof(uint64_t) / +- REG_LEN_PER_LINE + 1; ++ dfx_reg_cnt = regs_num_32_bit + ++ regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; + +- ret = hns3_get_dfx_reg_line(hw, &dfx_reg_lines); ++ ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt); + if (ret) { + hns3_err(hw, "fail to get the number of dfx registers, " + "ret = %d.", ret); + return ret; + } +- len += dfx_reg_lines * REG_NUM_PER_LINE; ++ len += dfx_reg_cnt; + } + + *length = len; +@@ -268,18 +261,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + return 0; + } + +-static int +-hns3_insert_reg_separator(int reg_num, uint32_t *data) +-{ +- int separator_num; +- int i; +- +- separator_num = MAX_SEPARATE_NUM - reg_num % REG_NUM_PER_LINE; +- for (i = 0; i < separator_num; i++) +- *data++ = SEPARATOR_VALUE; +- return separator_num; +-} +- + static int + hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + { +@@ -294,7 +275,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t); + for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]); +- data += hns3_insert_reg_separator(reg_num, data); + + if (hns->is_vf) + reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t); +@@ -305,7 +285,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + *data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]); + else + *data++ = hns3_read_dev(hw, common_reg_addrs[i]); +- data += hns3_insert_reg_separator(reg_num, data); + + reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t); + for (j = 0; j < hw->tqps_num; j++) { +@@ -313,7 +292,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, + ring_reg_addrs[i] + reg_offset); +- data += hns3_insert_reg_separator(reg_num, data); + } + + reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t); +@@ -322,7 +300,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + for (i = 0; i < reg_num; i++) + *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] + + reg_offset); +- data += hns3_insert_reg_separator(reg_num, data); + } + return data - origin_data_ptr; + } +@@ -398,17 +375,15 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg) + index = i % HNS3_CMD_DESC_DATA_NUM; + *reg++ = desc[desc_index].data[index]; + } +- reg_num += hns3_insert_reg_separator(reg_num, reg); + + return reg_num; + } + + static int +-hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines) ++hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count) + { + int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); + uint32_t bd_num_list[opcode_num]; +- uint32_t bd_num, data_len; + int ret; + int i; + +@@ -416,11 +391,8 @@ hns3_get_dfx_reg_line(struct hns3_hw *hw, uint32_t *lines) + if (ret) + return ret; + +- for (i = 0; i < opcode_num; i++) { +- bd_num = bd_num_list[i]; +- data_len = bd_num * HNS3_CMD_DESC_DATA_NUM * sizeof(uint32_t); +- *lines += data_len / REG_LEN_PER_LINE + 1; +- } ++ for (i = 0; i < opcode_num; i++) ++ *count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM; + + return 0; + } +@@ -467,7 +439,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data) + int + hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + { +-#define HNS3_64_BIT_REG_SIZE (sizeof(uint64_t) / sizeof(uint32_t)) + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + uint32_t regs_num_32_bit; +@@ -512,16 +483,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + return ret; + } + data += regs_num_32_bit; +- data += hns3_insert_reg_separator(regs_num_32_bit, data); + + ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data); + if (ret) { + hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); + return ret; + } +- data += regs_num_64_bit * HNS3_64_BIT_REG_SIZE; +- data += hns3_insert_reg_separator(regs_num_64_bit * +- HNS3_64_BIT_REG_SIZE, data); ++ data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; + + return hns3_get_dfx_regs(hw, (void **)&data); + } +-- +2.33.0 + diff --git a/0063-net-hns3-refactor-register-dump.patch b/0063-net-hns3-refactor-register-dump.patch new file mode 100644 index 0000000..05ea7c0 --- /dev/null +++ b/0063-net-hns3-refactor-register-dump.patch @@ -0,0 +1,275 @@ +From f1948283fb0d54c33db64897382d0c7c0d29eedc Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:47 +0800 +Subject: [PATCH] net/hns3: refactor register dump + +[ upstream commit 8cdddc252dd5320bbbb1df948bbdd8d19f8fda22 ] + +This patch refactors codes dumping registers from firmware. + +Signed-off-by: Jie Hai +Acked-by: Chengwen Feng +--- + drivers/net/hns3/hns3_regs.c | 203 ++++++++++++++++++++--------------- + 1 file changed, 115 insertions(+), 88 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index c8e3fb1..c7dadbe 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -104,12 +104,93 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit, + return 0; + } + ++static int ++hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count) ++{ ++ uint32_t regs_num_32_bit, regs_num_64_bit; ++ int ret; ++ ++ ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); ++ if (ret) { ++ hns3_err(hw, "fail to get the number of registers, " ++ "ret = %d.", ret); ++ return ret; ++ } ++ ++ *count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; ++ return 0; ++} ++ ++static int ++hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list, ++ uint32_t list_size) ++{ ++#define HNS3_GET_DFX_REG_BD_NUM_SIZE 4 ++ struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE]; ++ uint32_t index, desc_index; ++ uint32_t bd_num; ++ uint32_t i; ++ int ret; ++ ++ for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ /* The last BD does not need a next flag */ ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true); ++ ++ ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE); ++ if (ret) { ++ hns3_err(hw, "fail to get dfx bd num, ret = %d.", ret); ++ return ret; ++ } ++ ++ /* The first data in the first BD is a reserved field */ ++ for (i = 1; i <= list_size; i++) { ++ desc_index = i / HNS3_CMD_DESC_DATA_NUM; ++ index = i % HNS3_CMD_DESC_DATA_NUM; ++ bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]); ++ bd_num_list[i - 1] = bd_num; ++ } ++ ++ return 0; ++} ++ ++static int ++hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count) ++{ ++ int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); ++ uint32_t bd_num_list[opcode_num]; ++ int ret; ++ int i; ++ ++ ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < opcode_num; i++) ++ *count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM; ++ ++ return 0; ++} ++ ++static int ++hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count) ++{ ++ int ret; ++ ++ ret = hns3_get_32_64_regs_cnt(hw, count); ++ if (ret < 0) ++ return ret; ++ ++ return hns3_get_dfx_reg_cnt(hw, count); ++} ++ + static int + hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +- uint32_t regs_num_32_bit, regs_num_64_bit; +- uint32_t dfx_reg_cnt; ++ uint32_t dfx_reg_cnt = 0; + uint32_t common_cnt; + uint32_t len; + int ret; +@@ -125,16 +206,7 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + len /= sizeof(uint32_t); + + if (!hns->is_vf) { +- ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +- if (ret) { +- hns3_err(hw, "fail to get the number of registers, " +- "ret = %d.", ret); +- return ret; +- } +- dfx_reg_cnt = regs_num_32_bit + +- regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; +- +- ret = hns3_get_dfx_reg_cnt(hw, &dfx_reg_cnt); ++ ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt); + if (ret) { + hns3_err(hw, "fail to get the number of dfx registers, " + "ret = %d.", ret); +@@ -304,41 +376,6 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) + return data - origin_data_ptr; + } + +-static int +-hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list, +- uint32_t list_size) +-{ +-#define HNS3_GET_DFX_REG_BD_NUM_SIZE 4 +- struct hns3_cmd_desc desc[HNS3_GET_DFX_REG_BD_NUM_SIZE]; +- uint32_t index, desc_index; +- uint32_t bd_num; +- uint32_t i; +- int ret; +- +- for (i = 0; i < HNS3_GET_DFX_REG_BD_NUM_SIZE - 1; i++) { +- hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true); +- desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- } +- /* The last BD does not need a next flag */ +- hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_DFX_BD_NUM, true); +- +- ret = hns3_cmd_send(hw, desc, HNS3_GET_DFX_REG_BD_NUM_SIZE); +- if (ret) { +- hns3_err(hw, "fail to get dfx bd num, ret = %d.\n", ret); +- return ret; +- } +- +- /* The first data in the first BD is a reserved field */ +- for (i = 1; i <= list_size; i++) { +- desc_index = i / HNS3_CMD_DESC_DATA_NUM; +- index = i % HNS3_CMD_DESC_DATA_NUM; +- bd_num = rte_le_to_cpu_32(desc[desc_index].data[index]); +- bd_num_list[i - 1] = bd_num; +- } +- +- return 0; +-} +- + static int + hns3_dfx_reg_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, + int bd_num, uint32_t opcode) +@@ -379,24 +416,6 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg) + return reg_num; + } + +-static int +-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count) +-{ +- int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); +- uint32_t bd_num_list[opcode_num]; +- int ret; +- int i; +- +- ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num); +- if (ret) +- return ret; +- +- for (i = 0; i < opcode_num; i++) +- *count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM; +- +- return 0; +-} +- + static int + hns3_get_dfx_regs(struct hns3_hw *hw, void **data) + { +@@ -436,13 +455,41 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data) + return ret; + } + ++static int ++hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data) ++{ ++ uint32_t regs_num_32_bit; ++ uint32_t regs_num_64_bit; ++ int ret; ++ ++ ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); ++ if (ret) { ++ hns3_err(hw, "Get register number failed, ret = %d", ret); ++ return ret; ++ } ++ ++ ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data); ++ if (ret) { ++ hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); ++ return ret; ++ } ++ data += regs_num_32_bit; ++ ++ ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data); ++ if (ret) { ++ hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); ++ return ret; ++ } ++ data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; ++ ++ return hns3_get_dfx_regs(hw, (void **)&data); ++} ++ + int + hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + { + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- uint32_t regs_num_32_bit; +- uint32_t regs_num_64_bit; + uint32_t length; + uint32_t *data; + int ret; +@@ -470,26 +517,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + if (hns->is_vf) + return 0; + +- ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +- if (ret) { +- hns3_err(hw, "Get register number failed, ret = %d", ret); +- return ret; +- } +- + /* fetching PF common registers values from firmware */ +- ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data); +- if (ret) { +- hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); +- return ret; +- } +- data += regs_num_32_bit; +- +- ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data); +- if (ret) { +- hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); +- return ret; +- } +- data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; +- +- return hns3_get_dfx_regs(hw, (void **)&data); ++ return hns3_get_regs_from_firmware(hw, data); + } +-- +2.33.0 + diff --git a/0064-net-hns3-support-reporting-names-of-registers.patch b/0064-net-hns3-support-reporting-names-of-registers.patch new file mode 100644 index 0000000..ca45970 --- /dev/null +++ b/0064-net-hns3-support-reporting-names-of-registers.patch @@ -0,0 +1,1283 @@ +From dbf5d274ff1d324a33672ce69457a214e4d371d3 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:48 +0800 +Subject: [PATCH] net/hns3: support reporting names of registers + +[ upstream commit dd4b8bba785faf9d1bb9c4460e75068e2822bdb3 ] + +This patch adds names for register lists, and support report +names of registers. Some registers has different names on +different platform, use names of HIP08 as default names. + +Signed-off-by: Jie Hai +Acked-by: Chengwen Feng +--- + drivers/net/hns3/hns3_regs.c | 1088 +++++++++++++++++++++++++++++----- + 1 file changed, 955 insertions(+), 133 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index c7dadbe..22151dd 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -14,73 +14,827 @@ + + static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count); + +-static const uint32_t cmdq_reg_addrs[] = {HNS3_CMDQ_TX_DEPTH_REG, +- HNS3_CMDQ_TX_TAIL_REG, +- HNS3_CMDQ_TX_HEAD_REG, +- HNS3_CMDQ_RX_DEPTH_REG, +- HNS3_CMDQ_RX_TAIL_REG, +- HNS3_CMDQ_RX_HEAD_REG, +- HNS3_VECTOR0_CMDQ_SRC_REG, +- HNS3_CMDQ_INTR_STS_REG, +- HNS3_CMDQ_INTR_EN_REG, +- HNS3_CMDQ_INTR_GEN_REG}; +- +-static const uint32_t common_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE, +- HNS3_VECTOR0_OTER_EN_REG, +- HNS3_MISC_RESET_STS_REG, +- HNS3_VECTOR0_OTHER_INT_STS_REG, +- HNS3_GLOBAL_RESET_REG, +- HNS3_FUN_RST_ING, +- HNS3_GRO_EN_REG}; +- +-static const uint32_t common_vf_reg_addrs[] = {HNS3_MISC_VECTOR_REG_BASE, +- HNS3_FUN_RST_ING, +- HNS3_GRO_EN_REG}; +- +-static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BD_NUM_REG, +- HNS3_RING_RX_BD_LEN_REG, +- HNS3_RING_RX_EN_REG, +- HNS3_RING_RX_MERGE_EN_REG, +- HNS3_RING_RX_TAIL_REG, +- HNS3_RING_RX_HEAD_REG, +- HNS3_RING_RX_FBDNUM_REG, +- HNS3_RING_RX_OFFSET_REG, +- HNS3_RING_RX_FBD_OFFSET_REG, +- HNS3_RING_RX_STASH_REG, +- HNS3_RING_RX_BD_ERR_REG, +- HNS3_RING_TX_BD_NUM_REG, +- HNS3_RING_TX_EN_REG, +- HNS3_RING_TX_PRIORITY_REG, +- HNS3_RING_TX_TC_REG, +- HNS3_RING_TX_MERGE_EN_REG, +- HNS3_RING_TX_TAIL_REG, +- HNS3_RING_TX_HEAD_REG, +- HNS3_RING_TX_FBDNUM_REG, +- HNS3_RING_TX_OFFSET_REG, +- HNS3_RING_TX_EBD_NUM_REG, +- HNS3_RING_TX_EBD_OFFSET_REG, +- HNS3_RING_TX_BD_ERR_REG, +- HNS3_RING_EN_REG}; +- +-static const uint32_t tqp_intr_reg_addrs[] = {HNS3_TQP_INTR_CTRL_REG, +- HNS3_TQP_INTR_GL0_REG, +- HNS3_TQP_INTR_GL1_REG, +- HNS3_TQP_INTR_GL2_REG, +- HNS3_TQP_INTR_RL_REG}; ++struct hns3_dirt_reg_entry { ++ const char *name; ++ uint32_t addr; ++}; ++ ++static const struct hns3_dirt_reg_entry cmdq_reg_list[] = { ++ {"cmdq_tx_depth", HNS3_CMDQ_TX_DEPTH_REG}, ++ {"cmdq_tx_tail", HNS3_CMDQ_TX_TAIL_REG}, ++ {"cmdq_tx_head", HNS3_CMDQ_TX_HEAD_REG}, ++ {"cmdq_rx_depth", HNS3_CMDQ_RX_DEPTH_REG}, ++ {"cmdq_rx_tail", HNS3_CMDQ_RX_TAIL_REG}, ++ {"cmdq_rx_head", HNS3_CMDQ_RX_HEAD_REG}, ++ {"vector0_cmdq_src", HNS3_VECTOR0_CMDQ_SRC_REG}, ++ {"cmdq_intr_sts", HNS3_CMDQ_INTR_STS_REG}, ++ {"cmdq_intr_en", HNS3_CMDQ_INTR_EN_REG}, ++ {"cmdq_intr_gen", HNS3_CMDQ_INTR_GEN_REG}, ++}; ++ ++static const struct hns3_dirt_reg_entry common_reg_list[] = { ++ {"misc_vector_reg_base", HNS3_MISC_VECTOR_REG_BASE}, ++ {"vector0_oter_en", HNS3_VECTOR0_OTER_EN_REG}, ++ {"misc_reset_sts", HNS3_MISC_RESET_STS_REG}, ++ {"vector0_other_int_sts", HNS3_VECTOR0_OTHER_INT_STS_REG}, ++ {"global_reset", HNS3_GLOBAL_RESET_REG}, ++ {"fun_rst_ing", HNS3_FUN_RST_ING}, ++ {"gro_en", HNS3_GRO_EN_REG}, ++}; ++ ++static const struct hns3_dirt_reg_entry common_vf_reg_list[] = { ++ {"misc_vector_reg_base", HNS3_MISC_VECTOR_REG_BASE}, ++ {"fun_rst_ing", HNS3_FUN_RST_ING}, ++ {"gro_en", HNS3_GRO_EN_REG}, ++}; ++ ++static const struct hns3_dirt_reg_entry ring_reg_list[] = { ++ {"ring_rx_bd_num", HNS3_RING_RX_BD_NUM_REG}, ++ {"ring_rx_bd_len", HNS3_RING_RX_BD_LEN_REG}, ++ {"ring_rx_en", HNS3_RING_RX_EN_REG}, ++ {"ring_rx_merge_en", HNS3_RING_RX_MERGE_EN_REG}, ++ {"ring_rx_tail", HNS3_RING_RX_TAIL_REG}, ++ {"ring_rx_head", HNS3_RING_RX_HEAD_REG}, ++ {"ring_rx_fbdnum", HNS3_RING_RX_FBDNUM_REG}, ++ {"ring_rx_offset", HNS3_RING_RX_OFFSET_REG}, ++ {"ring_rx_fbd_offset", HNS3_RING_RX_FBD_OFFSET_REG}, ++ {"ring_rx_stash", HNS3_RING_RX_STASH_REG}, ++ {"ring_rx_bd_err", HNS3_RING_RX_BD_ERR_REG}, ++ {"ring_tx_bd_num", HNS3_RING_TX_BD_NUM_REG}, ++ {"ring_tx_en", HNS3_RING_TX_EN_REG}, ++ {"ring_tx_priority", HNS3_RING_TX_PRIORITY_REG}, ++ {"ring_tx_tc", HNS3_RING_TX_TC_REG}, ++ {"ring_tx_merge_en", HNS3_RING_TX_MERGE_EN_REG}, ++ {"ring_tx_tail", HNS3_RING_TX_TAIL_REG}, ++ {"ring_tx_head", HNS3_RING_TX_HEAD_REG}, ++ {"ring_tx_fbdnum", HNS3_RING_TX_FBDNUM_REG}, ++ {"ring_tx_offset", HNS3_RING_TX_OFFSET_REG}, ++ {"ring_tx_ebd_num", HNS3_RING_TX_EBD_NUM_REG}, ++ {"ring_tx_ebd_offset", HNS3_RING_TX_EBD_OFFSET_REG}, ++ {"ring_tx_bd_err", HNS3_RING_TX_BD_ERR_REG}, ++ {"ring_en", HNS3_RING_EN_REG}, ++}; ++ ++static const struct hns3_dirt_reg_entry tqp_intr_reg_list[] = { ++ {"tqp_intr_ctrl", HNS3_TQP_INTR_CTRL_REG}, ++ {"tqp_intr_gl0", HNS3_TQP_INTR_GL0_REG}, ++ {"tqp_intr_gl1", HNS3_TQP_INTR_GL1_REG}, ++ {"tqp_intr_gl2", HNS3_TQP_INTR_GL2_REG}, ++ {"tqp_intr_rl", HNS3_TQP_INTR_RL_REG}, ++}; ++ ++struct hns3_dfx_reg_entry { ++ /** ++ * name_v1 -- default register name for all platforms (HIP08/HIP09/newer). ++ * name_v2 -- register name different from the default for HIP09. ++ * If there are more platform with different register name, name_vXX is extended. ++ * If the platform is newer than HIP09, use default name. ++ */ ++ const char *name_v1; ++ const char *name_v2; ++}; ++ ++static struct hns3_dfx_reg_entry regs_32_bit_list[] = { ++ {"ssu_common_err_int"}, ++ {"ssu_port_based_err_int"}, ++ {"ssu_fifo_overflow_int"}, ++ {"ssu_ets_tcg_int"}, ++ {"ssu_bp_status_0"}, ++ {"ssu_bp_status_1"}, ++ ++ {"ssu_bp_status_2"}, ++ {"ssu_bp_status_3"}, ++ {"ssu_bp_status_4"}, ++ {"ssu_bp_status_5"}, ++ {"ssu_mac_tx_pfc_ind"}, ++ {"ssu_mac_rx_pfc_ind"}, ++ ++ {"ssu_rx_oq_drop_pkt_cnt"}, ++ {"ssu_tx_oq_drop_pkt_cnt"}, ++}; ++ ++static struct hns3_dfx_reg_entry regs_64_bit_list[] = { ++ {"ppp_get_rx_pkt_cnt_l"}, ++ {"ppp_get_rx_pkt_cnt_h"}, ++ {"ppp_get_tx_pkt_cnt_l"}, ++ {"ppp_get_tx_pkt_cnt_h"}, ++ {"ppp_send_uc_prt2host_pkt_cnt_l"}, ++ {"ppp_send_uc_prt2host_pkt_cnt_h"}, ++ ++ {"ppp_send_uc_prt2prt_pkt_cnt_l"}, ++ {"ppp_send_uc_prt2prt_pkt_cnt_h"}, ++ {"ppp_send_uc_host2host_pkt_cnt_l"}, ++ {"ppp_send_uc_host2host_pkt_cnt_h"}, ++ {"ppp_send_uc_host2prt_pkt_cnt_l"}, ++ {"ppp_send_uc_host2prt_pkt_cnt_h"}, ++ {"ppp_send_mc_from_prt_cnt_l"}, ++ {"ppp_send_mc_from_prt_cnt_h"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_bios_common_reg_list[] = { ++ {"bios_rsv0"}, ++ {"bp_cpu_state"}, ++ {"dfx_msix_info_nic_0"}, ++ {"dfx_msix_info_nic_1"}, ++ {"dfx_msix_info_nic_2"}, ++ {"dfx_msix_info_nic_3"}, ++ ++ {"dfx_msix_info_roce_0"}, ++ {"dfx_msix_info_roce_1"}, ++ {"dfx_msix_info_roce_2"}, ++ {"dfx_msix_info_roce_3"}, ++ {"bios_rsv1"}, ++ {"bios_rsv2"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_ssu_reg_0_list[] = { ++ {"dfx_ssu0_rsv0"}, ++ {"ssu_ets_port_status"}, ++ {"ssu_ets_tcg_status"}, ++ {"dfx_ssu0_rsv1"}, ++ {"dfx_ssu0_rsv2"}, ++ {"ssu_bp_status_0"}, ++ ++ {"ssu_bp_status_1"}, ++ {"ssu_bp_status_2"}, ++ {"ssu_bp_status_3"}, ++ {"ssu_bp_status_4"}, ++ {"ssu_bp_status_5"}, ++ {"ssu_mac_tx_pfc_ind"}, ++ ++ {"mac_ssu_rx_pfc_ind"}, ++ {"btmp_ageing_st_b0"}, ++ {"btmp_ageing_st_b1"}, ++ {"btmp_ageing_st_b2"}, ++ {"dfx_ssu0_rsv3"}, ++ {"dfx_ssu0_rsv4"}, ++ ++ {"ssu_full_drop_num"}, ++ {"ssu_part_drop_num"}, ++ {"ppp_key_drop_num"}, ++ {"ppp_rlt_drop_num"}, ++ {"lo_pri_unicast_rlt_drop_num"}, ++ {"hi_pri_multicast_rlt_drop_num"}, ++ ++ {"lo_pri_multicast_rlt_drop_num"}, ++ {"ncsi_packet_curr_buffer_cnt"}, ++ {"btmp_ageing_rls_cnt_bank0", "dfx_ssu0_rsv5"}, ++ {"btmp_ageing_rls_cnt_bank1", "dfx_ssu0_rsv6"}, ++ {"btmp_ageing_rls_cnt_bank2", "dfx_ssu0_rsv7"}, ++ {"ssu_mb_rd_rlt_drop_cnt"}, ++ ++ {"ssu_ppp_mac_key_num_l"}, ++ {"ssu_ppp_mac_key_num_h"}, ++ {"ssu_ppp_host_key_num_l"}, ++ {"ssu_ppp_host_key_num_h"}, ++ {"ppp_ssu_mac_rlt_num_l"}, ++ {"ppp_ssu_mac_rlt_num_h"}, ++ ++ {"ppp_ssu_host_rlt_num_l"}, ++ {"ppp_ssu_host_rlt_num_h"}, ++ {"ncsi_rx_packet_in_cnt_l"}, ++ {"ncsi_rx_packet_in_cnt_h"}, ++ {"ncsi_tx_packet_out_cnt_l"}, ++ {"ncsi_tx_packet_out_cnt_h"}, ++ ++ {"ssu_key_drop_num"}, ++ {"mb_uncopy_num"}, ++ {"rx_oq_drop_pkt_cnt"}, ++ {"tx_oq_drop_pkt_cnt"}, ++ {"bank_unbalance_drop_cnt"}, ++ {"bank_unbalance_rx_drop_cnt"}, ++ ++ {"nic_l2_eer_drop_pkt_cnt"}, ++ {"roc_l2_eer_drop_pkt_cnt"}, ++ {"nic_l2_eer_drop_pkt_cnt_rx"}, ++ {"roc_l2_eer_drop_pkt_cnt_rx"}, ++ {"rx_oq_glb_drop_pkt_cnt"}, ++ {"dfx_ssu0_rsv8"}, ++ ++ {"lo_pri_unicast_cur_cnt"}, ++ {"hi_pri_multicast_cur_cnt"}, ++ {"lo_pri_multicast_cur_cnt"}, ++ {"dfx_ssu0_rsv9"}, ++ {"dfx_ssu0_rsv10"}, ++ {"dfx_ssu0_rsv11"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_ssu_reg_1_list[] = { ++ {"dfx_ssu1_prt_id"}, ++ {"packet_tc_curr_buffer_cnt_0"}, ++ {"packet_tc_curr_buffer_cnt_1"}, ++ {"packet_tc_curr_buffer_cnt_2"}, ++ {"packet_tc_curr_buffer_cnt_3"}, ++ {"packet_tc_curr_buffer_cnt_4"}, ++ ++ {"packet_tc_curr_buffer_cnt_5"}, ++ {"packet_tc_curr_buffer_cnt_6"}, ++ {"packet_tc_curr_buffer_cnt_7"}, ++ {"packet_curr_buffer_cnt"}, ++ {"dfx_ssu1_rsv0"}, ++ {"dfx_ssu1_rsv1"}, ++ ++ {"rx_packet_in_cnt_l"}, ++ {"rx_packet_in_cnt_h"}, ++ {"rx_packet_out_cnt_l"}, ++ {"rx_packet_out_cnt_h"}, ++ {"tx_packet_in_cnt_l"}, ++ {"tx_packet_in_cnt_h"}, ++ ++ {"tx_packet_out_cnt_l"}, ++ {"tx_packet_out_cnt_h"}, ++ {"roc_rx_packet_in_cnt_l"}, ++ {"roc_rx_packet_in_cnt_h"}, ++ {"roc_tx_packet_in_cnt_l"}, ++ {"roc_tx_packet_in_cnt_h"}, ++ ++ {"rx_packet_tc_in_cnt_0_l"}, ++ {"rx_packet_tc_in_cnt_0_h"}, ++ {"rx_packet_tc_in_cnt_1_l"}, ++ {"rx_packet_tc_in_cnt_1_h"}, ++ {"rx_packet_tc_in_cnt_2_l"}, ++ {"rx_packet_tc_in_cnt_2_h"}, ++ ++ {"rx_packet_tc_in_cnt_3_l"}, ++ {"rx_packet_tc_in_cnt_3_h"}, ++ {"rx_packet_tc_in_cnt_4_l"}, ++ {"rx_packet_tc_in_cnt_4_h"}, ++ {"rx_packet_tc_in_cnt_5_l"}, ++ {"rx_packet_tc_in_cnt_5_h"}, ++ ++ {"rx_packet_tc_in_cnt_6_l"}, ++ {"rx_packet_tc_in_cnt_6_h"}, ++ {"rx_packet_tc_in_cnt_7_l"}, ++ {"rx_packet_tc_in_cnt_7_h"}, ++ {"rx_packet_tc_out_cnt_0_l"}, ++ {"rx_packet_tc_out_cnt_0_h"}, ++ ++ {"rx_packet_tc_out_cnt_1_l"}, ++ {"rx_packet_tc_out_cnt_1_h"}, ++ {"rx_packet_tc_out_cnt_2_l"}, ++ {"rx_packet_tc_out_cnt_2_h"}, ++ {"rx_packet_tc_out_cnt_3_l"}, ++ {"rx_packet_tc_out_cnt_3_h"}, ++ ++ {"rx_packet_tc_out_cnt_4_l"}, ++ {"rx_packet_tc_out_cnt_4_h"}, ++ {"rx_packet_tc_out_cnt_5_l"}, ++ {"rx_packet_tc_out_cnt_5_h"}, ++ {"rx_packet_tc_out_cnt_6_l"}, ++ {"rx_packet_tc_out_cnt_6_h"}, ++ ++ {"rx_packet_tc_out_cnt_7_l"}, ++ {"rx_packet_tc_out_cnt_7_h"}, ++ {"tx_packet_tc_in_cnt_0_l"}, ++ {"tx_packet_tc_in_cnt_0_h"}, ++ {"tx_packet_tc_in_cnt_1_l"}, ++ {"tx_packet_tc_in_cnt_1_h"}, ++ ++ {"tx_packet_tc_in_cnt_2_l"}, ++ {"tx_packet_tc_in_cnt_2_h"}, ++ {"tx_packet_tc_in_cnt_3_l"}, ++ {"tx_packet_tc_in_cnt_3_h"}, ++ {"tx_packet_tc_in_cnt_4_l"}, ++ {"tx_packet_tc_in_cnt_4_h"}, ++ ++ {"tx_packet_tc_in_cnt_5_l"}, ++ {"tx_packet_tc_in_cnt_5_h"}, ++ {"tx_packet_tc_in_cnt_6_l"}, ++ {"tx_packet_tc_in_cnt_6_h"}, ++ {"tx_packet_tc_in_cnt_7_l"}, ++ {"tx_packet_tc_in_cnt_7_h"}, ++ ++ {"tx_packet_tc_out_cnt_0_l"}, ++ {"tx_packet_tc_out_cnt_0_h"}, ++ {"tx_packet_tc_out_cnt_1_l"}, ++ {"tx_packet_tc_out_cnt_1_h"}, ++ {"tx_packet_tc_out_cnt_2_l"}, ++ {"tx_packet_tc_out_cnt_2_h"}, ++ ++ {"tx_packet_tc_out_cnt_3_l"}, ++ {"tx_packet_tc_out_cnt_3_h"}, ++ {"tx_packet_tc_out_cnt_4_l"}, ++ {"tx_packet_tc_out_cnt_4_h"}, ++ {"tx_packet_tc_out_cnt_5_l"}, ++ {"tx_packet_tc_out_cnt_5_h"}, ++ ++ {"tx_packet_tc_out_cnt_6_l"}, ++ {"tx_packet_tc_out_cnt_6_h"}, ++ {"tx_packet_tc_out_cnt_7_l"}, ++ {"tx_packet_tc_out_cnt_7_h"}, ++ {"dfx_ssu1_rsv2"}, ++ {"dfx_ssu1_rsv3"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_igu_egu_reg_list[] = { ++ {"igu_egu_prt_id"}, ++ {"igu_rx_err_pkt"}, ++ {"igu_rx_no_sof_pkt"}, ++ {"egu_tx_1588_short_pkt"}, ++ {"egu_tx_1588_pkt"}, ++ {"egu_tx_1588_err_pkt"}, ++ ++ {"igu_rx_out_l2_pkt"}, ++ {"igu_rx_out_l3_pkt"}, ++ {"igu_rx_out_l4_pkt"}, ++ {"igu_rx_in_l2_pkt"}, ++ {"igu_rx_in_l3_pkt"}, ++ {"igu_rx_in_l4_pkt"}, ++ ++ {"igu_rx_el3e_pkt"}, ++ {"igu_rx_el4e_pkt"}, ++ {"igu_rx_l3e_pkt"}, ++ {"igu_rx_l4e_pkt"}, ++ {"igu_rx_rocee_pkt"}, ++ {"igu_rx_out_udp0_pkt"}, ++ ++ {"igu_rx_in_udp0_pkt"}, ++ {"igu_egu_rsv0", "igu_egu_mul_car_drop_pkt_cnt_l"}, ++ {"igu_egu_rsv1", "igu_egu_mul_car_drop_pkt_cnt_h"}, ++ {"igu_egu_rsv2", "igu_egu_bro_car_drop_pkt_cnt_l"}, ++ {"igu_egu_rsv3", "igu_egu_bro_car_drop_pkt_cnt_h"}, ++ {"igu_egu_rsv4", "igu_egu_rsv0"}, ++ ++ {"igu_rx_oversize_pkt_l"}, ++ {"igu_rx_oversize_pkt_h"}, ++ {"igu_rx_undersize_pkt_l"}, ++ {"igu_rx_undersize_pkt_h"}, ++ {"igu_rx_out_all_pkt_l"}, ++ {"igu_rx_out_all_pkt_h"}, ++ ++ {"igu_tx_out_all_pkt_l"}, ++ {"igu_tx_out_all_pkt_h"}, ++ {"igu_rx_uni_pkt_l"}, ++ {"igu_rx_uni_pkt_h"}, ++ {"igu_rx_multi_pkt_l"}, ++ {"igu_rx_multi_pkt_h"}, ++ ++ {"igu_rx_broad_pkt_l"}, ++ {"igu_rx_broad_pkt_h"}, ++ {"egu_tx_out_all_pkt_l"}, ++ {"egu_tx_out_all_pkt_h"}, ++ {"egu_tx_uni_pkt_l"}, ++ {"egu_tx_uni_pkt_h"}, ++ ++ {"egu_tx_multi_pkt_l"}, ++ {"egu_tx_multi_pkt_h"}, ++ {"egu_tx_broad_pkt_l"}, ++ {"egu_tx_broad_pkt_h"}, ++ {"igu_tx_key_num_l"}, ++ {"igu_tx_key_num_h"}, ++ ++ {"igu_rx_non_tun_pkt_l"}, ++ {"igu_rx_non_tun_pkt_h"}, ++ {"igu_rx_tun_pkt_l"}, ++ {"igu_rx_tun_pkt_h"}, ++ {"igu_egu_rsv5"}, ++ {"igu_egu_rsv6"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_rpu_reg_0_list[] = { ++ {"rpu_tc_queue_num", "rpu_currport_tnl_index"}, ++ {"rpu_fsm_dfx_st0"}, ++ {"rpu_fsm_dfx_st1"}, ++ {"rpu_rpu_rx_pkt_drop_cnt"}, ++ {"rpu_buf_wait_timeout"}, ++ {"rpu_buf_wait_timeout_qid"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_rpu_reg_1_list[] = { ++ {"rpu_rsv0"}, ++ {"rpu_fifo_dfx_st0"}, ++ {"rpu_fifo_dfx_st1"}, ++ {"rpu_fifo_dfx_st2"}, ++ {"rpu_fifo_dfx_st3"}, ++ {"rpu_fifo_dfx_st4"}, ++ ++ {"rpu_fifo_dfx_st5"}, ++ {"rpu_rsv1"}, ++ {"rpu_rsv2"}, ++ {"rpu_rsv3"}, ++ {"rpu_rsv4"}, ++ {"rpu_rsv5"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_ncsi_reg_list[] = { ++ {"ncsi_rsv0"}, ++ {"ncsi_egu_tx_fifo_sts"}, ++ {"ncsi_pause_status"}, ++ {"ncsi_rx_ctrl_dmac_err_cnt"}, ++ {"ncsi_rx_ctrl_smac_err_cnt"}, ++ {"ncsi_rx_ctrl_cks_err_cnt"}, ++ ++ {"ncsi_rx_ctrl_pkt_err_cnt"}, ++ {"ncsi_rx_pt_dmac_err_cnt"}, ++ {"ncsi_rx_pt_smac_err_cnt"}, ++ {"ncsi_rx_pt_pkt_cnt"}, ++ {"ncsi_rx_fcs_err_cnt"}, ++ {"ncsi_tx_ctrl_dmac_err_cnt"}, ++ ++ {"ncsi_tx_ctrl_smac_err_cnt"}, ++ {"ncsi_tx_ctrl_pkt_cnt"}, ++ {"ncsi_tx_pt_dmac_err_cnt"}, ++ {"ncsi_tx_pt_smac_err_cnt"}, ++ {"ncsi_tx_pt_pkt_cnt"}, ++ {"ncsi_tx_pt_pkt_trun_cnt"}, ++ ++ {"ncsi_tx_pt_pkt_err_cnt"}, ++ {"ncsi_tx_ctrl_pkt_err_cnt"}, ++ {"ncsi_rx_ctrl_pkt_trun_cnt"}, ++ {"ncsi_rx_ctrl_pkt_cflit_cnt"}, ++ {"ncsi_rsv1"}, ++ {"ncsi_rsv2"}, ++ ++ {"ncsi_mac_rx_octets_ok"}, ++ {"ncsi_mac_rx_octets_bad"}, ++ {"ncsi_mac_rx_uc_pkts"}, ++ {"ncsi_mac_rx_mc_pkts"}, ++ {"ncsi_mac_rx_bc_pkts"}, ++ {"ncsi_mac_rx_pkts_64octets"}, ++ ++ {"ncsi_mac_rx_pkts_64to127_octets"}, ++ {"ncsi_mac_rx_pkts_128to255_octets"}, ++ {"ncsi_mac_rx_pkts_256to511_octets"}, ++ {"ncsi_mac_rx_pkts_512to1023_octets"}, ++ {"ncsi_mac_rx_pkts_1024to1518_octets"}, ++ {"ncsi_mac_rx_pkts_1519tomax_octets"}, ++ ++ {"ncsi_mac_rx_fcs_errors"}, ++ {"ncsi_mac_rx_long_errors"}, ++ {"ncsi_mac_rx_jabber_errors"}, ++ {"ncsi_mac_rx_runt_err_cnt"}, ++ {"ncsi_mac_rx_short_err_cnt"}, ++ {"ncsi_mac_rx_filt_pkt_cnt"}, ++ ++ {"ncsi_mac_rx_octets_total_filt"}, ++ {"ncsi_mac_tx_octets_ok"}, ++ {"ncsi_mac_tx_octets_bad"}, ++ {"ncsi_mac_tx_uc_pkts"}, ++ {"ncsi_mac_tx_mc_pkts"}, ++ {"ncsi_mac_tx_bc_pkts"}, ++ ++ {"ncsi_mac_tx_pkts_64octets"}, ++ {"ncsi_mac_tx_pkts_64to127_octets"}, ++ {"ncsi_mac_tx_pkts_128to255_octets"}, ++ {"ncsi_mac_tx_pkts_256to511_octets"}, ++ {"ncsi_mac_tx_pkts_512to1023_octets"}, ++ {"ncsi_mac_tx_pkts_1024to1518_octets"}, ++ ++ {"ncsi_mac_tx_pkts_1519tomax_octets"}, ++ {"ncsi_mac_tx_underrun"}, ++ {"ncsi_mac_tx_crc_error"}, ++ {"ncsi_mac_tx_pause_frames"}, ++ {"ncsi_mac_rx_pad_pkts"}, ++ {"ncsi_mac_rx_pause_frames"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_rtc_reg_list[] = { ++ {"rtc_rsv0"}, ++ {"lge_igu_afifo_dfx_0"}, ++ {"lge_igu_afifo_dfx_1"}, ++ {"lge_igu_afifo_dfx_2"}, ++ {"lge_igu_afifo_dfx_3"}, ++ {"lge_igu_afifo_dfx_4"}, ++ ++ {"lge_igu_afifo_dfx_5"}, ++ {"lge_igu_afifo_dfx_6"}, ++ {"lge_igu_afifo_dfx_7"}, ++ {"lge_egu_afifo_dfx_0"}, ++ {"lge_egu_afifo_dfx_1"}, ++ {"lge_egu_afifo_dfx_2"}, ++ ++ {"lge_egu_afifo_dfx_3"}, ++ {"lge_egu_afifo_dfx_4"}, ++ {"lge_egu_afifo_dfx_5"}, ++ {"lge_egu_afifo_dfx_6"}, ++ {"lge_egu_afifo_dfx_7"}, ++ {"cge_igu_afifo_dfx_0"}, ++ ++ {"cge_igu_afifo_dfx_1"}, ++ {"cge_egu_afifo_dfx_0"}, ++ {"cge_egu_afifo_dfx_i"}, ++ {"rtc_rsv1"}, ++ {"rtc_rsv2"}, ++ {"rtc_rsv3"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_ppp_reg_list[] = { ++ {"ppp_rsv0"}, ++ {"ppp_drop_from_prt_pkt_cnt"}, ++ {"ppp_drop_from_host_pkt_cnt"}, ++ {"ppp_drop_tx_vlan_proc_cnt"}, ++ {"ppp_drop_mng_cnt"}, ++ {"ppp_drop_fd_cnt"}, ++ ++ {"ppp_drop_no_dst_cnt"}, ++ {"ppp_drop_mc_mbid_full_cnt"}, ++ {"ppp_drop_sc_filtered"}, ++ {"ppp_ppp_mc_drop_pkt_cnt"}, ++ {"ppp_drop_pt_cnt"}, ++ {"ppp_drop_mac_anti_spoof_cnt"}, ++ ++ {"ppp_drop_ig_vfv_cnt"}, ++ {"ppp_drop_ig_prtv_cnt"}, ++ {"ppp_drop_cnm_pfc_pause_cnt"}, ++ {"ppp_drop_torus_tc_cnt"}, ++ {"ppp_drop_torus_lpbk_cnt"}, ++ {"ppp_ppp_hfs_sts"}, ++ ++ {"ppp_mc_rslt_sts"}, ++ {"ppp_p3u_sts"}, ++ {"ppp_rslt_descr_sts", "ppp_rsv1"}, ++ {"ppp_umv_sts_0"}, ++ {"ppp_umv_sts_1"}, ++ {"ppp_vfv_sts"}, ++ ++ {"ppp_gro_key_cnt"}, ++ {"ppp_gro_info_cnt"}, ++ {"ppp_gro_drop_cnt"}, ++ {"ppp_gro_out_cnt"}, ++ {"ppp_gro_key_match_data_cnt"}, ++ {"ppp_gro_key_match_tcam_cnt"}, ++ ++ {"ppp_gro_info_match_cnt"}, ++ {"ppp_gro_free_entry_cnt"}, ++ {"ppp_gro_inner_dfx_signal"}, ++ {"ppp_rsv2"}, ++ {"ppp_rsv3"}, ++ {"ppp_rsv4"}, ++ ++ {"ppp_get_rx_pkt_cnt_l"}, ++ {"ppp_get_rx_pkt_cnt_h"}, ++ {"ppp_get_tx_pkt_cnt_l"}, ++ {"ppp_get_tx_pkt_cnt_h"}, ++ {"ppp_send_uc_prt2host_pkt_cnt_l"}, ++ {"ppp_send_uc_prt2host_pkt_cnt_h"}, ++ ++ {"ppp_send_uc_prt2prt_pkt_cnt_l"}, ++ {"ppp_send_uc_prt2prt_pkt_cnt_h"}, ++ {"ppp_send_uc_host2host_pkt_cnt_l"}, ++ {"ppp_send_uc_host2host_pkt_cnt_h"}, ++ {"ppp_send_uc_host2prt_pkt_cnt_l"}, ++ {"ppp_send_uc_host2prt_pkt_cnt_h"}, ++ ++ {"ppp_send_mc_from_prt_cnt_l"}, ++ {"ppp_send_mc_from_prt_cnt_h"}, ++ {"ppp_send_mc_from_host_cnt_l"}, ++ {"ppp_send_mc_from_host_cnt_h"}, ++ {"ppp_ssu_mc_rd_cnt_l"}, ++ {"ppp_ssu_mc_rd_cnt_h"}, ++ ++ {"ppp_ssu_mc_drop_cnt_l"}, ++ {"ppp_ssu_mc_drop_cnt_h"}, ++ {"ppp_ssu_mc_rd_pkt_cnt_l"}, ++ {"ppp_ssu_mc_rd_pkt_cnt_h"}, ++ {"ppp_mc_2host_pkt_cnt_l"}, ++ {"ppp_mc_2host_pkt_cnt_h"}, ++ ++ {"ppp_mc_2prt_pkt_cnt_l"}, ++ {"ppp_mc_2prt_pkt_cnt_h"}, ++ {"ppp_ntsnos_pkt_cnt_l"}, ++ {"ppp_ntsnos_pkt_cnt_h"}, ++ {"ppp_ntup_pkt_cnt_l"}, ++ {"ppp_ntup_pkt_cnt_h"}, ++ ++ {"ppp_ntlcl_pkt_cnt_l"}, ++ {"ppp_ntlcl_pkt_cnt_h"}, ++ {"ppp_nttgt_pkt_cnt_l"}, ++ {"ppp_nttgt_pkt_cnt_h"}, ++ {"ppp_rtns_pkt_cnt_l"}, ++ {"ppp_rtns_pkt_cnt_h"}, ++ ++ {"ppp_rtlpbk_pkt_cnt_l"}, ++ {"ppp_rtlpbk_pkt_cnt_h"}, ++ {"ppp_nr_pkt_cnt_l"}, ++ {"ppp_nr_pkt_cnt_h"}, ++ {"ppp_rr_pkt_cnt_l"}, ++ {"ppp_rr_pkt_cnt_h"}, ++ ++ {"ppp_mng_tbl_hit_cnt_l"}, ++ {"ppp_mng_tbl_hit_cnt_h"}, ++ {"ppp_fd_tbl_hit_cnt_l"}, ++ {"ppp_fd_tbl_hit_cnt_h"}, ++ {"ppp_fd_lkup_cnt_l"}, ++ {"ppp_fd_lkup_cnt_h"}, ++ ++ {"ppp_bc_hit_cnt"}, ++ {"ppp_bc_hit_cnt_h"}, ++ {"ppp_um_tbl_uc_hit_cnt"}, ++ {"ppp_um_tbl_uc_hit_cnt_h"}, ++ {"ppp_um_tbl_mc_hit_cnt"}, ++ {"ppp_um_tbl_mc_hit_cnt_h"}, ++ ++ {"ppp_um_tbl_vmdq1_hit_cnt_l", "ppp_um_tbl_snq_hit_cnt_l"}, ++ {"ppp_um_tbl_vmdq1_hit_cnt_h", "ppp_um_tbl_snq_hit_cnt_h"}, ++ {"ppp_mta_tbl_hit_cnt_l", "ppp_rsv5"}, ++ {"ppp_mta_tbl_hit_cnt_h", "ppp_rsv6"}, ++ {"ppp_fwd_bonding_hit_cnt_l"}, ++ {"ppp_fwd_bonding_hit_cnt_h"}, ++ ++ {"ppp_promisc_tbl_hit_cnt_l"}, ++ {"ppp_promisc_tbl_hit_cnt_h"}, ++ {"ppp_get_tunl_pkt_cnt_l"}, ++ {"ppp_get_tunl_pkt_cnt_h"}, ++ {"ppp_get_bmc_pkt_cnt_l"}, ++ {"ppp_get_bmc_pkt_cnt_h"}, ++ ++ {"ppp_send_uc_prt2bmc_pkt_cnt_l"}, ++ {"ppp_send_uc_prt2bmc_pkt_cnt_h"}, ++ {"ppp_send_uc_host2bmc_pkt_cnt_l"}, ++ {"ppp_send_uc_host2bmc_pkt_cnt_h"}, ++ {"ppp_send_uc_bmc2host_pkt_cnt_l"}, ++ {"ppp_send_uc_bmc2host_pkt_cnt_h"}, ++ ++ {"ppp_send_uc_bmc2prt_pkt_cnt_l"}, ++ {"ppp_send_uc_bmc2prt_pkt_cnt_h"}, ++ {"ppp_mc_2bmc_pkt_cnt_l"}, ++ {"ppp_mc_2bmc_pkt_cnt_h"}, ++ {"ppp_vlan_mirr_cnt_l", "ppp_rsv7"}, ++ {"ppp_vlan_mirr_cnt_h", "ppp_rsv8"}, ++ ++ {"ppp_ig_mirr_cnt_l", "ppp_rsv9"}, ++ {"ppp_ig_mirr_cnt_h", "ppp_rsv10"}, ++ {"ppp_eg_mirr_cnt_l", "ppp_rsv11"}, ++ {"ppp_eg_mirr_cnt_h", "ppp_rsv12"}, ++ {"ppp_rx_default_host_hit_cnt_l"}, ++ {"ppp_rx_default_host_hit_cnt_h"}, ++ ++ {"ppp_lan_pair_cnt_l"}, ++ {"ppp_lan_pair_cnt_h"}, ++ {"ppp_um_tbl_mc_hit_pkt_cnt_l"}, ++ {"ppp_um_tbl_mc_hit_pkt_cnt_h"}, ++ {"ppp_mta_tbl_hit_pkt_cnt_l"}, ++ {"ppp_mta_tbl_hit_pkt_cnt_h"}, ++ ++ {"ppp_promisc_tbl_hit_pkt_cnt_l"}, ++ {"ppp_promisc_tbl_hit_pkt_cnt_h"}, ++ {"ppp_rsv13"}, ++ {"ppp_rsv14"}, ++ {"ppp_rsv15"}, ++ {"ppp_rsv16"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_rcb_reg_list[] = { ++ {"rcb_rsv0"}, ++ {"rcb_fsm_dfx_st0"}, ++ {"rcb_fsm_dfx_st1"}, ++ {"rcb_fsm_dfx_st2"}, ++ {"rcb_fifo_dfx_st0"}, ++ {"rcb_fifo_dfx_st1"}, ++ ++ {"rcb_fifo_dfx_st2"}, ++ {"rcb_fifo_dfx_st3"}, ++ {"rcb_fifo_dfx_st4"}, ++ {"rcb_fifo_dfx_st5"}, ++ {"rcb_fifo_dfx_st6"}, ++ {"rcb_fifo_dfx_st7"}, ++ ++ {"rcb_fifo_dfx_st8"}, ++ {"rcb_fifo_dfx_st9"}, ++ {"rcb_fifo_dfx_st10"}, ++ {"rcb_fifo_dfx_st11"}, ++ {"rcb_q_credit_vld_0"}, ++ {"rcb_q_credit_vld_1"}, ++ ++ {"rcb_q_credit_vld_2"}, ++ {"rcb_q_credit_vld_3"}, ++ {"rcb_q_credit_vld_4"}, ++ {"rcb_q_credit_vld_5"}, ++ {"rcb_q_credit_vld_6"}, ++ {"rcb_q_credit_vld_7"}, ++ ++ {"rcb_q_credit_vld_8"}, ++ {"rcb_q_credit_vld_9"}, ++ {"rcb_q_credit_vld_10"}, ++ {"rcb_q_credit_vld_11"}, ++ {"rcb_q_credit_vld_12"}, ++ {"rcb_q_credit_vld_13"}, ++ ++ {"rcb_q_credit_vld_14"}, ++ {"rcb_q_credit_vld_15"}, ++ {"rcb_q_credit_vld_16"}, ++ {"rcb_q_credit_vld_17"}, ++ {"rcb_q_credit_vld_18"}, ++ {"rcb_q_credit_vld_19"}, ++ ++ {"rcb_q_credit_vld_20"}, ++ {"rcb_q_credit_vld_21"}, ++ {"rcb_q_credit_vld_22"}, ++ {"rcb_q_credit_vld_23"}, ++ {"rcb_q_credit_vld_24"}, ++ {"rcb_q_credit_vld_25"}, ++ ++ {"rcb_q_credit_vld_26"}, ++ {"rcb_q_credit_vld_27"}, ++ {"rcb_q_credit_vld_28"}, ++ {"rcb_q_credit_vld_29"}, ++ {"rcb_q_credit_vld_30"}, ++ {"rcb_q_credit_vld_31"}, ++ ++ {"rcb_gro_bd_serr_cnt"}, ++ {"rcb_gro_context_serr_cnt"}, ++ {"rcb_rx_stash_cfg_serr_cnt"}, ++ {"rcb_axi_rd_fbd_serr_cnt", "rcb_rcb_tx_mem_serr_cnt"}, ++ {"rcb_gro_bd_merr_cnt"}, ++ {"rcb_gro_context_merr_cnt"}, ++ ++ {"rcb_rx_stash_cfg_merr_cnt"}, ++ {"rcb_axi_rd_fbd_merr_cnt"}, ++ {"rcb_rsv1"}, ++ {"rcb_rsv2"}, ++ {"rcb_rsv3"}, ++ {"rcb_rsv4"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_tqp_reg_list[] = { ++ {"dfx_tqp_q_num"}, ++ {"rcb_cfg_rx_ring_tail"}, ++ {"rcb_cfg_rx_ring_head"}, ++ {"rcb_cfg_rx_ring_fbdnum"}, ++ {"rcb_cfg_rx_ring_offset"}, ++ {"rcb_cfg_rx_ring_fbdoffset"}, ++ ++ {"rcb_cfg_rx_ring_pktnum_record"}, ++ {"rcb_cfg_tx_ring_tail"}, ++ {"rcb_cfg_tx_ring_head"}, ++ {"rcb_cfg_tx_ring_fbdnum"}, ++ {"rcb_cfg_tx_ring_offset"}, ++ {"rcb_cfg_tx_ring_ebdnum"}, ++}; ++ ++static struct hns3_dfx_reg_entry dfx_ssu_reg_2_list[] = { ++ {"dfx_ssu2_oq_index"}, ++ {"dfx_ssu2_queue_cnt"}, ++ {"dfx_ssu2_rsv0"}, ++ {"dfx_ssu2_rsv1"}, ++ {"dfx_ssu2_rsv2"}, ++ {"dfx_ssu2_rsv3"}, ++}; ++ ++enum hns3_reg_modules { ++ HNS3_BIOS_COMMON = 0, ++ HNS3_SSU_0, ++ HNS3_SSU_1, ++ HNS3_IGU_EGU, ++ HNS3_RPU_0, ++ HNS3_RPU_1, ++ HNS3_NCSI, ++ HNS3_RTC, ++ HNS3_PPP, ++ HNS3_RCB, ++ HNS3_TQP, ++ HNS3_SSU_2, ++ ++ HNS3_CMDQ = 12, ++ HNS3_COMMON_PF, ++ HNS3_COMMON_VF, ++ HNS3_RING, ++ HNS3_TQP_INTR, ++ ++ HNS3_32_BIT_DFX, ++ HNS3_64_BIT_DFX, ++}; ++ ++struct hns3_reg_list { ++ const void *reg_list; ++ uint32_t entry_num; ++}; ++ ++static struct hns3_reg_list hns3_reg_lists[] = { ++ [HNS3_BIOS_COMMON] = { dfx_bios_common_reg_list, RTE_DIM(dfx_bios_common_reg_list) }, ++ [HNS3_SSU_0] = { dfx_ssu_reg_0_list, RTE_DIM(dfx_ssu_reg_0_list) }, ++ [HNS3_SSU_1] = { dfx_ssu_reg_1_list, RTE_DIM(dfx_ssu_reg_1_list) }, ++ [HNS3_IGU_EGU] = { dfx_igu_egu_reg_list, RTE_DIM(dfx_igu_egu_reg_list) }, ++ [HNS3_RPU_0] = { dfx_rpu_reg_0_list, RTE_DIM(dfx_rpu_reg_0_list) }, ++ [HNS3_RPU_1] = { dfx_rpu_reg_1_list, RTE_DIM(dfx_rpu_reg_1_list) }, ++ [HNS3_NCSI] = { dfx_ncsi_reg_list, RTE_DIM(dfx_ncsi_reg_list) }, ++ [HNS3_RTC] = { dfx_rtc_reg_list, RTE_DIM(dfx_rtc_reg_list) }, ++ [HNS3_PPP] = { dfx_ppp_reg_list, RTE_DIM(dfx_ppp_reg_list) }, ++ [HNS3_RCB] = { dfx_rcb_reg_list, RTE_DIM(dfx_rcb_reg_list) }, ++ [HNS3_TQP] = { dfx_tqp_reg_list, RTE_DIM(dfx_tqp_reg_list) }, ++ [HNS3_SSU_2] = { dfx_ssu_reg_2_list, RTE_DIM(dfx_ssu_reg_2_list) }, ++ [HNS3_CMDQ] = { cmdq_reg_list, RTE_DIM(cmdq_reg_list) }, ++ [HNS3_COMMON_PF] = { common_reg_list, RTE_DIM(common_reg_list) }, ++ [HNS3_COMMON_VF] = { common_vf_reg_list, RTE_DIM(common_vf_reg_list) }, ++ [HNS3_RING] = { ring_reg_list, RTE_DIM(ring_reg_list) }, ++ [HNS3_TQP_INTR] = { tqp_intr_reg_list, RTE_DIM(tqp_intr_reg_list) }, ++ [HNS3_32_BIT_DFX] = { regs_32_bit_list, RTE_DIM(regs_32_bit_list) }, ++ [HNS3_64_BIT_DFX] = { regs_64_bit_list, RTE_DIM(regs_64_bit_list) }, ++}; + + static const uint32_t hns3_dfx_reg_opcode_list[] = { +- HNS3_OPC_DFX_BIOS_COMMON_REG, +- HNS3_OPC_DFX_SSU_REG_0, +- HNS3_OPC_DFX_SSU_REG_1, +- HNS3_OPC_DFX_IGU_EGU_REG, +- HNS3_OPC_DFX_RPU_REG_0, +- HNS3_OPC_DFX_RPU_REG_1, +- HNS3_OPC_DFX_NCSI_REG, +- HNS3_OPC_DFX_RTC_REG, +- HNS3_OPC_DFX_PPP_REG, +- HNS3_OPC_DFX_RCB_REG, +- HNS3_OPC_DFX_TQP_REG, +- HNS3_OPC_DFX_SSU_REG_2 ++ [HNS3_BIOS_COMMON] = HNS3_OPC_DFX_BIOS_COMMON_REG, ++ [HNS3_SSU_0] = HNS3_OPC_DFX_SSU_REG_0, ++ [HNS3_SSU_1] = HNS3_OPC_DFX_SSU_REG_1, ++ [HNS3_IGU_EGU] = HNS3_OPC_DFX_IGU_EGU_REG, ++ [HNS3_RPU_0] = HNS3_OPC_DFX_RPU_REG_0, ++ [HNS3_RPU_1] = HNS3_OPC_DFX_RPU_REG_1, ++ [HNS3_NCSI] = HNS3_OPC_DFX_NCSI_REG, ++ [HNS3_RTC] = HNS3_OPC_DFX_RTC_REG, ++ [HNS3_PPP] = HNS3_OPC_DFX_PPP_REG, ++ [HNS3_RCB] = HNS3_OPC_DFX_RCB_REG, ++ [HNS3_TQP] = HNS3_OPC_DFX_TQP_REG, ++ [HNS3_SSU_2] = HNS3_OPC_DFX_SSU_REG_2 + }; + + static int +@@ -100,6 +854,11 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit, + + *regs_num_32_bit = rte_le_to_cpu_32(desc.data[0]); + *regs_num_64_bit = rte_le_to_cpu_32(desc.data[1]); ++ if (*regs_num_32_bit != RTE_DIM(regs_32_bit_list) || ++ *regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE != RTE_DIM(regs_64_bit_list)) { ++ hns3_err(hw, "Query register number differ from the list!"); ++ return -EINVAL; ++ } + + return 0; + } +@@ -161,6 +920,7 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count) + { + int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); + uint32_t bd_num_list[opcode_num]; ++ uint32_t reg_num; + int ret; + int i; + +@@ -168,8 +928,14 @@ hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count) + if (ret) + return ret; + +- for (i = 0; i < opcode_num; i++) +- *count += bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM; ++ for (i = 0; i < opcode_num; i++) { ++ reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM; ++ if (reg_num != hns3_reg_lists[i].entry_num) { ++ hns3_err(hw, "Query register number differ from the list!"); ++ return -EINVAL; ++ } ++ *count += reg_num; ++ } + + return 0; + } +@@ -196,14 +962,13 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + int ret; + + if (hns->is_vf) +- common_cnt = sizeof(common_vf_reg_addrs); ++ common_cnt = RTE_DIM(common_vf_reg_list); + else +- common_cnt = sizeof(common_reg_addrs); ++ common_cnt = RTE_DIM(common_reg_list); + +- len = sizeof(cmdq_reg_addrs) + common_cnt + +- sizeof(ring_reg_addrs) * hw->tqps_num + +- sizeof(tqp_intr_reg_addrs) * hw->intr_tqps_num; +- len /= sizeof(uint32_t); ++ len = RTE_DIM(cmdq_reg_list) + common_cnt + ++ RTE_DIM(ring_reg_list) * hw->tqps_num + ++ RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num; + + if (!hns->is_vf) { + ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt); +@@ -219,13 +984,31 @@ hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) + return 0; + } + ++static void ++hns3_fill_dfx_regs_name(struct hns3_hw *hw, struct rte_dev_reg_info *regs, ++ const struct hns3_dfx_reg_entry *reg_list, uint32_t reg_num) ++{ ++ uint32_t i, cnt = regs->length; ++ const char *name; ++ ++ if (regs->names == NULL) ++ return; ++ ++ for (i = 0; i < reg_num; i++) { ++ name = reg_list[i].name_v1; ++ if (hw->revision == PCI_REVISION_ID_HIP09_A && reg_list[i].name_v2 != NULL) ++ name = reg_list[i].name_v2; ++ snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, "%s", name); ++ } ++} ++ + static int +-hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) ++hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs) + { + #define HNS3_32_BIT_REG_RTN_DATANUM 8 + #define HNS3_32_BIT_DESC_NODATA_LEN 2 ++ uint32_t *reg_val = regs->data; + struct hns3_cmd_desc *desc; +- uint32_t *reg_val = data; + uint32_t *desc_data; + int cmd_num; + int i, k, n; +@@ -254,6 +1037,9 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + return ret; + } + ++ hns3_fill_dfx_regs_name(hw, regs, regs_32_bit_list, regs_num); ++ reg_val += regs->length; ++ regs->length += regs_num; + for (i = 0; i < cmd_num; i++) { + if (i == 0) { + desc_data = &desc[i].data[0]; +@@ -265,7 +1051,6 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + } + for (k = 0; k < n; k++) { + *reg_val++ = rte_le_to_cpu_32(*desc_data++); +- + regs_num--; + if (regs_num == 0) + break; +@@ -277,12 +1062,12 @@ hns3_get_32_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + } + + static int +-hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) ++hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_info *regs) + { + #define HNS3_64_BIT_REG_RTN_DATANUM 4 + #define HNS3_64_BIT_DESC_NODATA_LEN 1 ++ uint32_t *reg_val = regs->data; + struct hns3_cmd_desc *desc; +- uint64_t *reg_val = data; + uint64_t *desc_data; + int cmd_num; + int i, k, n; +@@ -311,6 +1096,9 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + return ret; + } + ++ hns3_fill_dfx_regs_name(hw, regs, regs_64_bit_list, regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE); ++ reg_val += regs->length; ++ regs->length += regs_num * HNS3_64_BIT_REG_OUTPUT_SIZE; + for (i = 0; i < cmd_num; i++) { + if (i == 0) { + desc_data = (uint64_t *)(&desc[i].data[0]); +@@ -322,7 +1110,6 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + } + for (k = 0; k < n; k++) { + *reg_val++ = rte_le_to_cpu_64(*desc_data++); +- + regs_num--; + if (!regs_num) + break; +@@ -333,47 +1120,80 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, void *data) + return 0; + } + +-static int +-hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) ++static void ++hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs, ++ enum hns3_reg_modules idx) + { +- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +- uint32_t *origin_data_ptr = data; +- uint32_t reg_offset; +- size_t reg_num; +- uint16_t j; +- size_t i; ++ const struct hns3_dirt_reg_entry *reg_list; ++ uint32_t *data = regs->data; ++ size_t reg_num, i, cnt; ++ ++ data += regs->length; ++ reg_num = hns3_reg_lists[idx].entry_num; ++ reg_list = hns3_reg_lists[idx].reg_list; ++ cnt = regs->length; ++ for (i = 0; i < reg_num; i++) { ++ *data++ = hns3_read_dev(hw, reg_list[i].addr); ++ if (regs->names != NULL) ++ snprintf(regs->names[cnt++].name, RTE_ETH_REG_NAME_SIZE, ++ "%s", reg_list[i].name); ++ } + +- /* fetching per-PF registers values from PF PCIe register space */ +- reg_num = sizeof(cmdq_reg_addrs) / sizeof(uint32_t); +- for (i = 0; i < reg_num; i++) +- *data++ = hns3_read_dev(hw, cmdq_reg_addrs[i]); ++ regs->length += reg_num; ++} ++ ++static uint32_t ++hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id) ++{ ++ if (idx == HNS3_RING) ++ return hns3_get_tqp_reg_offset(queue_id); ++ else if (idx == HNS3_TQP_INTR) ++ return hns3_get_tqp_intr_reg_offset(queue_id); ++ ++ return 0; ++} ++ ++static void ++hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs, ++ enum hns3_reg_modules idx) ++{ ++ const struct hns3_dirt_reg_entry *reg_list; ++ uint16_t tqp_num, reg_offset; ++ uint32_t *data = regs->data; ++ uint32_t reg_num, i, j; ++ ++ if (idx != HNS3_RING && idx != HNS3_TQP_INTR) ++ return; ++ ++ tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num; ++ reg_list = hns3_reg_lists[idx].reg_list; ++ reg_num = hns3_reg_lists[idx].entry_num; ++ data += regs->length; ++ for (i = 0; i < tqp_num; i++) { ++ reg_offset = hns3_get_module_tqp_reg_offset(idx, i); ++ for (j = 0; j < reg_num; j++) { ++ *data++ = hns3_read_dev(hw, reg_list[j].addr + reg_offset); ++ if (regs->names != NULL) ++ snprintf(regs->names[regs->length].name, ++ RTE_ETH_REG_NAME_SIZE, "Q%u_%s", i, reg_list[j].name); ++ regs->length++; ++ } ++ } ++} ++ ++static void ++hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + + if (hns->is_vf) +- reg_num = sizeof(common_vf_reg_addrs) / sizeof(uint32_t); ++ hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF); + else +- reg_num = sizeof(common_reg_addrs) / sizeof(uint32_t); +- for (i = 0; i < reg_num; i++) +- if (hns->is_vf) +- *data++ = hns3_read_dev(hw, common_vf_reg_addrs[i]); +- else +- *data++ = hns3_read_dev(hw, common_reg_addrs[i]); +- +- reg_num = sizeof(ring_reg_addrs) / sizeof(uint32_t); +- for (j = 0; j < hw->tqps_num; j++) { +- reg_offset = hns3_get_tqp_reg_offset(j); +- for (i = 0; i < reg_num; i++) +- *data++ = hns3_read_dev(hw, +- ring_reg_addrs[i] + reg_offset); +- } ++ hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF); + +- reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t); +- for (j = 0; j < hw->intr_tqps_num; j++) { +- reg_offset = hns3_get_tqp_intr_reg_offset(j); +- for (i = 0; i < reg_num; i++) +- *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] + +- reg_offset); +- } +- return data - origin_data_ptr; ++ hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ); ++ hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING); ++ hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR); + } + + static int +@@ -417,13 +1237,13 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg) + } + + static int +-hns3_get_dfx_regs(struct hns3_hw *hw, void **data) ++hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) + { + int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); +- uint32_t max_bd_num, bd_num, opcode; ++ uint32_t max_bd_num, bd_num, opcode, regs_num; + uint32_t bd_num_list[opcode_num]; + struct hns3_cmd_desc *cmd_descs; +- uint32_t *reg_val = (uint32_t *)*data; ++ uint32_t *data = regs->data; + int ret; + int i; + +@@ -447,42 +1267,47 @@ hns3_get_dfx_regs(struct hns3_hw *hw, void **data) + ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode); + if (ret) + break; +- reg_val += hns3_dfx_reg_fetch_data(cmd_descs, bd_num, reg_val); ++ ++ data += regs->length; ++ regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data); ++ hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num); ++ regs->length += regs_num; + } + rte_free(cmd_descs); +- *data = (void *)reg_val; + + return ret; + } + + static int +-hns3_get_regs_from_firmware(struct hns3_hw *hw, uint32_t *data) ++hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + uint32_t regs_num_32_bit; + uint32_t regs_num_64_bit; + int ret; + ++ if (hns->is_vf) ++ return 0; ++ + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); + if (ret) { + hns3_err(hw, "Get register number failed, ret = %d", ret); + return ret; + } + +- ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, data); ++ ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs); + if (ret) { + hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); + return ret; + } +- data += regs_num_32_bit; + +- ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, data); ++ ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs); + if (ret) { + hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); + return ret; + } +- data += regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; + +- return hns3_get_dfx_regs(hw, (void **)&data); ++ return hns3_get_dfx_regs(hw, regs); + } + + int +@@ -491,15 +1316,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; + uint32_t length; +- uint32_t *data; + int ret; + + ret = hns3_get_regs_length(hw, &length); + if (ret) + return ret; + +- data = regs->data; +- if (data == NULL) { ++ if (regs->data == NULL) { + regs->length = length; + regs->width = sizeof(uint32_t); + return 0; +@@ -510,13 +1333,12 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + return -ENOTSUP; + + regs->version = hw->fw_version; ++ /* to count the number of filled registers */ ++ regs->length = 0; + + /* fetching per-PF registers values from PF PCIe register space */ +- data += hns3_direct_access_regs(hw, data); +- +- if (hns->is_vf) +- return 0; ++ hns3_direct_access_regs(hw, regs); + + /* fetching PF common registers values from firmware */ +- return hns3_get_regs_from_firmware(hw, data); ++ return hns3_get_regs_from_firmware(hw, regs); + } +-- +2.33.0 + diff --git a/0065-net-hns3-support-filtering-registers-by-module-names.patch b/0065-net-hns3-support-filtering-registers-by-module-names.patch new file mode 100644 index 0000000..6980df9 --- /dev/null +++ b/0065-net-hns3-support-filtering-registers-by-module-names.patch @@ -0,0 +1,440 @@ +From 9b47034619f1905f6e54d27d11606ad503115625 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Thu, 26 Sep 2024 20:42:49 +0800 +Subject: [PATCH] net/hns3: support filtering registers by module names + +[ upstream commit 99d3bd8b85d357c8d4e7ee23765a073f4970ff74 ] + +This patch support dumping registers which module name is the +`filter` string. The module names are in lower case and so is +the `filter`. Available module names are cmdq, common_pf, +common_vf, ring, tqp_intr, 32_bit_dfx, 64_bit_dfx, bios, igu_egu, +ssu, ppp, rpu, ncsi, rtc, rcb, etc. + +Signed-off-by: Jie Hai +Acked-by: Chengwen Feng +--- + doc/guides/nics/hns3.rst | 9 ++ + drivers/net/hns3/hns3_regs.c | 257 ++++++++++++++++++++--------------- + 2 files changed, 159 insertions(+), 107 deletions(-) + +diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst +index 4f0bc42..bdc10da 100644 +--- a/doc/guides/nics/hns3.rst ++++ b/doc/guides/nics/hns3.rst +@@ -417,6 +417,15 @@ be provided to avoid scheduling the CPU core used by DPDK application threads fo + other tasks. Before starting the Linux OS, add the kernel isolation boot parameter. + For example, "isolcpus=1-18 nohz_full=1-18 rcu_nocbs=1-18". + ++Dump registers ++-------------- ++ ++HNS3 supports dumping registers values with their names, ++and supports filtering by module names. ++The available module names are ``bios``, ``ssu``, ``igu_egu``, ++``rpu``, ``ncsi``, ``rtc``, ``ppp``, ``rcb``, ``tqp``, ``rtc``, ``cmdq``, ++``common_pf``, ``common_vf``, ``ring``, ``tqp_intr``, ``32_bit_dfx``, ++``64_bit_dfx``. + + Limitations or Known issues + --------------------------- +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 22151dd..8148a63 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -12,7 +12,7 @@ + + #define HNS3_64_BIT_REG_OUTPUT_SIZE (sizeof(uint64_t) / sizeof(uint32_t)) + +-static int hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count); ++#define HNS3_MAX_MODULES_LEN 512 + + struct hns3_dirt_reg_entry { + const char *name; +@@ -795,11 +795,39 @@ enum hns3_reg_modules { + HNS3_64_BIT_DFX, + }; + ++#define HNS3_MODULE_MASK(x) RTE_BIT32(x) ++#define HNS3_VF_MODULES (HNS3_MODULE_MASK(HNS3_CMDQ) | HNS3_MODULE_MASK(HNS3_COMMON_VF) | \ ++ HNS3_MODULE_MASK(HNS3_RING) | HNS3_MODULE_MASK(HNS3_TQP_INTR)) ++#define HNS3_VF_ONLY_MODULES HNS3_MODULE_MASK(HNS3_COMMON_VF) ++ + struct hns3_reg_list { + const void *reg_list; + uint32_t entry_num; + }; + ++struct { ++ const char *name; ++ uint32_t module; ++} hns3_module_name_map[] = { ++ { "bios", HNS3_MODULE_MASK(HNS3_BIOS_COMMON) }, ++ { "ssu", HNS3_MODULE_MASK(HNS3_SSU_0) | HNS3_MODULE_MASK(HNS3_SSU_1) | ++ HNS3_MODULE_MASK(HNS3_SSU_2) }, ++ { "igu_egu", HNS3_MODULE_MASK(HNS3_IGU_EGU) }, ++ { "rpu", HNS3_MODULE_MASK(HNS3_RPU_0) | HNS3_MODULE_MASK(HNS3_RPU_1) }, ++ { "ncsi", HNS3_MODULE_MASK(HNS3_NCSI) }, ++ { "rtc", HNS3_MODULE_MASK(HNS3_RTC) }, ++ { "ppp", HNS3_MODULE_MASK(HNS3_PPP) }, ++ { "rcb", HNS3_MODULE_MASK(HNS3_RCB) }, ++ { "tqp", HNS3_MODULE_MASK(HNS3_TQP) }, ++ { "cmdq", HNS3_MODULE_MASK(HNS3_CMDQ) }, ++ { "common_pf", HNS3_MODULE_MASK(HNS3_COMMON_PF) }, ++ { "common_vf", HNS3_MODULE_MASK(HNS3_COMMON_VF) }, ++ { "ring", HNS3_MODULE_MASK(HNS3_RING) }, ++ { "tqp_intr", HNS3_MODULE_MASK(HNS3_TQP_INTR) }, ++ { "32_bit_dfx", HNS3_MODULE_MASK(HNS3_32_BIT_DFX) }, ++ { "64_bit_dfx", HNS3_MODULE_MASK(HNS3_64_BIT_DFX) }, ++}; ++ + static struct hns3_reg_list hns3_reg_lists[] = { + [HNS3_BIOS_COMMON] = { dfx_bios_common_reg_list, RTE_DIM(dfx_bios_common_reg_list) }, + [HNS3_SSU_0] = { dfx_ssu_reg_0_list, RTE_DIM(dfx_ssu_reg_0_list) }, +@@ -863,21 +891,58 @@ hns3_get_regs_num(struct hns3_hw *hw, uint32_t *regs_num_32_bit, + return 0; + } + +-static int +-hns3_get_32_64_regs_cnt(struct hns3_hw *hw, uint32_t *count) ++static const char * ++hns3_get_name_by_module(enum hns3_reg_modules module) + { +- uint32_t regs_num_32_bit, regs_num_64_bit; +- int ret; ++ size_t i; + +- ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +- if (ret) { +- hns3_err(hw, "fail to get the number of registers, " +- "ret = %d.", ret); +- return ret; ++ for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) { ++ if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0) ++ return hns3_module_name_map[i].name; + } ++ return "unknown"; ++} + +- *count += regs_num_32_bit + regs_num_64_bit * HNS3_64_BIT_REG_OUTPUT_SIZE; +- return 0; ++static void ++hns3_get_module_names(char *names, uint32_t len) ++{ ++ size_t i; ++ ++ for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) { ++ strlcat(names, " ", len); ++ strlcat(names, hns3_module_name_map[i].name, len); ++ } ++} ++ ++static uint32_t ++hns3_parse_modules_by_filter(struct hns3_hw *hw, const char *filter) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ char names[HNS3_MAX_MODULES_LEN] = {0}; ++ uint32_t modules = 0; ++ size_t i; ++ ++ if (filter == NULL) { ++ modules = (1 << RTE_DIM(hns3_reg_lists)) - 1; ++ } else { ++ for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) { ++ if (strcmp(filter, hns3_module_name_map[i].name) == 0) { ++ modules |= hns3_module_name_map[i].module; ++ break; ++ } ++ } ++ } ++ ++ if (hns->is_vf) ++ modules &= HNS3_VF_MODULES; ++ else ++ modules &= ~HNS3_VF_ONLY_MODULES; ++ if (modules == 0) { ++ hns3_get_module_names(names, HNS3_MAX_MODULES_LEN); ++ hns3_err(hw, "mismatched module name! Available names are:%s.", ++ names); ++ } ++ return modules; + } + + static int +@@ -915,73 +980,25 @@ hns3_get_dfx_reg_bd_num(struct hns3_hw *hw, uint32_t *bd_num_list, + return 0; + } + +-static int +-hns3_get_dfx_reg_cnt(struct hns3_hw *hw, uint32_t *count) +-{ +- int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); +- uint32_t bd_num_list[opcode_num]; +- uint32_t reg_num; +- int ret; +- int i; +- +- ret = hns3_get_dfx_reg_bd_num(hw, bd_num_list, opcode_num); +- if (ret) +- return ret; +- +- for (i = 0; i < opcode_num; i++) { +- reg_num = bd_num_list[i] * HNS3_CMD_DESC_DATA_NUM; +- if (reg_num != hns3_reg_lists[i].entry_num) { +- hns3_err(hw, "Query register number differ from the list!"); +- return -EINVAL; +- } +- *count += reg_num; +- } +- +- return 0; +-} +- +-static int +-hns3_get_firmware_reg_cnt(struct hns3_hw *hw, uint32_t *count) +-{ +- int ret; +- +- ret = hns3_get_32_64_regs_cnt(hw, count); +- if (ret < 0) +- return ret; +- +- return hns3_get_dfx_reg_cnt(hw, count); +-} +- +-static int +-hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) ++static uint32_t ++hns3_get_regs_length(struct hns3_hw *hw, uint32_t modules) + { +- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +- uint32_t dfx_reg_cnt = 0; +- uint32_t common_cnt; +- uint32_t len; +- int ret; +- +- if (hns->is_vf) +- common_cnt = RTE_DIM(common_vf_reg_list); +- else +- common_cnt = RTE_DIM(common_reg_list); ++ uint32_t reg_num = 0, length = 0; ++ uint32_t i; + +- len = RTE_DIM(cmdq_reg_list) + common_cnt + +- RTE_DIM(ring_reg_list) * hw->tqps_num + +- RTE_DIM(tqp_intr_reg_list) * hw->intr_tqps_num; ++ for (i = 0; i < RTE_DIM(hns3_reg_lists); i++) { ++ if ((RTE_BIT32(i) & modules) == 0) ++ continue; ++ reg_num = hns3_reg_lists[i].entry_num; ++ if (i == HNS3_RING) ++ reg_num *= hw->tqps_num; ++ else if (i == HNS3_TQP_INTR) ++ reg_num *= hw->intr_tqps_num; + +- if (!hns->is_vf) { +- ret = hns3_get_firmware_reg_cnt(hw, &dfx_reg_cnt); +- if (ret) { +- hns3_err(hw, "fail to get the number of dfx registers, " +- "ret = %d.", ret); +- return ret; +- } +- len += dfx_reg_cnt; ++ length += reg_num; + } + +- *length = len; +- return 0; ++ return length; + } + + static void +@@ -1122,12 +1139,15 @@ hns3_get_64_bit_regs(struct hns3_hw *hw, uint32_t regs_num, struct rte_dev_reg_i + + static void + hns3_direct_access_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs, +- enum hns3_reg_modules idx) ++ uint32_t modules, enum hns3_reg_modules idx) + { + const struct hns3_dirt_reg_entry *reg_list; + uint32_t *data = regs->data; + size_t reg_num, i, cnt; + ++ if ((modules & HNS3_MODULE_MASK(idx)) == 0) ++ return; ++ + data += regs->length; + reg_num = hns3_reg_lists[idx].entry_num; + reg_list = hns3_reg_lists[idx].reg_list; +@@ -1155,14 +1175,14 @@ hns3_get_module_tqp_reg_offset(enum hns3_reg_modules idx, uint16_t queue_id) + + static void + hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *regs, +- enum hns3_reg_modules idx) ++ uint32_t modules, enum hns3_reg_modules idx) + { + const struct hns3_dirt_reg_entry *reg_list; + uint16_t tqp_num, reg_offset; + uint32_t *data = regs->data; + uint32_t reg_num, i, j; + +- if (idx != HNS3_RING && idx != HNS3_TQP_INTR) ++ if ((modules & HNS3_MODULE_MASK(idx)) == 0) + return; + + tqp_num = (idx == HNS3_RING) ? hw->tqps_num : hw->intr_tqps_num; +@@ -1182,18 +1202,13 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re + } + + static void +-hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) ++hns3_direct_access_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules) + { +- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); +- +- if (hns->is_vf) +- hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_VF); +- else +- hns3_direct_access_regs_help(hw, regs, HNS3_COMMON_PF); +- +- hns3_direct_access_regs_help(hw, regs, HNS3_CMDQ); +- hns3_direct_access_tqp_regs_help(hw, regs, HNS3_RING); +- hns3_direct_access_tqp_regs_help(hw, regs, HNS3_TQP_INTR); ++ hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_VF); ++ hns3_direct_access_regs_help(hw, regs, modules, HNS3_COMMON_PF); ++ hns3_direct_access_regs_help(hw, regs, modules, HNS3_CMDQ); ++ hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_RING); ++ hns3_direct_access_tqp_regs_help(hw, regs, modules, HNS3_TQP_INTR); + } + + static int +@@ -1237,7 +1252,7 @@ hns3_dfx_reg_fetch_data(struct hns3_cmd_desc *desc, int bd_num, uint32_t *reg) + } + + static int +-hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) ++hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules) + { + int opcode_num = RTE_DIM(hns3_dfx_reg_opcode_list); + uint32_t max_bd_num, bd_num, opcode, regs_num; +@@ -1262,6 +1277,8 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) + for (i = 0; i < opcode_num; i++) { + opcode = hns3_dfx_reg_opcode_list[i]; + bd_num = bd_num_list[i]; ++ if ((modules & HNS3_MODULE_MASK(i)) == 0) ++ continue; + if (bd_num == 0) + continue; + ret = hns3_dfx_reg_cmd_send(hw, cmd_descs, bd_num, opcode); +@@ -1270,6 +1287,11 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) + + data += regs->length; + regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data); ++ if (regs_num != hns3_reg_lists[i].entry_num) { ++ hns3_err(hw, "Query register number differ from the list for module %s!", ++ hns3_get_name_by_module(i)); ++ return -EINVAL; ++ } + hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num); + regs->length += regs_num; + } +@@ -1279,14 +1301,14 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs) + } + + static int +-hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs) ++hns3_get_32_b4_bit_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules) + { +- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + uint32_t regs_num_32_bit; + uint32_t regs_num_64_bit; + int ret; + +- if (hns->is_vf) ++ if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) == 0 && ++ (modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) == 0) + return 0; + + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); +@@ -1295,19 +1317,39 @@ hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs) + return ret; + } + +- ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs); +- if (ret) { +- hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); +- return ret; ++ if ((modules & HNS3_MODULE_MASK(HNS3_32_BIT_DFX)) != 0) { ++ ret = hns3_get_32_bit_regs(hw, regs_num_32_bit, regs); ++ if (ret) { ++ hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); ++ return ret; ++ } + } + +- ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs); +- if (ret) { +- hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); +- return ret; ++ if ((modules & HNS3_MODULE_MASK(HNS3_64_BIT_DFX)) != 0) { ++ ret = hns3_get_64_bit_regs(hw, regs_num_64_bit, regs); ++ if (ret) { ++ hns3_err(hw, "Get 64 bit register failed, ret = %d", ret); ++ return ret; ++ } + } + +- return hns3_get_dfx_regs(hw, regs); ++ return 0; ++} ++ ++static int ++hns3_get_regs_from_firmware(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t modules) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ int ret; ++ ++ if (hns->is_vf) ++ return 0; ++ ++ ret = hns3_get_32_b4_bit_regs(hw, regs, modules); ++ if (ret != 0) ++ return ret; ++ ++ return hns3_get_dfx_regs(hw, regs, modules); + } + + int +@@ -1315,13 +1357,14 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + { + struct hns3_adapter *hns = eth_dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; ++ uint32_t modules; + uint32_t length; +- int ret; + +- ret = hns3_get_regs_length(hw, &length); +- if (ret) +- return ret; ++ modules = hns3_parse_modules_by_filter(hw, regs->filter); ++ if (modules == 0) ++ return -EINVAL; + ++ length = hns3_get_regs_length(hw, modules); + if (regs->data == NULL) { + regs->length = length; + regs->width = sizeof(uint32_t); +@@ -1337,8 +1380,8 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + regs->length = 0; + + /* fetching per-PF registers values from PF PCIe register space */ +- hns3_direct_access_regs(hw, regs); ++ hns3_direct_access_regs(hw, regs, modules); + + /* fetching PF common registers values from firmware */ +- return hns3_get_regs_from_firmware(hw, regs); ++ return hns3_get_regs_from_firmware(hw, regs, modules); + } +-- +2.33.0 + diff --git a/0066-net-hns3-fix-error-log.patch b/0066-net-hns3-fix-error-log.patch new file mode 100644 index 0000000..3055961 --- /dev/null +++ b/0066-net-hns3-fix-error-log.patch @@ -0,0 +1,34 @@ +From 6f09fb9ce1bccd21cfa39f0a927f05d4c0a87b70 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Wed, 23 Oct 2024 15:12:35 +0800 +Subject: [PATCH] net/hns3: fix error log + +[ upstream commit f58fd22240c27ea20cf41dd2aa15810712f518bf ] + +If register number obtained from firmware is different from the +register list driver hold, an error log occurs. The incorrect +use of `&&` makes this log inaccurate, change it to `&`. + +Fixes: 99d3bd8b85d3 ("net/hns3: support filtering registers by module names") + +Signed-off-by: Jie Hai +--- + 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 8148a63..def775a 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -897,7 +897,7 @@ hns3_get_name_by_module(enum hns3_reg_modules module) + size_t i; + + for (i = 0; i < RTE_DIM(hns3_module_name_map); i++) { +- if (hns3_module_name_map[i].module && HNS3_MODULE_MASK(module) != 0) ++ if ((hns3_module_name_map[i].module & HNS3_MODULE_MASK(module)) != 0) + return hns3_module_name_map[i].name; + } + return "unknown"; +-- +2.33.0 + diff --git a/0067-net-hns3-fix-pointer-offset-for-registers.patch b/0067-net-hns3-fix-pointer-offset-for-registers.patch new file mode 100644 index 0000000..b2b03f5 --- /dev/null +++ b/0067-net-hns3-fix-pointer-offset-for-registers.patch @@ -0,0 +1,53 @@ +From 3ba4957b2ea84b1cf93ec7e4b2e0e3c00672f6c9 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 22 Oct 2024 12:01:13 +0800 +Subject: [PATCH] net/hns3: fix pointer offset for registers + +[ upstream commit 013fdd2d7b319e6a35d966f375e33ee330d9ccb5 ] + +If the register values of multiple modules are obtained at a time, +the register values are incorrect because the data field to be filled +pointing to a wrong address. Update the pointer offset of data to +get the correct address. + +Fixes: dd4b8bba785f ("net/hns3: support reporting names of registers") +Cc: stable@dpdk.org + +Signed-off-by: Jie Hai +Acked-by: Chengwen Feng +Acked-by: Huisong Li +--- + drivers/net/hns3/hns3_regs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index def775a..83dda4b 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -1274,6 +1274,7 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t mo + if (cmd_descs == NULL) + return -ENOMEM; + ++ data += regs->length; + for (i = 0; i < opcode_num; i++) { + opcode = hns3_dfx_reg_opcode_list[i]; + bd_num = bd_num_list[i]; +@@ -1285,7 +1286,6 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t mo + if (ret) + break; + +- data += regs->length; + regs_num = hns3_dfx_reg_fetch_data(cmd_descs, bd_num, data); + if (regs_num != hns3_reg_lists[i].entry_num) { + hns3_err(hw, "Query register number differ from the list for module %s!", +@@ -1294,6 +1294,7 @@ hns3_get_dfx_regs(struct hns3_hw *hw, struct rte_dev_reg_info *regs, uint32_t mo + } + hns3_fill_dfx_regs_name(hw, regs, hns3_reg_lists[i].reg_list, regs_num); + regs->length += regs_num; ++ data += regs_num; + } + rte_free(cmd_descs); + +-- +2.33.0 + diff --git a/0068-net-hns3-fix-integer-type.patch b/0068-net-hns3-fix-integer-type.patch new file mode 100644 index 0000000..e0e4ce4 --- /dev/null +++ b/0068-net-hns3-fix-integer-type.patch @@ -0,0 +1,38 @@ +From cbef92f6f6b6e25da5f674a35139abf2a2156d01 Mon Sep 17 00:00:00 2001 +From: Jie Hai +Date: Tue, 22 Oct 2024 12:01:12 +0800 +Subject: [PATCH] net/hns3: fix integer overflow + +[ upstream commit b1fefe40550836b58c4ec50dce14a6e6dbda8499 ] + +The patch fixes variable type in case of data truncation. + +Fixes: dd4b8bba785f ("net/hns3: support reporting names of registers") +Cc: stable@dpdk.org + +Signed-off-by: Jie Hai +Acked-by: Chengwen Feng +Acked-by: Huisong Li +--- + drivers/net/hns3/hns3_regs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c +index 83dda4b..37ac957 100644 +--- a/drivers/net/hns3/hns3_regs.c ++++ b/drivers/net/hns3/hns3_regs.c +@@ -1178,9 +1178,9 @@ hns3_direct_access_tqp_regs_help(struct hns3_hw *hw, struct rte_dev_reg_info *re + uint32_t modules, enum hns3_reg_modules idx) + { + const struct hns3_dirt_reg_entry *reg_list; +- uint16_t tqp_num, reg_offset; ++ uint32_t reg_num, i, j, reg_offset; + uint32_t *data = regs->data; +- uint32_t reg_num, i, j; ++ uint16_t tqp_num; + + if ((modules & HNS3_MODULE_MASK(idx)) == 0) + return; +-- +2.33.0 + diff --git a/0069-kvargs-rework-process-API.patch b/0069-kvargs-rework-process-API.patch new file mode 100644 index 0000000..0c17648 --- /dev/null +++ b/0069-kvargs-rework-process-API.patch @@ -0,0 +1,167 @@ +From 43b961b62562d44b11ccbbb025abe12b4f20e6b2 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 9 Oct 2024 04:50:27 +0000 +Subject: [PATCH] kvargs: rework process API + +[ upstream commit de89988365a7ca4087dd451c675320c993910332 ] + +The rte_kvargs_process() was used to handle: +- key=value (e.g. socket_id=0), +- key (e.g. socket_id). + +But many drivers callback only handle key=value, which results in +crashes if being passed only-key. +Rather than go and fix all drivers as proposed in the link mentioned +below: +- a new API rte_kvargs_process_opt() was introduced: it inherits the + function of rte_kvargs_process() which could handle both key=value and + only-key cases. +- the original rte_kvargs_process() is now limited to the key=value cases, + it will return -1 when handle only-key case, + +This patch also makes sure that both process API reject a NULL kvlist +parameter. + +Link: https://patches.dpdk.org/project/dpdk/patch/20230320092110.37295-1-fengchengwen@huawei.com/ +Signed-off-by: Chengwen Feng +Acked-by: Ferruh Yigit +--- + lib/kvargs/rte_kvargs.c | 36 +++++++++++++++++++++++++++--------- + lib/kvargs/rte_kvargs.h | 33 ++++++++++++++++++++++++++++++--- + lib/kvargs/version.map | 1 + + 3 files changed, 58 insertions(+), 12 deletions(-) + +diff --git a/lib/kvargs/rte_kvargs.c b/lib/kvargs/rte_kvargs.c +index c77bb82..1d35551 100644 +--- a/lib/kvargs/rte_kvargs.c ++++ b/lib/kvargs/rte_kvargs.c +@@ -167,31 +167,49 @@ rte_kvargs_count(const struct rte_kvargs *kvlist, const char *key_match) + return ret; + } + +-/* +- * For each matching key, call the given handler function. +- */ +-int +-rte_kvargs_process(const struct rte_kvargs *kvlist, +- const char *key_match, +- arg_handler_t handler, +- void *opaque_arg) ++static int ++kvargs_process_common(const struct rte_kvargs *kvlist, const char *key_match, ++ arg_handler_t handler, void *opaque_arg, bool support_only_key) + { + const struct rte_kvargs_pair *pair; + unsigned i; + + if (kvlist == NULL) +- return 0; ++ return -1; + + for (i = 0; i < kvlist->count; i++) { + pair = &kvlist->pairs[i]; + if (key_match == NULL || strcmp(pair->key, key_match) == 0) { ++ if (!support_only_key && pair->value == NULL) ++ return -1; + if ((*handler)(pair->key, pair->value, opaque_arg) < 0) + return -1; + } + } ++ + return 0; + } + ++/* ++ * For each matching key in key=value, call the given handler function. ++ */ ++int ++rte_kvargs_process(const struct rte_kvargs *kvlist, const char *key_match, arg_handler_t handler, ++ void *opaque_arg) ++{ ++ return kvargs_process_common(kvlist, key_match, handler, opaque_arg, false); ++} ++ ++/* ++ * For each matching key in key=value or only-key, call the given handler function. ++ */ ++int ++rte_kvargs_process_opt(const struct rte_kvargs *kvlist, const char *key_match, ++ arg_handler_t handler, void *opaque_arg) ++{ ++ return kvargs_process_common(kvlist, key_match, handler, opaque_arg, true); ++} ++ + /* free the rte_kvargs structure */ + void + rte_kvargs_free(struct rte_kvargs *kvlist) +diff --git a/lib/kvargs/rte_kvargs.h b/lib/kvargs/rte_kvargs.h +index b0d1301..73fa1e6 100644 +--- a/lib/kvargs/rte_kvargs.h ++++ b/lib/kvargs/rte_kvargs.h +@@ -166,14 +166,17 @@ const char *rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, + const char *key, const char *value); + + /** +- * Call a handler function for each key/value matching the key ++ * Call a handler function for each key=value matching the key + * +- * For each key/value association that matches the given key, calls the ++ * For each key=value association that matches the given key, calls the + * handler function with the for a given arg_name passing the value on the + * dictionary for that key and a given extra argument. + * ++ * @note Compared to @see rte_kvargs_process_opt, this API will return -1 ++ * when handle only-key case (that is the matched key's value is NULL). ++ * + * @param kvlist +- * The rte_kvargs structure. No error if NULL. ++ * The rte_kvargs structure. + * @param key_match + * The key on which the handler should be called, or NULL to process handler + * on all associations +@@ -189,6 +192,30 @@ const char *rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, + int rte_kvargs_process(const struct rte_kvargs *kvlist, + const char *key_match, arg_handler_t handler, void *opaque_arg); + ++/** ++ * Call a handler function for each key=value or only-key matching the key ++ * ++ * For each key=value or only-key association that matches the given key, calls ++ * the handler function with the for a given arg_name passing the value on the ++ * dictionary for that key and a given extra argument. ++ * ++ * @param kvlist ++ * The rte_kvargs structure. ++ * @param key_match ++ * The key on which the handler should be called, or NULL to process handler ++ * on all associations ++ * @param handler ++ * The function to call for each matching key ++ * @param opaque_arg ++ * A pointer passed unchanged to the handler ++ * ++ * @return ++ * - 0 on success ++ * - Negative on error ++ */ ++int rte_kvargs_process_opt(const struct rte_kvargs *kvlist, ++ const char *key_match, arg_handler_t handler, void *opaque_arg); ++ + /** + * Count the number of associations matching the given key + * +diff --git a/lib/kvargs/version.map b/lib/kvargs/version.map +index cda85d1..0720b1b 100644 +--- a/lib/kvargs/version.map ++++ b/lib/kvargs/version.map +@@ -8,6 +8,7 @@ DPDK_24 { + rte_kvargs_parse; + rte_kvargs_parse_delim; + rte_kvargs_process; ++ rte_kvargs_process_opt; + + local: *; + }; +-- +2.33.0 + diff --git a/0070-net-sfc-use-new-kvargs-process-API.patch b/0070-net-sfc-use-new-kvargs-process-API.patch new file mode 100644 index 0000000..1ab2950 --- /dev/null +++ b/0070-net-sfc-use-new-kvargs-process-API.patch @@ -0,0 +1,116 @@ +From 45f9f54fa1a896d8bf579723c8e1bc42c3dff7d2 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 9 Oct 2024 04:50:28 +0000 +Subject: [PATCH] net/sfc: use new kvargs process API + +[ upstream commit f33e8c0e4a80c1456987f96c1ce448d65e7d6dfb ] + +Add sfc_kvargs_process_opt() function to handle only-key case, and +remove redundancy NULL judgement of value because the rte_kvargs_process +(which invoked in sfc_kvargs_process()) will handle it. + +Signed-off-by: Chengwen Feng +--- + drivers/common/sfc_efx/sfc_efx.c | 3 --- + drivers/net/sfc/sfc_ethdev.c | 12 ++++++------ + drivers/net/sfc/sfc_kvargs.c | 12 +++++++++++- + drivers/net/sfc/sfc_kvargs.h | 2 ++ + 4 files changed, 19 insertions(+), 10 deletions(-) + +diff --git a/drivers/common/sfc_efx/sfc_efx.c b/drivers/common/sfc_efx/sfc_efx.c +index 2dc5545..f96b5e5 100644 +--- a/drivers/common/sfc_efx/sfc_efx.c ++++ b/drivers/common/sfc_efx/sfc_efx.c +@@ -23,9 +23,6 @@ sfc_efx_kvarg_dev_class_handler(__rte_unused const char *key, + { + enum sfc_efx_dev_class *dev_class = opaque; + +- if (class_str == NULL) +- return *dev_class; +- + if (strcmp(class_str, "vdpa") == 0) { + *dev_class = SFC_EFX_DEV_CLASS_VDPA; + } else if (strcmp(class_str, "net") == 0) { +diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c +index 6d57b2b..eacd6c2 100644 +--- a/drivers/net/sfc/sfc_ethdev.c ++++ b/drivers/net/sfc/sfc_ethdev.c +@@ -2836,8 +2836,8 @@ sfc_eth_dev_set_ops(struct rte_eth_dev *dev) + if (encp->enc_rx_es_super_buffer_supported) + avail_caps |= SFC_DP_HW_FW_CAP_RX_ES_SUPER_BUFFER; + +- rc = sfc_kvargs_process(sa, SFC_KVARG_RX_DATAPATH, +- sfc_kvarg_string_handler, &rx_name); ++ rc = sfc_kvargs_process_opt(sa, SFC_KVARG_RX_DATAPATH, ++ sfc_kvarg_string_handler, &rx_name); + if (rc != 0) + goto fail_kvarg_rx_datapath; + +@@ -2879,8 +2879,8 @@ sfc_eth_dev_set_ops(struct rte_eth_dev *dev) + + sfc_notice(sa, "use %s Rx datapath", sas->dp_rx_name); + +- rc = sfc_kvargs_process(sa, SFC_KVARG_TX_DATAPATH, +- sfc_kvarg_string_handler, &tx_name); ++ rc = sfc_kvargs_process_opt(sa, SFC_KVARG_TX_DATAPATH, ++ sfc_kvarg_string_handler, &tx_name); + if (rc != 0) + goto fail_kvarg_tx_datapath; + +@@ -3074,8 +3074,8 @@ sfc_parse_switch_mode(struct sfc_adapter *sa, bool has_representors) + + sfc_log_init(sa, "entry"); + +- rc = sfc_kvargs_process(sa, SFC_KVARG_SWITCH_MODE, +- sfc_kvarg_string_handler, &switch_mode); ++ rc = sfc_kvargs_process_opt(sa, SFC_KVARG_SWITCH_MODE, ++ sfc_kvarg_string_handler, &switch_mode); + if (rc != 0) + goto fail_kvargs; + +diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c +index 783cb43..eb36fa9 100644 +--- a/drivers/net/sfc/sfc_kvargs.c ++++ b/drivers/net/sfc/sfc_kvargs.c +@@ -73,6 +73,16 @@ sfc_kvargs_process(struct sfc_adapter *sa, const char *key_match, + return -rte_kvargs_process(sa->kvargs, key_match, handler, opaque_arg); + } + ++int ++sfc_kvargs_process_opt(struct sfc_adapter *sa, const char *key_match, ++ arg_handler_t handler, void *opaque_arg) ++{ ++ if (sa->kvargs == NULL) ++ return 0; ++ ++ return -rte_kvargs_process_opt(sa->kvargs, key_match, handler, opaque_arg); ++} ++ + int + sfc_kvarg_bool_handler(__rte_unused const char *key, + const char *value_str, void *opaque) +@@ -104,7 +114,7 @@ sfc_kvarg_long_handler(__rte_unused const char *key, + long value; + char *endptr; + +- if (!value_str || !opaque) ++ if (!opaque) + return -EINVAL; + + value = strtol(value_str, &endptr, 0); +diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h +index 2226f2b..4dcc61e 100644 +--- a/drivers/net/sfc/sfc_kvargs.h ++++ b/drivers/net/sfc/sfc_kvargs.h +@@ -83,6 +83,8 @@ void sfc_kvargs_cleanup(struct sfc_adapter *sa); + + int sfc_kvargs_process(struct sfc_adapter *sa, const char *key_match, + arg_handler_t handler, void *opaque_arg); ++int sfc_kvargs_process_opt(struct sfc_adapter *sa, const char *key_match, ++ arg_handler_t handler, void *opaque_arg); + + int sfc_kvarg_bool_handler(const char *key, const char *value_str, + void *opaque); +-- +2.33.0 + diff --git a/0071-net-tap-use-new-kvargs-process-API.patch b/0071-net-tap-use-new-kvargs-process-API.patch new file mode 100644 index 0000000..239aa17 --- /dev/null +++ b/0071-net-tap-use-new-kvargs-process-API.patch @@ -0,0 +1,47 @@ +From b3dd6876cdd40346cc7282955b8cc31401cffb31 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 9 Oct 2024 04:50:29 +0000 +Subject: [PATCH] net/tap: use new kvargs process API + +[ upstream commit 4ed306131f85ef180589169b868f292d9149b0c7 ] + +Some kvargs could be key=value or only-key, it should use +rte_kvargs_process_opt() instead of rte_kvargs_process() to handle +these kvargs. + +Signed-off-by: Chengwen Feng +--- + drivers/net/tap/rte_eth_tap.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c +index b41fa97..cdb52cf 100644 +--- a/drivers/net/tap/rte_eth_tap.c ++++ b/drivers/net/tap/rte_eth_tap.c +@@ -2292,7 +2292,7 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) + kvlist = rte_kvargs_parse(params, valid_arguments); + if (kvlist) { + if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) { +- ret = rte_kvargs_process(kvlist, ++ ret = rte_kvargs_process_opt(kvlist, + ETH_TAP_IFACE_ARG, + &set_interface_name, + tun_name); +@@ -2496,10 +2496,10 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) + kvlist = rte_kvargs_parse(params, valid_arguments); + if (kvlist) { + if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) { +- ret = rte_kvargs_process(kvlist, +- ETH_TAP_IFACE_ARG, +- &set_interface_name, +- tap_name); ++ ret = rte_kvargs_process_opt(kvlist, ++ ETH_TAP_IFACE_ARG, ++ &set_interface_name, ++ tap_name); + if (ret == -1) + goto leave; + } +-- +2.33.0 + diff --git a/0072-common-nfp-use-new-kvargs-process-API.patch b/0072-common-nfp-use-new-kvargs-process-API.patch new file mode 100644 index 0000000..da0cb10 --- /dev/null +++ b/0072-common-nfp-use-new-kvargs-process-API.patch @@ -0,0 +1,37 @@ +From da4cbebd60eab9feb65055ea849eae75683dde43 Mon Sep 17 00:00:00 2001 +From: Chengwen Feng +Date: Wed, 9 Oct 2024 04:50:30 +0000 +Subject: [PATCH] common/nfp: use new kvargs process API + +[ upstream commit 3977d07df186e6f4c79802db19451f51703a3d60 ] + +The nfp_parse_class_options() function could handle both key=value and +only-key, so it should use rte_kvargs_process_opt() instead of +rte_kvargs_process() to parse. + +Signed-off-by: Chengwen Feng +Acked-by: Chaoyong He +--- + drivers/common/nfp/nfp_common_pci.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/common/nfp/nfp_common_pci.c b/drivers/common/nfp/nfp_common_pci.c +index 723035d..5c36052 100644 +--- a/drivers/common/nfp/nfp_common_pci.c ++++ b/drivers/common/nfp/nfp_common_pci.c +@@ -170,10 +170,8 @@ nfp_parse_class_options(const struct rte_devargs *devargs) + if (kvargs == NULL) + return dev_class; + +- if (rte_kvargs_count(kvargs, RTE_DEVARGS_KEY_CLASS) != 0) { +- rte_kvargs_process(kvargs, RTE_DEVARGS_KEY_CLASS, +- nfp_kvarg_dev_class_handler, &dev_class); +- } ++ rte_kvargs_process_opt(kvargs, RTE_DEVARGS_KEY_CLASS, ++ nfp_kvarg_dev_class_handler, &dev_class); + + rte_kvargs_free(kvargs); + +-- +2.33.0 + diff --git a/0073-net-hns3-support-flow-rule-priority.patch b/0073-net-hns3-support-flow-rule-priority.patch new file mode 100644 index 0000000..c44efd2 --- /dev/null +++ b/0073-net-hns3-support-flow-rule-priority.patch @@ -0,0 +1,380 @@ +From a93a030ea0c817a229ce92df315a3cd72dcee6d5 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Wed, 30 Oct 2024 17:29:19 +0800 +Subject: [PATCH] net/hns3: support flow rule priority + +[ upstream commit ac72aae60f71b8716f65d1e2daf531a5ca38c998 ] + +The hardware determines the priority of the flow rule based on the position +of the rule in the hardware flow director table. Lower index denotes higher +priority (it means when a packet matches multiple indexes, the smaller +index wins). This patch implements flow priority based on this feature. + +To avoid affecting the current use, use runtime config 'fdir_index_config' +to select flow director index strategy. The options are as follows: +1. hash: Default config, the rule priority level cannot be set. + The driver generates a flow index based on the hash of the rte_flow key. +2. priority: The flow rule priority feature is supported. + The driver uses the rte_flow priority field as the flow director index. + +Signed-off-by: Dengdui Huang +Signed-off-by: Jie Hai +--- + doc/guides/nics/hns3.rst | 12 +++++++ + drivers/net/hns3/hns3_common.c | 25 ++++++++++++++ + drivers/net/hns3/hns3_common.h | 1 + + drivers/net/hns3/hns3_dump.c | 2 ++ + drivers/net/hns3/hns3_ethdev.c | 3 +- + drivers/net/hns3/hns3_fdir.c | 62 ++++++++++++++++++++++++---------- + drivers/net/hns3/hns3_fdir.h | 10 ++++++ + drivers/net/hns3/hns3_flow.c | 45 +++++++++++++++++++++--- + 8 files changed, 136 insertions(+), 24 deletions(-) + +diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst +index bdc10da..b8e79c1 100644 +--- a/doc/guides/nics/hns3.rst ++++ b/doc/guides/nics/hns3.rst +@@ -193,6 +193,15 @@ Runtime Configuration + ``+outvlan-sctptag``: means disable sctp tag tuple, and enable outer vlan tuple. + ``+outvlan-tunvni``: means disable tunnel vni tuple, and enable outer vlan tuple. + ++- ``fdir_index_config`` (default ``hash``) ++ ++ Used to select flow director index strategy, the flow director index is the index ++ position in the hardware flow director table. Lower index denotes higher priority ++ (it means when a packet matches multiple indexes, the smaller index wins). ++ Current supported options are as follows: ++ ``hash``: The driver generates a flow index based on the hash of the rte_flow key. ++ ``priority``: the driver uses the rte_flow priority field as the flow director index. ++ + Driver compilation and testing + ------------------------------ + +@@ -322,6 +331,9 @@ Generic flow API + configuration for hardware which will affect other rules. + The rule just setting input tuple is completely independent. + ++ In addition, if the rule priority level is set, no error is reported, ++ but the rule priority level does not take effect. ++ + Run ``testpmd``: + + .. code-block:: console +diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c +index 99a1d59..25a4521 100644 +--- a/drivers/net/hns3/hns3_common.c ++++ b/drivers/net/hns3/hns3_common.c +@@ -290,6 +290,27 @@ hns3_parse_fdir_tuple_config(const char *key, const char *value, void *args) + return 0; + } + ++static int ++hns3_parse_fdir_index_config(const char *key, const char *value, void *args) ++{ ++ enum hns3_fdir_index_config cfg; ++ ++ if (strcmp(value, "hash") == 0) { ++ cfg = HNS3_FDIR_INDEX_CONFIG_HASH; ++ } else if (strcmp(value, "priority") == 0) { ++ cfg = HNS3_FDIR_INDEX_CONFIG_PRIORITY; ++ } else { ++ PMD_INIT_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", " ++ "value must be 'hash' or 'priority'", ++ value, key); ++ return -1; ++ } ++ ++ *(enum hns3_fdir_index_config *)args = cfg; ++ ++ return 0; ++} ++ + void + hns3_parse_devargs(struct rte_eth_dev *dev) + { +@@ -333,6 +354,10 @@ hns3_parse_devargs(struct rte_eth_dev *dev) + HNS3_DEVARG_FDIR_TUPLE_CONFIG, + &hns3_parse_fdir_tuple_config, + &hns->pf.fdir.tuple_cfg); ++ (void)rte_kvargs_process(kvlist, ++ HNS3_DEVARG_FDIR_INDEX_CONFIG, ++ &hns3_parse_fdir_index_config, ++ &hns->pf.fdir.index_cfg); + } + + rte_kvargs_free(kvlist); +diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h +index ca90936..7b3f96b 100644 +--- a/drivers/net/hns3/hns3_common.h ++++ b/drivers/net/hns3/hns3_common.h +@@ -29,6 +29,7 @@ enum { + + #define HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "fdir_vlan_match_mode" + #define HNS3_DEVARG_FDIR_TUPLE_CONFIG "fdir_tuple_config" ++#define HNS3_DEVARG_FDIR_INDEX_CONFIG "fdir_index_config" + + #define MSEC_PER_SEC 1000L + #define USEC_PER_MSEC 1000L +diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c +index fbe3716..dcdfcf4 100644 +--- a/drivers/net/hns3/hns3_dump.c ++++ b/drivers/net/hns3/hns3_dump.c +@@ -169,6 +169,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf) + "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n" + "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n" + "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n" ++ "\t -- index_cfg: %s\n" + "\t -- tuple_config: %s\n" + "\t -- active_tuples:\n", + fdcfg->fd_mode, fdcfg->max_key_length, +@@ -181,6 +182,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf) + fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en, + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en, + fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en, ++ hns3_fdir_index_config_name(pf->fdir.index_cfg), + hns3_tuple_config_name(pf->fdir.tuple_cfg)); + + for (i = 0; i < MAX_TUPLE; i++) { +diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c +index 30b7aaa..12bb834 100644 +--- a/drivers/net/hns3/hns3_ethdev.c ++++ b/drivers/net/hns3/hns3_ethdev.c +@@ -6672,7 +6672,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_hns3, + HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "=strict|nostrict " + HNS3_DEVARG_FDIR_TUPLE_CONFIG "=+outvlan-insmac|+outvlan-indmac|" + "+outvlan-insip|+outvlan-indip" +- "+outvlan-sctptag|+outvlan-tunvni "); ++ "+outvlan-sctptag|+outvlan-tunvni " ++ HNS3_DEVARG_FDIR_INDEX_CONFIG "=hash|priority "); + RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE); + RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE); + #ifdef RTE_ETHDEV_DEBUG_RX +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index 389dec2..1e9932b 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -981,39 +981,44 @@ static int hns3_insert_fdir_filter(struct hns3_hw *hw, + { + struct hns3_fdir_key_conf *key; + hash_sig_t sig; +- int ret; ++ int index; + + key = &fdir_filter->fdir_conf.key_conf; + sig = rte_hash_crc(key, sizeof(*key), 0); +- ret = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig); +- if (ret < 0) { +- hns3_err(hw, "Hash table full? err:%d!", ret); +- return ret; ++ index = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig); ++ if (index < 0) { ++ hns3_err(hw, "Hash table full? err:%d!", index); ++ return index; + } + +- fdir_info->hash_map[ret] = fdir_filter; ++ if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY) ++ index = fdir_filter->fdir_conf.location; ++ ++ fdir_info->hash_map[index] = fdir_filter; + TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries); + +- return ret; ++ return index; + } + + static int hns3_remove_fdir_filter(struct hns3_hw *hw, + struct hns3_fdir_info *fdir_info, +- struct hns3_fdir_key_conf *key) ++ struct hns3_fdir_rule *rule) + { + struct hns3_fdir_rule_ele *fdir_filter; + hash_sig_t sig; +- int ret; ++ int index; + +- sig = rte_hash_crc(key, sizeof(*key), 0); +- ret = rte_hash_del_key_with_hash(fdir_info->hash_handle, key, sig); +- if (ret < 0) { +- hns3_err(hw, "Delete hash key fail ret=%d", ret); +- return ret; ++ sig = rte_hash_crc(&rule->key_conf, sizeof(rule->key_conf), 0); ++ index = rte_hash_del_key_with_hash(fdir_info->hash_handle, &rule->key_conf, sig); ++ if (index < 0) { ++ hns3_err(hw, "Delete hash key fail ret=%d", index); ++ return index; + } + +- fdir_filter = fdir_info->hash_map[ret]; +- fdir_info->hash_map[ret] = NULL; ++ if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY) ++ index = rule->location; ++ fdir_filter = fdir_info->hash_map[index]; ++ fdir_info->hash_map[index] = NULL; + TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); + + rte_free(fdir_filter); +@@ -1042,7 +1047,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns, + rule->key_conf.spec.src_port, + rule->key_conf.spec.dst_port, ret); + else +- ret = hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf); ++ ret = hns3_remove_fdir_filter(hw, fdir_info, rule); + + return ret; + } +@@ -1080,7 +1085,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns, + rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID], + rule->key_conf.spec.src_port, + rule->key_conf.spec.dst_port, ret); +- (void)hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf); ++ (void)hns3_remove_fdir_filter(hw, fdir_info, rule); + } + + return ret; +@@ -1231,3 +1236,24 @@ hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg) + + return "unknown"; + } ++ ++static struct { ++ enum hns3_fdir_index_config cfg; ++ const char *name; ++} index_cfg_map[] = { ++ { HNS3_FDIR_INDEX_CONFIG_HASH, "hash"}, ++ { HNS3_FDIR_INDEX_CONFIG_PRIORITY, "priority"}, ++}; ++ ++const char * ++hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < RTE_DIM(index_cfg_map); i++) { ++ if (cfg == index_cfg_map[i].cfg) ++ return index_cfg_map[i].name; ++ } ++ ++ return "unknown"; ++} +diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h +index 2d0c9bf..5ba7b5b 100644 +--- a/drivers/net/hns3/hns3_fdir.h ++++ b/drivers/net/hns3/hns3_fdir.h +@@ -228,6 +228,14 @@ enum hns3_fdir_tuple_config { + HNS3_FDIR_TUPLE_CONFIG_BUTT + }; + ++enum hns3_fdir_index_config { ++ /* Generate the hardware flow director index based on rte_hash (Default) */ ++ HNS3_FDIR_INDEX_CONFIG_HASH, ++ ++ /* Use the rte_flow priority field as the hardware flow director index. */ ++ HNS3_FDIR_INDEX_CONFIG_PRIORITY ++}; ++ + /* + * A structure used to define fields of a FDIR related info. + */ +@@ -238,6 +246,7 @@ struct hns3_fdir_info { + struct hns3_fd_cfg fd_cfg; + uint8_t vlan_match_mode; + enum hns3_fdir_tuple_config tuple_cfg; ++ enum hns3_fdir_index_config index_cfg; + }; + + struct hns3_adapter; +@@ -254,5 +263,6 @@ int hns3_restore_all_fdir_filter(struct hns3_adapter *hns); + + enum hns3_fdir_tuple_config hns3_parse_tuple_config(const char *name); + const char *hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg); ++const char *hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg); + + #endif /* HNS3_FDIR_H */ +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 4674f74..40e2409 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -597,10 +597,6 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, + attr, "No support for transfer"); +- if (attr->priority) +- return rte_flow_error_set(error, ENOTSUP, +- RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, +- attr, "Not support priority"); + if (attr->group) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, +@@ -1441,6 +1437,40 @@ is_tunnel_packet(enum rte_flow_item_type type) + return false; + } + ++static int ++hns3_handle_attributes(struct rte_eth_dev *dev, ++ const struct rte_flow_attr *attr, ++ struct hns3_fdir_rule *rule, ++ struct rte_flow_error *error) ++{ ++ struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct hns3_fdir_info fdir = pf->fdir; ++ uint32_t rule_num; ++ ++ if (fdir.index_cfg != HNS3_FDIR_INDEX_CONFIG_PRIORITY) { ++ if (attr->priority == 0) ++ return 0; ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, ++ attr, "Not support priority"); ++ } ++ ++ rule_num = fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1]; ++ if (attr->priority >= rule_num) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, ++ attr, "Priority out of range"); ++ ++ if (fdir.hash_map[attr->priority] != NULL) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, ++ attr, "Priority already exists"); ++ ++ rule->location = attr->priority; ++ ++ return 0; ++} ++ + /* + * Parse the flow director rule. + * The supported PATTERN: +@@ -1468,6 +1498,7 @@ is_tunnel_packet(enum rte_flow_item_type type) + */ + static int + hns3_parse_fdir_filter(struct rte_eth_dev *dev, ++ const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct hns3_fdir_rule *rule, +@@ -1484,6 +1515,10 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Fdir not supported in VF"); + ++ ret = hns3_handle_attributes(dev, attr, rule, error); ++ if (ret) ++ return ret; ++ + step_mngr.items = first_items; + step_mngr.count = RTE_DIM(first_items); + for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { +@@ -2248,7 +2283,7 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + return hns3_parse_rss_filter(dev, pattern, actions, + &conf->rss_conf, error); + +- return hns3_parse_fdir_filter(dev, pattern, actions, ++ return hns3_parse_fdir_filter(dev, attr, pattern, actions, + &conf->fdir_conf, error); + } + +-- +2.33.0 + diff --git a/0074-net-hns3-fix-error-code-for-repeatedly-create-counter.patch b/0074-net-hns3-fix-error-code-for-repeatedly-create-counter.patch new file mode 100644 index 0000000..f7e6d86 --- /dev/null +++ b/0074-net-hns3-fix-error-code-for-repeatedly-create-counter.patch @@ -0,0 +1,36 @@ +From 520399c4f369d94e3ab5a35683ef381c6a8d36f1 Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Thu, 7 Nov 2024 19:56:44 +0800 +Subject: [PATCH] net/hns3: fix error code for repeatedly create counter + +[ upstream commit 585f1f68f18c7acbc4f920053cbf4ba888e0c271 ] + +Return EINVAL instead of ENOSPC when the same counter ID is +used for multiple times to create a counter. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +Signed-off-by: Jie Hai +Acked-by: Stephen Hemminger +--- + drivers/net/hns3/hns3_flow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c +index 40e2409..9a0b5d2 100644 +--- a/drivers/net/hns3/hns3_flow.c ++++ b/drivers/net/hns3/hns3_flow.c +@@ -286,7 +286,7 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t indirect, uint32_t id, + cnt = hns3_counter_lookup(dev, id); + if (cnt) { + if (!cnt->indirect || cnt->indirect != indirect) +- return rte_flow_error_set(error, ENOTSUP, ++ return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + cnt, + "Counter id is used, indirect flag not match"); +-- +2.33.0 + diff --git a/0075-net-hns3-fix-fully-use-hardware-flow-director-table.patch b/0075-net-hns3-fix-fully-use-hardware-flow-director-table.patch new file mode 100644 index 0000000..525fb84 --- /dev/null +++ b/0075-net-hns3-fix-fully-use-hardware-flow-director-table.patch @@ -0,0 +1,40 @@ +From 58ab4881de0966ab351fc2d423fd98cfb3c0332f Mon Sep 17 00:00:00 2001 +From: Dengdui Huang +Date: Thu, 7 Nov 2024 19:56:45 +0800 +Subject: [PATCH] net/hns3: fix fully use hardware flow director table + +[ upstream commit b8e60c33168a2999604c17322dd0198a6746428f ] + +The hns3 driver checks whether the flow rule is repeatedly inserted +based on rte_hash. Currently, the rte_hash extendable bucket table +feature is not enabled. When there are many hash conflicts, the hash +table space cannot be fully used. So the flow rule maybe cannot be +inserted even if the hardware flow director table there are still free. +This patch fix it by enabling the rte_hash extensible bucket table +feature. + +Fixes: fcba820d9b9e ("net/hns3: support flow director") +Cc: stable@dpdk.org + +Signed-off-by: Dengdui Huang +Signed-off-by: Jie Hai +Acked-by: Stephen Hemminger +--- + drivers/net/hns3/hns3_fdir.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c +index 1e9932b..d645471 100644 +--- a/drivers/net/hns3/hns3_fdir.c ++++ b/drivers/net/hns3/hns3_fdir.c +@@ -900,6 +900,7 @@ int hns3_fdir_filter_init(struct hns3_adapter *hns) + .key_len = sizeof(struct hns3_fdir_key_conf), + .hash_func = rte_hash_crc, + .hash_func_init_val = 0, ++ .extra_flag = RTE_HASH_EXTRA_FLAGS_EXT_TABLE, + }; + int ret; + +-- +2.33.0 + diff --git a/dpdk.spec b/dpdk.spec index 2b8f415..b444627 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -11,7 +11,7 @@ Name: dpdk Version: 23.11 -Release: 23 +Release: 24 URL: http://dpdk.org Source: https://fast.dpdk.org/rel/dpdk-%{version}.tar.xz @@ -73,6 +73,35 @@ Patch6044: 0044-net-hns3-support-more-VLAN-fields-matching.patch Patch6045: 0045-net-hns3-add-Rx-DMA-address-align-check.patch Patch6046: 0046-bus-pci-fix-UIO-resource-mapping-in-secondary-process.patch +Patch6047: 0047-ethdev-verify-queue-ID-in-Tx-done-cleanup.patch +Patch6048: 0048-net-hns3-verify-reset-type-from-firmware.patch +Patch6049: 0049-dmadev-fix-potential-null-pointer-access.patch +Patch6050: 0050-net-hns3-dump-queue-head-and-tail-pointer-info.patch +Patch6051: 0051-net-hns3-remove-ROH-devices.patch +Patch6052: 0052-net-hns3-restrict-tunnel-flow-rule-to-one-header.patch +Patch6053: 0053-net-hns3-support-general-tunnel-flow-match.patch +Patch6054: 0054-net-hns3-register-VLAN-flow-match-mode-parameter.patch +Patch6055: 0055-net-hns3-support-outer-VLAN-flow-match.patch +Patch6056: 0056-telemetry-register-command-with-private-argument.patch +Patch6057: 0057-ethdev-fix-race-on-ports-in-telemetry-endpoints.patch +Patch6058: 0058-ethdev-add-report-of-register-names-and-filter.patch +Patch6059: 0059-ethdev-add-telemetry-command-for-registers.patch +Patch6060: 0060-net-hns3-remove-some-basic-address-dump.patch +Patch6061: 0061-net-hns3-fix-dump-counter-of-registers.patch +Patch6062: 0062-net-hns3-remove-separators-between-register-module.patch +Patch6063: 0063-net-hns3-refactor-register-dump.patch +Patch6064: 0064-net-hns3-support-reporting-names-of-registers.patch +Patch6065: 0065-net-hns3-support-filtering-registers-by-module-names.patch +Patch6066: 0066-net-hns3-fix-error-log.patch +Patch6067: 0067-net-hns3-fix-pointer-offset-for-registers.patch +Patch6068: 0068-net-hns3-fix-integer-type.patch +Patch6069: 0069-kvargs-rework-process-API.patch +Patch6070: 0070-net-sfc-use-new-kvargs-process-API.patch +Patch6071: 0071-net-tap-use-new-kvargs-process-API.patch +Patch6072: 0072-common-nfp-use-new-kvargs-process-API.patch +Patch6073: 0073-net-hns3-support-flow-rule-priority.patch +Patch6074: 0074-net-hns3-fix-error-code-for-repeatedly-create-counter.patch +Patch6075: 0075-net-hns3-fix-fully-use-hardware-flow-director-table.patch BuildRequires: meson BuildRequires: python3-pyelftools @@ -277,6 +306,41 @@ fi /usr/sbin/depmod %changelog +* Mon Nov 11 2024 huangdengdui - 23.11-24 + Sync some patchs from upstreaming, includind some bugfixes, hns3 pmd + flow rule priority feature, hns3 pmd outer VLAN flow match feature, + and support dump reigser names and filter. + This patch set is modified as follows: + - net/hns3: fix cannot fully use hardware flow director table + - net/hns3: fix error code for repeatedly create counter + - net/hns3: support flow rule priority + - common/nfp: use new kvargs process API + - net/tap: use new kvargs process API + - net/sfc: use new kvargs process API + - kvargs: rework process API + - net/hns3: fix variable type + - net/hns3: fix pointer offset + - net/hns3: fix error log + - net/hns3: support filtering registers by module names + - net/hns3: support reporting names of registers + - net/hns3: refactor register dump + - net/hns3: remove separators between register module + - net/hns3: fix dump counter of registers + - net/hns3: remove some basic address dump + - telemetry: register command with private argument + - ethdev: fix race on ports in telemetry endpoints + - ethdev: add telemetry command for registers + - ethdev: add report of register names and filter + - net/hns3: support outer VLAN flow match + - net/hns3: register VLAN flow match mode parameter + - net/hns3: support general tunnel flow match + - net/hns3: restrict tunnel flow rule to one header + - net/hns3: remove ROH devices + - net/hns3: dump queue head and tail pointer info + - dmadev: fix potential null pointer access + - net/hns3: verify reset type from firmware + - ethdev: verify queue ID in Tx done cleanup + * Fri Oct 11 2024 huangdengdui - 23.11-23 Fix UIO resource mapping in secondary process -- Gitee