Commit 5c9166f0 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-next'

Huazhong Tan says:

====================
net: hns3: add some misc update about reset issue

This series includes some misc update relating to reset issue.
[patch 1/7] & [patch 2/7] splits hclge_reset()/hclgevf_reset()
into two parts: preparing and rebuilding. Since the procedure
of FLR should be separated out from the reset task([patch 3/7 &
patch 3/7]), then the FLR's processing can reuse these codes.

pci_error_handlers.reset_prepare() is void type function, so
[patch 6/7] & [patch 7/7] factor some codes related to PF
function reset to make the preparing done before .reset_prepare()
return.

BTW, [patch 5/7] enlarges the waiting time of reset for matching
the hardware's.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6821af8b c7554dcd
...@@ -167,11 +167,6 @@ enum hnae3_reset_type { ...@@ -167,11 +167,6 @@ enum hnae3_reset_type {
HNAE3_MAX_RESET, HNAE3_MAX_RESET,
}; };
enum hnae3_flr_state {
HNAE3_FLR_DOWN,
HNAE3_FLR_DONE,
};
enum hnae3_port_base_vlan_state { enum hnae3_port_base_vlan_state {
HNAE3_PORT_BASE_VLAN_DISABLE, HNAE3_PORT_BASE_VLAN_DISABLE,
HNAE3_PORT_BASE_VLAN_ENABLE, HNAE3_PORT_BASE_VLAN_ENABLE,
......
...@@ -3260,7 +3260,8 @@ static int hclge_notify_roce_client(struct hclge_dev *hdev, ...@@ -3260,7 +3260,8 @@ static int hclge_notify_roce_client(struct hclge_dev *hdev,
static int hclge_reset_wait(struct hclge_dev *hdev) static int hclge_reset_wait(struct hclge_dev *hdev)
{ {
#define HCLGE_RESET_WATI_MS 100 #define HCLGE_RESET_WATI_MS 100
#define HCLGE_RESET_WAIT_CNT 200 #define HCLGE_RESET_WAIT_CNT 350
u32 val, reg, reg_bit; u32 val, reg, reg_bit;
u32 cnt = 0; u32 cnt = 0;
...@@ -3277,8 +3278,6 @@ static int hclge_reset_wait(struct hclge_dev *hdev) ...@@ -3277,8 +3278,6 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
reg = HCLGE_FUN_RST_ING; reg = HCLGE_FUN_RST_ING;
reg_bit = HCLGE_FUN_RST_ING_B; reg_bit = HCLGE_FUN_RST_ING_B;
break; break;
case HNAE3_FLR_RESET:
break;
default: default:
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"Wait for unsupported reset type: %d\n", "Wait for unsupported reset type: %d\n",
...@@ -3286,20 +3285,6 @@ static int hclge_reset_wait(struct hclge_dev *hdev) ...@@ -3286,20 +3285,6 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
return -EINVAL; return -EINVAL;
} }
if (hdev->reset_type == HNAE3_FLR_RESET) {
while (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state) &&
cnt++ < HCLGE_RESET_WAIT_CNT)
msleep(HCLGE_RESET_WATI_MS);
if (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state)) {
dev_err(&hdev->pdev->dev,
"flr wait timeout: %u\n", cnt);
return -EBUSY;
}
return 0;
}
val = hclge_read_dev(&hdev->hw, reg); val = hclge_read_dev(&hdev->hw, reg);
while (hnae3_get_bit(val, reg_bit) && cnt < HCLGE_RESET_WAIT_CNT) { while (hnae3_get_bit(val, reg_bit) && cnt < HCLGE_RESET_WAIT_CNT) {
msleep(HCLGE_RESET_WATI_MS); msleep(HCLGE_RESET_WATI_MS);
...@@ -3377,7 +3362,7 @@ static void hclge_mailbox_service_task(struct hclge_dev *hdev) ...@@ -3377,7 +3362,7 @@ static void hclge_mailbox_service_task(struct hclge_dev *hdev)
clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state); clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
} }
static int hclge_func_reset_sync_vf(struct hclge_dev *hdev) static void hclge_func_reset_sync_vf(struct hclge_dev *hdev)
{ {
struct hclge_pf_rst_sync_cmd *req; struct hclge_pf_rst_sync_cmd *req;
struct hclge_desc desc; struct hclge_desc desc;
...@@ -3397,20 +3382,19 @@ static int hclge_func_reset_sync_vf(struct hclge_dev *hdev) ...@@ -3397,20 +3382,19 @@ static int hclge_func_reset_sync_vf(struct hclge_dev *hdev)
*/ */
if (ret == -EOPNOTSUPP) { if (ret == -EOPNOTSUPP) {
msleep(HCLGE_RESET_SYNC_TIME); msleep(HCLGE_RESET_SYNC_TIME);
return 0; return;
} else if (ret) { } else if (ret) {
dev_err(&hdev->pdev->dev, "sync with VF fail %d!\n", dev_warn(&hdev->pdev->dev, "sync with VF fail %d!\n",
ret); ret);
return ret; return;
} else if (req->all_vf_ready) { } else if (req->all_vf_ready) {
return 0; return;
} }
msleep(HCLGE_PF_RESET_SYNC_TIME); msleep(HCLGE_PF_RESET_SYNC_TIME);
hclge_cmd_reuse_desc(&desc, true); hclge_cmd_reuse_desc(&desc, true);
} while (cnt++ < HCLGE_PF_RESET_SYNC_CNT); } while (cnt++ < HCLGE_PF_RESET_SYNC_CNT);
dev_err(&hdev->pdev->dev, "sync with VF timeout!\n"); dev_warn(&hdev->pdev->dev, "sync with VF timeout!\n");
return -ETIME;
} }
void hclge_report_hw_error(struct hclge_dev *hdev, void hclge_report_hw_error(struct hclge_dev *hdev,
...@@ -3490,12 +3474,6 @@ static void hclge_do_reset(struct hclge_dev *hdev) ...@@ -3490,12 +3474,6 @@ static void hclge_do_reset(struct hclge_dev *hdev)
set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending); set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
hclge_reset_task_schedule(hdev); hclge_reset_task_schedule(hdev);
break; break;
case HNAE3_FLR_RESET:
dev_info(&pdev->dev, "FLR requested\n");
/* schedule again to check later */
set_bit(HNAE3_FLR_RESET, &hdev->reset_pending);
hclge_reset_task_schedule(hdev);
break;
default: default:
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"Unsupported reset type: %d\n", hdev->reset_type); "Unsupported reset type: %d\n", hdev->reset_type);
...@@ -3584,23 +3562,6 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev) ...@@ -3584,23 +3562,6 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev)
hclge_enable_vector(&hdev->misc_vector, true); hclge_enable_vector(&hdev->misc_vector, true);
} }
static int hclge_reset_prepare_down(struct hclge_dev *hdev)
{
int ret = 0;
switch (hdev->reset_type) {
case HNAE3_FUNC_RESET:
/* fall through */
case HNAE3_FLR_RESET:
ret = hclge_set_all_vf_rst(hdev, true);
break;
default:
break;
}
return ret;
}
static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable) static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable)
{ {
u32 reg_val; u32 reg_val;
...@@ -3614,6 +3575,19 @@ static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable) ...@@ -3614,6 +3575,19 @@ static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable)
hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val); hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
} }
static int hclge_func_reset_notify_vf(struct hclge_dev *hdev)
{
int ret;
ret = hclge_set_all_vf_rst(hdev, true);
if (ret)
return ret;
hclge_func_reset_sync_vf(hdev);
return 0;
}
static int hclge_reset_prepare_wait(struct hclge_dev *hdev) static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
{ {
u32 reg_val; u32 reg_val;
...@@ -3621,10 +3595,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev) ...@@ -3621,10 +3595,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
switch (hdev->reset_type) { switch (hdev->reset_type) {
case HNAE3_FUNC_RESET: case HNAE3_FUNC_RESET:
/* to confirm whether all running VF is ready ret = hclge_func_reset_notify_vf(hdev);
* before request PF reset
*/
ret = hclge_func_reset_sync_vf(hdev);
if (ret) if (ret)
return ret; return ret;
...@@ -3644,16 +3615,9 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev) ...@@ -3644,16 +3615,9 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
hdev->rst_stats.pf_rst_cnt++; hdev->rst_stats.pf_rst_cnt++;
break; break;
case HNAE3_FLR_RESET: case HNAE3_FLR_RESET:
/* to confirm whether all running VF is ready ret = hclge_func_reset_notify_vf(hdev);
* before request PF reset
*/
ret = hclge_func_reset_sync_vf(hdev);
if (ret) if (ret)
return ret; return ret;
set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
set_bit(HNAE3_FLR_DOWN, &hdev->flr_state);
hdev->rst_stats.flr_rst_cnt++;
break; break;
case HNAE3_IMP_RESET: case HNAE3_IMP_RESET:
hclge_handle_imp_error(hdev); hclge_handle_imp_error(hdev);
...@@ -3782,10 +3746,9 @@ static int hclge_reset_stack(struct hclge_dev *hdev) ...@@ -3782,10 +3746,9 @@ static int hclge_reset_stack(struct hclge_dev *hdev)
return hclge_notify_client(hdev, HNAE3_RESTORE_CLIENT); return hclge_notify_client(hdev, HNAE3_RESTORE_CLIENT);
} }
static void hclge_reset(struct hclge_dev *hdev) static int hclge_reset_prepare(struct hclge_dev *hdev)
{ {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
enum hnae3_reset_type reset_level;
int ret; int ret;
/* Initialize ae_dev reset status as well, in case enet layer wants to /* Initialize ae_dev reset status as well, in case enet layer wants to
...@@ -3796,45 +3759,41 @@ static void hclge_reset(struct hclge_dev *hdev) ...@@ -3796,45 +3759,41 @@ static void hclge_reset(struct hclge_dev *hdev)
/* perform reset of the stack & ae device for a client */ /* perform reset of the stack & ae device for a client */
ret = hclge_notify_roce_client(hdev, HNAE3_DOWN_CLIENT); ret = hclge_notify_roce_client(hdev, HNAE3_DOWN_CLIENT);
if (ret) if (ret)
goto err_reset; return ret;
ret = hclge_reset_prepare_down(hdev);
if (ret)
goto err_reset;
rtnl_lock(); rtnl_lock();
ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT); ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
if (ret)
goto err_reset_lock;
rtnl_unlock(); rtnl_unlock();
ret = hclge_reset_prepare_wait(hdev);
if (ret) if (ret)
goto err_reset; return ret;
if (hclge_reset_wait(hdev)) return hclge_reset_prepare_wait(hdev);
goto err_reset; }
static int hclge_reset_rebuild(struct hclge_dev *hdev)
{
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
enum hnae3_reset_type reset_level;
int ret;
hdev->rst_stats.hw_reset_done_cnt++; hdev->rst_stats.hw_reset_done_cnt++;
ret = hclge_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT); ret = hclge_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT);
if (ret) if (ret)
goto err_reset; return ret;
rtnl_lock(); rtnl_lock();
ret = hclge_reset_stack(hdev); ret = hclge_reset_stack(hdev);
rtnl_unlock();
if (ret) if (ret)
goto err_reset_lock; return ret;
hclge_clear_reset_cause(hdev); hclge_clear_reset_cause(hdev);
ret = hclge_reset_prepare_up(hdev); ret = hclge_reset_prepare_up(hdev);
if (ret) if (ret)
goto err_reset_lock; return ret;
rtnl_unlock();
ret = hclge_notify_roce_client(hdev, HNAE3_INIT_CLIENT); ret = hclge_notify_roce_client(hdev, HNAE3_INIT_CLIENT);
/* ignore RoCE notify error if it fails HCLGE_RESET_MAX_FAIL_CNT - 1 /* ignore RoCE notify error if it fails HCLGE_RESET_MAX_FAIL_CNT - 1
...@@ -3842,19 +3801,17 @@ static void hclge_reset(struct hclge_dev *hdev) ...@@ -3842,19 +3801,17 @@ static void hclge_reset(struct hclge_dev *hdev)
*/ */
if (ret && if (ret &&
hdev->rst_stats.reset_fail_cnt < HCLGE_RESET_MAX_FAIL_CNT - 1) hdev->rst_stats.reset_fail_cnt < HCLGE_RESET_MAX_FAIL_CNT - 1)
goto err_reset; return ret;
rtnl_lock(); rtnl_lock();
ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT); ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT);
if (ret)
goto err_reset_lock;
rtnl_unlock(); rtnl_unlock();
if (ret)
return ret;
ret = hclge_notify_roce_client(hdev, HNAE3_UP_CLIENT); ret = hclge_notify_roce_client(hdev, HNAE3_UP_CLIENT);
if (ret) if (ret)
goto err_reset; return ret;
hdev->last_reset_time = jiffies; hdev->last_reset_time = jiffies;
hdev->rst_stats.reset_fail_cnt = 0; hdev->rst_stats.reset_fail_cnt = 0;
...@@ -3871,10 +3828,22 @@ static void hclge_reset(struct hclge_dev *hdev) ...@@ -3871,10 +3828,22 @@ static void hclge_reset(struct hclge_dev *hdev)
if (reset_level != HNAE3_NONE_RESET) if (reset_level != HNAE3_NONE_RESET)
set_bit(reset_level, &hdev->reset_request); set_bit(reset_level, &hdev->reset_request);
return 0;
}
static void hclge_reset(struct hclge_dev *hdev)
{
if (hclge_reset_prepare(hdev))
goto err_reset;
if (hclge_reset_wait(hdev))
goto err_reset;
if (hclge_reset_rebuild(hdev))
goto err_reset;
return; return;
err_reset_lock:
rtnl_unlock();
err_reset: err_reset:
if (hclge_reset_err_handle(hdev)) if (hclge_reset_err_handle(hdev))
hclge_reset_task_schedule(hdev); hclge_reset_task_schedule(hdev);
...@@ -3980,12 +3949,13 @@ static void hclge_reset_service_task(struct hclge_dev *hdev) ...@@ -3980,12 +3949,13 @@ static void hclge_reset_service_task(struct hclge_dev *hdev)
if (!test_and_clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state)) if (!test_and_clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
return; return;
if (test_and_set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) down(&hdev->reset_sem);
return; set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
hclge_reset_subtask(hdev); hclge_reset_subtask(hdev);
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
} }
static void hclge_update_vport_alive(struct hclge_dev *hdev) static void hclge_update_vport_alive(struct hclge_dev *hdev)
...@@ -9332,30 +9302,53 @@ static void hclge_state_uninit(struct hclge_dev *hdev) ...@@ -9332,30 +9302,53 @@ static void hclge_state_uninit(struct hclge_dev *hdev)
static void hclge_flr_prepare(struct hnae3_ae_dev *ae_dev) static void hclge_flr_prepare(struct hnae3_ae_dev *ae_dev)
{ {
#define HCLGE_FLR_WAIT_MS 100 #define HCLGE_FLR_RETRY_WAIT_MS 500
#define HCLGE_FLR_WAIT_CNT 50 #define HCLGE_FLR_RETRY_CNT 5
struct hclge_dev *hdev = ae_dev->priv;
int cnt = 0;
clear_bit(HNAE3_FLR_DOWN, &hdev->flr_state); struct hclge_dev *hdev = ae_dev->priv;
clear_bit(HNAE3_FLR_DONE, &hdev->flr_state); int retry_cnt = 0;
set_bit(HNAE3_FLR_RESET, &hdev->default_reset_request); int ret;
hclge_reset_event(hdev->pdev, NULL);
while (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state) && retry:
cnt++ < HCLGE_FLR_WAIT_CNT) down(&hdev->reset_sem);
msleep(HCLGE_FLR_WAIT_MS); set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
hdev->reset_type = HNAE3_FLR_RESET;
ret = hclge_reset_prepare(hdev);
if (ret) {
dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n",
ret);
if (hdev->reset_pending ||
retry_cnt++ < HCLGE_FLR_RETRY_CNT) {
dev_err(&hdev->pdev->dev,
"reset_pending:0x%lx, retry_cnt:%d\n",
hdev->reset_pending, retry_cnt);
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
msleep(HCLGE_FLR_RETRY_WAIT_MS);
goto retry;
}
}
if (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state)) /* disable misc vector before FLR done */
dev_err(&hdev->pdev->dev, hclge_enable_vector(&hdev->misc_vector, false);
"flr wait down timeout: %d\n", cnt); set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);
hdev->rst_stats.flr_rst_cnt++;
} }
static void hclge_flr_done(struct hnae3_ae_dev *ae_dev) static void hclge_flr_done(struct hnae3_ae_dev *ae_dev)
{ {
struct hclge_dev *hdev = ae_dev->priv; struct hclge_dev *hdev = ae_dev->priv;
int ret;
hclge_enable_vector(&hdev->misc_vector, true);
set_bit(HNAE3_FLR_DONE, &hdev->flr_state); ret = hclge_reset_rebuild(hdev);
if (ret)
dev_err(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", ret);
hdev->reset_type = HNAE3_NONE_RESET;
clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
} }
static void hclge_clear_resetting_state(struct hclge_dev *hdev) static void hclge_clear_resetting_state(struct hclge_dev *hdev)
...@@ -9398,6 +9391,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) ...@@ -9398,6 +9391,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
mutex_init(&hdev->vport_lock); mutex_init(&hdev->vport_lock);
spin_lock_init(&hdev->fd_rule_lock); spin_lock_init(&hdev->fd_rule_lock);
sema_init(&hdev->reset_sem, 1);
ret = hclge_pci_init(hdev); ret = hclge_pci_init(hdev);
if (ret) { if (ret) {
......
...@@ -720,6 +720,7 @@ struct hclge_dev { ...@@ -720,6 +720,7 @@ struct hclge_dev {
unsigned long reset_request; /* reset has been requested */ unsigned long reset_request; /* reset has been requested */
unsigned long reset_pending; /* client rst is pending to be served */ unsigned long reset_pending; /* client rst is pending to be served */
struct hclge_rst_stats rst_stats; struct hclge_rst_stats rst_stats;
struct semaphore reset_sem; /* protect reset process */
u32 fw_version; u32 fw_version;
u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */ u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */
u16 num_tqps; /* Num task queue pairs of this PF */ u16 num_tqps; /* Num task queue pairs of this PF */
......
...@@ -1411,32 +1411,6 @@ static int hclgevf_notify_client(struct hclgevf_dev *hdev, ...@@ -1411,32 +1411,6 @@ static int hclgevf_notify_client(struct hclgevf_dev *hdev,
return ret; return ret;
} }
static void hclgevf_flr_done(struct hnae3_ae_dev *ae_dev)
{
struct hclgevf_dev *hdev = ae_dev->priv;
set_bit(HNAE3_FLR_DONE, &hdev->flr_state);
}
static int hclgevf_flr_poll_timeout(struct hclgevf_dev *hdev,
unsigned long delay_us,
unsigned long wait_cnt)
{
unsigned long cnt = 0;
while (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state) &&
cnt++ < wait_cnt)
usleep_range(delay_us, delay_us * 2);
if (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state)) {
dev_err(&hdev->pdev->dev,
"flr wait timeout\n");
return -ETIMEDOUT;
}
return 0;
}
static int hclgevf_reset_wait(struct hclgevf_dev *hdev) static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
{ {
#define HCLGEVF_RESET_WAIT_US 20000 #define HCLGEVF_RESET_WAIT_US 20000
...@@ -1447,11 +1421,7 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev) ...@@ -1447,11 +1421,7 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
u32 val; u32 val;
int ret; int ret;
if (hdev->reset_type == HNAE3_FLR_RESET) if (hdev->reset_type == HNAE3_VF_RESET)
return hclgevf_flr_poll_timeout(hdev,
HCLGEVF_RESET_WAIT_US,
HCLGEVF_RESET_WAIT_CNT);
else if (hdev->reset_type == HNAE3_VF_RESET)
ret = readl_poll_timeout(hdev->hw.io_base + ret = readl_poll_timeout(hdev->hw.io_base +
HCLGEVF_VF_RST_ING, val, HCLGEVF_VF_RST_ING, val,
!(val & HCLGEVF_VF_RST_ING_BIT), !(val & HCLGEVF_VF_RST_ING_BIT),
...@@ -1523,7 +1493,8 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev) ...@@ -1523,7 +1493,8 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
/* clear handshake status with IMP */ /* clear handshake status with IMP */
hclgevf_reset_handshake(hdev, false); hclgevf_reset_handshake(hdev, false);
return 0; /* bring up the nic to enable TX/RX again */
return hclgevf_notify_client(hdev, HNAE3_UP_CLIENT);
} }
static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
...@@ -1532,18 +1503,10 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) ...@@ -1532,18 +1503,10 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
int ret = 0; int ret = 0;
switch (hdev->reset_type) { if (hdev->reset_type == HNAE3_VF_FUNC_RESET) {
case HNAE3_VF_FUNC_RESET:
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL, ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL,
0, true, NULL, sizeof(u8)); 0, true, NULL, sizeof(u8));
hdev->rst_stats.vf_func_rst_cnt++; hdev->rst_stats.vf_func_rst_cnt++;
break;
case HNAE3_FLR_RESET:
set_bit(HNAE3_FLR_DOWN, &hdev->flr_state);
hdev->rst_stats.flr_rst_cnt++;
break;
default:
break;
} }
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
...@@ -1603,7 +1566,7 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) ...@@ -1603,7 +1566,7 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
} }
} }
static int hclgevf_reset(struct hclgevf_dev *hdev) static int hclgevf_reset_prepare(struct hclgevf_dev *hdev)
{ {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
int ret; int ret;
...@@ -1613,62 +1576,64 @@ static int hclgevf_reset(struct hclgevf_dev *hdev) ...@@ -1613,62 +1576,64 @@ static int hclgevf_reset(struct hclgevf_dev *hdev)
*/ */
ae_dev->reset_type = hdev->reset_type; ae_dev->reset_type = hdev->reset_type;
hdev->rst_stats.rst_cnt++; hdev->rst_stats.rst_cnt++;
rtnl_lock();
rtnl_lock();
/* bring down the nic to stop any ongoing TX/RX */ /* bring down the nic to stop any ongoing TX/RX */
ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
if (ret)
goto err_reset_lock;
rtnl_unlock(); rtnl_unlock();
ret = hclgevf_reset_prepare_wait(hdev);
if (ret) if (ret)
goto err_reset; return ret;
/* check if VF could successfully fetch the hardware reset completion return hclgevf_reset_prepare_wait(hdev);
* status from the hardware }
*/
ret = hclgevf_reset_wait(hdev); static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev)
if (ret) { {
/* can't do much in this situation, will disable VF */ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
dev_err(&hdev->pdev->dev, int ret;
"VF failed(=%d) to fetch H/W reset completion status\n",
ret);
goto err_reset;
}
hdev->rst_stats.hw_rst_done_cnt++; hdev->rst_stats.hw_rst_done_cnt++;
rtnl_lock(); rtnl_lock();
/* now, re-initialize the nic client and ae device */ /* now, re-initialize the nic client and ae device */
ret = hclgevf_reset_stack(hdev); ret = hclgevf_reset_stack(hdev);
rtnl_unlock();
if (ret) { if (ret) {
dev_err(&hdev->pdev->dev, "failed to reset VF stack\n"); dev_err(&hdev->pdev->dev, "failed to reset VF stack\n");
goto err_reset_lock; return ret;
} }
/* bring up the nic to enable TX/RX again */
ret = hclgevf_notify_client(hdev, HNAE3_UP_CLIENT);
if (ret)
goto err_reset_lock;
rtnl_unlock();
hdev->last_reset_time = jiffies; hdev->last_reset_time = jiffies;
ae_dev->reset_type = HNAE3_NONE_RESET; ae_dev->reset_type = HNAE3_NONE_RESET;
hdev->rst_stats.rst_done_cnt++; hdev->rst_stats.rst_done_cnt++;
hdev->rst_stats.rst_fail_cnt = 0; hdev->rst_stats.rst_fail_cnt = 0;
clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state);
return ret; return 0;
err_reset_lock: }
rtnl_unlock();
static void hclgevf_reset(struct hclgevf_dev *hdev)
{
if (hclgevf_reset_prepare(hdev))
goto err_reset;
/* check if VF could successfully fetch the hardware reset completion
* status from the hardware
*/
if (hclgevf_reset_wait(hdev)) {
/* can't do much in this situation, will disable VF */
dev_err(&hdev->pdev->dev,
"failed to fetch H/W reset completion status\n");
goto err_reset;
}
if (hclgevf_reset_rebuild(hdev))
goto err_reset;
return;
err_reset: err_reset:
hclgevf_reset_err_handle(hdev); hclgevf_reset_err_handle(hdev);
return ret;
} }
static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev, static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev,
...@@ -1731,25 +1696,60 @@ static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, ...@@ -1731,25 +1696,60 @@ static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
set_bit(rst_type, &hdev->default_reset_request); set_bit(rst_type, &hdev->default_reset_request);
} }
static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en)
{
writel(en ? 1 : 0, vector->addr);
}
static void hclgevf_flr_prepare(struct hnae3_ae_dev *ae_dev) static void hclgevf_flr_prepare(struct hnae3_ae_dev *ae_dev)
{ {
#define HCLGEVF_FLR_WAIT_MS 100 #define HCLGEVF_FLR_RETRY_WAIT_MS 500
#define HCLGEVF_FLR_WAIT_CNT 50 #define HCLGEVF_FLR_RETRY_CNT 5
struct hclgevf_dev *hdev = ae_dev->priv; struct hclgevf_dev *hdev = ae_dev->priv;
int cnt = 0; int retry_cnt = 0;
int ret;
clear_bit(HNAE3_FLR_DOWN, &hdev->flr_state); retry:
clear_bit(HNAE3_FLR_DONE, &hdev->flr_state); down(&hdev->reset_sem);
set_bit(HNAE3_FLR_RESET, &hdev->default_reset_request); set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
hclgevf_reset_event(hdev->pdev, NULL); hdev->reset_type = HNAE3_FLR_RESET;
ret = hclgevf_reset_prepare(hdev);
if (ret) {
dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n",
ret);
if (hdev->reset_pending ||
retry_cnt++ < HCLGEVF_FLR_RETRY_CNT) {
dev_err(&hdev->pdev->dev,
"reset_pending:0x%lx, retry_cnt:%d\n",
hdev->reset_pending, retry_cnt);
clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
msleep(HCLGEVF_FLR_RETRY_WAIT_MS);
goto retry;
}
}
while (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state) && /* disable misc vector before FLR done */
cnt++ < HCLGEVF_FLR_WAIT_CNT) hclgevf_enable_vector(&hdev->misc_vector, false);
msleep(HCLGEVF_FLR_WAIT_MS); hdev->rst_stats.flr_rst_cnt++;
}
if (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state)) static void hclgevf_flr_done(struct hnae3_ae_dev *ae_dev)
dev_err(&hdev->pdev->dev, {
"flr wait down timeout: %d\n", cnt); struct hclgevf_dev *hdev = ae_dev->priv;
int ret;
hclgevf_enable_vector(&hdev->misc_vector, true);
ret = hclgevf_reset_rebuild(hdev);
if (ret)
dev_warn(&hdev->pdev->dev, "fail to rebuild, ret=%d\n",
ret);
hdev->reset_type = HNAE3_NONE_RESET;
clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
} }
static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
...@@ -1802,13 +1802,11 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) ...@@ -1802,13 +1802,11 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
{ {
#define HCLGEVF_MAX_RESET_ATTEMPTS_CNT 3 #define HCLGEVF_MAX_RESET_ATTEMPTS_CNT 3
int ret;
if (!test_and_clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state)) if (!test_and_clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state))
return; return;
if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) down(&hdev->reset_sem);
return; set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
if (test_and_clear_bit(HCLGEVF_RESET_PENDING, if (test_and_clear_bit(HCLGEVF_RESET_PENDING,
&hdev->reset_state)) { &hdev->reset_state)) {
...@@ -1822,12 +1820,8 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) ...@@ -1822,12 +1820,8 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
hdev->last_reset_time = jiffies; hdev->last_reset_time = jiffies;
while ((hdev->reset_type = while ((hdev->reset_type =
hclgevf_get_reset_level(hdev, &hdev->reset_pending)) hclgevf_get_reset_level(hdev, &hdev->reset_pending))
!= HNAE3_NONE_RESET) { != HNAE3_NONE_RESET)
ret = hclgevf_reset(hdev); hclgevf_reset(hdev);
if (ret)
dev_err(&hdev->pdev->dev,
"VF stack reset failed %d.\n", ret);
}
} else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED, } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED,
&hdev->reset_state)) { &hdev->reset_state)) {
/* we could be here when either of below happens: /* we could be here when either of below happens:
...@@ -1869,6 +1863,7 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) ...@@ -1869,6 +1863,7 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
} }
clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
up(&hdev->reset_sem);
} }
static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev) static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev)
...@@ -2012,11 +2007,6 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, ...@@ -2012,11 +2007,6 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
return HCLGEVF_VECTOR0_EVENT_OTHER; return HCLGEVF_VECTOR0_EVENT_OTHER;
} }
static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en)
{
writel(en ? 1 : 0, vector->addr);
}
static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data)
{ {
enum hclgevf_evt_cause event_cause; enum hclgevf_evt_cause event_cause;
...@@ -2291,6 +2281,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) ...@@ -2291,6 +2281,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task);
mutex_init(&hdev->mbx_resp.mbx_mutex); mutex_init(&hdev->mbx_resp.mbx_mutex);
sema_init(&hdev->reset_sem, 1);
/* bring the device down */ /* bring the device down */
set_bit(HCLGEVF_STATE_DOWN, &hdev->state); set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
......
...@@ -253,6 +253,7 @@ struct hclgevf_dev { ...@@ -253,6 +253,7 @@ struct hclgevf_dev {
unsigned long reset_state; /* requested, pending */ unsigned long reset_state; /* requested, pending */
struct hclgevf_rst_stats rst_stats; struct hclgevf_rst_stats rst_stats;
u32 reset_attempts; u32 reset_attempts;
struct semaphore reset_sem; /* protect reset process */
u32 fw_version; u32 fw_version;
u16 num_tqps; /* num task queue pairs of this PF */ u16 num_tqps; /* num task queue pairs of this PF */
......
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