|
@@ -250,7 +250,7 @@ int mlx5_cmd_force_teardown_hca(struct mlx5_core_dev *dev)
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- force_state = MLX5_GET(teardown_hca_out, out, force_state);
|
|
|
+ force_state = MLX5_GET(teardown_hca_out, out, state);
|
|
|
if (force_state == MLX5_TEARDOWN_HCA_OUT_FORCE_STATE_FAIL) {
|
|
|
mlx5_core_warn(dev, "teardown with force mode failed, doing normal teardown\n");
|
|
|
return -EIO;
|
|
@@ -259,6 +259,54 @@ int mlx5_cmd_force_teardown_hca(struct mlx5_core_dev *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+#define MLX5_FAST_TEARDOWN_WAIT_MS 3000
|
|
|
+int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev)
|
|
|
+{
|
|
|
+ unsigned long end, delay_ms = MLX5_FAST_TEARDOWN_WAIT_MS;
|
|
|
+ u32 out[MLX5_ST_SZ_DW(teardown_hca_out)] = {0};
|
|
|
+ u32 in[MLX5_ST_SZ_DW(teardown_hca_in)] = {0};
|
|
|
+ int state;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!MLX5_CAP_GEN(dev, fast_teardown)) {
|
|
|
+ mlx5_core_dbg(dev, "fast teardown is not supported in the firmware\n");
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ }
|
|
|
+
|
|
|
+ MLX5_SET(teardown_hca_in, in, opcode, MLX5_CMD_OP_TEARDOWN_HCA);
|
|
|
+ MLX5_SET(teardown_hca_in, in, profile,
|
|
|
+ MLX5_TEARDOWN_HCA_IN_PROFILE_PREPARE_FAST_TEARDOWN);
|
|
|
+
|
|
|
+ ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ state = MLX5_GET(teardown_hca_out, out, state);
|
|
|
+ if (state == MLX5_TEARDOWN_HCA_OUT_FORCE_STATE_FAIL) {
|
|
|
+ mlx5_core_warn(dev, "teardown with fast mode failed\n");
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ mlx5_set_nic_state(dev, MLX5_NIC_IFC_DISABLED);
|
|
|
+
|
|
|
+ /* Loop until device state turns to disable */
|
|
|
+ end = jiffies + msecs_to_jiffies(delay_ms);
|
|
|
+ do {
|
|
|
+ if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED)
|
|
|
+ break;
|
|
|
+
|
|
|
+ cond_resched();
|
|
|
+ } while (!time_after(jiffies, end));
|
|
|
+
|
|
|
+ if (mlx5_get_nic_state(dev) != MLX5_NIC_IFC_DISABLED) {
|
|
|
+ dev_err(&dev->pdev->dev, "NIC IFC still %d after %lums.\n",
|
|
|
+ mlx5_get_nic_state(dev), delay_ms);
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
enum mlxsw_reg_mcc_instruction {
|
|
|
MLX5_REG_MCC_INSTRUCTION_LOCK_UPDATE_HANDLE = 0x01,
|
|
|
MLX5_REG_MCC_INSTRUCTION_RELEASE_UPDATE_HANDLE = 0x02,
|