From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ 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: shaojijie shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 10 +++ .../net/ethernet/hisilicon/hns3/hns3_ext.c | 70 +++++++++++++++++++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 11 +++ .../hisilicon/hns3/hns3pf/hclge_ext.c | 60 ++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 13 ++++ 5 files changed, 164 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index f2ffc6f1b989..769b85e0d072 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -29,5 +29,15 @@ enum hnae3_event_type_custom { enum hnae3_ext_opcode { HNAE3_EXT_OPC_RESET, HNAE3_EXT_OPC_EVENT_CALLBACK, + HNAE3_EXT_OPC_GET_PFC_STORM_PARA, + HNAE3_EXT_OPC_SET_PFC_STORM_PARA, +}; + +struct hnae3_pfc_storm_para { + u32 dir; + u32 enable; + u32 period_ms; + u32 times; + u32 recovery_period_ms; }; #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index d8264b6e48b4..0369a6029d30 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -73,3 +73,73 @@ void nic_chip_recover_handler(struct net_device *ndev, nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_RESET, &event_t, sizeof(event_t)); } EXPORT_SYMBOL(nic_chip_recover_handler); + +static int nic_check_pfc_storm_para(u32 dir, u32 enable, u32 period_ms, + u32 times, u32 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, u32 dir, u32 enable, + u32 period_ms, u32 times, u32 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, u32 dir, u32 *enable, + u32 *period_ms, u32 *times, u32 *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); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index ce92a666db17..a0feac3cfc13 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -7,7 +7,18 @@ #include "hns3_enet.h" #include "hnae3_ext.h"
+#define HNS3_PFC_STORM_PARA_DIR_RX 0 +#define HNS3_PFC_STORM_PARA_DIR_TX 1 +#define HNS3_PFC_STORM_PARA_DISABLE 0 +#define HNS3_PFC_STORM_PARA_ENABLE 1 +#define HNS3_PFC_STORM_PARA_PERIOD_MIN 5 +#define HNS3_PFC_STORM_PARA_PERIOD_MAX 2000 + int nic_netdev_match_check(struct net_device *netdev); void nic_chip_recover_handler(struct net_device *ndev, enum hnae3_event_type_custom event_t); +int nic_set_pfc_storm_para(struct net_device *ndev, u32 dir, u32 enable, + u32 period_ms, u32 times, u32 recovery_period_ms); +int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, + u32 *period_ms, u32 *times, u32 *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 e6b8b6acb025..8451b446f6d6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -15,6 +15,64 @@ static nic_event_fn_t nic_event_call; */ static DEFINE_MUTEX(hclge_nic_event_lock);
+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) { @@ -152,6 +210,8 @@ void hclge_ext_reset_end(struct hclge_dev *hdev, bool done) static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [HNAE3_EXT_OPC_RESET] = hclge_set_reset_task, [HNAE3_EXT_OPC_EVENT_CALLBACK] = hclge_nic_call_event, + [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, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h index 1c1b04765e7e..d87d6bb0e4c5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -5,6 +5,19 @@ #define __HCLGE_EXT_H #include <linux/types.h>
+struct hclge_pfc_storm_para_cmd { + __le32 dir; + __le32 enable; + __le32 period_ms; + __le32 times; + __le32 recovery_period_ms; + __le32 rsv; +}; + +enum hclge_ext_opcode_type { + HCLGE_OPC_CFG_PAUSE_STORM_PARA = 0x7019, +}; + struct hclge_reset_fail_type_map { enum hnae3_reset_type reset_type; enum hnae3_event_type_custom custom_type;