From: shaojijie shaojijie@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I94FVZ 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 shaojijie@huawei.com Signed-off-by: Jiantao Xiao xiaojiantao1@h-partners.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 4 + .../net/ethernet/hisilicon/hns3/hnae3_ext.h | 10 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 1 + .../net/ethernet/hisilicon/hns3/hns3_ext.c | 14 +++ .../net/ethernet/hisilicon/hns3/hns3_ext.h | 3 + .../hisilicon/hns3/hns3pf/hclge_ext.c | 98 +++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_ext.h | 16 +++ .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + 9 files changed, 148 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 9b98dea8a590..a9f675b64d18 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -104,6 +104,7 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_WOL_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B, HNAE3_DEV_SUPPORT_VF_FAULT_B, + HNAE3_DEV_SUPPORT_NOTIFY_PKT_B, };
#define hnae3_ae_dev_fd_supported(ae_dev) \ @@ -181,6 +182,9 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_vf_fault_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_VF_FAULT_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/hnae3_ext.h b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h index 769b85e0d072..274a79414f47 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3_ext.h @@ -31,6 +31,8 @@ enum hnae3_ext_opcode { HNAE3_EXT_OPC_EVENT_CALLBACK, HNAE3_EXT_OPC_GET_PFC_STORM_PARA, HNAE3_EXT_OPC_SET_PFC_STORM_PARA, + HNAE3_EXT_OPC_SET_NOTIFY_PARAM, + HNAE3_EXT_OPC_SET_NOTIFY_START, };
struct hnae3_pfc_storm_para { @@ -40,4 +42,12 @@ struct hnae3_pfc_storm_para { u32 times; u32 recovery_period_ms; }; + +struct hnae3_notify_pkt_param { + u32 ipg; /* inter-packet gap of sending, the unit is one cycle of clock */ + u16 num; /* packet number of sending */ + u8 enable; /* send enable, 0=Disable, 1=Enable */ + u8 init; /* initialization flag, product does not need to set value */ + u8 data[64]; /* note packet data */ +}; #endif 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 d92ad6082d8e..e629b1483a42 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 @@ -158,6 +158,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, {HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B}, {HCLGE_COMM_CAP_VF_FAULT_B, HNAE3_DEV_SUPPORT_VF_FAULT_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 533c19d25e4f..cbc5f8fc8788 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 @@ -352,6 +352,7 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_VF_FAULT_B = 26, HCLGE_COMM_CAP_LANE_NUM_B = 27, HCLGE_COMM_CAP_WOL_B = 28, + HCLGE_COMM_CAP_NOTIFY_PKT_B = 29, HCLGE_COMM_CAP_TM_FLUSH_B = 31, };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c index 0369a6029d30..5b7183daba4c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.c @@ -143,3 +143,17 @@ int nic_get_pfc_storm_para(struct net_device *ndev, u32 dir, u32 *enable, return 0; } EXPORT_SYMBOL(nic_get_pfc_storm_para); + +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 a0feac3cfc13..d75fd9fecef1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ext.h @@ -21,4 +21,7 @@ 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); +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 8451b446f6d6..80f0bb0d738c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.c @@ -73,6 +73,101 @@ static int hclge_get_pfc_storm_para(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) { @@ -203,6 +298,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"); } @@ -212,6 +308,8 @@ static const hclge_priv_ops_fn hclge_ext_func_arr[] = { [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, + [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 d87d6bb0e4c5..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,11 @@ #define __HCLGE_EXT_H #include <linux/types.h>
+#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; @@ -14,7 +19,18 @@ struct hclge_pfc_storm_para_cmd { __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, };
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index e96f049df20f..18c3c4ff9ba6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -974,6 +974,7 @@ struct hclge_dev { struct hclge_ptp *ptp; struct devlink *devlink; struct hclge_comm_rss_cfg rss_cfg; + struct hnae3_notify_pkt_param notify_param; };
/* VPort level vlan tag configuration for TX direction */