From bdb17a497df12e7315c56647305899cf194db751 Mon Sep 17 00:00:00 2001 From: shaojijie Date: Thu, 16 Mar 2023 16:00:17 +0800 Subject: [PATCH 194/283] net: hns3: add supports fast reporting of faulty nodes driver inclusion category: feature bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EN3D CVE: NA ---------------------------------------------------------------------- Services are switched only when no response is received within 10 seconds. As a result, services cannot be switched quickly. Therefore, if the chip is not suspended, the NIC sends a specific message to notify other nodes of the event. In this way, the service switchover is performed quickly. Signed-off-by: shaojijie Signed-off-by: Tian Jiang Signed-off-by: Jiantao Xiao Signed-off-by: Xiaodong Li Conflicts: drivers/net/ethernet/hisilicon/hns3/hnae3.h drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c 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 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 5 + .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 16 +++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 3 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 98 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 29 ++++++ .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + 8 files changed, 154 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 970ef08ce9cc..838bb4956ee4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -103,6 +103,8 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_CQ_B, HNAE3_DEV_SUPPORT_LANE_NUM_B, HNAE3_DEV_SUPPORT_WOL_B, + HNAE3_DEV_SUPPORT_VF_FAULT_B, + HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, }; #define hnae3_ae_dev_fd_supported(ae_dev) \ @@ -174,6 +176,9 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_wol_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) +#define hnae3_ae_dev_notify_pkt_supported(ae_dev) \ + test_bit(HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, (ae_dev)->caps) + enum HNAE3_PF_CAP_BITS { HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index a899b4c535dd..2cb06661bef9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -154,6 +154,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_FD_B, HNAE3_DEV_SUPPORT_FD_B}, {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, + {HCLGE_COMM_CAP_NOTIFY_PKT_B, HNAE3_DEV_SUPPORT_NOTIFY_PKT_B}, }; static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index 13562209f74d..05b8252c2522 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -97,6 +97,7 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_FD_B = 21, HCLGE_COMM_CAP_LANE_NUM_B = 27, HCLGE_COMM_CAP_WOL_B = 28, + HCLGE_COMM_CAP_NOTIFY_PKT_B = 29, }; enum HCLGE_COMM_API_CAP_BITS { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 4af709b1dc40..08ef05d76b57 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -170,3 +170,19 @@ int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask) return ret; } EXPORT_SYMBOL(nic_set_cpu_affinity); + +int nic_set_notify_pkt_param(struct net_device *ndev, + struct hnae3_notify_pkt_param *param) +{ + return nic_invoke_pri_ops(ndev, HNAE3_EXT_OPC_SET_NOTIFY_PARAM, + param, sizeof(*param)); +} +EXPORT_SYMBOL(nic_set_notify_pkt_param); + +int nic_set_notify_pkt_start(struct net_device *ndev) +{ + return nic_invoke_pri_ops(ndev, + HNAE3_EXT_OPC_SET_NOTIFY_START, + NULL, 0); +} +EXPORT_SYMBOL(nic_set_notify_pkt_start); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h index c0d943050922..ec661b400f20 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -12,4 +12,7 @@ void nic_chip_recover_handler(struct net_device *ndev, enum hnae3_event_type_custom event_t); int nic_clean_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); int nic_set_cpu_affinity(struct net_device *ndev, cpumask_t *affinity_mask); +int nic_set_notify_pkt_param(struct net_device *ndev, + struct hnae3_notify_pkt_param *param); +int nic_set_notify_pkt_start(struct net_device *ndev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c index a79451ef44d0..ba612b21a8ee 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -33,6 +33,101 @@ static int hclge_clean_stats64(struct hclge_dev *hdev, void *data, return 0; } +static int hclge_notify_packet_para_cmd_send(struct hclge_dev *hdev, + struct hclge_notify_pkt_param_cmd *param_cmd) +{ +#define HCLGE_NOTIFY_PKT_DESC_NUM 4 + + struct hclge_desc desc[HCLGE_NOTIFY_PKT_DESC_NUM]; + u32 i, desc_data_len; + + desc_data_len = ARRAY_SIZE(desc[0].data); + for (i = 0; i < HCLGE_NOTIFY_PKT_DESC_NUM; i++) { + hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_SET_NOTIFY_PKT, + false); + if (i != HCLGE_NOTIFY_PKT_DESC_NUM - 1) + desc[i].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); + } + + for (i = 0; i < HCLGE_NOTIFY_PKT_DESC_NUM * desc_data_len; i++) + desc[i / desc_data_len].data[i % desc_data_len] = + *((__le32 *)param_cmd + i); + + return hclge_cmd_send(&hdev->hw, desc, HCLGE_NOTIFY_PKT_DESC_NUM); +} + +static int hclge_set_notify_packet_para(struct hclge_dev *hdev, + void *data, size_t length) +{ + struct hnae3_notify_pkt_param *param = (struct hnae3_notify_pkt_param *)data; + struct hclge_notify_pkt_param_cmd param_cmd; + u32 i, pkt_cfg = 0; + int ret; + + if (length != sizeof(struct hnae3_notify_pkt_param)) + return -EINVAL; + + if (!hnae3_ae_dev_notify_pkt_supported(hdev->ae_dev)) + return -EOPNOTSUPP; + + if (param->enable) + pkt_cfg = HCLGE_NOTIFY_PARA_CFG_PKT_EN; + hnae3_set_field(pkt_cfg, HCLGE_NOTIFY_PARA_CFG_PKT_NUM_M, + HCLGE_NOTIFY_PARA_CFG_PKT_NUM_S, param->num); + + param_cmd.cfg = cpu_to_le32(pkt_cfg); + param_cmd.ipg = cpu_to_le32(param->ipg); + for (i = 0; i < ARRAY_SIZE(param_cmd.data); i++) + param_cmd.data[i] = cpu_to_le32(*((u32 *)param->data + i)); + + hnae3_set_bit(param_cmd.vld_cfg, 0, 1); + hnae3_set_bit(param_cmd.vld_ipg, 0, 1); + hnae3_set_bit(param_cmd.vld_data, 0, 1); + + ret = hclge_notify_packet_para_cmd_send(hdev, ¶m_cmd); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to set notify packet content, ret = %d\n", ret); + return ret; + } + + param->init = 1; + memcpy(&hdev->notify_param, param, sizeof(*param)); + return 0; +} + +static int hclge_set_notify_packet_start(struct hclge_dev *hdev, + void *data, size_t length) +{ + u32 pkt_cfg = HCLGE_NOTIFY_PARA_CFG_START_EN; + struct hclge_notify_pkt_param_cmd param_cmd; + int ret; + + if (!hnae3_ae_dev_notify_pkt_supported(hdev->ae_dev)) + return -EOPNOTSUPP; + + memset(¶m_cmd, 0, sizeof(param_cmd)); + param_cmd.cfg = cpu_to_le32(pkt_cfg); + hnae3_set_bit(param_cmd.vld_cfg, 0, 1); + + ret = hclge_notify_packet_para_cmd_send(hdev, ¶m_cmd); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to send notify packet, ret = %d\n", ret); + return ret; +} + +static void hclge_ext_resotre_config(struct hclge_dev *hdev) +{ + if (hdev->reset_type != HNAE3_IMP_RESET && + hdev->reset_type != HNAE3_GLOBAL_RESET) + return; + + if (hdev->notify_param.init) + hclge_set_notify_packet_para(hdev, &hdev->notify_param, + sizeof(hdev->notify_param)); +} + static int hclge_set_reset_task(struct hclge_dev *hdev, void *data, size_t length) { @@ -162,6 +257,7 @@ void hclge_ext_reset_end(struct hclge_dev *hdev, bool done) return; } + hclge_ext_resotre_config(hdev); hclge_ext_call_event(hdev, HNAE3_RESET_DONE_CUSTOM); dev_info(&hdev->pdev->dev, "report reset done!\n"); } @@ -170,6 +266,8 @@ 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_CLEAN_STATS64] = hclge_clean_stats64, + [HNAE3_EXT_OPC_SET_NOTIFY_PARAM] = hclge_set_notify_packet_para, + [HNAE3_EXT_OPC_SET_NOTIFY_START] = hclge_set_notify_packet_start, }; 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..ce8fc17741fc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -5,6 +5,35 @@ #define __HCLGE_EXT_H #include +#define HCLGE_NOTIFY_PARA_CFG_PKT_EN BIT(0) +#define HCLGE_NOTIFY_PARA_CFG_START_EN BIT(1) +#define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_M GENMASK(5, 2) +#define HCLGE_NOTIFY_PARA_CFG_PKT_NUM_S 2 + +struct hclge_pfc_storm_para_cmd { + __le32 dir; + __le32 enable; + __le32 period_ms; + __le32 times; + __le32 recovery_period_ms; + __le32 rsv; +}; + +struct hclge_notify_pkt_param_cmd { + __le32 cfg; + __le32 ipg; + __le32 data[16]; + u8 vld_cfg; + u8 vld_ipg; + u8 vld_data; + u8 rsv[21]; +}; + +enum hclge_ext_opcode_type { + HCLGE_OPC_SET_NOTIFY_PKT = 0x180A, + 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; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index f32c8b52f022..647b0ca14e1c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -943,6 +943,7 @@ struct hclge_dev { cpumask_t affinity_mask; struct irq_affinity_notify affinity_notify; struct hclge_ptp *ptp; + struct hnae3_notify_pkt_param notify_param; }; /* VPort level vlan tag configuration for TX direction */ -- 2.34.1