211 lines
7.3 KiB
Diff
211 lines
7.3 KiB
Diff
From b863e1ccdb78ffba61a54078e45e5aabb4a45837 Mon Sep 17 00:00:00 2001
|
|
From: Tian Jiang <jiangtian6@h-partners.com>
|
|
Date: Thu, 16 Mar 2023 14:05:22 +0800
|
|
Subject: [PATCH 256/283] net: hns3: add supports pfc storm detection and
|
|
suppression
|
|
|
|
driver inclusion
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EN49
|
|
CVE: NA
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
To solve the problem of abnormal transmission of pauses or PFC frames,
|
|
the IMP periodically checks the transmission and reception status of
|
|
packets. If a pause frame storm occurs, the pause storm response of
|
|
the MAC address is disabled for a period of time.
|
|
|
|
Signed-off-by: Tian Jiang <jiangtian6@h-partners.com>
|
|
Signed-off-by: shaojijie <shaojijie@huawei.com>
|
|
Signed-off-by: Jiantao Xiao <xiaojiantao1@h-partners.com>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
|
|
Conflicts:
|
|
drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h
|
|
drivers/net/ethernet/hisilicon/hns3/hns3_ext.c
|
|
drivers/net/ethernet/hisilicon/hns3/hns3_ext.h
|
|
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c
|
|
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h
|
|
---
|
|
.../net/ethernet/hisilicon/hns3/hns3_ext.c | 70 +++++++++++++++++++
|
|
.../net/ethernet/hisilicon/hns3/hns3_ext.h | 4 ++
|
|
.../hisilicon/hns3/hns3pf/hclge_ext.c | 60 ++++++++++++++++
|
|
3 files changed, 134 insertions(+)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c
|
|
index 45189aaea9a3..e51a281844b9 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c
|
|
@@ -462,6 +462,76 @@ int nic_get_phy_reg(struct net_device *ndev, u32 page_select_addr,
|
|
}
|
|
EXPORT_SYMBOL(nic_get_phy_reg);
|
|
|
|
+static int nic_check_pfc_storm_para(int dir, int enable, int period_ms,
|
|
+ int times, int recovery_period_ms)
|
|
+{
|
|
+ if ((dir != HNS3_PFC_STORM_PARA_DIR_RX &&
|
|
+ dir != HNS3_PFC_STORM_PARA_DIR_TX) ||
|
|
+ (enable != HNS3_PFC_STORM_PARA_DISABLE &&
|
|
+ enable != HNS3_PFC_STORM_PARA_ENABLE))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (period_ms < HNS3_PFC_STORM_PARA_PERIOD_MIN ||
|
|
+ period_ms > HNS3_PFC_STORM_PARA_PERIOD_MAX ||
|
|
+ recovery_period_ms < HNS3_PFC_STORM_PARA_PERIOD_MIN ||
|
|
+ recovery_period_ms > HNS3_PFC_STORM_PARA_PERIOD_MAX ||
|
|
+ times <= 0)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int nic_set_pfc_storm_para(struct net_device *ndev, int dir, int enable,
|
|
+ int period_ms, int times, int recovery_period_ms)
|
|
+{
|
|
+ struct hnae3_pfc_storm_para para;
|
|
+
|
|
+ if (nic_check_pfc_storm_para(dir, enable, period_ms, times,
|
|
+ recovery_period_ms)) {
|
|
+ dev_err(&ndev->dev,
|
|
+ "set pfc storm para failed because invalid input param.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ para.dir = dir;
|
|
+ para.enable = enable;
|
|
+ para.period_ms = period_ms;
|
|
+ para.times = times;
|
|
+ para.recovery_period_ms = recovery_period_ms;
|
|
+
|
|
+ return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_PFC_STORM_PARA,
|
|
+ ¶, sizeof(para));
|
|
+}
|
|
+EXPORT_SYMBOL(nic_set_pfc_storm_para);
|
|
+
|
|
+int nic_get_pfc_storm_para(struct net_device *ndev, int dir, int *enable,
|
|
+ int *period_ms, int *times, int *recovery_period_ms)
|
|
+{
|
|
+ struct hnae3_pfc_storm_para para;
|
|
+ int ret;
|
|
+
|
|
+ if (!enable || !period_ms || !times || !recovery_period_ms ||
|
|
+ (dir != HNS3_PFC_STORM_PARA_DIR_RX &&
|
|
+ dir != HNS3_PFC_STORM_PARA_DIR_TX)) {
|
|
+ dev_err(&ndev->dev,
|
|
+ "get pfc storm para failed because invalid input param.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ para.dir = dir;
|
|
+ ret = nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_GET_PFC_STORM_PARA,
|
|
+ ¶, sizeof(para));
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ *enable = para.enable;
|
|
+ *period_ms = para.period_ms;
|
|
+ *times = para.times;
|
|
+ *recovery_period_ms = para.recovery_period_ms;
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(nic_get_pfc_storm_para);
|
|
+
|
|
int nic_set_phy_reg(struct net_device *ndev, u32 page_select_addr,
|
|
u16 page, u32 reg_addr, u16 data)
|
|
{
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h
|
|
index f883beae8bf4..b1e358173819 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h
|
|
@@ -70,4 +70,8 @@ int nic_get_phy_reg(struct net_device *ndev, u32 page_select_addr,
|
|
u16 page, u32 reg_addr, u16 *data);
|
|
int nic_set_phy_reg(struct net_device *ndev, u32 page_select_addr,
|
|
u16 page, u32 reg_addr, u16 data);
|
|
+int nic_set_pfc_storm_para(struct net_device *ndev, int dir, int enable,
|
|
+ int period_ms, int times, int recovery_period_ms);
|
|
+int nic_get_pfc_storm_para(struct net_device *ndev, int dir, int *enable,
|
|
+ int *period_ms, int *times, int *recovery_period_ms);
|
|
#endif
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c
|
|
index 4f93ad1ac62e..7b9d6d861b42 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c
|
|
@@ -1249,6 +1249,64 @@ static void hclge_ext_resotre_config(struct hclge_dev *hdev)
|
|
sizeof(hdev->torus_param));
|
|
}
|
|
|
|
+static int hclge_set_pfc_storm_para(struct hclge_dev *hdev, void *data,
|
|
+ size_t length)
|
|
+{
|
|
+ struct hclge_pfc_storm_para_cmd *para_cmd;
|
|
+ struct hnae3_pfc_storm_para *para;
|
|
+ struct hclge_desc desc;
|
|
+ int ret;
|
|
+
|
|
+ if (length != sizeof(struct hnae3_pfc_storm_para))
|
|
+ return -EINVAL;
|
|
+
|
|
+ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PAUSE_STORM_PARA,
|
|
+ false);
|
|
+ para = (struct hnae3_pfc_storm_para *)data;
|
|
+ para_cmd = (struct hclge_pfc_storm_para_cmd *)desc.data;
|
|
+ para_cmd->dir = cpu_to_le32(para->dir);
|
|
+ para_cmd->enable = cpu_to_le32(para->enable);
|
|
+ para_cmd->period_ms = cpu_to_le32(para->period_ms);
|
|
+ para_cmd->times = cpu_to_le32(para->times);
|
|
+ para_cmd->recovery_period_ms = cpu_to_le32(para->recovery_period_ms);
|
|
+
|
|
+ ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
|
+ if (ret)
|
|
+ dev_err(&hdev->pdev->dev,
|
|
+ "failed to set pfc storm para, ret = %d\n", ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int hclge_get_pfc_storm_para(struct hclge_dev *hdev, void *data,
|
|
+ size_t length)
|
|
+{
|
|
+ struct hclge_pfc_storm_para_cmd *para_cmd;
|
|
+ struct hnae3_pfc_storm_para *para;
|
|
+ struct hclge_desc desc;
|
|
+ int ret;
|
|
+
|
|
+ if (length != sizeof(struct hnae3_pfc_storm_para))
|
|
+ return -EINVAL;
|
|
+
|
|
+ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PAUSE_STORM_PARA, true);
|
|
+ para = (struct hnae3_pfc_storm_para *)data;
|
|
+ para_cmd = (struct hclge_pfc_storm_para_cmd *)desc.data;
|
|
+ para_cmd->dir = cpu_to_le32(para->dir);
|
|
+ ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
|
+ if (ret) {
|
|
+ dev_err(&hdev->pdev->dev,
|
|
+ "failed to get pfc storm para, ret = %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ para->enable = le32_to_cpu(para_cmd->enable);
|
|
+ para->period_ms = le32_to_cpu(para_cmd->period_ms);
|
|
+ para->times = le32_to_cpu(para_cmd->times);
|
|
+ para->recovery_period_ms = le32_to_cpu(para_cmd->recovery_period_ms);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int hclge_set_reset_task(struct hclge_dev *hdev, void *data,
|
|
size_t length)
|
|
{
|
|
@@ -1408,6 +1466,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = {
|
|
[HNAE3_EXT_OPC_GET_LED_SIGNAL] = hclge_get_led_signal,
|
|
[HNAE3_EXT_OPC_GET_PHY_REG] = hclge_get_phy_reg,
|
|
[HNAE3_EXT_OPC_SET_PHY_REG] = hclge_set_phy_reg,
|
|
+ [HNAE3_EXT_OPC_GET_PFC_STORM_PARA] = hclge_get_pfc_storm_para,
|
|
+ [HNAE3_EXT_OPC_SET_PFC_STORM_PARA] = hclge_set_pfc_storm_para,
|
|
};
|
|
|
|
int hclge_ext_ops_handle(struct hnae3_handle *handle, int opcode,
|
|
--
|
|
2.34.1
|
|
|