diff options
Diffstat (limited to 'drivers/net/mlx4/main.c')
| -rw-r--r-- | drivers/net/mlx4/main.c | 53 |
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: | |||
| 908 | static void mlx4_enable_msi_x(struct mlx4_dev *dev) | 906 | static 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 | ||
| 934 | no_msi: | 949 | no_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 | ||
| 1138 | err_free_eq: | ||
| 1139 | mlx4_free_eq_table(dev); | ||
| 1140 | |||
| 1117 | err_close: | 1141 | err_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 | ||
