aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/main.c
diff options
context:
space:
mode:
authorYevgeny Petrilin <yevgenyp@mellanox.co.il>2008-12-22 10:15:03 -0500
committerRoland Dreier <rolandd@cisco.com>2008-12-22 10:15:03 -0500
commitb8dd786f9417e5885929bfe33a235c76a9c1c569 (patch)
tree16b38c672980d142ffa0ac0ccdeb4af19c20cc31 /drivers/net/mlx4/main.c
parent061e41fdb5047b1fb161e89664057835935ca1d2 (diff)
mlx4_core: Add support for multiple completion event vectors
When using MSI-X mode, create a completion event queue for each CPU. Report the number of completion EQs in a new struct mlx4_caps member, num_comp_vectors, and extend the mlx4_cq_alloc() interface with a vector parameter so that consumers can specify which completion EQ should be used to report events for the CQ being created. Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r--drivers/net/mlx4/main.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 90a0281d15ea..710c79e7a2db 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -421,9 +421,7 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
421 ((u64) (MLX4_CMPT_TYPE_EQ * 421 ((u64) (MLX4_CMPT_TYPE_EQ *
422 cmpt_entry_sz) << MLX4_CMPT_SHIFT), 422 cmpt_entry_sz) << MLX4_CMPT_SHIFT),
423 cmpt_entry_sz, 423 cmpt_entry_sz,
424 roundup_pow_of_two(MLX4_NUM_EQ + 424 dev->caps.num_eqs, dev->caps.num_eqs, 0, 0);
425 dev->caps.reserved_eqs),
426 MLX4_NUM_EQ + dev->caps.reserved_eqs, 0, 0);
427 if (err) 425 if (err)
428 goto err_cq; 426 goto err_cq;
429 427
@@ -810,12 +808,12 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
810 if (dev->flags & MLX4_FLAG_MSI_X) { 808 if (dev->flags & MLX4_FLAG_MSI_X) {
811 mlx4_warn(dev, "NOP command failed to generate MSI-X " 809 mlx4_warn(dev, "NOP command failed to generate MSI-X "
812 "interrupt IRQ %d).\n", 810 "interrupt IRQ %d).\n",
813 priv->eq_table.eq[MLX4_EQ_ASYNC].irq); 811 priv->eq_table.eq[dev->caps.num_comp_vectors].irq);
814 mlx4_warn(dev, "Trying again without MSI-X.\n"); 812 mlx4_warn(dev, "Trying again without MSI-X.\n");
815 } else { 813 } else {
816 mlx4_err(dev, "NOP command failed to generate interrupt " 814 mlx4_err(dev, "NOP command failed to generate interrupt "
817 "(IRQ %d), aborting.\n", 815 "(IRQ %d), aborting.\n",
818 priv->eq_table.eq[MLX4_EQ_ASYNC].irq); 816 priv->eq_table.eq[dev->caps.num_comp_vectors].irq);
819 mlx4_err(dev, "BIOS or ACPI interrupt routing problem?\n"); 817 mlx4_err(dev, "BIOS or ACPI interrupt routing problem?\n");
820 } 818 }
821 819
@@ -908,31 +906,50 @@ err_uar_table_free:
908static void mlx4_enable_msi_x(struct mlx4_dev *dev) 906static void mlx4_enable_msi_x(struct mlx4_dev *dev)
909{ 907{
910 struct mlx4_priv *priv = mlx4_priv(dev); 908 struct mlx4_priv *priv = mlx4_priv(dev);
911 struct msix_entry entries[MLX4_NUM_EQ]; 909 struct msix_entry *entries;
910 int nreq;
912 int err; 911 int err;
913 int i; 912 int i;
914 913
915 if (msi_x) { 914 if (msi_x) {
916 for (i = 0; i < MLX4_NUM_EQ; ++i) 915 nreq = min(dev->caps.num_eqs - dev->caps.reserved_eqs,
916 num_possible_cpus() + 1);
917 entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
918 if (!entries)
919 goto no_msi;
920
921 for (i = 0; i < nreq; ++i)
917 entries[i].entry = i; 922 entries[i].entry = i;
918 923
919 err = pci_enable_msix(dev->pdev, entries, ARRAY_SIZE(entries)); 924 retry:
925 err = pci_enable_msix(dev->pdev, entries, nreq);
920 if (err) { 926 if (err) {
921 if (err > 0) 927 /* Try again if at least 2 vectors are available */
922 mlx4_info(dev, "Only %d MSI-X vectors available, " 928 if (err > 1) {
923 "not using MSI-X\n", err); 929 mlx4_info(dev, "Requested %d vectors, "
930 "but only %d MSI-X vectors available, "
931 "trying again\n", nreq, err);
932 nreq = err;
933 goto retry;
934 }
935
924 goto no_msi; 936 goto no_msi;
925 } 937 }
926 938
927 for (i = 0; i < MLX4_NUM_EQ; ++i) 939 dev->caps.num_comp_vectors = nreq - 1;
940 for (i = 0; i < nreq; ++i)
928 priv->eq_table.eq[i].irq = entries[i].vector; 941 priv->eq_table.eq[i].irq = entries[i].vector;
929 942
930 dev->flags |= MLX4_FLAG_MSI_X; 943 dev->flags |= MLX4_FLAG_MSI_X;
944
945 kfree(entries);
931 return; 946 return;
932 } 947 }
933 948
934no_msi: 949no_msi:
935 for (i = 0; i < MLX4_NUM_EQ; ++i) 950 dev->caps.num_comp_vectors = 1;
951
952 for (i = 0; i < 2; ++i)
936 priv->eq_table.eq[i].irq = dev->pdev->irq; 953 priv->eq_table.eq[i].irq = dev->pdev->irq;
937} 954}
938 955
@@ -1074,6 +1091,10 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1074 if (err) 1091 if (err)
1075 goto err_cmd; 1092 goto err_cmd;
1076 1093
1094 err = mlx4_alloc_eq_table(dev);
1095 if (err)
1096 goto err_close;
1097
1077 mlx4_enable_msi_x(dev); 1098 mlx4_enable_msi_x(dev);
1078 1099
1079 err = mlx4_setup_hca(dev); 1100 err = mlx4_setup_hca(dev);
@@ -1084,7 +1105,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
1084 } 1105 }
1085 1106
1086 if (err) 1107 if (err)
1087 goto err_close; 1108 goto err_free_eq;
1088 1109
1089 for (port = 1; port <= dev->caps.num_ports; port++) { 1110 for (port = 1; port <= dev->caps.num_ports; port++) {
1090 err = mlx4_init_port_info(dev, port); 1111 err = mlx4_init_port_info(dev, port);
@@ -1114,6 +1135,9 @@ err_port:
1114 mlx4_cleanup_pd_table(dev); 1135 mlx4_cleanup_pd_table(dev);
1115 mlx4_cleanup_uar_table(dev); 1136 mlx4_cleanup_uar_table(dev);
1116 1137
1138err_free_eq:
1139 mlx4_free_eq_table(dev);
1140
1117err_close: 1141err_close:
1118 if (dev->flags & MLX4_FLAG_MSI_X) 1142 if (dev->flags & MLX4_FLAG_MSI_X)
1119 pci_disable_msix(pdev); 1143 pci_disable_msix(pdev);
@@ -1177,6 +1201,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
1177 iounmap(priv->kar); 1201 iounmap(priv->kar);
1178 mlx4_uar_free(dev, &priv->driver_uar); 1202 mlx4_uar_free(dev, &priv->driver_uar);
1179 mlx4_cleanup_uar_table(dev); 1203 mlx4_cleanup_uar_table(dev);
1204 mlx4_free_eq_table(dev);
1180 mlx4_close_hca(dev); 1205 mlx4_close_hca(dev);
1181 mlx4_cmd_cleanup(dev); 1206 mlx4_cmd_cleanup(dev);
1182 1207