mlx4_core: Reset device when internal error is detected

Reset the device when an internal error is detected.

Also, detect errors by polling the error buffer rather than using
interrupts.  This is more robust and doesn't depend on MSI-X.  Remove
the old interrupt handler entirely, since we don't want to support two
mechanisms for detecting internal errors.

Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 27a82ce..2095c84 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -89,14 +89,12 @@
 			       (1ull << MLX4_EVENT_TYPE_PATH_MIG_FAILED)    | \
 			       (1ull << MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \
 			       (1ull << MLX4_EVENT_TYPE_WQ_ACCESS_ERROR)    | \
-			       (1ull << MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR)  | \
 			       (1ull << MLX4_EVENT_TYPE_PORT_CHANGE)	    | \
 			       (1ull << MLX4_EVENT_TYPE_ECC_DETECT)	    | \
 			       (1ull << MLX4_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
 			       (1ull << MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE)    | \
 			       (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT)	    | \
 			       (1ull << MLX4_EVENT_TYPE_CMD))
-#define MLX4_CATAS_EVENT_MASK  (1ull << MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR)
 
 struct mlx4_eqe {
 	u8			reserved1;
@@ -264,7 +262,7 @@
 
 	writel(priv->eq_table.clr_mask, priv->eq_table.clr_int);
 
-	for (i = 0; i < MLX4_EQ_CATAS; ++i)
+	for (i = 0; i < MLX4_NUM_EQ; ++i)
 		work |= mlx4_eq_int(dev, &priv->eq_table.eq[i]);
 
 	return IRQ_RETVAL(work);
@@ -281,14 +279,6 @@
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t mlx4_catas_interrupt(int irq, void *dev_ptr)
-{
-	mlx4_handle_catas_err(dev_ptr);
-
-	/* MSI-X vectors always belong to us */
-	return IRQ_HANDLED;
-}
-
 static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap,
 			int eq_num)
 {
@@ -490,11 +480,9 @@
 
 	if (eq_table->have_irq)
 		free_irq(dev->pdev->irq, dev);
-	for (i = 0; i < MLX4_EQ_CATAS; ++i)
+	for (i = 0; i < MLX4_NUM_EQ; ++i)
 		if (eq_table->eq[i].have_irq)
 			free_irq(eq_table->eq[i].irq, eq_table->eq + i);
-	if (eq_table->eq[MLX4_EQ_CATAS].have_irq)
-		free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev);
 }
 
 static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev)
@@ -598,32 +586,19 @@
 	if (dev->flags & MLX4_FLAG_MSI_X) {
 		static const char *eq_name[] = {
 			[MLX4_EQ_COMP]  = DRV_NAME " (comp)",
-			[MLX4_EQ_ASYNC] = DRV_NAME " (async)",
-			[MLX4_EQ_CATAS] = DRV_NAME " (catas)"
+			[MLX4_EQ_ASYNC] = DRV_NAME " (async)"
 		};
 
-		err = mlx4_create_eq(dev, 1, MLX4_EQ_CATAS,
-				     &priv->eq_table.eq[MLX4_EQ_CATAS]);
-		if (err)
-			goto err_out_async;
-
-		for (i = 0; i < MLX4_EQ_CATAS; ++i) {
+		for (i = 0; i < MLX4_NUM_EQ; ++i) {
 			err = request_irq(priv->eq_table.eq[i].irq,
 					  mlx4_msi_x_interrupt,
 					  0, eq_name[i], priv->eq_table.eq + i);
 			if (err)
-				goto err_out_catas;
+				goto err_out_async;
 
 			priv->eq_table.eq[i].have_irq = 1;
 		}
 
-		err = request_irq(priv->eq_table.eq[MLX4_EQ_CATAS].irq,
-				  mlx4_catas_interrupt, 0,
-				  eq_name[MLX4_EQ_CATAS], dev);
-		if (err)
-			goto err_out_catas;
-
-		priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1;
 	} else {
 		err = request_irq(dev->pdev->irq, mlx4_interrupt,
 				  IRQF_SHARED, DRV_NAME, dev);
@@ -639,22 +614,11 @@
 		mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n",
 			   priv->eq_table.eq[MLX4_EQ_ASYNC].eqn, err);
 
-	for (i = 0; i < MLX4_EQ_CATAS; ++i)
+	for (i = 0; i < MLX4_NUM_EQ; ++i)
 		eq_set_ci(&priv->eq_table.eq[i], 1);
 
-	if (dev->flags & MLX4_FLAG_MSI_X) {
-		err = mlx4_MAP_EQ(dev, MLX4_CATAS_EVENT_MASK, 0,
-				  priv->eq_table.eq[MLX4_EQ_CATAS].eqn);
-		if (err)
-			mlx4_warn(dev, "MAP_EQ for catas EQ %d failed (%d)\n",
-				  priv->eq_table.eq[MLX4_EQ_CATAS].eqn, err);
-	}
-
 	return 0;
 
-err_out_catas:
-	mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_CATAS]);
-
 err_out_async:
 	mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_ASYNC]);
 
@@ -675,19 +639,13 @@
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	int i;
 
-	if (dev->flags & MLX4_FLAG_MSI_X)
-		mlx4_MAP_EQ(dev, MLX4_CATAS_EVENT_MASK, 1,
-			    priv->eq_table.eq[MLX4_EQ_CATAS].eqn);
-
 	mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1,
 		    priv->eq_table.eq[MLX4_EQ_ASYNC].eqn);
 
 	mlx4_free_irqs(dev);
 
-	for (i = 0; i < MLX4_EQ_CATAS; ++i)
+	for (i = 0; i < MLX4_NUM_EQ; ++i)
 		mlx4_free_eq(dev, &priv->eq_table.eq[i]);
-	if (dev->flags & MLX4_FLAG_MSI_X)
-		mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_CATAS]);
 
 	mlx4_unmap_clr_int(dev);