Commit 76f82fd9 authored by Yufeng Mo's avatar Yufeng Mo Committed by David S. Miller

net: hns3: split out hclge_cmd_send()

hclge_cmd_send() is bloated, so split it into separate
functions for readability and maintainability.
Signed-off-by: default avatarYufeng Mo <moyufeng@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b3712fa7
...@@ -194,6 +194,22 @@ struct errcode { ...@@ -194,6 +194,22 @@ struct errcode {
int common_errno; 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) static int hclge_cmd_convert_err_code(u16 desc_ret)
{ {
struct errcode hclge_cmd_errcode[] = { struct errcode hclge_cmd_errcode[] = {
...@@ -243,6 +259,44 @@ static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc, ...@@ -243,6 +259,44 @@ static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc,
return hclge_cmd_convert_err_code(desc_ret); 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 * hclge_cmd_send - send command to command queue
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
...@@ -256,11 +310,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) ...@@ -256,11 +310,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_dev *hdev = container_of(hw, struct hclge_dev, hw);
struct hclge_cmq_ring *csq = &hw->cmq.csq; struct hclge_cmq_ring *csq = &hw->cmq.csq;
struct hclge_desc *desc_to_use; int ret;
bool complete = false;
u32 timeout = 0;
int handle = 0;
int retval;
int ntc; int ntc;
spin_lock_bh(&hw->cmq.csq.lock); spin_lock_bh(&hw->cmq.csq.lock);
...@@ -284,49 +334,17 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) ...@@ -284,49 +334,17 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
* which will be use for hardware to write back * which will be use for hardware to write back
*/ */
ntc = hw->cmq.csq.next_to_use; ntc = hw->cmq.csq.next_to_use;
while (handle < num) {
desc_to_use = &hw->cmq.csq.desc[hw->cmq.csq.next_to_use]; hclge_cmd_copy_desc(hw, desc, num);
*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++;
}
/* Write to hardware */ /* Write to hardware */
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, hw->cmq.csq.next_to_use); hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, hw->cmq.csq.next_to_use);
/** ret = hclge_cmd_check_result(hw, desc, num, ntc);
* 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);
spin_unlock_bh(&hw->cmq.csq.lock); spin_unlock_bh(&hw->cmq.csq.lock);
return retval; return ret;
} }
static void hclge_set_default_capability(struct hclge_dev *hdev) static void hclge_set_default_capability(struct hclge_dev *hdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment