summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorLang Cheng <chenglang@huawei.com>2019-08-21 09:14:33 -0400
committerDoug Ledford <dledford@redhat.com>2019-08-28 11:57:26 -0400
commite075da5e7c47ee1c20b4e8f9a20c6105be99b10f (patch)
tree591799255fd4e84048f6bada5fa7ce24934703c4 /drivers/infiniband/hw
parentbfe860351e31e71913d4e6c46aae5724b661a519 (diff)
RDMA/hns: Add reset process for function-clear
If the hardware is resetting, the driver should not perform the mailbox operation.Function-clear needs to add relevant judgment. Signed-off-by: Lang Cheng <chenglang@huawei.com> Link: https://lore.kernel.org/r/1566393276-42555-7-git-send-email-oulijun@huawei.com Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.c98
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.h2
2 files changed, 98 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 77309832100a..ecd0283f98c2 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -1125,26 +1125,118 @@ static int hns_roce_cmq_query_hw_info(struct hns_roce_dev *hr_dev)
1125 return 0; 1125 return 0;
1126} 1126}
1127 1127
1128static bool hns_roce_func_clr_chk_rst(struct hns_roce_dev *hr_dev)
1129{
1130 struct hns_roce_v2_priv *priv = (struct hns_roce_v2_priv *)hr_dev->priv;
1131 struct hnae3_handle *handle = priv->handle;
1132 const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
1133 unsigned long reset_cnt;
1134 bool sw_resetting;
1135 bool hw_resetting;
1136
1137 reset_cnt = ops->ae_dev_reset_cnt(handle);
1138 hw_resetting = ops->get_hw_reset_stat(handle);
1139 sw_resetting = ops->ae_dev_resetting(handle);
1140
1141 if (reset_cnt != hr_dev->reset_cnt || hw_resetting || sw_resetting)
1142 return true;
1143
1144 return false;
1145}
1146
1147static void hns_roce_func_clr_rst_prc(struct hns_roce_dev *hr_dev, int retval,
1148 int flag)
1149{
1150 struct hns_roce_v2_priv *priv = (struct hns_roce_v2_priv *)hr_dev->priv;
1151 struct hnae3_handle *handle = priv->handle;
1152 const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
1153 unsigned long instance_stage;
1154 unsigned long reset_cnt;
1155 unsigned long end;
1156 bool sw_resetting;
1157 bool hw_resetting;
1158
1159 instance_stage = handle->rinfo.instance_state;
1160 reset_cnt = ops->ae_dev_reset_cnt(handle);
1161 hw_resetting = ops->get_hw_reset_stat(handle);
1162 sw_resetting = ops->ae_dev_resetting(handle);
1163
1164 if (reset_cnt != hr_dev->reset_cnt) {
1165 hr_dev->dis_db = true;
1166 hr_dev->is_reset = true;
1167 dev_info(hr_dev->dev, "Func clear success after reset.\n");
1168 } else if (hw_resetting) {
1169 hr_dev->dis_db = true;
1170
1171 dev_warn(hr_dev->dev,
1172 "Func clear is pending, device in resetting state.\n");
1173 end = HNS_ROCE_V2_HW_RST_TIMEOUT;
1174 while (end) {
1175 if (!ops->get_hw_reset_stat(handle)) {
1176 hr_dev->is_reset = true;
1177 dev_info(hr_dev->dev,
1178 "Func clear success after reset.\n");
1179 return;
1180 }
1181 msleep(HNS_ROCE_V2_HW_RST_COMPLETION_WAIT);
1182 end -= HNS_ROCE_V2_HW_RST_COMPLETION_WAIT;
1183 }
1184
1185 dev_warn(hr_dev->dev, "Func clear failed.\n");
1186 } else if (sw_resetting && instance_stage == HNS_ROCE_STATE_INIT) {
1187 hr_dev->dis_db = true;
1188
1189 dev_warn(hr_dev->dev,
1190 "Func clear is pending, device in resetting state.\n");
1191 end = HNS_ROCE_V2_HW_RST_TIMEOUT;
1192 while (end) {
1193 if (ops->ae_dev_reset_cnt(handle) !=
1194 hr_dev->reset_cnt) {
1195 hr_dev->is_reset = true;
1196 dev_info(hr_dev->dev,
1197 "Func clear success after sw reset\n");
1198 return;
1199 }
1200 msleep(HNS_ROCE_V2_HW_RST_COMPLETION_WAIT);
1201 end -= HNS_ROCE_V2_HW_RST_COMPLETION_WAIT;
1202 }
1203
1204 dev_warn(hr_dev->dev, "Func clear failed because of unfinished sw reset\n");
1205 } else {
1206 if (retval && !flag)
1207 dev_warn(hr_dev->dev,
1208 "Func clear read failed, ret = %d.\n", retval);
1209
1210 dev_warn(hr_dev->dev, "Func clear failed.\n");
1211 }
1212}
1128static void hns_roce_function_clear(struct hns_roce_dev *hr_dev) 1213static void hns_roce_function_clear(struct hns_roce_dev *hr_dev)
1129{ 1214{
1215 bool fclr_write_fail_flag = false;
1130 struct hns_roce_func_clear *resp; 1216 struct hns_roce_func_clear *resp;
1131 struct hns_roce_cmq_desc desc; 1217 struct hns_roce_cmq_desc desc;
1132 unsigned long end; 1218 unsigned long end;
1133 int ret; 1219 int ret = 0;
1220
1221 if (hns_roce_func_clr_chk_rst(hr_dev))
1222 goto out;
1134 1223
1135 hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_FUNC_CLEAR, false); 1224 hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_FUNC_CLEAR, false);
1136 resp = (struct hns_roce_func_clear *)desc.data; 1225 resp = (struct hns_roce_func_clear *)desc.data;
1137 1226
1138 ret = hns_roce_cmq_send(hr_dev, &desc, 1); 1227 ret = hns_roce_cmq_send(hr_dev, &desc, 1);
1139 if (ret) { 1228 if (ret) {
1229 fclr_write_fail_flag = true;
1140 dev_err(hr_dev->dev, "Func clear write failed, ret = %d.\n", 1230 dev_err(hr_dev->dev, "Func clear write failed, ret = %d.\n",
1141 ret); 1231 ret);
1142 return; 1232 goto out;
1143 } 1233 }
1144 1234
1145 msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_INTERVAL); 1235 msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_INTERVAL);
1146 end = HNS_ROCE_V2_FUNC_CLEAR_TIMEOUT_MSECS; 1236 end = HNS_ROCE_V2_FUNC_CLEAR_TIMEOUT_MSECS;
1147 while (end) { 1237 while (end) {
1238 if (hns_roce_func_clr_chk_rst(hr_dev))
1239 goto out;
1148 msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT); 1240 msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT);
1149 end -= HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT; 1241 end -= HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT;
1150 1242
@@ -1161,7 +1253,9 @@ static void hns_roce_function_clear(struct hns_roce_dev *hr_dev)
1161 } 1253 }
1162 } 1254 }
1163 1255
1256out:
1164 dev_err(hr_dev->dev, "Func clear fail.\n"); 1257 dev_err(hr_dev->dev, "Func clear fail.\n");
1258 hns_roce_func_clr_rst_prc(hr_dev, ret, fclr_write_fail_flag);
1165} 1259}
1166 1260
1167static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev) 1261static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 1301629769ed..43219d2f7de0 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -99,6 +99,8 @@
99#define HNS_ROCE_V2_HW_RST_TIMEOUT 1000 99#define HNS_ROCE_V2_HW_RST_TIMEOUT 1000
100#define HNS_ROCE_V2_HW_RST_UNINT_DELAY 100 100#define HNS_ROCE_V2_HW_RST_UNINT_DELAY 100
101 101
102#define HNS_ROCE_V2_HW_RST_COMPLETION_WAIT 20
103
102#define HNS_ROCE_CONTEXT_HOP_NUM 1 104#define HNS_ROCE_CONTEXT_HOP_NUM 1
103#define HNS_ROCE_SCCC_HOP_NUM 1 105#define HNS_ROCE_SCCC_HOP_NUM 1
104#define HNS_ROCE_MTT_HOP_NUM 1 106#define HNS_ROCE_MTT_HOP_NUM 1