aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.c44
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.h17
2 files changed, 61 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index e7024b3e171a..5c8551b54444 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -1130,6 +1130,47 @@ static int hns_roce_cmq_query_hw_info(struct hns_roce_dev *hr_dev)
1130 return 0; 1130 return 0;
1131} 1131}
1132 1132
1133static void hns_roce_function_clear(struct hns_roce_dev *hr_dev)
1134{
1135 bool fclr_write_fail_flag = false;
1136 struct hns_roce_func_clear *resp;
1137 struct hns_roce_cmq_desc desc;
1138 unsigned long end;
1139 int ret;
1140
1141 hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_FUNC_CLEAR, false);
1142 resp = (struct hns_roce_func_clear *)desc.data;
1143
1144 ret = hns_roce_cmq_send(hr_dev, &desc, 1);
1145 if (ret) {
1146 fclr_write_fail_flag = true;
1147 dev_err(hr_dev->dev, "Func clear write failed, ret = %d.\n",
1148 ret);
1149 return;
1150 }
1151
1152 msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_INTERVAL);
1153 end = HNS_ROCE_V2_FUNC_CLEAR_TIMEOUT_MSECS;
1154 while (end) {
1155 msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT);
1156 end -= HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT;
1157
1158 hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_FUNC_CLEAR,
1159 true);
1160
1161 ret = hns_roce_cmq_send(hr_dev, &desc, 1);
1162 if (ret)
1163 continue;
1164
1165 if (roce_get_bit(resp->func_done, FUNC_CLEAR_RST_FUN_DONE_S)) {
1166 hr_dev->is_reset = true;
1167 return;
1168 }
1169 }
1170
1171 dev_err(hr_dev->dev, "Func clear fail.\n");
1172}
1173
1133static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev) 1174static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev)
1134{ 1175{
1135 struct hns_roce_query_fw_info *resp; 1176 struct hns_roce_query_fw_info *resp;
@@ -1894,6 +1935,9 @@ static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev)
1894{ 1935{
1895 struct hns_roce_v2_priv *priv = hr_dev->priv; 1936 struct hns_roce_v2_priv *priv = hr_dev->priv;
1896 1937
1938 if (hr_dev->pci_dev->revision == 0x21)
1939 hns_roce_function_clear(hr_dev);
1940
1897 hns_roce_free_link_table(hr_dev, &priv->tpq); 1941 hns_roce_free_link_table(hr_dev, &priv->tpq);
1898 hns_roce_free_link_table(hr_dev, &priv->tsq); 1942 hns_roce_free_link_table(hr_dev, &priv->tsq);
1899} 1943}
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index bce21fd2ebb6..478f5a5b7aa1 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -241,6 +241,7 @@ enum hns_roce_opcode_type {
241 HNS_ROCE_OPC_POST_MB = 0x8504, 241 HNS_ROCE_OPC_POST_MB = 0x8504,
242 HNS_ROCE_OPC_QUERY_MB_ST = 0x8505, 242 HNS_ROCE_OPC_QUERY_MB_ST = 0x8505,
243 HNS_ROCE_OPC_CFG_BT_ATTR = 0x8506, 243 HNS_ROCE_OPC_CFG_BT_ATTR = 0x8506,
244 HNS_ROCE_OPC_FUNC_CLEAR = 0x8508,
244 HNS_ROCE_OPC_CLR_SCCC = 0x8509, 245 HNS_ROCE_OPC_CLR_SCCC = 0x8509,
245 HNS_ROCE_OPC_QUERY_SCCC = 0x850a, 246 HNS_ROCE_OPC_QUERY_SCCC = 0x850a,
246 HNS_ROCE_OPC_RESET_SCCC = 0x850b, 247 HNS_ROCE_OPC_RESET_SCCC = 0x850b,
@@ -1230,6 +1231,22 @@ struct hns_roce_query_fw_info {
1230 __le32 rsv[5]; 1231 __le32 rsv[5];
1231}; 1232};
1232 1233
1234struct hns_roce_func_clear {
1235 __le32 rst_funcid_en;
1236 __le32 func_done;
1237 __le32 rsv[4];
1238};
1239
1240#define FUNC_CLEAR_RST_FUN_DONE_S 0
1241/* Each physical function manages up to 248 virtual functions;
1242 * it takes up to 100ms for each function to execute clear;
1243 * if an abnormal reset occurs, it is executed twice at most;
1244 * so it takes up to 249 * 2 * 100ms.
1245 */
1246#define HNS_ROCE_V2_FUNC_CLEAR_TIMEOUT_MSECS (249 * 2 * 100)
1247#define HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_INTERVAL 40
1248#define HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT 20
1249
1233struct hns_roce_cfg_llm_a { 1250struct hns_roce_cfg_llm_a {
1234 __le32 base_addr_l; 1251 __le32 base_addr_l;
1235 __le32 base_addr_h; 1252 __le32 base_addr_h;