mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 06:32:08 +00:00
net: hns3: add PCIe FLR support for VF
This patch implements the .reset_prepare and .reset_done ops from pci framework to support the VF FLR. This patch uses hclgevf_set_def_reset_request() and hclgevf_reset_event() to handle FLR, so when hdev->default_reset_request is non zero, it means there is some reset requseted by hclgevf_set_def_reset_request() need to be processed. Also get the hdev from the ae_dev because hclgevf_reset_event is called with handle being NULL. Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
862d969a3a
commit
6ff3cf0783
2 changed files with 64 additions and 2 deletions
|
@ -1099,6 +1099,32 @@ 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
|
||||||
|
@ -1113,6 +1139,11 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
|
||||||
val = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
|
val = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
|
||||||
dev_info(&hdev->pdev->dev, "checking vf resetting status: %x\n", val);
|
dev_info(&hdev->pdev->dev, "checking vf resetting status: %x\n", val);
|
||||||
|
|
||||||
|
if (hdev->reset_type == HNAE3_FLR_RESET)
|
||||||
|
return hclgevf_flr_poll_timeout(hdev,
|
||||||
|
HCLGEVF_RESET_WAIT_US,
|
||||||
|
HCLGEVF_RESET_WAIT_CNT);
|
||||||
|
|
||||||
ret = readl_poll_timeout(hdev->hw.io_base + HCLGEVF_RST_ING, val,
|
ret = readl_poll_timeout(hdev->hw.io_base + HCLGEVF_RST_ING, val,
|
||||||
!(val & HCLGEVF_RST_ING_BITS),
|
!(val & HCLGEVF_RST_ING_BITS),
|
||||||
HCLGEVF_RESET_WAIT_US,
|
HCLGEVF_RESET_WAIT_US,
|
||||||
|
@ -1168,6 +1199,9 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
|
||||||
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));
|
||||||
break;
|
break;
|
||||||
|
case HNAE3_FLR_RESET:
|
||||||
|
set_bit(HNAE3_FLR_DOWN, &hdev->flr_state);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1267,6 +1301,9 @@ static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev,
|
||||||
} else if (test_bit(HNAE3_VF_FUNC_RESET, addr)) {
|
} else if (test_bit(HNAE3_VF_FUNC_RESET, addr)) {
|
||||||
rst_level = HNAE3_VF_FUNC_RESET;
|
rst_level = HNAE3_VF_FUNC_RESET;
|
||||||
clear_bit(HNAE3_VF_FUNC_RESET, addr);
|
clear_bit(HNAE3_VF_FUNC_RESET, addr);
|
||||||
|
} else if (test_bit(HNAE3_FLR_RESET, addr)) {
|
||||||
|
rst_level = HNAE3_FLR_RESET;
|
||||||
|
clear_bit(HNAE3_FLR_RESET, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rst_level;
|
return rst_level;
|
||||||
|
@ -1275,11 +1312,12 @@ static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev,
|
||||||
static void hclgevf_reset_event(struct pci_dev *pdev,
|
static void hclgevf_reset_event(struct pci_dev *pdev,
|
||||||
struct hnae3_handle *handle)
|
struct hnae3_handle *handle)
|
||||||
{
|
{
|
||||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
|
||||||
|
struct hclgevf_dev *hdev = ae_dev->priv;
|
||||||
|
|
||||||
dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
|
dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
|
||||||
|
|
||||||
if (!hdev->default_reset_request)
|
if (hdev->default_reset_request)
|
||||||
hdev->reset_level =
|
hdev->reset_level =
|
||||||
hclgevf_get_reset_level(hdev,
|
hclgevf_get_reset_level(hdev,
|
||||||
&hdev->default_reset_request);
|
&hdev->default_reset_request);
|
||||||
|
@ -1301,6 +1339,27 @@ 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_flr_prepare(struct hnae3_ae_dev *ae_dev)
|
||||||
|
{
|
||||||
|
#define HCLGEVF_FLR_WAIT_MS 100
|
||||||
|
#define HCLGEVF_FLR_WAIT_CNT 50
|
||||||
|
struct hclgevf_dev *hdev = ae_dev->priv;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
clear_bit(HNAE3_FLR_DOWN, &hdev->flr_state);
|
||||||
|
clear_bit(HNAE3_FLR_DONE, &hdev->flr_state);
|
||||||
|
set_bit(HNAE3_FLR_RESET, &hdev->default_reset_request);
|
||||||
|
hclgevf_reset_event(hdev->pdev, NULL);
|
||||||
|
|
||||||
|
while (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state) &&
|
||||||
|
cnt++ < HCLGEVF_FLR_WAIT_CNT)
|
||||||
|
msleep(HCLGEVF_FLR_WAIT_MS);
|
||||||
|
|
||||||
|
if (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state))
|
||||||
|
dev_err(&hdev->pdev->dev,
|
||||||
|
"flr wait down timeout: %d\n", cnt);
|
||||||
|
}
|
||||||
|
|
||||||
static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
|
static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
|
||||||
{
|
{
|
||||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||||
|
@ -2310,6 +2369,8 @@ static unsigned long hclgevf_ae_dev_reset_cnt(struct hnae3_handle *handle)
|
||||||
static const struct hnae3_ae_ops hclgevf_ops = {
|
static const struct hnae3_ae_ops hclgevf_ops = {
|
||||||
.init_ae_dev = hclgevf_init_ae_dev,
|
.init_ae_dev = hclgevf_init_ae_dev,
|
||||||
.uninit_ae_dev = hclgevf_uninit_ae_dev,
|
.uninit_ae_dev = hclgevf_uninit_ae_dev,
|
||||||
|
.flr_prepare = hclgevf_flr_prepare,
|
||||||
|
.flr_done = hclgevf_flr_done,
|
||||||
.init_client_instance = hclgevf_init_client_instance,
|
.init_client_instance = hclgevf_init_client_instance,
|
||||||
.uninit_client_instance = hclgevf_uninit_client_instance,
|
.uninit_client_instance = hclgevf_uninit_client_instance,
|
||||||
.start = hclgevf_ae_start,
|
.start = hclgevf_ae_start,
|
||||||
|
|
|
@ -161,6 +161,7 @@ struct hclgevf_dev {
|
||||||
struct hclgevf_misc_vector misc_vector;
|
struct hclgevf_misc_vector misc_vector;
|
||||||
struct hclgevf_rss_cfg rss_cfg;
|
struct hclgevf_rss_cfg rss_cfg;
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
|
unsigned long flr_state;
|
||||||
unsigned long default_reset_request;
|
unsigned long default_reset_request;
|
||||||
unsigned long last_reset_time;
|
unsigned long last_reset_time;
|
||||||
enum hnae3_reset_type reset_level;
|
enum hnae3_reset_type reset_level;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue