From 743e1a8438e5a37f9ab1846e75a47de8e9cd522f Mon Sep 17 00:00:00 2001 From: Salil Mehta Date: Sat, 19 May 2018 16:53:15 +0100 Subject: [PATCH 1/9] net: hns3: Fixes error reported by Kbuild and internal review This patch fixes the error reported by Intel's kbuild and fixes a return value in one of the legs, caught during review of the original patch sent by kbuild. Fixes: fdb793670a00 ("net: hns3: Add support of .sriov_configure in HNS3 driver") Signed-off-by: Fengguang Wu Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index e85ff3805c96..e75c65270222 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1579,7 +1579,7 @@ static void hns3_remove(struct pci_dev *pdev) * Enable or change the number of VFs. Called when the user updates the number * of VFs in sysfs. **/ -int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) +static int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) { int ret; @@ -1592,6 +1592,8 @@ int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) ret = pci_enable_sriov(pdev, num_vfs); if (ret) dev_err(&pdev->dev, "SRIOV enable failed %d\n", ret); + else + return num_vfs; } else if (!pci_vfs_assigned(pdev)) { pci_disable_sriov(pdev); } else { From e63cd65f435c77eb2bc0c4f6691be350cd749dce Mon Sep 17 00:00:00 2001 From: Peng Li Date: Sat, 19 May 2018 16:53:16 +0100 Subject: [PATCH 2/9] net: hns3: Fixes API to fetch ethernet header length with kernel default During the RX leg driver needs to fetch the ethernet header length from the RX'ed Buffer Descriptor. Currently, proprietary version hns3_nic_get_headlen is being used to fetch the header length which uses l234info present in the Buffer Descriptor which might not be valid for the first Buffer Descriptor if the packet is spanning across multiple descriptors. Kernel default eth_get_headlen API does the job correctly. Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") Signed-off-by: Peng Li Reviewed-by: Yisen Zhuang Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 104 +----------------- 1 file changed, 2 insertions(+), 102 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index e75c65270222..66cbb66b2326 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1954,106 +1954,6 @@ hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring, int cleand_count) writel_relaxed(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG); } -/* hns3_nic_get_headlen - determine size of header for LRO/GRO - * @data: pointer to the start of the headers - * @max: total length of section to find headers in - * - * This function is meant to determine the length of headers that will - * be recognized by hardware for LRO, GRO, and RSC offloads. The main - * motivation of doing this is to only perform one pull for IPv4 TCP - * packets so that we can do basic things like calculating the gso_size - * based on the average data per packet. - */ -static unsigned int hns3_nic_get_headlen(unsigned char *data, u32 flag, - unsigned int max_size) -{ - unsigned char *network; - u8 hlen; - - /* This should never happen, but better safe than sorry */ - if (max_size < ETH_HLEN) - return max_size; - - /* Initialize network frame pointer */ - network = data; - - /* Set first protocol and move network header forward */ - network += ETH_HLEN; - - /* Handle any vlan tag if present */ - if (hnae_get_field(flag, HNS3_RXD_VLAN_M, HNS3_RXD_VLAN_S) - == HNS3_RX_FLAG_VLAN_PRESENT) { - if ((typeof(max_size))(network - data) > (max_size - VLAN_HLEN)) - return max_size; - - network += VLAN_HLEN; - } - - /* Handle L3 protocols */ - if (hnae_get_field(flag, HNS3_RXD_L3ID_M, HNS3_RXD_L3ID_S) - == HNS3_RX_FLAG_L3ID_IPV4) { - if ((typeof(max_size))(network - data) > - (max_size - sizeof(struct iphdr))) - return max_size; - - /* Access ihl as a u8 to avoid unaligned access on ia64 */ - hlen = (network[0] & 0x0F) << 2; - - /* Verify hlen meets minimum size requirements */ - if (hlen < sizeof(struct iphdr)) - return network - data; - - /* Record next protocol if header is present */ - } else if (hnae_get_field(flag, HNS3_RXD_L3ID_M, HNS3_RXD_L3ID_S) - == HNS3_RX_FLAG_L3ID_IPV6) { - if ((typeof(max_size))(network - data) > - (max_size - sizeof(struct ipv6hdr))) - return max_size; - - /* Record next protocol */ - hlen = sizeof(struct ipv6hdr); - } else { - return network - data; - } - - /* Relocate pointer to start of L4 header */ - network += hlen; - - /* Finally sort out TCP/UDP */ - if (hnae_get_field(flag, HNS3_RXD_L4ID_M, HNS3_RXD_L4ID_S) - == HNS3_RX_FLAG_L4ID_TCP) { - if ((typeof(max_size))(network - data) > - (max_size - sizeof(struct tcphdr))) - return max_size; - - /* Access doff as a u8 to avoid unaligned access on ia64 */ - hlen = (network[12] & 0xF0) >> 2; - - /* Verify hlen meets minimum size requirements */ - if (hlen < sizeof(struct tcphdr)) - return network - data; - - network += hlen; - } else if (hnae_get_field(flag, HNS3_RXD_L4ID_M, HNS3_RXD_L4ID_S) - == HNS3_RX_FLAG_L4ID_UDP) { - if ((typeof(max_size))(network - data) > - (max_size - sizeof(struct udphdr))) - return max_size; - - network += sizeof(struct udphdr); - } - - /* If everything has gone correctly network should be the - * data section of the packet and will be the end of the header. - * If not then it probably represents the end of the last recognized - * header. - */ - if ((typeof(max_size))(network - data) < max_size) - return network - data; - else - return max_size; -} - static void hns3_nic_reuse_page(struct sk_buff *skb, int i, struct hns3_enet_ring *ring, int pull_len, struct hns3_desc_cb *desc_cb) @@ -2253,8 +2153,8 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring, ring->stats.seg_pkt_cnt++; u64_stats_update_end(&ring->syncp); - pull_len = hns3_nic_get_headlen(va, l234info, - HNS3_RX_HEAD_SIZE); + pull_len = eth_get_headlen(va, HNS3_RX_HEAD_SIZE); + memcpy(__skb_put(skb, pull_len), va, ALIGN(pull_len, sizeof(long))); From 99a6993a6933acbf791d1c7bb789e0ebe5bd7127 Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Sat, 19 May 2018 16:53:17 +0100 Subject: [PATCH 3/9] net: hns3: cleanup of return values in hclge_init_client_instance() Removes the goto and directly returns in case of errors as part of the cleanup. Signed-off-by: Jian Shen Signed-off-by: Peng Li Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 46435c85b160..46e030c41fe9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -5297,7 +5297,7 @@ static int hclge_init_client_instance(struct hnae3_client *client, vport->nic.client = client; ret = client->ops->init_instance(&vport->nic); if (ret) - goto err; + return ret; if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { @@ -5305,11 +5305,11 @@ static int hclge_init_client_instance(struct hnae3_client *client, ret = hclge_init_roce_base_info(vport); if (ret) - goto err; + return ret; ret = rc->ops->init_instance(&vport->roce); if (ret) - goto err; + return ret; } break; @@ -5319,7 +5319,7 @@ static int hclge_init_client_instance(struct hnae3_client *client, ret = client->ops->init_instance(&vport->nic); if (ret) - goto err; + return ret; break; case HNAE3_CLIENT_ROCE: @@ -5331,18 +5331,16 @@ static int hclge_init_client_instance(struct hnae3_client *client, if (hdev->roce_client && hdev->nic_client) { ret = hclge_init_roce_base_info(vport); if (ret) - goto err; + return ret; ret = client->ops->init_instance(&vport->roce); if (ret) - goto err; + return ret; } } } return 0; -err: - return ret; } static void hclge_uninit_client_instance(struct hnae3_client *client, From 13562d1f5e2fbe2cf33b23a00abca3f71264c4ac Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 19 May 2018 16:53:18 +0100 Subject: [PATCH 4/9] net: hns3: Fix the missing client list node initialization This patch fixes the missing initialization of the client list node in the hnae3_register_client() function. Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") Signed-off-by: Xi Wang Signed-off-by: Peng Li Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 66cbb66b2326..701ae5e79219 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -3509,6 +3509,8 @@ static int __init hns3_init_module(void) client.ops = &client_ops; + INIT_LIST_HEAD(&client.node); + ret = hnae3_register_client(&client); if (ret) return ret; From 3c7624d8fc0b893b644b945ab904c629ebc9611e Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 19 May 2018 16:53:19 +0100 Subject: [PATCH 5/9] net: hns3: Fix for hns3 module is loaded multiple times problem If the hns3 driver has been built into kernel and then loaded with the same driver which built as KLM, it may trigger an error like below: [ 20.009555] hns3: Hisilicon Ethernet Network Driver for Hip08 Family - version [ 20.016789] hns3: Copyright (c) 2017 Huawei Corporation. [ 20.022100] Error: Driver 'hns3' is already registered, aborting... [ 23.517397] Unable to handle kernel NULL pointer dereference at virtual address 00000000 ... [ 23.691583] Process insmod (pid: 1982, stack limit = 0x00000000cd5f21cb) [ 23.698270] Call trace: [ 23.700705] __list_del_entry_valid+0x2c/0xd8 [ 23.705049] hnae3_unregister_client+0x68/0xa8 [ 23.709487] hns3_init_module+0x98/0x1000 [hns3] [ 23.714093] do_one_initcall+0x5c/0x170 [ 23.717918] do_init_module+0x64/0x1f4 [ 23.721654] load_module+0x1d14/0x24b0 [ 23.725390] SyS_init_module+0x158/0x208 [ 23.729300] el0_svc_naked+0x30/0x34 This patch fixes it by adding module version info. Fixes: 38caee9d3ee8 ("net: hns3: Add support of the HNAE3 framework") Signed-off-by: Xi Wang Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hnae3.c | 1 + drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 ++ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 1 + drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 ++ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 2 +- 6 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c index bd3c232234d7..63d7dbfb90bf 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c @@ -285,3 +285,4 @@ EXPORT_SYMBOL(hnae3_unregister_ae_dev); MODULE_AUTHOR("Huawei Tech. Co., Ltd."); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework"); +MODULE_VERSION(HNAE3_MOD_VERSION); diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 2f266ef96582..45c571eea2ae 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -36,6 +36,8 @@ #include #include +#define HNAE3_MOD_VERSION "1.0" + /* Device IDs */ #define HNAE3_DEV_ID_GE 0xA220 #define HNAE3_DEV_ID_25GE 0xA221 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 701ae5e79219..cac51954f2cf 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -3538,3 +3538,4 @@ MODULE_DESCRIPTION("HNS3: Hisilicon Ethernet Driver"); MODULE_AUTHOR("Huawei Tech. Co., Ltd."); MODULE_LICENSE("GPL"); MODULE_ALIAS("pci:hns-nic"); +MODULE_VERSION(HNS3_MOD_VERSION); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 98cdbd3a1163..5b40f5a53761 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -14,6 +14,8 @@ #include "hnae3.h" +#define HNS3_MOD_VERSION "1.0" + extern const char hns3_driver_version[]; enum hns3_nic_state { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index af736a44607c..93177d91eea4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -17,7 +17,7 @@ #include "hclge_cmd.h" #include "hnae3.h" -#define HCLGE_MOD_VERSION "v1.0" +#define HCLGE_MOD_VERSION "1.0" #define HCLGE_DRIVER_NAME "hclge" #define HCLGE_INVALID_VPORT 0xffff diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index a477a7c36bbd..9763e742e6fb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -9,7 +9,7 @@ #include "hclgevf_cmd.h" #include "hnae3.h" -#define HCLGEVF_MOD_VERSION "v1.0" +#define HCLGEVF_MOD_VERSION "1.0" #define HCLGEVF_DRIVER_NAME "hclgevf" #define HCLGEVF_ROCEE_VECTOR_NUM 0 From 42687543ca18c106ffd562b40199bd31ab3a347a Mon Sep 17 00:00:00 2001 From: Huazhong Tan Date: Sat, 19 May 2018 16:53:20 +0100 Subject: [PATCH 6/9] net: hns3: Use enums instead of magic number in hclge_is_special_opcode This patch does bit of a clean-up by using already defined enums for certain values in function hclge_is_special_opcode(). Below enums from have been used as replacements for magic values: enum hclge_opcode_type{ HCLGE_OPC_STATS_64_BIT = 0x0030, HCLGE_OPC_STATS_32_BIT = 0x0031, HCLGE_OPC_STATS_MAC = 0x0032, }; Signed-off-by: Huazhong Tan Signed-off-by: Peng Li Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c index fab70683bbf7..59fb0eb755e7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c @@ -190,7 +190,11 @@ static int hclge_cmd_csq_done(struct hclge_hw *hw) static bool hclge_is_special_opcode(u16 opcode) { - u16 spec_opcode[3] = {0x0030, 0x0031, 0x0032}; + /* these commands have several descriptors, + * and use the first one to save opcode and return value + */ + u16 spec_opcode[3] = {HCLGE_OPC_STATS_64_BIT, + HCLGE_OPC_STATS_32_BIT, HCLGE_OPC_STATS_MAC}; int i; for (i = 0; i < ARRAY_SIZE(spec_opcode); i++) { From f30dfddcca1b7773ef8ed8ddbf2d477bc5eb9f3e Mon Sep 17 00:00:00 2001 From: Fuyun Liang Date: Sat, 19 May 2018 16:53:21 +0100 Subject: [PATCH 7/9] net: hns3: Fix for netdev not running problem after calling net_stop and net_open The link status update function is called by timer every second. But net_stop and net_open may be called with very short intervals. The link status update function can not detect the link state has changed. It causes the netdev not running problem. This patch fixes it by updating the link state in ae_stop function. Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") Signed-off-by: Fuyun Liang Signed-off-by: Peng Li Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 46e030c41fe9..2f0bbb6708b9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -3793,6 +3793,9 @@ static void hclge_ae_stop(struct hnae3_handle *handle) /* reset tqp stats */ hclge_reset_tqp_stats(handle); + del_timer_sync(&hdev->service_timer); + cancel_work_sync(&hdev->service_task); + hclge_update_link_status(hdev); } static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, From 7bb572fddd757512130afcc0a8a683095eee1cd5 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 19 May 2018 16:53:22 +0100 Subject: [PATCH 8/9] net: hns3: Fixes kernel panic issue during rmmod hns3 driver If CONFIG_ARM_SMMU_V3 is enabled, arm64's dma_ops will replace arm64_swiotlb_dma_ops with iommu_dma_ops. When releasing contiguous dma memory, the new ops will call the vunmap function which cannot be run in interrupt context. Currently, spin_lock_bh is called before vunmap is executed. This disables BH and causes the interrupt context to be detected to generate a kernel panic like below: [ 2831.573400] kernel BUG at mm/vmalloc.c:1621! [ 2831.577659] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ... [ 2831.699907] Process rmmod (pid: 1893, stack limit = 0x0000000055103ee2) [ 2831.706507] Call trace: [ 2831.708941] vunmap+0x48/0x50 [ 2831.711897] dma_common_free_remap+0x78/0x88 [ 2831.716155] __iommu_free_attrs+0xa8/0x1c0 [ 2831.720255] hclge_free_cmd_desc+0xc8/0x118 [hclge] [ 2831.725128] hclge_destroy_cmd_queue+0x34/0x68 [hclge] [ 2831.730261] hclge_uninit_ae_dev+0x90/0x100 [hclge] [ 2831.735127] hnae3_unregister_ae_dev+0xb0/0x868 [hnae3] [ 2831.740345] hns3_remove+0x3c/0x90 [hns3] [ 2831.744344] pci_device_remove+0x48/0x108 [ 2831.748342] device_release_driver_internal+0x164/0x200 [ 2831.753553] driver_detach+0x4c/0x88 [ 2831.757116] bus_remove_driver+0x60/0xc0 [ 2831.761026] driver_unregister+0x34/0x60 [ 2831.764935] pci_unregister_driver+0x30/0xb0 [ 2831.769197] hns3_exit_module+0x10/0x978 [hns3] [ 2831.773715] SyS_delete_module+0x1f8/0x248 [ 2831.777799] el0_svc_naked+0x30/0x34 This patch fixes it by using spin_lock instead of spin_lock_bh. Fixes: 68c0a5c70614 ("net: hns3: Add HNS3 IMP(Integrated Mgmt Proc) Cmd Interface Support") Signed-off-by: Xi Wang Signed-off-by: Peng Li Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c index 59fb0eb755e7..c36d64710fa6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c @@ -385,9 +385,9 @@ int hclge_cmd_init(struct hclge_dev *hdev) static void hclge_destroy_queue(struct hclge_cmq_ring *ring) { - spin_lock_bh(&ring->lock); + spin_lock(&ring->lock); hclge_free_cmd_desc(ring); - spin_unlock_bh(&ring->lock); + spin_unlock(&ring->lock); } void hclge_destroy_cmd_queue(struct hclge_hw *hw) From eddf04626d1d6d0bcd01ac6a287e49f5ddb90a26 Mon Sep 17 00:00:00 2001 From: Yunsheng Lin Date: Sat, 19 May 2018 16:53:23 +0100 Subject: [PATCH 9/9] net: hns3: Fix for CMDQ and Misc. interrupt init order problem When vf module is loading, the cmd queue initialization should happen before misc interrupt initialization, otherwise the misc interrupt handle will cause using uninitialized cmd queue problem. There is also the same issue when vf module is unloading. This patch fixes it by adjusting the location of some function. Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support") Signed-off-by: Yunsheng Lin Signed-off-by: Peng Li Signed-off-by: Salil Mehta Signed-off-by: David S. Miller --- .../hisilicon/hns3/hns3vf/hclgevf_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index f1f4a17340a5..2b0e3295989f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -1634,6 +1634,10 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) hclgevf_state_init(hdev); + ret = hclgevf_cmd_init(hdev); + if (ret) + goto err_cmd_init; + ret = hclgevf_misc_irq_init(hdev); if (ret) { dev_err(&pdev->dev, "failed(%d) to init Misc IRQ(vector0)\n", @@ -1641,10 +1645,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) goto err_misc_irq_init; } - ret = hclgevf_cmd_init(hdev); - if (ret) - goto err_cmd_init; - ret = hclgevf_configure(hdev); if (ret) { dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", ret); @@ -1692,10 +1692,10 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) return 0; err_config: - hclgevf_cmd_uninit(hdev); -err_cmd_init: hclgevf_misc_irq_uninit(hdev); err_misc_irq_init: + hclgevf_cmd_uninit(hdev); +err_cmd_init: hclgevf_state_uninit(hdev); hclgevf_uninit_msi(hdev); err_irq_init: @@ -1705,9 +1705,9 @@ err_irq_init: static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev) { - hclgevf_cmd_uninit(hdev); - hclgevf_misc_irq_uninit(hdev); hclgevf_state_uninit(hdev); + hclgevf_misc_irq_uninit(hdev); + hclgevf_cmd_uninit(hdev); hclgevf_uninit_msi(hdev); hclgevf_pci_uninit(hdev); }