172 lines
6.1 KiB
Diff
172 lines
6.1 KiB
Diff
From a239416d71310c1163a9ea05016aabcb6d8cdd25 Mon Sep 17 00:00:00 2001
|
|
From: Yufeng Mo <moyufeng@huawei.com>
|
|
Date: Sat, 21 Aug 2021 17:00:37 +0800
|
|
Subject: [PATCH 097/283] net: hns3: add support for triggering reset by
|
|
ethtool
|
|
|
|
mainline inclusion
|
|
from mainline-v5.15-rc1
|
|
commit ddccc5e368a33daeb6862192d4dca8e59af9234a
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EMYT
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ddccc5e368a33daeb6862192d4dca8e59af9234a
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
Currently, four reset types are supported for the HNS3 ethernet
|
|
driver: IMP reset, global reset, function reset, and FLR. Only
|
|
FLR can now be triggered by the user. To restore the device when
|
|
an exception occurs, add support for triggering reset by ethtool.
|
|
|
|
Run the "ethtool --reset DEVNAME mgmt | all | dedicated" to
|
|
trigger the IMP | global | function reset manually.
|
|
|
|
In addition, VF can only trigger function reset.
|
|
|
|
Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
|
|
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
|
|
Link: https://lore.kernel.org/r/1628602128-15640-1-git-send-email-huangguangbin2@huawei.com
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Reviewed-by: Yongxin Li <liyongxin1@huawei.com>
|
|
Signed-off-by: Junxin Chen <chenjunxin1@huawei.com>
|
|
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
---
|
|
.../net/ethernet/hisilicon/hns3/hns3_enet.h | 5 ++
|
|
.../ethernet/hisilicon/hns3/hns3_ethtool.c | 56 +++++++++++++++++++
|
|
.../hisilicon/hns3/hns3pf/hclge_main.c | 6 ++
|
|
.../hisilicon/hns3/hns3pf/hclge_main.h | 1 +
|
|
4 files changed, 68 insertions(+)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
index d7238d0744f3..416c0c44b11d 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
@@ -577,6 +577,11 @@ struct hns3_hw_error_info {
|
|
const char *msg;
|
|
};
|
|
|
|
+struct hns3_reset_type_map {
|
|
+ enum ethtool_reset_flags rst_flags;
|
|
+ enum hnae3_reset_type rst_type;
|
|
+};
|
|
+
|
|
static inline int ring_space(struct hns3_enet_ring *ring)
|
|
{
|
|
/* This smp_load_acquire() pairs with smp_store_release() in
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
index 8d73f15be8d6..4197d40471f4 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
@@ -965,6 +965,60 @@ static int hns3_get_rxnfc(struct net_device *netdev,
|
|
}
|
|
}
|
|
|
|
+static const struct hns3_reset_type_map hns3_reset_type[] = {
|
|
+ {ETH_RESET_MGMT, HNAE3_IMP_RESET},
|
|
+ {ETH_RESET_ALL, HNAE3_GLOBAL_RESET},
|
|
+ {ETH_RESET_DEDICATED, HNAE3_FUNC_RESET},
|
|
+};
|
|
+
|
|
+static const struct hns3_reset_type_map hns3vf_reset_type[] = {
|
|
+ {ETH_RESET_DEDICATED, HNAE3_VF_FUNC_RESET},
|
|
+};
|
|
+
|
|
+static int hns3_set_reset(struct net_device *netdev, u32 *flags)
|
|
+{
|
|
+ enum hnae3_reset_type rst_type = HNAE3_NONE_RESET;
|
|
+ struct hnae3_handle *h = hns3_get_handle(netdev);
|
|
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
|
|
+ const struct hnae3_ae_ops *ops = h->ae_algo->ops;
|
|
+ const struct hns3_reset_type_map *rst_type_map;
|
|
+ u32 i, size;
|
|
+
|
|
+ if (ops->ae_dev_resetting && ops->ae_dev_resetting(h))
|
|
+ return -EBUSY;
|
|
+
|
|
+ if (!ops->set_default_reset_request || !ops->reset_event)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ if (h->flags & HNAE3_SUPPORT_VF) {
|
|
+ rst_type_map = hns3vf_reset_type;
|
|
+ size = ARRAY_SIZE(hns3vf_reset_type);
|
|
+ } else {
|
|
+ rst_type_map = hns3_reset_type;
|
|
+ size = ARRAY_SIZE(hns3_reset_type);
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < size; i++) {
|
|
+ if (rst_type_map[i].rst_flags == *flags) {
|
|
+ rst_type = rst_type_map[i].rst_type;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (rst_type == HNAE3_NONE_RESET ||
|
|
+ (rst_type == HNAE3_IMP_RESET &&
|
|
+ ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2))
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ netdev_info(netdev, "Setting reset type %d\n", rst_type);
|
|
+
|
|
+ ops->set_default_reset_request(ae_dev, rst_type);
|
|
+
|
|
+ ops->reset_event(h->pdev, h);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static void hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
|
|
u32 tx_desc_num, u32 rx_desc_num)
|
|
{
|
|
@@ -1711,6 +1765,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
|
|
.set_priv_flags = hns3_set_priv_flags,
|
|
.get_tunable = hns3_get_tunable,
|
|
.set_tunable = hns3_set_tunable,
|
|
+ .reset = hns3_set_reset,
|
|
};
|
|
|
|
static const struct ethtool_ops hns3_ethtool_ops = {
|
|
@@ -1752,6 +1807,7 @@ static const struct ethtool_ops hns3_ethtool_ops = {
|
|
.get_ts_info = hns3_get_ts_info,
|
|
.get_tunable = hns3_get_tunable,
|
|
.set_tunable = hns3_set_tunable,
|
|
+ .reset = hns3_set_reset,
|
|
};
|
|
|
|
void hns3_ethtool_set_ops(struct net_device *netdev)
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
index 7196dd27e230..359c6fc4ca1d 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
@@ -3700,6 +3700,12 @@ static void hclge_do_reset(struct hclge_dev *hdev)
|
|
}
|
|
|
|
switch (hdev->reset_type) {
|
|
+ case HNAE3_IMP_RESET:
|
|
+ dev_info(&pdev->dev, "IMP reset requested\n");
|
|
+ val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
|
|
+ hnae3_set_bit(val, HCLGE_TRIGGER_IMP_RESET_B, 1);
|
|
+ hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, val);
|
|
+ break;
|
|
case HNAE3_GLOBAL_RESET:
|
|
dev_info(&pdev->dev, "global reset requested\n");
|
|
val = hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG);
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
|
|
index 07a1e7ed734b..e04488bb7278 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
|
|
@@ -192,6 +192,7 @@ enum HLCGE_PORT_TYPE {
|
|
#define HCLGE_VECTOR0_IMP_CMDQ_ERR_B 4U
|
|
#define HCLGE_VECTOR0_IMP_RD_POISON_B 5U
|
|
#define HCLGE_VECTOR0_ALL_MSIX_ERR_B 6U
|
|
+#define HCLGE_TRIGGER_IMP_RESET_B 7U
|
|
|
|
#define HCLGE_MAC_DEFAULT_FRAME \
|
|
(ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN + ETH_DATA_LEN)
|
|
--
|
|
2.34.1
|
|
|