kernel/patches/0617-net-hns3-add-supports-pfc-storm-detection-and-suppre.patch
2023-11-17 14:19:46 +08:00

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,
+ &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,
+ &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