aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mthca')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c110
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c8
4 files changed, 65 insertions, 61 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index acc95892713..6966f943f44 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -290,6 +290,12 @@ static int mthca_cmd_post(struct mthca_dev *dev,
290 err = mthca_cmd_post_hcr(dev, in_param, out_param, in_modifier, 290 err = mthca_cmd_post_hcr(dev, in_param, out_param, in_modifier,
291 op_modifier, op, token, event); 291 op_modifier, op, token, event);
292 292
293 /*
294 * Make sure that our HCR writes don't get mixed in with
295 * writes from another CPU starting a FW command.
296 */
297 mmiowb();
298
293 mutex_unlock(&dev->cmd.hcr_mutex); 299 mutex_unlock(&dev->cmd.hcr_mutex);
294 return err; 300 return err;
295} 301}
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 9bae3cc6060..15aa32eb78b 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -83,7 +83,7 @@ enum {
83 MTHCA_QP_CONTEXT_SIZE = 0x200, 83 MTHCA_QP_CONTEXT_SIZE = 0x200,
84 MTHCA_RDB_ENTRY_SIZE = 0x20, 84 MTHCA_RDB_ENTRY_SIZE = 0x20,
85 MTHCA_AV_SIZE = 0x20, 85 MTHCA_AV_SIZE = 0x20,
86 MTHCA_MGM_ENTRY_SIZE = 0x40, 86 MTHCA_MGM_ENTRY_SIZE = 0x100,
87 87
88 /* Arbel FW gives us these, but we need them for Tavor */ 88 /* Arbel FW gives us these, but we need them for Tavor */
89 MTHCA_MPT_ENTRY_SIZE = 0x40, 89 MTHCA_MPT_ENTRY_SIZE = 0x40,
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 76fed7545c5..60de6f93869 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -61,7 +61,7 @@ MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
61 61
62#ifdef CONFIG_PCI_MSI 62#ifdef CONFIG_PCI_MSI
63 63
64static int msi_x = 0; 64static int msi_x = 1;
65module_param(msi_x, int, 0444); 65module_param(msi_x, int, 0444);
66MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero"); 66MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero");
67 67
@@ -137,40 +137,23 @@ static const char mthca_version[] __devinitdata =
137 137
138static int mthca_tune_pci(struct mthca_dev *mdev) 138static int mthca_tune_pci(struct mthca_dev *mdev)
139{ 139{
140 int cap;
141 u16 val;
142
143 if (!tune_pci) 140 if (!tune_pci)
144 return 0; 141 return 0;
145 142
146 /* First try to max out Read Byte Count */ 143 /* First try to max out Read Byte Count */
147 cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); 144 if (pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX)) {
148 if (cap) { 145 if (pcix_set_mmrbc(mdev->pdev, pcix_get_max_mmrbc(mdev->pdev))) {
149 if (pci_read_config_word(mdev->pdev, cap + PCI_X_CMD, &val)) { 146 mthca_err(mdev, "Couldn't set PCI-X max read count, "
150 mthca_err(mdev, "Couldn't read PCI-X command register, " 147 "aborting.\n");
151 "aborting.\n");
152 return -ENODEV;
153 }
154 val = (val & ~PCI_X_CMD_MAX_READ) | (3 << 2);
155 if (pci_write_config_word(mdev->pdev, cap + PCI_X_CMD, val)) {
156 mthca_err(mdev, "Couldn't write PCI-X command register, "
157 "aborting.\n");
158 return -ENODEV; 148 return -ENODEV;
159 } 149 }
160 } else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) 150 } else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE))
161 mthca_info(mdev, "No PCI-X capability, not setting RBC.\n"); 151 mthca_info(mdev, "No PCI-X capability, not setting RBC.\n");
162 152
163 cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); 153 if (pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP)) {
164 if (cap) { 154 if (pcie_set_readrq(mdev->pdev, 4096)) {
165 if (pci_read_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, &val)) { 155 mthca_err(mdev, "Couldn't write PCI Express read request, "
166 mthca_err(mdev, "Couldn't read PCI Express device control " 156 "aborting.\n");
167 "register, aborting.\n");
168 return -ENODEV;
169 }
170 val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12);
171 if (pci_write_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, val)) {
172 mthca_err(mdev, "Couldn't write PCI Express device control "
173 "register, aborting.\n");
174 return -ENODEV; 157 return -ENODEV;
175 } 158 }
176 } else if (mdev->mthca_flags & MTHCA_FLAG_PCIE) 159 } else if (mdev->mthca_flags & MTHCA_FLAG_PCIE)
@@ -833,14 +816,19 @@ static int mthca_setup_hca(struct mthca_dev *dev)
833 816
834 err = mthca_NOP(dev, &status); 817 err = mthca_NOP(dev, &status);
835 if (err || status) { 818 if (err || status) {
836 mthca_err(dev, "NOP command failed to generate interrupt (IRQ %d), aborting.\n", 819 if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)) {
837 dev->mthca_flags & MTHCA_FLAG_MSI_X ? 820 mthca_warn(dev, "NOP command failed to generate interrupt "
838 dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector : 821 "(IRQ %d).\n",
839 dev->pdev->irq); 822 dev->mthca_flags & MTHCA_FLAG_MSI_X ?
840 if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)) 823 dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector :
841 mthca_err(dev, "Try again with MSI/MSI-X disabled.\n"); 824 dev->pdev->irq);
842 else 825 mthca_warn(dev, "Trying again with MSI/MSI-X disabled.\n");
826 } else {
827 mthca_err(dev, "NOP command failed to generate interrupt "
828 "(IRQ %d), aborting.\n",
829 dev->pdev->irq);
843 mthca_err(dev, "BIOS or ACPI interrupt routing problem?\n"); 830 mthca_err(dev, "BIOS or ACPI interrupt routing problem?\n");
831 }
844 832
845 goto err_cmd_poll; 833 goto err_cmd_poll;
846 } 834 }
@@ -1115,24 +1103,6 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
1115 goto err_free_dev; 1103 goto err_free_dev;
1116 } 1104 }
1117 1105
1118 if (msi_x && !mthca_enable_msi_x(mdev))
1119 mdev->mthca_flags |= MTHCA_FLAG_MSI_X;
1120 else if (msi) {
1121 static int warned;
1122
1123 if (!warned) {
1124 printk(KERN_WARNING PFX "WARNING: MSI support will be "
1125 "removed from the ib_mthca driver in January 2008.\n");
1126 printk(KERN_WARNING " If you are using MSI and cannot "
1127 "switch to MSI-X, please tell "
1128 "<general@lists.openfabrics.org>.\n");
1129 ++warned;
1130 }
1131
1132 if (!pci_enable_msi(pdev))
1133 mdev->mthca_flags |= MTHCA_FLAG_MSI;
1134 }
1135
1136 if (mthca_cmd_init(mdev)) { 1106 if (mthca_cmd_init(mdev)) {
1137 mthca_err(mdev, "Failed to init command interface, aborting.\n"); 1107 mthca_err(mdev, "Failed to init command interface, aborting.\n");
1138 goto err_free_dev; 1108 goto err_free_dev;
@@ -1156,7 +1126,35 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
1156 mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n"); 1126 mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n");
1157 } 1127 }
1158 1128
1129 if (msi_x && !mthca_enable_msi_x(mdev))
1130 mdev->mthca_flags |= MTHCA_FLAG_MSI_X;
1131 else if (msi) {
1132 static int warned;
1133
1134 if (!warned) {
1135 printk(KERN_WARNING PFX "WARNING: MSI support will be "
1136 "removed from the ib_mthca driver in January 2008.\n");
1137 printk(KERN_WARNING " If you are using MSI and cannot "
1138 "switch to MSI-X, please tell "
1139 "<general@lists.openfabrics.org>.\n");
1140 ++warned;
1141 }
1142
1143 if (!pci_enable_msi(pdev))
1144 mdev->mthca_flags |= MTHCA_FLAG_MSI;
1145 }
1146
1159 err = mthca_setup_hca(mdev); 1147 err = mthca_setup_hca(mdev);
1148 if (err == -EBUSY && (mdev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X))) {
1149 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
1150 pci_disable_msix(pdev);
1151 if (mdev->mthca_flags & MTHCA_FLAG_MSI)
1152 pci_disable_msi(pdev);
1153 mdev->mthca_flags &= ~(MTHCA_FLAG_MSI_X | MTHCA_FLAG_MSI);
1154
1155 err = mthca_setup_hca(mdev);
1156 }
1157
1160 if (err) 1158 if (err)
1161 goto err_close; 1159 goto err_close;
1162 1160
@@ -1192,17 +1190,17 @@ err_cleanup:
1192 mthca_cleanup_uar_table(mdev); 1190 mthca_cleanup_uar_table(mdev);
1193 1191
1194err_close: 1192err_close:
1193 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
1194 pci_disable_msix(pdev);
1195 if (mdev->mthca_flags & MTHCA_FLAG_MSI)
1196 pci_disable_msi(pdev);
1197
1195 mthca_close_hca(mdev); 1198 mthca_close_hca(mdev);
1196 1199
1197err_cmd: 1200err_cmd:
1198 mthca_cmd_cleanup(mdev); 1201 mthca_cmd_cleanup(mdev);
1199 1202
1200err_free_dev: 1203err_free_dev:
1201 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
1202 pci_disable_msix(pdev);
1203 if (mdev->mthca_flags & MTHCA_FLAG_MSI)
1204 pci_disable_msi(pdev);
1205
1206 ib_dealloc_device(&mdev->ib_dev); 1204 ib_dealloc_device(&mdev->ib_dev);
1207 1205
1208err_free_res: 1206err_free_res:
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 88d219e730a..3f58c11a62b 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -509,7 +509,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
509 for (nreq = 0; wr; wr = wr->next) { 509 for (nreq = 0; wr; wr = wr->next) {
510 ind = srq->first_free; 510 ind = srq->first_free;
511 511
512 if (ind < 0) { 512 if (unlikely(ind < 0)) {
513 mthca_err(dev, "SRQ %06x full\n", srq->srqn); 513 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
514 err = -ENOMEM; 514 err = -ENOMEM;
515 *bad_wr = wr; 515 *bad_wr = wr;
@@ -519,7 +519,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
519 wqe = get_wqe(srq, ind); 519 wqe = get_wqe(srq, ind);
520 next_ind = *wqe_to_link(wqe); 520 next_ind = *wqe_to_link(wqe);
521 521
522 if (next_ind < 0) { 522 if (unlikely(next_ind < 0)) {
523 mthca_err(dev, "SRQ %06x full\n", srq->srqn); 523 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
524 err = -ENOMEM; 524 err = -ENOMEM;
525 *bad_wr = wr; 525 *bad_wr = wr;
@@ -623,7 +623,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
623 for (nreq = 0; wr; ++nreq, wr = wr->next) { 623 for (nreq = 0; wr; ++nreq, wr = wr->next) {
624 ind = srq->first_free; 624 ind = srq->first_free;
625 625
626 if (ind < 0) { 626 if (unlikely(ind < 0)) {
627 mthca_err(dev, "SRQ %06x full\n", srq->srqn); 627 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
628 err = -ENOMEM; 628 err = -ENOMEM;
629 *bad_wr = wr; 629 *bad_wr = wr;
@@ -633,7 +633,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
633 wqe = get_wqe(srq, ind); 633 wqe = get_wqe(srq, ind);
634 next_ind = *wqe_to_link(wqe); 634 next_ind = *wqe_to_link(wqe);
635 635
636 if (next_ind < 0) { 636 if (unlikely(next_ind < 0)) {
637 mthca_err(dev, "SRQ %06x full\n", srq->srqn); 637 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
638 err = -ENOMEM; 638 err = -ENOMEM;
639 *bad_wr = wr; 639 *bad_wr = wr;