173 lines
5.0 KiB
Diff
173 lines
5.0 KiB
Diff
From 33374df5fd3f1c4d0da46856e84e1afd4a16d0fb Mon Sep 17 00:00:00 2001
|
|
From: Yufeng Mo <moyufeng@huawei.com>
|
|
Date: Sat, 24 Jul 2021 15:43:41 +0800
|
|
Subject: [PATCH 051/283] net: hns3: split out hclge_cmd_send()
|
|
|
|
mainline inclusion
|
|
from mainline-v5.12-rc1-dontuse
|
|
commit 76f82fd9b1230332db2b3bc3916d097b92acbf29
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EMQV
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76f82fd9b1230332db2b3bc3916d097b92acbf29
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
hclge_cmd_send() is bloated, so split it into separate
|
|
functions for readability and maintainability.
|
|
|
|
Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
|
|
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Reviewed-by: Yongxin Li <liyongxin1@huawei.com>
|
|
Signed-off-by: Junxin Chen <chenjunxin1@huawei.com>
|
|
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
---
|
|
.../hisilicon/hns3/hns3pf/hclge_cmd.c | 100 +++++++++++-------
|
|
1 file changed, 59 insertions(+), 41 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
|
|
index 5f0c645eb292..64476a2629ba 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
|
|
@@ -210,6 +210,22 @@ struct errcode {
|
|
int common_errno;
|
|
};
|
|
|
|
+static void hclge_cmd_copy_desc(struct hclge_hw *hw, struct hclge_desc *desc,
|
|
+ int num)
|
|
+{
|
|
+ struct hclge_desc *desc_to_use;
|
|
+ int handle = 0;
|
|
+
|
|
+ while (handle < num) {
|
|
+ desc_to_use = &hw->cmq.csq.desc[hw->cmq.csq.next_to_use];
|
|
+ *desc_to_use = desc[handle];
|
|
+ (hw->cmq.csq.next_to_use)++;
|
|
+ if (hw->cmq.csq.next_to_use >= hw->cmq.csq.desc_num)
|
|
+ hw->cmq.csq.next_to_use = 0;
|
|
+ handle++;
|
|
+ }
|
|
+}
|
|
+
|
|
static int hclge_cmd_convert_err_code(u16 desc_ret)
|
|
{
|
|
struct errcode hclge_cmd_errcode[] = {
|
|
@@ -259,6 +275,44 @@ static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc,
|
|
return hclge_cmd_convert_err_code(desc_ret);
|
|
}
|
|
|
|
+static int hclge_cmd_check_result(struct hclge_hw *hw, struct hclge_desc *desc,
|
|
+ int num, int ntc)
|
|
+{
|
|
+ struct hclge_dev *hdev = container_of(hw, struct hclge_dev, hw);
|
|
+ bool is_completed = false;
|
|
+ u32 timeout = 0;
|
|
+ int handle, ret;
|
|
+
|
|
+ /**
|
|
+ * If the command is sync, wait for the firmware to write back,
|
|
+ * if multi descriptors to be sent, use the first one to check
|
|
+ */
|
|
+ if (HCLGE_SEND_SYNC(le16_to_cpu(desc->flag))) {
|
|
+ do {
|
|
+ if (hclge_cmd_csq_done(hw)) {
|
|
+ is_completed = true;
|
|
+ break;
|
|
+ }
|
|
+ udelay(1);
|
|
+ timeout++;
|
|
+ } while (timeout < hw->cmq.tx_timeout);
|
|
+ }
|
|
+
|
|
+ if (!is_completed)
|
|
+ ret = -EBADE;
|
|
+ else
|
|
+ ret = hclge_cmd_check_retval(hw, desc, num, ntc);
|
|
+
|
|
+ /* Clean the command send queue */
|
|
+ handle = hclge_cmd_csq_clean(hw);
|
|
+ if (handle < 0)
|
|
+ ret = handle;
|
|
+ else if (handle != num)
|
|
+ dev_warn(&hdev->pdev->dev,
|
|
+ "cleaned %d, need to clean %d\n", handle, num);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/**
|
|
* hclge_cmd_send - send command to command queue
|
|
* @hw: pointer to the hw struct
|
|
@@ -272,11 +326,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
|
|
{
|
|
struct hclge_dev *hdev = container_of(hw, struct hclge_dev, hw);
|
|
struct hclge_cmq_ring *csq = &hw->cmq.csq;
|
|
- struct hclge_desc *desc_to_use;
|
|
- bool complete = false;
|
|
- u32 timeout = 0;
|
|
- int handle = 0;
|
|
- int retval;
|
|
+ int ret;
|
|
int ntc;
|
|
|
|
spin_lock_bh(&hw->cmq.csq.lock);
|
|
@@ -300,49 +350,17 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
|
|
* which will be use for hardware to write back
|
|
*/
|
|
ntc = hw->cmq.csq.next_to_use;
|
|
- while (handle < num) {
|
|
- desc_to_use = &hw->cmq.csq.desc[hw->cmq.csq.next_to_use];
|
|
- *desc_to_use = desc[handle];
|
|
- (hw->cmq.csq.next_to_use)++;
|
|
- if (hw->cmq.csq.next_to_use >= hw->cmq.csq.desc_num)
|
|
- hw->cmq.csq.next_to_use = 0;
|
|
- handle++;
|
|
- }
|
|
+
|
|
+ hclge_cmd_copy_desc(hw, desc, num);
|
|
|
|
/* Write to hardware */
|
|
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, hw->cmq.csq.next_to_use);
|
|
|
|
- /**
|
|
- * If the command is sync, wait for the firmware to write back,
|
|
- * if multi descriptors to be sent, use the first one to check
|
|
- */
|
|
- if (HCLGE_SEND_SYNC(le16_to_cpu(desc->flag))) {
|
|
- do {
|
|
- if (hclge_cmd_csq_done(hw)) {
|
|
- complete = true;
|
|
- break;
|
|
- }
|
|
- udelay(1);
|
|
- timeout++;
|
|
- } while (timeout < hw->cmq.tx_timeout);
|
|
- }
|
|
-
|
|
- if (!complete)
|
|
- retval = -EBADE;
|
|
- else
|
|
- retval = hclge_cmd_check_retval(hw, desc, num, ntc);
|
|
-
|
|
- /* Clean the command send queue */
|
|
- handle = hclge_cmd_csq_clean(hw);
|
|
- if (handle < 0)
|
|
- retval = handle;
|
|
- else if (handle != num)
|
|
- dev_warn(&hdev->pdev->dev,
|
|
- "cleaned %d, need to clean %d\n", handle, num);
|
|
+ ret = hclge_cmd_check_result(hw, desc, num, ntc);
|
|
|
|
spin_unlock_bh(&hw->cmq.csq.lock);
|
|
|
|
- return retval;
|
|
+ return ret;
|
|
}
|
|
|
|
static void hclge_set_default_capability(struct hclge_dev *hdev)
|
|
--
|
|
2.34.1
|
|
|