Skip to content

Commit 6988eb2

Browse files
Salil Mehtadavem330
authored andcommitted
net: hns3: Add support to reset the enet/ring mgmt layer
After VF driver knows that hardware reset has been performed successfully, it should proceed ahead and reset the enet layer. This primarily consists of bringing down interface, clearing TX/RX rings, disassociating vectors from ring etc. Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a8dedb6 commit 6988eb2

File tree

2 files changed

+102
-4
lines changed

2 files changed

+102
-4
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright (c) 2016-2017 Hisilicon Limited.
33

44
#include <linux/etherdevice.h>
5+
#include <net/rtnetlink.h>
56
#include "hclgevf_cmd.h"
67
#include "hclgevf_main.h"
78
#include "hclge_mbx.h"
@@ -832,6 +833,101 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
832833
2, true, NULL, 0);
833834
}
834835

836+
static int hclgevf_notify_client(struct hclgevf_dev *hdev,
837+
enum hnae3_reset_notify_type type)
838+
{
839+
struct hnae3_client *client = hdev->nic_client;
840+
struct hnae3_handle *handle = &hdev->nic;
841+
842+
if (!client->ops->reset_notify)
843+
return -EOPNOTSUPP;
844+
845+
return client->ops->reset_notify(handle, type);
846+
}
847+
848+
static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
849+
{
850+
#define HCLGEVF_RESET_WAIT_MS 500
851+
#define HCLGEVF_RESET_WAIT_CNT 20
852+
u32 val, cnt = 0;
853+
854+
/* wait to check the hardware reset completion status */
855+
val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
856+
while (hnae_get_bit(val, HCLGEVF_FUN_RST_ING_B) &&
857+
(cnt < HCLGEVF_RESET_WAIT_CNT)) {
858+
msleep(HCLGEVF_RESET_WAIT_MS);
859+
val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
860+
cnt++;
861+
}
862+
863+
/* hardware completion status should be available by this time */
864+
if (cnt >= HCLGEVF_RESET_WAIT_CNT) {
865+
dev_warn(&hdev->pdev->dev,
866+
"could'nt get reset done status from h/w, timeout!\n");
867+
return -EBUSY;
868+
}
869+
870+
/* we will wait a bit more to let reset of the stack to complete. This
871+
* might happen in case reset assertion was made by PF. Yes, this also
872+
* means we might end up waiting bit more even for VF reset.
873+
*/
874+
msleep(5000);
875+
876+
return 0;
877+
}
878+
879+
static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
880+
{
881+
/* uninitialize the nic client */
882+
hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT);
883+
884+
/* re-initialize the hclge device - add code here */
885+
886+
/* bring up the nic client again */
887+
hclgevf_notify_client(hdev, HNAE3_INIT_CLIENT);
888+
889+
return 0;
890+
}
891+
892+
static int hclgevf_reset(struct hclgevf_dev *hdev)
893+
{
894+
int ret;
895+
896+
rtnl_lock();
897+
898+
/* bring down the nic to stop any ongoing TX/RX */
899+
hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
900+
901+
/* check if VF could successfully fetch the hardware reset completion
902+
* status from the hardware
903+
*/
904+
ret = hclgevf_reset_wait(hdev);
905+
if (ret) {
906+
/* can't do much in this situation, will disable VF */
907+
dev_err(&hdev->pdev->dev,
908+
"VF failed(=%d) to fetch H/W reset completion status\n",
909+
ret);
910+
911+
dev_warn(&hdev->pdev->dev, "VF reset failed, disabling VF!\n");
912+
hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT);
913+
914+
rtnl_unlock();
915+
return ret;
916+
}
917+
918+
/* now, re-initialize the nic client and ae device*/
919+
ret = hclgevf_reset_stack(hdev);
920+
if (ret)
921+
dev_err(&hdev->pdev->dev, "failed to reset VF stack\n");
922+
923+
/* bring up the nic to enable TX/RX again */
924+
hclgevf_notify_client(hdev, HNAE3_UP_CLIENT);
925+
926+
rtnl_unlock();
927+
928+
return ret;
929+
}
930+
835931
static int hclgevf_do_reset(struct hclgevf_dev *hdev)
836932
{
837933
int status;
@@ -940,10 +1036,9 @@ static void hclgevf_reset_service_task(struct work_struct *work)
9401036
*/
9411037
hdev->reset_attempts = 0;
9421038

943-
/* code to check/wait for hardware reset completion and the
944-
* further initiating software stack reset would be added here
945-
*/
946-
1039+
ret = hclgevf_reset(hdev);
1040+
if (ret)
1041+
dev_err(&hdev->pdev->dev, "VF stack reset failed.\n");
9471042
} else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED,
9481043
&hdev->reset_state)) {
9491044
/* we could be here when either of below happens:

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#define HCLGEVF_VECTOR0_RX_CMDQ_INT_B 1
3535

3636
#define HCLGEVF_TQP_RESET_TRY_TIMES 10
37+
/* Reset related Registers */
38+
#define HCLGEVF_FUN_RST_ING 0x20C00
39+
#define HCLGEVF_FUN_RST_ING_B 0
3740

3841
#define HCLGEVF_RSS_IND_TBL_SIZE 512
3942
#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff

0 commit comments

Comments
 (0)