aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/eq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mlx4/eq.c')
-rw-r--r--drivers/net/mlx4/eq.c107
1 files changed, 101 insertions, 6 deletions
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 552d0fce6f67..506cfd0372ec 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -42,7 +42,7 @@
42#include "fw.h" 42#include "fw.h"
43 43
44enum { 44enum {
45 MLX4_IRQNAME_SIZE = 64 45 MLX4_IRQNAME_SIZE = 32
46}; 46};
47 47
48enum { 48enum {
@@ -317,8 +317,8 @@ static int mlx4_num_eq_uar(struct mlx4_dev *dev)
317 * we need to map, take the difference of highest index and 317 * we need to map, take the difference of highest index and
318 * the lowest index we'll use and add 1. 318 * the lowest index we'll use and add 1.
319 */ 319 */
320 return (dev->caps.num_comp_vectors + 1 + dev->caps.reserved_eqs) / 4 - 320 return (dev->caps.num_comp_vectors + 1 + dev->caps.reserved_eqs +
321 dev->caps.reserved_eqs / 4 + 1; 321 dev->caps.comp_pool)/4 - dev->caps.reserved_eqs/4 + 1;
322} 322}
323 323
324static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq) 324static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq)
@@ -496,16 +496,32 @@ static void mlx4_free_eq(struct mlx4_dev *dev,
496static void mlx4_free_irqs(struct mlx4_dev *dev) 496static void mlx4_free_irqs(struct mlx4_dev *dev)
497{ 497{
498 struct mlx4_eq_table *eq_table = &mlx4_priv(dev)->eq_table; 498 struct mlx4_eq_table *eq_table = &mlx4_priv(dev)->eq_table;
499 int i; 499 struct mlx4_priv *priv = mlx4_priv(dev);
500 int i, vec;
500 501
501 if (eq_table->have_irq) 502 if (eq_table->have_irq)
502 free_irq(dev->pdev->irq, dev); 503 free_irq(dev->pdev->irq, dev);
504
503 for (i = 0; i < dev->caps.num_comp_vectors + 1; ++i) 505 for (i = 0; i < dev->caps.num_comp_vectors + 1; ++i)
504 if (eq_table->eq[i].have_irq) { 506 if (eq_table->eq[i].have_irq) {
505 free_irq(eq_table->eq[i].irq, eq_table->eq + i); 507 free_irq(eq_table->eq[i].irq, eq_table->eq + i);
506 eq_table->eq[i].have_irq = 0; 508 eq_table->eq[i].have_irq = 0;
507 } 509 }
508 510
511 for (i = 0; i < dev->caps.comp_pool; i++) {
512 /*
513 * Freeing the assigned irq's
514 * all bits should be 0, but we need to validate
515 */
516 if (priv->msix_ctl.pool_bm & 1ULL << i) {
517 /* NO need protecting*/
518 vec = dev->caps.num_comp_vectors + 1 + i;
519 free_irq(priv->eq_table.eq[vec].irq,
520 &priv->eq_table.eq[vec]);
521 }
522 }
523
524
509 kfree(eq_table->irq_names); 525 kfree(eq_table->irq_names);
510} 526}
511 527
@@ -578,7 +594,8 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
578 (priv->eq_table.inta_pin < 32 ? 4 : 0); 594 (priv->eq_table.inta_pin < 32 ? 4 : 0);
579 595
580 priv->eq_table.irq_names = 596 priv->eq_table.irq_names =
581 kmalloc(MLX4_IRQNAME_SIZE * (dev->caps.num_comp_vectors + 1), 597 kmalloc(MLX4_IRQNAME_SIZE * (dev->caps.num_comp_vectors + 1 +
598 dev->caps.comp_pool),
582 GFP_KERNEL); 599 GFP_KERNEL);
583 if (!priv->eq_table.irq_names) { 600 if (!priv->eq_table.irq_names) {
584 err = -ENOMEM; 601 err = -ENOMEM;
@@ -601,6 +618,22 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
601 if (err) 618 if (err)
602 goto err_out_comp; 619 goto err_out_comp;
603 620
621 /*if additional completion vectors poolsize is 0 this loop will not run*/
622 for (i = dev->caps.num_comp_vectors + 1;
623 i < dev->caps.num_comp_vectors + dev->caps.comp_pool + 1; ++i) {
624
625 err = mlx4_create_eq(dev, dev->caps.num_cqs -
626 dev->caps.reserved_cqs +
627 MLX4_NUM_SPARE_EQE,
628 (dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
629 &priv->eq_table.eq[i]);
630 if (err) {
631 --i;
632 goto err_out_unmap;
633 }
634 }
635
636
604 if (dev->flags & MLX4_FLAG_MSI_X) { 637 if (dev->flags & MLX4_FLAG_MSI_X) {
605 const char *eq_name; 638 const char *eq_name;
606 639
@@ -686,7 +719,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
686 719
687 mlx4_free_irqs(dev); 720 mlx4_free_irqs(dev);
688 721
689 for (i = 0; i < dev->caps.num_comp_vectors + 1; ++i) 722 for (i = 0; i < dev->caps.num_comp_vectors + dev->caps.comp_pool + 1; ++i)
690 mlx4_free_eq(dev, &priv->eq_table.eq[i]); 723 mlx4_free_eq(dev, &priv->eq_table.eq[i]);
691 724
692 mlx4_unmap_clr_int(dev); 725 mlx4_unmap_clr_int(dev);
@@ -743,3 +776,65 @@ int mlx4_test_interrupts(struct mlx4_dev *dev)
743 return err; 776 return err;
744} 777}
745EXPORT_SYMBOL(mlx4_test_interrupts); 778EXPORT_SYMBOL(mlx4_test_interrupts);
779
780int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
781{
782
783 struct mlx4_priv *priv = mlx4_priv(dev);
784 int vec = 0, err = 0, i;
785
786 spin_lock(&priv->msix_ctl.pool_lock);
787 for (i = 0; !vec && i < dev->caps.comp_pool; i++) {
788 if (~priv->msix_ctl.pool_bm & 1ULL << i) {
789 priv->msix_ctl.pool_bm |= 1ULL << i;
790 vec = dev->caps.num_comp_vectors + 1 + i;
791 snprintf(priv->eq_table.irq_names +
792 vec * MLX4_IRQNAME_SIZE,
793 MLX4_IRQNAME_SIZE, "%s", name);
794 err = request_irq(priv->eq_table.eq[vec].irq,
795 mlx4_msi_x_interrupt, 0,
796 &priv->eq_table.irq_names[vec<<5],
797 priv->eq_table.eq + vec);
798 if (err) {
799 /*zero out bit by fliping it*/
800 priv->msix_ctl.pool_bm ^= 1 << i;
801 vec = 0;
802 continue;
803 /*we dont want to break here*/
804 }
805 eq_set_ci(&priv->eq_table.eq[vec], 1);
806 }
807 }
808 spin_unlock(&priv->msix_ctl.pool_lock);
809
810 if (vec) {
811 *vector = vec;
812 } else {
813 *vector = 0;
814 err = (i == dev->caps.comp_pool) ? -ENOSPC : err;
815 }
816 return err;
817}
818EXPORT_SYMBOL(mlx4_assign_eq);
819
820void mlx4_release_eq(struct mlx4_dev *dev, int vec)
821{
822 struct mlx4_priv *priv = mlx4_priv(dev);
823 /*bm index*/
824 int i = vec - dev->caps.num_comp_vectors - 1;
825
826 if (likely(i >= 0)) {
827 /*sanity check , making sure were not trying to free irq's
828 Belonging to a legacy EQ*/
829 spin_lock(&priv->msix_ctl.pool_lock);
830 if (priv->msix_ctl.pool_bm & 1ULL << i) {
831 free_irq(priv->eq_table.eq[vec].irq,
832 &priv->eq_table.eq[vec]);
833 priv->msix_ctl.pool_bm &= ~(1ULL << i);
834 }
835 spin_unlock(&priv->msix_ctl.pool_lock);
836 }
837
838}
839EXPORT_SYMBOL(mlx4_release_eq);
840