1 | There are some bugfix for the HNS3 ethernet driver | 1 | There are some bugfix for the HNS3 ethernet driver |
---|---|---|---|
2 | 2 | ||
3 | Hao Lan (1): | 3 | Hao Lan (4): |
4 | net: hns3: fix spelling mistake "reg_um" -> "reg_num" | 4 | net: hns3: fixed reset failure issues caused by the incorrect reset |
5 | type | ||
6 | net: hns3: fix missing features due to dev->features configuration too | ||
7 | early | ||
8 | net: hns3: Resolved the issue that the debugfs query result is | ||
9 | inconsistent. | ||
10 | net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds | ||
11 | issue | ||
5 | 12 | ||
6 | Jian Shen (1): | 13 | Jian Shen (3): |
7 | net: hns3: store rx VLAN tag offload state for VF | 14 | net: hns3: add sync command to sync io-pgtable |
15 | net: hns3: don't auto enable misc vector | ||
16 | net: hns3: initialize reset_timer before hclgevf_misc_irq_init() | ||
8 | 17 | ||
9 | Yonglong Liu (1): | 18 | Jie Wang (1): |
10 | net: hns3: fix a use of uninitialized variable problem | 19 | net: hns3: fix kernel crash when 1588 is sent on HIP08 devices |
11 | 20 | ||
12 | .../hisilicon/hns3/hns3pf/hclge_main.c | 2 +- | 21 | Peiyang Wang (1): |
13 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++----- | 22 | net: hns3: default enable tx bounce buffer when smmu enabled |
14 | .../hisilicon/hns3/hns3vf/hclgevf_main.h | 3 ++- | 23 | |
15 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 27 ++++++++++--------- | 24 | .../ethernet/hisilicon/hns3/hns3_debugfs.c | 4 +- |
16 | 4 files changed, 36 insertions(+), 21 deletions(-) | 25 | .../net/ethernet/hisilicon/hns3/hns3_enet.c | 59 ++++++++++++++++++- |
26 | .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 + | ||
27 | .../ethernet/hisilicon/hns3/hns3_ethtool.c | 33 +++++++++++ | ||
28 | .../hisilicon/hns3/hns3pf/hclge_main.c | 44 +++++++++++--- | ||
29 | .../hisilicon/hns3/hns3pf/hclge_ptp.c | 3 + | ||
30 | .../hisilicon/hns3/hns3pf/hclge_regs.c | 9 +-- | ||
31 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 40 ++++++++++--- | ||
32 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 9 +-- | ||
33 | 9 files changed, 178 insertions(+), 25 deletions(-) | ||
17 | 34 | ||
18 | -- | 35 | -- |
19 | 2.33.0 | 36 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Peiyang Wang <wangpeiyang1@huawei.com> | ||
1 | 2 | ||
3 | When TX bounce buffer is enabled, dma map is used only when the buffer | ||
4 | initialized. When spending packages, the driver only do dma sync. To | ||
5 | avoid SMMU prefetch, default enable tx bounce buffer if smmu enabled. | ||
6 | |||
7 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
8 | Signed-off-by: Peiyang Wang <wangpeiyang1@huawei.com> | ||
9 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
10 | --- | ||
11 | .../net/ethernet/hisilicon/hns3/hns3_enet.c | 31 +++++++++++++++++ | ||
12 | .../net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++ | ||
13 | .../ethernet/hisilicon/hns3/hns3_ethtool.c | 33 +++++++++++++++++++ | ||
14 | 3 files changed, 66 insertions(+) | ||
15 | |||
16 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
19 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | #include <linux/irq.h> | ||
22 | #include <linux/ip.h> | ||
23 | #include <linux/ipv6.h> | ||
24 | +#include <linux/iommu.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/skbuff.h> | ||
28 | @@ -XXX,XX +XXX,XX @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring, | ||
29 | static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) | ||
30 | { | ||
31 | u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size; | ||
32 | + struct net_device *netdev = ring_to_netdev(ring); | ||
33 | + struct hns3_nic_priv *priv = netdev_priv(netdev); | ||
34 | struct hns3_tx_spare *tx_spare; | ||
35 | struct page *page; | ||
36 | dma_addr_t dma; | ||
37 | @@ -XXX,XX +XXX,XX @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) | ||
38 | tx_spare->buf = page_address(page); | ||
39 | tx_spare->len = PAGE_SIZE << order; | ||
40 | ring->tx_spare = tx_spare; | ||
41 | + ring->tx_copybreak = priv->tx_copybreak; | ||
42 | return; | ||
43 | |||
44 | dma_mapping_error: | ||
45 | @@ -XXX,XX +XXX,XX @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) | ||
46 | devm_kfree(&pdev->dev, priv->tqp_vector); | ||
47 | } | ||
48 | |||
49 | +static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv) | ||
50 | +{ | ||
51 | +#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024) | ||
52 | +#define HNS3_MAX_PACKET_SIZE (64 * 1024) | ||
53 | + | ||
54 | + struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev); | ||
55 | + struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle); | ||
56 | + struct hnae3_handle *handle = priv->ae_handle; | ||
57 | + | ||
58 | + if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) | ||
59 | + return; | ||
60 | + | ||
61 | + if (!(domain && iommu_is_dma_domain(domain))) | ||
62 | + return; | ||
63 | + | ||
64 | + priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE; | ||
65 | + priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE; | ||
66 | + | ||
67 | + if (priv->tx_copybreak < priv->min_tx_copybreak) | ||
68 | + priv->tx_copybreak = priv->min_tx_copybreak; | ||
69 | + if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size) | ||
70 | + handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size; | ||
71 | +} | ||
72 | + | ||
73 | static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, | ||
74 | unsigned int ring_type) | ||
75 | { | ||
76 | @@ -XXX,XX +XXX,XX @@ int hns3_init_all_ring(struct hns3_nic_priv *priv) | ||
77 | int i, j; | ||
78 | int ret; | ||
79 | |||
80 | + hns3_update_tx_spare_buf_config(priv); | ||
81 | for (i = 0; i < ring_num; i++) { | ||
82 | ret = hns3_alloc_ring_memory(&priv->ring[i]); | ||
83 | if (ret) { | ||
84 | @@ -XXX,XX +XXX,XX @@ static int hns3_client_init(struct hnae3_handle *handle) | ||
85 | priv->ae_handle = handle; | ||
86 | priv->tx_timeout_count = 0; | ||
87 | priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num; | ||
88 | + priv->min_tx_copybreak = 0; | ||
89 | + priv->min_tx_spare_buf_size = 0; | ||
90 | set_bit(HNS3_NIC_STATE_DOWN, &priv->state); | ||
91 | |||
92 | handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); | ||
93 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | ||
96 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | ||
97 | @@ -XXX,XX +XXX,XX @@ struct hns3_nic_priv { | ||
98 | struct hns3_enet_coalesce rx_coal; | ||
99 | u32 tx_copybreak; | ||
100 | u32 rx_copybreak; | ||
101 | + u32 min_tx_copybreak; | ||
102 | + u32 min_tx_spare_buf_size; | ||
103 | }; | ||
104 | |||
105 | union l3_hdr_info { | ||
106 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | ||
107 | index XXXXXXX..XXXXXXX 100644 | ||
108 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | ||
109 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | ||
110 | @@ -XXX,XX +XXX,XX @@ static int hns3_set_tx_spare_buf_size(struct net_device *netdev, | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | +static int hns3_check_tx_copybreak(struct net_device *netdev, u32 copybreak) | ||
115 | +{ | ||
116 | + struct hns3_nic_priv *priv = netdev_priv(netdev); | ||
117 | + | ||
118 | + if (copybreak < priv->min_tx_copybreak) { | ||
119 | + netdev_err(netdev, "tx copybreak %u should be no less than %u!\n", | ||
120 | + copybreak, priv->min_tx_copybreak); | ||
121 | + return -EINVAL; | ||
122 | + } | ||
123 | + return 0; | ||
124 | +} | ||
125 | + | ||
126 | +static int hns3_check_tx_spare_buf_size(struct net_device *netdev, u32 buf_size) | ||
127 | +{ | ||
128 | + struct hns3_nic_priv *priv = netdev_priv(netdev); | ||
129 | + | ||
130 | + if (buf_size < priv->min_tx_spare_buf_size) { | ||
131 | + netdev_err(netdev, | ||
132 | + "tx spare buf size %u should be no less than %u!\n", | ||
133 | + buf_size, priv->min_tx_spare_buf_size); | ||
134 | + return -EINVAL; | ||
135 | + } | ||
136 | + return 0; | ||
137 | +} | ||
138 | + | ||
139 | static int hns3_set_tunable(struct net_device *netdev, | ||
140 | const struct ethtool_tunable *tuna, | ||
141 | const void *data) | ||
142 | @@ -XXX,XX +XXX,XX @@ static int hns3_set_tunable(struct net_device *netdev, | ||
143 | |||
144 | switch (tuna->id) { | ||
145 | case ETHTOOL_TX_COPYBREAK: | ||
146 | + ret = hns3_check_tx_copybreak(netdev, *(u32 *)data); | ||
147 | + if (ret) | ||
148 | + return ret; | ||
149 | + | ||
150 | priv->tx_copybreak = *(u32 *)data; | ||
151 | |||
152 | for (i = 0; i < h->kinfo.num_tqps; i++) | ||
153 | @@ -XXX,XX +XXX,XX @@ static int hns3_set_tunable(struct net_device *netdev, | ||
154 | |||
155 | break; | ||
156 | case ETHTOOL_TX_COPYBREAK_BUF_SIZE: | ||
157 | + ret = hns3_check_tx_spare_buf_size(netdev, *(u32 *)data); | ||
158 | + if (ret) | ||
159 | + return ret; | ||
160 | + | ||
161 | old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size; | ||
162 | new_tx_spare_buf_size = *(u32 *)data; | ||
163 | netdev_info(netdev, "request to set tx spare buf size from %u to %u\n", | ||
164 | -- | ||
165 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jian Shen <shenjian15@huawei.com> | ||
1 | 2 | ||
3 | To avoid errors in pgtable prefectch, add a sync command to sync | ||
4 | io-pagtable. | ||
5 | |||
6 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
7 | Signed-off-by: Peiyang Wang <wangpeiyang1@huawei.com> | ||
8 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
9 | --- | ||
10 | .../net/ethernet/hisilicon/hns3/hns3_enet.c | 27 +++++++++++++++++++ | ||
11 | 1 file changed, 27 insertions(+) | ||
12 | |||
13 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
16 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = { | ||
18 | #define HNS3_INVALID_PTYPE \ | ||
19 | ARRAY_SIZE(hns3_rx_ptype_tbl) | ||
20 | |||
21 | +static void hns3_dma_map_sync(struct device *dev, unsigned long iova) | ||
22 | +{ | ||
23 | + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); | ||
24 | + struct iommu_iotlb_gather iotlb_gather; | ||
25 | + size_t granule; | ||
26 | + | ||
27 | + if (!domain || !iommu_is_dma_domain(domain)) | ||
28 | + return; | ||
29 | + | ||
30 | + granule = 1 << __ffs(domain->pgsize_bitmap); | ||
31 | + iova = ALIGN_DOWN(iova, granule); | ||
32 | + iotlb_gather.start = iova; | ||
33 | + iotlb_gather.end = iova + granule - 1; | ||
34 | + iotlb_gather.pgsize = granule; | ||
35 | + | ||
36 | + iommu_iotlb_sync(domain, &iotlb_gather); | ||
37 | +} | ||
38 | + | ||
39 | static irqreturn_t hns3_irq_handle(int irq, void *vector) | ||
40 | { | ||
41 | struct hns3_enet_tqp_vector *tqp_vector = vector; | ||
42 | @@ -XXX,XX +XXX,XX @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv, | ||
43 | unsigned int type) | ||
44 | { | ||
45 | struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; | ||
46 | + struct hnae3_handle *handle = ring->tqp->handle; | ||
47 | struct device *dev = ring_to_dev(ring); | ||
48 | + struct hnae3_ae_dev *ae_dev; | ||
49 | unsigned int size; | ||
50 | dma_addr_t dma; | ||
51 | |||
52 | @@ -XXX,XX +XXX,XX @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv, | ||
53 | return -ENOMEM; | ||
54 | } | ||
55 | |||
56 | + /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable | ||
57 | + * prefetch | ||
58 | + */ | ||
59 | + ae_dev = hns3_get_ae_dev(handle); | ||
60 | + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) | ||
61 | + hns3_dma_map_sync(dev, dma); | ||
62 | + | ||
63 | desc_cb->priv = priv; | ||
64 | desc_cb->length = size; | ||
65 | desc_cb->dma = dma; | ||
66 | -- | ||
67 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Hao Lan <lanhao@huawei.com> | |
2 | |||
3 | When a reset type that is not supported by the driver is input, a reset | ||
4 | pending flag bit of the HNAE3_NONE_RESET type is generated in | ||
5 | reset_pending. The driver does not have a mechanism to clear this type | ||
6 | of error. As a result, the driver considers that the reset is not | ||
7 | complete. This patch provides a mechanism to clear the | ||
8 | HNAE3_NONE_RESET flag and the parameter of | ||
9 | hnae3_ae_ops.set_default_reset_request is verified. | ||
10 | |||
11 | The error message: | ||
12 | hns3 0000:39:01.0: cmd failed -16 | ||
13 | hns3 0000:39:01.0: hclge device re-init failed, VF is disabled! | ||
14 | hns3 0000:39:01.0: failed to reset VF stack | ||
15 | hns3 0000:39:01.0: failed to reset VF(4) | ||
16 | hns3 0000:39:01.0: prepare reset(2) wait done | ||
17 | hns3 0000:39:01.0 eth4: already uninitialized | ||
18 | |||
19 | Use the crash tool to view struct hclgevf_dev: | ||
20 | struct hclgevf_dev { | ||
21 | ... | ||
22 | default_reset_request = 0x20, | ||
23 | reset_level = HNAE3_NONE_RESET, | ||
24 | reset_pending = 0x100, | ||
25 | reset_type = HNAE3_NONE_RESET, | ||
26 | ... | ||
27 | }; | ||
28 | |||
29 | Fixes: 720bd5837e37 ("net: hns3: add set_default_reset_request in the hnae3_ae_ops") | ||
30 | Signed-off-by: Hao Lan <lanhao@huawei.com> | ||
31 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
32 | --- | ||
33 | .../hisilicon/hns3/hns3pf/hclge_main.c | 33 ++++++++++++++-- | ||
34 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 38 ++++++++++++++++--- | ||
35 | 2 files changed, 61 insertions(+), 10 deletions(-) | ||
36 | |||
37 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | ||
40 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, | ||
42 | return ret; | ||
43 | } | ||
44 | |||
45 | +static void hclge_set_reset_pending(struct hclge_dev *hdev, | ||
46 | + enum hnae3_reset_type reset_type) | ||
47 | +{ | ||
48 | + /* When an incorrect reset type is executed, the get_reset_level | ||
49 | + * function generates the HNAE3_NONE_RESET flag. As a result, this | ||
50 | + * type do not need to pending. | ||
51 | + */ | ||
52 | + if (reset_type != HNAE3_NONE_RESET) | ||
53 | + set_bit(reset_type, &hdev->reset_pending); | ||
54 | +} | ||
55 | + | ||
56 | static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | ||
57 | { | ||
58 | u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg; | ||
59 | @@ -XXX,XX +XXX,XX @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | ||
60 | */ | ||
61 | if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) { | ||
62 | dev_info(&hdev->pdev->dev, "IMP reset interrupt\n"); | ||
63 | - set_bit(HNAE3_IMP_RESET, &hdev->reset_pending); | ||
64 | + hclge_set_reset_pending(hdev, HNAE3_IMP_RESET); | ||
65 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | ||
66 | *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); | ||
67 | hdev->rst_stats.imp_rst_cnt++; | ||
68 | @@ -XXX,XX +XXX,XX @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | ||
69 | if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) { | ||
70 | dev_info(&hdev->pdev->dev, "global reset interrupt\n"); | ||
71 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | ||
72 | - set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending); | ||
73 | + hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET); | ||
74 | *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); | ||
75 | hdev->rst_stats.global_rst_cnt++; | ||
76 | return HCLGE_VECTOR0_EVENT_RST; | ||
77 | @@ -XXX,XX +XXX,XX @@ static void hclge_do_reset(struct hclge_dev *hdev) | ||
78 | case HNAE3_FUNC_RESET: | ||
79 | dev_info(&pdev->dev, "PF reset requested\n"); | ||
80 | /* schedule again to check later */ | ||
81 | - set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending); | ||
82 | + hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET); | ||
83 | hclge_reset_task_schedule(hdev); | ||
84 | break; | ||
85 | default: | ||
86 | @@ -XXX,XX +XXX,XX @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev, | ||
87 | clear_bit(HNAE3_FLR_RESET, addr); | ||
88 | } | ||
89 | |||
90 | + clear_bit(HNAE3_NONE_RESET, addr); | ||
91 | + | ||
92 | if (hdev->reset_type != HNAE3_NONE_RESET && | ||
93 | rst_level < hdev->reset_type) | ||
94 | return HNAE3_NONE_RESET; | ||
95 | @@ -XXX,XX +XXX,XX @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) | ||
96 | return false; | ||
97 | } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) { | ||
98 | hdev->rst_stats.reset_fail_cnt++; | ||
99 | - set_bit(hdev->reset_type, &hdev->reset_pending); | ||
100 | + hclge_set_reset_pending(hdev, hdev->reset_type); | ||
101 | dev_info(&hdev->pdev->dev, | ||
102 | "re-schedule reset task(%u)\n", | ||
103 | hdev->rst_stats.reset_fail_cnt); | ||
104 | @@ -XXX,XX +XXX,XX @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) | ||
105 | static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev, | ||
106 | enum hnae3_reset_type rst_type) | ||
107 | { | ||
108 | +#define HCLGE_SUPPORT_RESET_TYPE \ | ||
109 | + (BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \ | ||
110 | + BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET)) | ||
111 | + | ||
112 | struct hclge_dev *hdev = ae_dev->priv; | ||
113 | |||
114 | + if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) { | ||
115 | + /* To prevent reset triggered by hclge_reset_event */ | ||
116 | + set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request); | ||
117 | + dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n", | ||
118 | + rst_type); | ||
119 | + return; | ||
120 | + } | ||
121 | + | ||
122 | set_bit(rst_type, &hdev->default_reset_request); | ||
123 | } | ||
124 | |||
125 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
128 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | ||
129 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev, | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | +static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev, | ||
134 | + enum hnae3_reset_type reset_type) | ||
135 | +{ | ||
136 | + /* When an incorrect reset type is executed, the get_reset_level | ||
137 | + * function generates the HNAE3_NONE_RESET flag. As a result, this | ||
138 | + * type do not need to pending. | ||
139 | + */ | ||
140 | + if (reset_type != HNAE3_NONE_RESET) | ||
141 | + set_bit(reset_type, &hdev->reset_pending); | ||
142 | +} | ||
143 | + | ||
144 | static int hclgevf_reset_wait(struct hclgevf_dev *hdev) | ||
145 | { | ||
146 | #define HCLGEVF_RESET_WAIT_US 20000 | ||
147 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) | ||
148 | hdev->rst_stats.rst_fail_cnt); | ||
149 | |||
150 | if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT) | ||
151 | - set_bit(hdev->reset_type, &hdev->reset_pending); | ||
152 | + hclgevf_set_reset_pending(hdev, hdev->reset_type); | ||
153 | |||
154 | if (hclgevf_is_reset_pending(hdev)) { | ||
155 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
156 | @@ -XXX,XX +XXX,XX @@ static enum hnae3_reset_type hclgevf_get_reset_level(unsigned long *addr) | ||
157 | clear_bit(HNAE3_FLR_RESET, addr); | ||
158 | } | ||
159 | |||
160 | + clear_bit(HNAE3_NONE_RESET, addr); | ||
161 | + | ||
162 | return rst_level; | ||
163 | } | ||
164 | |||
165 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_event(struct pci_dev *pdev, | ||
166 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); | ||
167 | struct hclgevf_dev *hdev = ae_dev->priv; | ||
168 | |||
169 | - dev_info(&hdev->pdev->dev, "received reset request from VF enet\n"); | ||
170 | - | ||
171 | if (hdev->default_reset_request) | ||
172 | hdev->reset_level = | ||
173 | hclgevf_get_reset_level(&hdev->default_reset_request); | ||
174 | else | ||
175 | hdev->reset_level = HNAE3_VF_FUNC_RESET; | ||
176 | |||
177 | + dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n", | ||
178 | + hdev->reset_level); | ||
179 | + | ||
180 | /* reset of this VF requested */ | ||
181 | set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); | ||
182 | hclgevf_reset_task_schedule(hdev); | ||
183 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_event(struct pci_dev *pdev, | ||
184 | static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, | ||
185 | enum hnae3_reset_type rst_type) | ||
186 | { | ||
187 | +#define HCLGEVF_SUPPORT_RESET_TYPE \ | ||
188 | + (BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \ | ||
189 | + BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \ | ||
190 | + BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET)) | ||
191 | + | ||
192 | struct hclgevf_dev *hdev = ae_dev->priv; | ||
193 | |||
194 | + if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) { | ||
195 | + /* To prevent reset triggered by hclge_reset_event */ | ||
196 | + set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request); | ||
197 | + dev_info(&hdev->pdev->dev, "unsupported reset type %d\n", | ||
198 | + rst_type); | ||
199 | + return; | ||
200 | + } | ||
201 | set_bit(rst_type, &hdev->default_reset_request); | ||
202 | } | ||
203 | |||
204 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) | ||
205 | */ | ||
206 | if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { | ||
207 | /* prepare for full reset of stack + pcie interface */ | ||
208 | - set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending); | ||
209 | + hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET); | ||
210 | |||
211 | /* "defer" schedule the reset task again */ | ||
212 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
213 | } else { | ||
214 | hdev->reset_attempts++; | ||
215 | |||
216 | - set_bit(hdev->reset_level, &hdev->reset_pending); | ||
217 | + hclgevf_set_reset_pending(hdev, hdev->reset_level); | ||
218 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
219 | } | ||
220 | hclgevf_reset_task_schedule(hdev); | ||
221 | @@ -XXX,XX +XXX,XX @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, | ||
222 | rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); | ||
223 | dev_info(&hdev->pdev->dev, | ||
224 | "receive reset interrupt 0x%x!\n", rst_ing_reg); | ||
225 | - set_bit(HNAE3_VF_RESET, &hdev->reset_pending); | ||
226 | + hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET); | ||
227 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | ||
228 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | ||
229 | *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B); | ||
230 | -- | ||
231 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Hao Lan <lanhao@huawei.com> | ||
1 | 2 | ||
3 | Currently, the netdev->features is configured in hns3_nic_set_features. | ||
4 | As a result, __netdev_update_features considers that there is no feature | ||
5 | difference, and the procedures of the real features are missing. | ||
6 | |||
7 | Fixes: 2a7556bb2b73 ("net: hns3: implement ndo_features_check ops for hns3 driver") | ||
8 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
9 | Signed-off-by: Hao Lan <lanhao@huawei.com> | ||
10 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
11 | --- | ||
12 | drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 1 - | ||
13 | 1 file changed, 1 deletion(-) | ||
14 | |||
15 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
18 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static int hns3_nic_set_features(struct net_device *netdev, | ||
20 | return ret; | ||
21 | } | ||
22 | |||
23 | - netdev->features = features; | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | -- | ||
28 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Hao Lan <lanhao@huawei.com> | ||
1 | 2 | ||
3 | This patch modifies the implementation of debugfs: | ||
4 | When the user process stops unexpectedly, not all data of the file system | ||
5 | is read. In this case, the save_buf pointer is not released. When the user | ||
6 | process is called next time, save_buf is used to copy the cached data | ||
7 | to the user space. As a result, the queried data is inconsistent. To solve | ||
8 | this problem, determine whether the function is invoked for the first time | ||
9 | based on the value of *ppos. If *ppos is 0, obtain the actual data. | ||
10 | |||
11 | Fixes: 5e69ea7ee2a6 ("net: hns3: refactor the debugfs process") | ||
12 | Signed-off-by: Guangwei Zhang <zhangwangwei6@huawei.com> | ||
13 | Signed-off-by: Hao Lan <lanhao@huawei.com> | ||
14 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
15 | --- | ||
16 | drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 4 +++- | ||
17 | 1 file changed, 3 insertions(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | ||
22 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, | ||
24 | |||
25 | /* save the buffer addr until the last read operation */ | ||
26 | *save_buf = read_buf; | ||
27 | + } | ||
28 | |||
29 | - /* get data ready for the first time to read */ | ||
30 | + /* get data ready for the first time to read */ | ||
31 | + if (!*ppos) { | ||
32 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, | ||
33 | read_buf, hns3_dbg_cmd[index].buf_len); | ||
34 | if (ret) | ||
35 | -- | ||
36 | 2.33.0 | diff view generated by jsdifflib |
1 | From: Yonglong Liu <liuyonglong@huawei.com> | 1 | From: Jian Shen <shenjian15@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | In hclge_add_fd_entry(), if the flow type is FLOW_EXT, and the data of | 3 | Currently, there is a time window between misc irq enabled |
4 | m_ext is all zero, then some members of the local variable "info" are | 4 | and service task inited. If an interrupte is reported at |
5 | not initialized. | 5 | this time, it will cause warning like below: |
6 | 6 | ||
7 | Fixes: 67b0e1428e2f ("net: hns3: add support for user-def data of flow director") | 7 | [ 16.324639] Call trace: |
8 | Signed-off-by: Yonglong Liu <liuyonglong@huawei.com> | 8 | [ 16.324641] __queue_delayed_work+0xb8/0xe0 |
9 | [ 16.324643] mod_delayed_work_on+0x78/0xd0 | ||
10 | [ 16.324655] hclge_errhand_task_schedule+0x58/0x90 [hclge] | ||
11 | [ 16.324662] hclge_misc_irq_handle+0x168/0x240 [hclge] | ||
12 | [ 16.324666] __handle_irq_event_percpu+0x64/0x1e0 | ||
13 | [ 16.324667] handle_irq_event+0x80/0x170 | ||
14 | [ 16.324670] handle_fasteoi_edge_irq+0x110/0x2bc | ||
15 | [ 16.324671] __handle_domain_irq+0x84/0xfc | ||
16 | [ 16.324673] gic_handle_irq+0x88/0x2c0 | ||
17 | [ 16.324674] el1_irq+0xb8/0x140 | ||
18 | [ 16.324677] arch_cpu_idle+0x18/0x40 | ||
19 | [ 16.324679] default_idle_call+0x5c/0x1bc | ||
20 | [ 16.324682] cpuidle_idle_call+0x18c/0x1c4 | ||
21 | [ 16.324684] do_idle+0x174/0x17c | ||
22 | [ 16.324685] cpu_startup_entry+0x30/0x6c | ||
23 | [ 16.324687] secondary_start_kernel+0x1a4/0x280 | ||
24 | [ 16.324688] ---[ end trace 6aa0bff672a964aa ]--- | ||
25 | |||
26 | So don't auto enable misc vector when request irq.. | ||
27 | |||
28 | Fixes: 7be1b9f3e99f ("net: hns3: make hclge_service use delayed workqueue") | ||
29 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | ||
9 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 30 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
10 | --- | 31 | --- |
11 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- | 32 | .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 11 +++++++---- |
12 | 1 file changed, 1 insertion(+), 1 deletion(-) | 33 | 1 file changed, 7 insertions(+), 4 deletions(-) |
13 | 34 | ||
14 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 35 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
15 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 37 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
17 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 38 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
18 | @@ -XXX,XX +XXX,XX @@ static int hclge_add_fd_entry(struct hnae3_handle *handle, | 39 | @@ -XXX,XX +XXX,XX @@ |
19 | struct ethtool_rxnfc *cmd) | 40 | #include <linux/etherdevice.h> |
20 | { | 41 | #include <linux/init.h> |
21 | struct hclge_vport *vport = hclge_get_vport(handle); | 42 | #include <linux/interrupt.h> |
22 | + struct hclge_fd_user_def_info info = {0}; | 43 | +#include <linux/irq.h> |
23 | struct hclge_dev *hdev = vport->back; | 44 | #include <linux/kernel.h> |
24 | - struct hclge_fd_user_def_info info; | 45 | #include <linux/module.h> |
25 | u16 dst_vport_id = 0, q_index = 0; | 46 | #include <linux/netdevice.h> |
26 | struct ethtool_rx_flow_spec *fs; | 47 | @@ -XXX,XX +XXX,XX @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) |
27 | struct hclge_fd_rule *rule; | 48 | /* this would be explicitly freed in the end */ |
49 | snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", | ||
50 | HCLGE_NAME, pci_name(hdev->pdev)); | ||
51 | + irq_set_status_flags(hdev->misc_vector.vector_irq, IRQ_NOAUTOEN); | ||
52 | ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle, | ||
53 | 0, hdev->misc_vector.name, hdev); | ||
54 | if (ret) { | ||
55 | @@ -XXX,XX +XXX,XX @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) | ||
56 | |||
57 | hclge_init_rxd_adv_layout(hdev); | ||
58 | |||
59 | - /* Enable MISC vector(vector0) */ | ||
60 | - hclge_enable_vector(&hdev->misc_vector, true); | ||
61 | - | ||
62 | ret = hclge_init_wol(hdev); | ||
63 | if (ret) | ||
64 | dev_warn(&pdev->dev, | ||
65 | @@ -XXX,XX +XXX,XX @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) | ||
66 | hclge_state_init(hdev); | ||
67 | hdev->last_reset_time = jiffies; | ||
68 | |||
69 | + /* Enable MISC vector(vector0) */ | ||
70 | + enable_irq(hdev->misc_vector.vector_irq); | ||
71 | + hclge_enable_vector(&hdev->misc_vector, true); | ||
72 | + | ||
73 | dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n", | ||
74 | HCLGE_DRIVER_NAME); | ||
75 | |||
76 | @@ -XXX,XX +XXX,XX @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) | ||
77 | |||
78 | /* Disable MISC vector(vector0) */ | ||
79 | hclge_enable_vector(&hdev->misc_vector, false); | ||
80 | - synchronize_irq(hdev->misc_vector.vector_irq); | ||
81 | + disable_irq(hdev->misc_vector.vector_irq); | ||
82 | |||
83 | /* Disable all hw interrupts */ | ||
84 | hclge_config_mac_tnl_int(hdev, false); | ||
28 | -- | 85 | -- |
29 | 2.33.0 | 86 | 2.33.0 | diff view generated by jsdifflib |
1 | From: Jian Shen <shenjian15@huawei.com> | 1 | From: Jian Shen <shenjian15@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | The VF driver missed to store the rx VLAN tag strip state when | 3 | Currently the misc irq is initialized before reset_timer setup. But |
4 | user change the rx VLAN tag offload state. And it will default | 4 | it will access the reset_timer in the irq handler. So initialize |
5 | to enable the rx vlan tag strip when re-init VF device after | 5 | the reset_timer earlier. |
6 | reset. So if user disable rx VLAN tag offload, and trig reset, | ||
7 | then the HW will still strip the VLAN tag from packet nad fill | ||
8 | into RX BD, but the VF driver will ignore it for rx VLAN tag | ||
9 | offload disabled. It may cause the rx VLAN tag dropped. | ||
10 | 6 | ||
11 | Fixes: b2641e2ad456 ("net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver") | 7 | Fixes: ff200099d271 ("net: hns3: remove unnecessary work in hclgevf_main") |
12 | Signed-off-by: Jian Shen <shenjian15@huawei.com> | 8 | Signed-off-by: Jian Shen <shenjian15@huawei.com> |
13 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 9 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
14 | --- | 10 | --- |
15 | .../hisilicon/hns3/hns3vf/hclgevf_main.c | 25 ++++++++++++++----- | 11 | drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +- |
16 | .../hisilicon/hns3/hns3vf/hclgevf_main.h | 3 ++- | 12 | 1 file changed, 1 insertion(+), 1 deletion(-) |
17 | 2 files changed, 21 insertions(+), 7 deletions(-) | ||
18 | 13 | ||
19 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 14 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |
20 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 16 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |
22 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 17 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |
23 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) | 18 | @@ -XXX,XX +XXX,XX @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) |
24 | rtnl_unlock(); | 19 | clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); |
25 | } | 20 | |
26 | 21 | INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); | |
27 | -static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | 22 | + timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); |
28 | +static int hclgevf_en_hw_strip_rxvtag_cmd(struct hclgevf_dev *hdev, bool enable) | 23 | |
29 | { | 24 | mutex_init(&hdev->mbx_resp.mbx_mutex); |
30 | - struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | 25 | sema_init(&hdev->reset_sem, 1); |
31 | struct hclge_vf_to_pf_msg send_msg; | ||
32 | |||
33 | hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, | ||
34 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | ||
35 | return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); | ||
36 | } | ||
37 | |||
38 | +static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) | ||
39 | +{ | ||
40 | + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
41 | + int ret; | ||
42 | + | ||
43 | + ret = hclgevf_en_hw_strip_rxvtag_cmd(hdev, enable); | ||
44 | + if (ret) | ||
45 | + return ret; | ||
46 | + | ||
47 | + hdev->rxvtag_strip_en = enable; | ||
48 | + return 0; | ||
49 | +} | ||
50 | + | ||
51 | static int hclgevf_reset_tqp(struct hnae3_handle *handle) | ||
52 | { | ||
53 | #define HCLGEVF_RESET_ALL_QUEUE_DONE 1U | ||
54 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) | ||
55 | tc_valid, tc_size); | ||
56 | } | ||
57 | |||
58 | -static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) | ||
59 | +static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev, | ||
60 | + bool rxvtag_strip_en) | ||
61 | { | ||
62 | struct hnae3_handle *nic = &hdev->nic; | ||
63 | int ret; | ||
64 | |||
65 | - ret = hclgevf_en_hw_strip_rxvtag(nic, true); | ||
66 | + ret = hclgevf_en_hw_strip_rxvtag(nic, rxvtag_strip_en); | ||
67 | if (ret) { | ||
68 | dev_err(&hdev->pdev->dev, | ||
69 | "failed to enable rx vlan offload, ret = %d\n", ret); | ||
70 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) | ||
71 | if (ret) | ||
72 | return ret; | ||
73 | |||
74 | - ret = hclgevf_init_vlan_config(hdev); | ||
75 | + ret = hclgevf_init_vlan_config(hdev, hdev->rxvtag_strip_en); | ||
76 | if (ret) { | ||
77 | dev_err(&hdev->pdev->dev, | ||
78 | "failed(%d) to initialize VLAN config\n", ret); | ||
79 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) | 26 | @@ -XXX,XX +XXX,XX @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) |
80 | goto err_config; | 27 | HCLGEVF_DRIVER_NAME); |
81 | } | 28 | |
82 | 29 | hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); | |
83 | - ret = hclgevf_init_vlan_config(hdev); | 30 | - timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); |
84 | + ret = hclgevf_init_vlan_config(hdev, true); | 31 | |
85 | if (ret) { | 32 | return 0; |
86 | dev_err(&hdev->pdev->dev, | ||
87 | "failed(%d) to initialize VLAN config\n", ret); | ||
88 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | ||
89 | index XXXXXXX..XXXXXXX 100644 | ||
90 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | ||
91 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | ||
92 | @@ -XXX,XX +XXX,XX @@ struct hclgevf_dev { | ||
93 | u16 *vector_status; | ||
94 | int *vector_irq; | ||
95 | |||
96 | - bool gro_en; | ||
97 | + u32 gro_en :1; | ||
98 | + u32 rxvtag_strip_en :1; | ||
99 | |||
100 | unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)]; | ||
101 | 33 | ||
102 | -- | 34 | -- |
103 | 2.33.0 | 35 | 2.33.0 | diff view generated by jsdifflib |
1 | From: Hao Lan <lanhao@huawei.com> | 1 | From: Hao Lan <lanhao@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | There are spelling mistakes in hclgevf_get_regs. Fix them. | 3 | The TQP BAR space is divided into two segments. TQPs 0-1023 and TQPs |
4 | 1024-1279 are in different BAR space addresses. However, | ||
5 | hclge_fetch_pf_reg does not distinguish the tqp space information when | ||
6 | reading the tqp space information. When the number of TQPs is greater | ||
7 | than 1024, access bar space overwriting occurs. | ||
8 | The problem of different segments has been considered during the | ||
9 | initialization of tqp.io_base. Therefore, tqp.io_base is directly used | ||
10 | when the queue is read in hclge_fetch_pf_reg. | ||
4 | 11 | ||
12 | The error message: | ||
13 | |||
14 | Unable to handle kernel paging request at virtual address ffff800037200000 | ||
15 | pc : hclge_fetch_pf_reg+0x138/0x250 [hclge] | ||
16 | lr : hclge_get_regs+0x84/0x1d0 [hclge] | ||
17 | Call trace: | ||
18 | hclge_fetch_pf_reg+0x138/0x250 [hclge] | ||
19 | hclge_get_regs+0x84/0x1d0 [hclge] | ||
20 | hns3_get_regs+0x2c/0x50 [hns3] | ||
21 | ethtool_get_regs+0xf4/0x270 | ||
22 | dev_ethtool+0x674/0x8a0 | ||
23 | dev_ioctl+0x270/0x36c | ||
24 | sock_do_ioctl+0x110/0x2a0 | ||
25 | sock_ioctl+0x2ac/0x530 | ||
26 | __arm64_sys_ioctl+0xa8/0x100 | ||
27 | invoke_syscall+0x4c/0x124 | ||
28 | el0_svc_common.constprop.0+0x140/0x15c | ||
29 | do_el0_svc+0x30/0xd0 | ||
30 | el0_svc+0x1c/0x2c | ||
31 | el0_sync_handler+0xb0/0xb4 | ||
32 | el0_sync+0x168/0x180 | ||
33 | |||
34 | Fixes: 939ccd107ffc ("net: hns3: move dump regs function to a separate file") | ||
5 | Signed-off-by: Hao Lan <lanhao@huawei.com> | 35 | Signed-off-by: Hao Lan <lanhao@huawei.com> |
6 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | 36 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> |
7 | --- | 37 | --- |
8 | .../hisilicon/hns3/hns3vf/hclgevf_regs.c | 27 ++++++++++--------- | 38 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | 9 +++++---- |
9 | 1 file changed, 14 insertions(+), 13 deletions(-) | 39 | .../net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 9 +++++---- |
40 | 2 files changed, 10 insertions(+), 8 deletions(-) | ||
10 | 41 | ||
42 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | ||
45 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c | ||
46 | @@ -XXX,XX +XXX,XX @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data) | ||
47 | static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, | ||
48 | struct hnae3_knic_private_info *kinfo) | ||
49 | { | ||
50 | -#define HCLGE_RING_REG_OFFSET 0x200 | ||
51 | #define HCLGE_RING_INT_REG_OFFSET 0x4 | ||
52 | |||
53 | + struct hnae3_queue *tqp; | ||
54 | int i, j, reg_num; | ||
55 | int data_num_sum; | ||
56 | u32 *reg = data; | ||
57 | @@ -XXX,XX +XXX,XX @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, | ||
58 | reg_num = ARRAY_SIZE(ring_reg_addr_list); | ||
59 | for (j = 0; j < kinfo->num_tqps; j++) { | ||
60 | reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); | ||
61 | + tqp = kinfo->tqp[j]; | ||
62 | for (i = 0; i < reg_num; i++) | ||
63 | - *reg++ = hclge_read_dev(&hdev->hw, | ||
64 | - ring_reg_addr_list[i] + | ||
65 | - HCLGE_RING_REG_OFFSET * j); | ||
66 | + *reg++ = readl_relaxed(tqp->io_base - | ||
67 | + HCLGE_TQP_REG_OFFSET + | ||
68 | + ring_reg_addr_list[i]); | ||
69 | } | ||
70 | data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps; | ||
71 | |||
11 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 72 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c |
12 | index XXXXXXX..XXXXXXX 100644 | 73 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 74 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c |
14 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c | 75 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c |
76 | @@ -XXX,XX +XXX,XX @@ int hclgevf_get_regs_len(struct hnae3_handle *handle) | ||
77 | void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, | ||
78 | void *data) | ||
79 | { | ||
80 | -#define HCLGEVF_RING_REG_OFFSET 0x200 | ||
81 | #define HCLGEVF_RING_INT_REG_OFFSET 0x4 | ||
82 | |||
83 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
84 | + struct hnae3_queue *tqp; | ||
85 | int i, j, reg_um; | ||
86 | u32 *reg = data; | ||
87 | |||
15 | @@ -XXX,XX +XXX,XX @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, | 88 | @@ -XXX,XX +XXX,XX @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, |
16 | 89 | reg_um = ARRAY_SIZE(ring_reg_addr_list); | |
17 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
18 | struct hnae3_queue *tqp; | ||
19 | - int i, j, reg_um; | ||
20 | + int i, j, reg_num; | ||
21 | u32 *reg = data; | ||
22 | |||
23 | *version = hdev->fw_version; | ||
24 | reg += hclgevf_reg_get_header(reg); | ||
25 | |||
26 | /* fetching per-VF registers values from VF PCIe register space */ | ||
27 | - reg_um = ARRAY_SIZE(cmdq_reg_addr_list); | ||
28 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_um, reg); | ||
29 | - for (i = 0; i < reg_um; i++) | ||
30 | + reg_num = ARRAY_SIZE(cmdq_reg_addr_list); | ||
31 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_num, reg); | ||
32 | + for (i = 0; i < reg_num; i++) | ||
33 | *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); | ||
34 | |||
35 | - reg_um = ARRAY_SIZE(common_reg_addr_list); | ||
36 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_um, reg); | ||
37 | - for (i = 0; i < reg_um; i++) | ||
38 | + reg_num = ARRAY_SIZE(common_reg_addr_list); | ||
39 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_num, reg); | ||
40 | + for (i = 0; i < reg_num; i++) | ||
41 | *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); | ||
42 | |||
43 | - reg_um = ARRAY_SIZE(ring_reg_addr_list); | ||
44 | + reg_num = ARRAY_SIZE(ring_reg_addr_list); | ||
45 | for (j = 0; j < hdev->num_tqps; j++) { | 90 | for (j = 0; j < hdev->num_tqps; j++) { |
46 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); | 91 | reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); |
47 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_num, reg); | 92 | + tqp = &hdev->htqp[j].q; |
48 | tqp = &hdev->htqp[j].q; | 93 | for (i = 0; i < reg_um; i++) |
49 | - for (i = 0; i < reg_um; i++) | 94 | - *reg++ = hclgevf_read_dev(&hdev->hw, |
50 | + for (i = 0; i < reg_num; i++) | 95 | - ring_reg_addr_list[i] + |
51 | *reg++ = readl_relaxed(tqp->io_base - | 96 | - HCLGEVF_RING_REG_OFFSET * j); |
52 | HCLGEVF_TQP_REG_OFFSET + | 97 | + *reg++ = readl_relaxed(tqp->io_base - |
53 | ring_reg_addr_list[i]); | 98 | + HCLGEVF_TQP_REG_OFFSET + |
99 | + ring_reg_addr_list[i]); | ||
54 | } | 100 | } |
55 | 101 | ||
56 | - reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); | 102 | reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); |
57 | + reg_num = ARRAY_SIZE(tqp_intr_reg_addr_list); | ||
58 | for (j = 0; j < hdev->num_msi_used - 1; j++) { | ||
59 | - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_um, reg); | ||
60 | - for (i = 0; i < reg_um; i++) | ||
61 | + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, | ||
62 | + reg_num, reg); | ||
63 | + for (i = 0; i < reg_num; i++) | ||
64 | *reg++ = hclgevf_read_dev(&hdev->hw, | ||
65 | tqp_intr_reg_addr_list[i] + | ||
66 | HCLGEVF_RING_INT_REG_OFFSET * j); | ||
67 | -- | 103 | -- |
68 | 2.33.0 | 104 | 2.33.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jie Wang <wangjie125@huawei.com> | ||
1 | 2 | ||
3 | Currently, HIP08 devices does not register the ptp devices, so the | ||
4 | hdev->ptp is NULL. But the tx process would still try to set hardware time | ||
5 | stamp info with SKBTX_HW_TSTAMP flag and cause a kernel crash. | ||
6 | |||
7 | [ 128.087798] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018 | ||
8 | ... | ||
9 | [ 128.280251] pc : hclge_ptp_set_tx_info+0x2c/0x140 [hclge] | ||
10 | [ 128.286600] lr : hclge_ptp_set_tx_info+0x20/0x140 [hclge] | ||
11 | [ 128.292938] sp : ffff800059b93140 | ||
12 | [ 128.297200] x29: ffff800059b93140 x28: 0000000000003280 | ||
13 | [ 128.303455] x27: ffff800020d48280 x26: ffff0cb9dc814080 | ||
14 | [ 128.309715] x25: ffff0cb9cde93fa0 x24: 0000000000000001 | ||
15 | [ 128.315969] x23: 0000000000000000 x22: 0000000000000194 | ||
16 | [ 128.322219] x21: ffff0cd94f986000 x20: 0000000000000000 | ||
17 | [ 128.328462] x19: ffff0cb9d2a166c0 x18: 0000000000000000 | ||
18 | [ 128.334698] x17: 0000000000000000 x16: ffffcf1fc523ed24 | ||
19 | [ 128.340934] x15: 0000ffffd530a518 x14: 0000000000000000 | ||
20 | [ 128.347162] x13: ffff0cd6bdb31310 x12: 0000000000000368 | ||
21 | [ 128.353388] x11: ffff0cb9cfbc7070 x10: ffff2cf55dd11e02 | ||
22 | [ 128.359606] x9 : ffffcf1f85a212b4 x8 : ffff0cd7cf27dab0 | ||
23 | [ 128.365831] x7 : 0000000000000a20 x6 : ffff0cd7cf27d000 | ||
24 | [ 128.372040] x5 : 0000000000000000 x4 : 000000000000ffff | ||
25 | [ 128.378243] x3 : 0000000000000400 x2 : ffffcf1f85a21294 | ||
26 | [ 128.384437] x1 : ffff0cb9db520080 x0 : ffff0cb9db500080 | ||
27 | [ 128.390626] Call trace: | ||
28 | [ 128.393964] hclge_ptp_set_tx_info+0x2c/0x140 [hclge] | ||
29 | [ 128.399893] hns3_nic_net_xmit+0x39c/0x4c4 [hns3] | ||
30 | [ 128.405468] xmit_one.constprop.0+0xc4/0x200 | ||
31 | [ 128.410600] dev_hard_start_xmit+0x54/0xf0 | ||
32 | [ 128.415556] sch_direct_xmit+0xe8/0x634 | ||
33 | [ 128.420246] __dev_queue_xmit+0x224/0xc70 | ||
34 | [ 128.425101] dev_queue_xmit+0x1c/0x40 | ||
35 | [ 128.429608] ovs_vport_send+0xac/0x1a0 [openvswitch] | ||
36 | [ 128.435409] do_output+0x60/0x17c [openvswitch] | ||
37 | [ 128.440770] do_execute_actions+0x898/0x8c4 [openvswitch] | ||
38 | [ 128.446993] ovs_execute_actions+0x64/0xf0 [openvswitch] | ||
39 | [ 128.453129] ovs_dp_process_packet+0xa0/0x224 [openvswitch] | ||
40 | [ 128.459530] ovs_vport_receive+0x7c/0xfc [openvswitch] | ||
41 | [ 128.465497] internal_dev_xmit+0x34/0xb0 [openvswitch] | ||
42 | [ 128.471460] xmit_one.constprop.0+0xc4/0x200 | ||
43 | [ 128.476561] dev_hard_start_xmit+0x54/0xf0 | ||
44 | [ 128.481489] __dev_queue_xmit+0x968/0xc70 | ||
45 | [ 128.486330] dev_queue_xmit+0x1c/0x40 | ||
46 | [ 128.490856] ip_finish_output2+0x250/0x570 | ||
47 | [ 128.495810] __ip_finish_output+0x170/0x1e0 | ||
48 | [ 128.500832] ip_finish_output+0x3c/0xf0 | ||
49 | [ 128.505504] ip_output+0xbc/0x160 | ||
50 | [ 128.509654] ip_send_skb+0x58/0xd4 | ||
51 | [ 128.513892] udp_send_skb+0x12c/0x354 | ||
52 | [ 128.518387] udp_sendmsg+0x7a8/0x9c0 | ||
53 | [ 128.522793] inet_sendmsg+0x4c/0x8c | ||
54 | [ 128.527116] __sock_sendmsg+0x48/0x80 | ||
55 | [ 128.531609] __sys_sendto+0x124/0x164 | ||
56 | [ 128.536099] __arm64_sys_sendto+0x30/0x5c | ||
57 | [ 128.540935] invoke_syscall+0x50/0x130 | ||
58 | [ 128.545508] el0_svc_common.constprop.0+0x10c/0x124 | ||
59 | [ 128.551205] do_el0_svc+0x34/0xdc | ||
60 | [ 128.555347] el0_svc+0x20/0x30 | ||
61 | [ 128.559227] el0_sync_handler+0xb8/0xc0 | ||
62 | [ 128.563883] el0_sync+0x160/0x180 | ||
63 | |||
64 | Fixes: 0bf5eb788512 ("net: hns3: add support for PTP") | ||
65 | Signed-off-by: Jie Wang <wangjie125@huawei.com> | ||
66 | Signed-off-by: Jijie Shao <shaojijie@huawei.com> | ||
67 | --- | ||
68 | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 3 +++ | ||
69 | 1 file changed, 3 insertions(+) | ||
70 | |||
71 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | ||
72 | index XXXXXXX..XXXXXXX 100644 | ||
73 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | ||
74 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | ||
75 | @@ -XXX,XX +XXX,XX @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb) | ||
76 | struct hclge_dev *hdev = vport->back; | ||
77 | struct hclge_ptp *ptp = hdev->ptp; | ||
78 | |||
79 | + if (!ptp) | ||
80 | + return false; | ||
81 | + | ||
82 | if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) || | ||
83 | test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) { | ||
84 | ptp->tx_skipped++; | ||
85 | -- | ||
86 | 2.33.0 | diff view generated by jsdifflib |