1c50de4afSAya Levin // SPDX-License-Identifier: GPL-2.0 2c50de4afSAya Levin // Copyright (c) 2019 Mellanox Technologies. 3c50de4afSAya Levin 4c50de4afSAya Levin #include "health.h" 5c50de4afSAya Levin #include "lib/eq.h" 6c50de4afSAya Levin 7c50de4afSAya Levin int mlx5e_health_sq_to_ready(struct mlx5e_channel *channel, u32 sqn) 8c50de4afSAya Levin { 9c50de4afSAya Levin struct mlx5_core_dev *mdev = channel->mdev; 10c50de4afSAya Levin struct net_device *dev = channel->netdev; 11c50de4afSAya Levin struct mlx5e_modify_sq_param msp = {}; 12c50de4afSAya Levin int err; 13c50de4afSAya Levin 14c50de4afSAya Levin msp.curr_state = MLX5_SQC_STATE_ERR; 15c50de4afSAya Levin msp.next_state = MLX5_SQC_STATE_RST; 16c50de4afSAya Levin 17c50de4afSAya Levin err = mlx5e_modify_sq(mdev, sqn, &msp); 18c50de4afSAya Levin if (err) { 19c50de4afSAya Levin netdev_err(dev, "Failed to move sq 0x%x to reset\n", sqn); 20c50de4afSAya Levin return err; 21c50de4afSAya Levin } 22c50de4afSAya Levin 23c50de4afSAya Levin memset(&msp, 0, sizeof(msp)); 24c50de4afSAya Levin msp.curr_state = MLX5_SQC_STATE_RST; 25c50de4afSAya Levin msp.next_state = MLX5_SQC_STATE_RDY; 26c50de4afSAya Levin 27c50de4afSAya Levin err = mlx5e_modify_sq(mdev, sqn, &msp); 28c50de4afSAya Levin if (err) { 29c50de4afSAya Levin netdev_err(dev, "Failed to move sq 0x%x to ready\n", sqn); 30c50de4afSAya Levin return err; 31c50de4afSAya Levin } 32c50de4afSAya Levin 33c50de4afSAya Levin return 0; 34c50de4afSAya Levin } 35c50de4afSAya Levin 36c50de4afSAya Levin int mlx5e_health_recover_channels(struct mlx5e_priv *priv) 37c50de4afSAya Levin { 38c50de4afSAya Levin int err = 0; 39c50de4afSAya Levin 40c50de4afSAya Levin rtnl_lock(); 41c50de4afSAya Levin mutex_lock(&priv->state_lock); 42c50de4afSAya Levin 43c50de4afSAya Levin if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) 44c50de4afSAya Levin goto out; 45c50de4afSAya Levin 46c50de4afSAya Levin err = mlx5e_safe_reopen_channels(priv); 47c50de4afSAya Levin 48c50de4afSAya Levin out: 49c50de4afSAya Levin mutex_unlock(&priv->state_lock); 50c50de4afSAya Levin rtnl_unlock(); 51c50de4afSAya Levin 52c50de4afSAya Levin return err; 53c50de4afSAya Levin } 54c50de4afSAya Levin 55c50de4afSAya Levin int mlx5e_health_channel_eq_recover(struct mlx5_eq_comp *eq, struct mlx5e_channel *channel) 56c50de4afSAya Levin { 57c50de4afSAya Levin u32 eqe_count; 58c50de4afSAya Levin 59c50de4afSAya Levin netdev_err(channel->netdev, "EQ 0x%x: Cons = 0x%x, irqn = 0x%x\n", 60c50de4afSAya Levin eq->core.eqn, eq->core.cons_index, eq->core.irqn); 61c50de4afSAya Levin 62c50de4afSAya Levin eqe_count = mlx5_eq_poll_irq_disabled(eq); 63c50de4afSAya Levin if (!eqe_count) 64c50de4afSAya Levin return -EIO; 65c50de4afSAya Levin 66c50de4afSAya Levin netdev_err(channel->netdev, "Recovered %d eqes on EQ 0x%x\n", 67c50de4afSAya Levin eqe_count, eq->core.eqn); 68c50de4afSAya Levin 69c50de4afSAya Levin channel->stats->eq_rearm++; 70c50de4afSAya Levin return 0; 71c50de4afSAya Levin } 72c50de4afSAya Levin 73c50de4afSAya Levin int mlx5e_health_report(struct mlx5e_priv *priv, 74c50de4afSAya Levin struct devlink_health_reporter *reporter, char *err_str, 75c50de4afSAya Levin struct mlx5e_err_ctx *err_ctx) 76c50de4afSAya Levin { 77c50de4afSAya Levin if (!reporter) { 78c50de4afSAya Levin netdev_err(priv->netdev, err_str); 79c50de4afSAya Levin return err_ctx->recover(&err_ctx->ctx); 80c50de4afSAya Levin } 81c50de4afSAya Levin return devlink_health_report(reporter, err_str, err_ctx); 82c50de4afSAya Levin } 83