]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/net/ethernet/mellanox/mlx4/catas.c
mlx4: Add support for EEH error recovery
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / mellanox / mlx4 / catas.c
index 915e947b422d63888dfd65522b7d14a3fa4162ff..9c656fe4983dda7fbb10dd1b195bf12b2808c8e8 100644 (file)
@@ -69,16 +69,21 @@ static void poll_catas(unsigned long dev_ptr)
        struct mlx4_priv *priv = mlx4_priv(dev);
 
        if (readl(priv->catas_err.map)) {
-               dump_err_buf(dev);
-
-               mlx4_dispatch_event(dev, MLX4_DEV_EVENT_CATASTROPHIC_ERROR, 0);
+               /* If the device is off-line, we cannot try to recover it */
+               if (pci_channel_offline(dev->pdev))
+                       mod_timer(&priv->catas_err.timer,
+                                 round_jiffies(jiffies + MLX4_CATAS_POLL_INTERVAL));
+               else {
+                       dump_err_buf(dev);
+                       mlx4_dispatch_event(dev, MLX4_DEV_EVENT_CATASTROPHIC_ERROR, 0);
 
-               if (internal_err_reset) {
-                       spin_lock(&catas_lock);
-                       list_add(&priv->catas_err.list, &catas_list);
-                       spin_unlock(&catas_lock);
+                       if (internal_err_reset) {
+                               spin_lock(&catas_lock);
+                               list_add(&priv->catas_err.list, &catas_list);
+                               spin_unlock(&catas_lock);
 
-                       queue_work(mlx4_wq, &catas_work);
+                               queue_work(mlx4_wq, &catas_work);
+                       }
                }
        } else
                mod_timer(&priv->catas_err.timer,
@@ -100,6 +105,10 @@ static void catas_reset(struct work_struct *work)
        list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) {
                struct pci_dev *pdev = priv->dev.pdev;
 
+               /* If the device is off-line, we cannot reset it */
+               if (pci_channel_offline(pdev))
+                       continue;
+
                ret = mlx4_restart_one(priv->dev.pdev);
                /* 'priv' now is not valid */
                if (ret)