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: Yufeng Mo <moyufeng@huawei.com> Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b3712fa73d
commit
76f82fd9b1
|
@ -194,6 +194,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[] = {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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_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);
|
||||
|
@ -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
|
||||
*/
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue