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.c11
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c45
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c8
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c22
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c47
8 files changed, 60 insertions, 105 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 6966f943f440..09a30dd12b14 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1255,9 +1255,14 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
1255 if (err) 1255 if (err)
1256 goto out; 1256 goto out;
1257 1257
1258 MTHCA_GET(adapter->vendor_id, outbox, QUERY_ADAPTER_VENDOR_ID_OFFSET); 1258 if (!mthca_is_memfree(dev)) {
1259 MTHCA_GET(adapter->device_id, outbox, QUERY_ADAPTER_DEVICE_ID_OFFSET); 1259 MTHCA_GET(adapter->vendor_id, outbox,
1260 MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET); 1260 QUERY_ADAPTER_VENDOR_ID_OFFSET);
1261 MTHCA_GET(adapter->device_id, outbox,
1262 QUERY_ADAPTER_DEVICE_ID_OFFSET);
1263 MTHCA_GET(adapter->revision_id, outbox,
1264 QUERY_ADAPTER_REVISION_ID_OFFSET);
1265 }
1261 MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); 1266 MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET);
1262 1267
1263 get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4, 1268 get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4,
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 15aa32eb78b6..7bbdd1f4e6c7 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -60,13 +60,12 @@
60enum { 60enum {
61 MTHCA_FLAG_DDR_HIDDEN = 1 << 1, 61 MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
62 MTHCA_FLAG_SRQ = 1 << 2, 62 MTHCA_FLAG_SRQ = 1 << 2,
63 MTHCA_FLAG_MSI = 1 << 3, 63 MTHCA_FLAG_MSI_X = 1 << 3,
64 MTHCA_FLAG_MSI_X = 1 << 4, 64 MTHCA_FLAG_NO_LAM = 1 << 4,
65 MTHCA_FLAG_NO_LAM = 1 << 5, 65 MTHCA_FLAG_FMR = 1 << 5,
66 MTHCA_FLAG_FMR = 1 << 6, 66 MTHCA_FLAG_MEMFREE = 1 << 6,
67 MTHCA_FLAG_MEMFREE = 1 << 7, 67 MTHCA_FLAG_PCIE = 1 << 7,
68 MTHCA_FLAG_PCIE = 1 << 8, 68 MTHCA_FLAG_SINAI_OPT = 1 << 8
69 MTHCA_FLAG_SINAI_OPT = 1 << 9
70}; 69};
71 70
72enum { 71enum {
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index b29de51b7f35..b60eb5df96e8 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -827,8 +827,7 @@ int mthca_init_eq_table(struct mthca_dev *dev)
827 if (err) 827 if (err)
828 goto err_out_free; 828 goto err_out_free;
829 829
830 if (dev->mthca_flags & MTHCA_FLAG_MSI || 830 if (dev->mthca_flags & MTHCA_FLAG_MSI_X) {
831 dev->mthca_flags & MTHCA_FLAG_MSI_X) {
832 dev->eq_table.clr_mask = 0; 831 dev->eq_table.clr_mask = 0;
833 } else { 832 } else {
834 dev->eq_table.clr_mask = 833 dev->eq_table.clr_mask =
@@ -839,8 +838,7 @@ int mthca_init_eq_table(struct mthca_dev *dev)
839 838
840 dev->eq_table.arm_mask = 0; 839 dev->eq_table.arm_mask = 0;
841 840
842 intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ? 841 intr = dev->eq_table.inta_pin;
843 128 : dev->eq_table.inta_pin;
844 842
845 err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE, 843 err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE,
846 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr, 844 (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr,
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 60de6f93869e..cd3d8adbef9f 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -65,14 +65,9 @@ static 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
68static int msi = 0;
69module_param(msi, int, 0444);
70MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero (deprecated, use MSI-X instead)");
71
72#else /* CONFIG_PCI_MSI */ 68#else /* CONFIG_PCI_MSI */
73 69
74#define msi_x (0) 70#define msi_x (0)
75#define msi (0)
76 71
77#endif /* CONFIG_PCI_MSI */ 72#endif /* CONFIG_PCI_MSI */
78 73
@@ -131,7 +126,7 @@ module_param_named(fmr_reserved_mtts, hca_profile.fmr_reserved_mtts, int, 0444);
131MODULE_PARM_DESC(fmr_reserved_mtts, 126MODULE_PARM_DESC(fmr_reserved_mtts,
132 "number of memory translation table segments reserved for FMR"); 127 "number of memory translation table segments reserved for FMR");
133 128
134static const char mthca_version[] __devinitdata = 129static char mthca_version[] __devinitdata =
135 DRV_NAME ": Mellanox InfiniBand HCA driver v" 130 DRV_NAME ": Mellanox InfiniBand HCA driver v"
136 DRV_VERSION " (" DRV_RELDATE ")\n"; 131 DRV_VERSION " (" DRV_RELDATE ")\n";
137 132
@@ -740,7 +735,8 @@ static int mthca_init_hca(struct mthca_dev *mdev)
740 } 735 }
741 736
742 mdev->eq_table.inta_pin = adapter.inta_pin; 737 mdev->eq_table.inta_pin = adapter.inta_pin;
743 mdev->rev_id = adapter.revision_id; 738 if (!mthca_is_memfree(mdev))
739 mdev->rev_id = adapter.revision_id;
744 memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id); 740 memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id);
745 741
746 return 0; 742 return 0;
@@ -816,13 +812,11 @@ static int mthca_setup_hca(struct mthca_dev *dev)
816 812
817 err = mthca_NOP(dev, &status); 813 err = mthca_NOP(dev, &status);
818 if (err || status) { 814 if (err || status) {
819 if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)) { 815 if (dev->mthca_flags & MTHCA_FLAG_MSI_X) {
820 mthca_warn(dev, "NOP command failed to generate interrupt " 816 mthca_warn(dev, "NOP command failed to generate interrupt "
821 "(IRQ %d).\n", 817 "(IRQ %d).\n",
822 dev->mthca_flags & MTHCA_FLAG_MSI_X ? 818 dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector);
823 dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector : 819 mthca_warn(dev, "Trying again with MSI-X disabled.\n");
824 dev->pdev->irq);
825 mthca_warn(dev, "Trying again with MSI/MSI-X disabled.\n");
826 } else { 820 } else {
827 mthca_err(dev, "NOP command failed to generate interrupt " 821 mthca_err(dev, "NOP command failed to generate interrupt "
828 "(IRQ %d), aborting.\n", 822 "(IRQ %d), aborting.\n",
@@ -1005,7 +999,7 @@ static struct {
1005 .flags = 0 }, 999 .flags = 0 },
1006 [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 8, 200), 1000 [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 8, 200),
1007 .flags = MTHCA_FLAG_PCIE }, 1001 .flags = MTHCA_FLAG_PCIE },
1008 [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 2, 0), 1002 [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 3, 0),
1009 .flags = MTHCA_FLAG_MEMFREE | 1003 .flags = MTHCA_FLAG_MEMFREE |
1010 MTHCA_FLAG_PCIE }, 1004 MTHCA_FLAG_PCIE },
1011 [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 2, 0), 1005 [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 2, 0),
@@ -1128,29 +1122,12 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
1128 1122
1129 if (msi_x && !mthca_enable_msi_x(mdev)) 1123 if (msi_x && !mthca_enable_msi_x(mdev))
1130 mdev->mthca_flags |= MTHCA_FLAG_MSI_X; 1124 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 1125
1147 err = mthca_setup_hca(mdev); 1126 err = mthca_setup_hca(mdev);
1148 if (err == -EBUSY && (mdev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X))) { 1127 if (err == -EBUSY && (mdev->mthca_flags & MTHCA_FLAG_MSI_X)) {
1149 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) 1128 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
1150 pci_disable_msix(pdev); 1129 pci_disable_msix(pdev);
1151 if (mdev->mthca_flags & MTHCA_FLAG_MSI) 1130 mdev->mthca_flags &= ~MTHCA_FLAG_MSI_X;
1152 pci_disable_msi(pdev);
1153 mdev->mthca_flags &= ~(MTHCA_FLAG_MSI_X | MTHCA_FLAG_MSI);
1154 1131
1155 err = mthca_setup_hca(mdev); 1132 err = mthca_setup_hca(mdev);
1156 } 1133 }
@@ -1192,8 +1169,6 @@ err_cleanup:
1192err_close: 1169err_close:
1193 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) 1170 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
1194 pci_disable_msix(pdev); 1171 pci_disable_msix(pdev);
1195 if (mdev->mthca_flags & MTHCA_FLAG_MSI)
1196 pci_disable_msi(pdev);
1197 1172
1198 mthca_close_hca(mdev); 1173 mthca_close_hca(mdev);
1199 1174
@@ -1246,8 +1221,6 @@ static void __mthca_remove_one(struct pci_dev *pdev)
1246 1221
1247 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) 1222 if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
1248 pci_disable_msix(pdev); 1223 pci_disable_msix(pdev);
1249 if (mdev->mthca_flags & MTHCA_FLAG_MSI)
1250 pci_disable_msi(pdev);
1251 1224
1252 ib_dealloc_device(&mdev->ib_dev); 1225 ib_dealloc_device(&mdev->ib_dev);
1253 mthca_release_regions(pdev, mdev->mthca_flags & 1226 mthca_release_regions(pdev, mdev->mthca_flags &
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index aa6c70a6a36f..3b6985557cb2 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -613,8 +613,10 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
613 sizeof *(mr->mem.tavor.mpt) * idx; 613 sizeof *(mr->mem.tavor.mpt) * idx;
614 614
615 mr->mtt = __mthca_alloc_mtt(dev, list_len, dev->mr_table.fmr_mtt_buddy); 615 mr->mtt = __mthca_alloc_mtt(dev, list_len, dev->mr_table.fmr_mtt_buddy);
616 if (IS_ERR(mr->mtt)) 616 if (IS_ERR(mr->mtt)) {
617 err = PTR_ERR(mr->mtt);
617 goto err_out_table; 618 goto err_out_table;
619 }
618 620
619 mtt_seg = mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE; 621 mtt_seg = mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE;
620 622
@@ -627,8 +629,10 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
627 mr->mem.tavor.mtts = dev->mr_table.tavor_fmr.mtt_base + mtt_seg; 629 mr->mem.tavor.mtts = dev->mr_table.tavor_fmr.mtt_base + mtt_seg;
628 630
629 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 631 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
630 if (IS_ERR(mailbox)) 632 if (IS_ERR(mailbox)) {
633 err = PTR_ERR(mailbox);
631 goto err_out_free_mtt; 634 goto err_out_free_mtt;
635 }
632 636
633 mpt_entry = mailbox->buf; 637 mpt_entry = mailbox->buf;
634 638
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 6bcde1cb9688..9e491df6419c 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -923,17 +923,13 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd,
923 struct mthca_mr *mr; 923 struct mthca_mr *mr;
924 u64 *page_list; 924 u64 *page_list;
925 u64 total_size; 925 u64 total_size;
926 u64 mask; 926 unsigned long mask;
927 int shift; 927 int shift;
928 int npages; 928 int npages;
929 int err; 929 int err;
930 int i, j, n; 930 int i, j, n;
931 931
932 /* First check that we have enough alignment */ 932 mask = buffer_list[0].addr ^ *iova_start;
933 if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK))
934 return ERR_PTR(-EINVAL);
935
936 mask = 0;
937 total_size = 0; 933 total_size = 0;
938 for (i = 0; i < num_phys_buf; ++i) { 934 for (i = 0; i < num_phys_buf; ++i) {
939 if (i != 0) 935 if (i != 0)
@@ -947,17 +943,7 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd,
947 if (mask & ~PAGE_MASK) 943 if (mask & ~PAGE_MASK)
948 return ERR_PTR(-EINVAL); 944 return ERR_PTR(-EINVAL);
949 945
950 /* Find largest page shift we can use to cover buffers */ 946 shift = __ffs(mask | 1 << 31);
951 for (shift = PAGE_SHIFT; shift < 31; ++shift)
952 if (num_phys_buf > 1) {
953 if ((1ULL << shift) & mask)
954 break;
955 } else {
956 if (1ULL << shift >=
957 buffer_list[0].size +
958 (buffer_list[0].addr & ((1ULL << shift) - 1)))
959 break;
960 }
961 947
962 buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1); 948 buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1);
963 buffer_list[0].addr &= ~0ull << shift; 949 buffer_list[0].addr &= ~0ull << shift;
@@ -1270,6 +1256,8 @@ static int mthca_init_node_data(struct mthca_dev *dev)
1270 goto out; 1256 goto out;
1271 } 1257 }
1272 1258
1259 if (mthca_is_memfree(dev))
1260 dev->rev_id = be32_to_cpup((__be32 *) (out_mad->data + 32));
1273 memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8); 1261 memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8);
1274 1262
1275out: 1263out:
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 0e5461c65731..db5595bbf7f0 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1175,6 +1175,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1175{ 1175{
1176 int ret; 1176 int ret;
1177 int i; 1177 int i;
1178 struct mthca_next_seg *next;
1178 1179
1179 qp->refcount = 1; 1180 qp->refcount = 1;
1180 init_waitqueue_head(&qp->wait); 1181 init_waitqueue_head(&qp->wait);
@@ -1217,7 +1218,6 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1217 } 1218 }
1218 1219
1219 if (mthca_is_memfree(dev)) { 1220 if (mthca_is_memfree(dev)) {
1220 struct mthca_next_seg *next;
1221 struct mthca_data_seg *scatter; 1221 struct mthca_data_seg *scatter;
1222 int size = (sizeof (struct mthca_next_seg) + 1222 int size = (sizeof (struct mthca_next_seg) +
1223 qp->rq.max_gs * sizeof (struct mthca_data_seg)) / 16; 1223 qp->rq.max_gs * sizeof (struct mthca_data_seg)) / 16;
@@ -1240,6 +1240,13 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1240 qp->sq.wqe_shift) + 1240 qp->sq.wqe_shift) +
1241 qp->send_wqe_offset); 1241 qp->send_wqe_offset);
1242 } 1242 }
1243 } else {
1244 for (i = 0; i < qp->rq.max; ++i) {
1245 next = get_recv_wqe(qp, i);
1246 next->nda_op = htonl((((i + 1) % qp->rq.max) <<
1247 qp->rq.wqe_shift) | 1);
1248 }
1249
1243 } 1250 }
1244 1251
1245 qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); 1252 qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
@@ -1863,7 +1870,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1863 prev_wqe = qp->rq.last; 1870 prev_wqe = qp->rq.last;
1864 qp->rq.last = wqe; 1871 qp->rq.last = wqe;
1865 1872
1866 ((struct mthca_next_seg *) wqe)->nda_op = 0;
1867 ((struct mthca_next_seg *) wqe)->ee_nds = 1873 ((struct mthca_next_seg *) wqe)->ee_nds =
1868 cpu_to_be32(MTHCA_NEXT_DBD); 1874 cpu_to_be32(MTHCA_NEXT_DBD);
1869 ((struct mthca_next_seg *) wqe)->flags = 0; 1875 ((struct mthca_next_seg *) wqe)->flags = 0;
@@ -1885,9 +1891,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1885 1891
1886 qp->wrid[ind] = wr->wr_id; 1892 qp->wrid[ind] = wr->wr_id;
1887 1893
1888 ((struct mthca_next_seg *) prev_wqe)->nda_op =
1889 cpu_to_be32((ind << qp->rq.wqe_shift) | 1);
1890 wmb();
1891 ((struct mthca_next_seg *) prev_wqe)->ee_nds = 1894 ((struct mthca_next_seg *) prev_wqe)->ee_nds =
1892 cpu_to_be32(MTHCA_NEXT_DBD | size); 1895 cpu_to_be32(MTHCA_NEXT_DBD | size);
1893 1896
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 553d681f6813..a5ffff6e1026 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -175,9 +175,17 @@ static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd,
175 * scatter list L_Keys to the sentry value of 0x100. 175 * scatter list L_Keys to the sentry value of 0x100.
176 */ 176 */
177 for (i = 0; i < srq->max; ++i) { 177 for (i = 0; i < srq->max; ++i) {
178 wqe = get_wqe(srq, i); 178 struct mthca_next_seg *next;
179 179
180 *wqe_to_link(wqe) = i < srq->max - 1 ? i + 1 : -1; 180 next = wqe = get_wqe(srq, i);
181
182 if (i < srq->max - 1) {
183 *wqe_to_link(wqe) = i + 1;
184 next->nda_op = htonl(((i + 1) << srq->wqe_shift) | 1);
185 } else {
186 *wqe_to_link(wqe) = -1;
187 next->nda_op = 0;
188 }
181 189
182 for (scatter = wqe + sizeof (struct mthca_next_seg); 190 for (scatter = wqe + sizeof (struct mthca_next_seg);
183 (void *) scatter < wqe + (1 << srq->wqe_shift); 191 (void *) scatter < wqe + (1 << srq->wqe_shift);
@@ -470,16 +478,15 @@ out:
470void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr) 478void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr)
471{ 479{
472 int ind; 480 int ind;
481 struct mthca_next_seg *last_free;
473 482
474 ind = wqe_addr >> srq->wqe_shift; 483 ind = wqe_addr >> srq->wqe_shift;
475 484
476 spin_lock(&srq->lock); 485 spin_lock(&srq->lock);
477 486
478 if (likely(srq->first_free >= 0)) 487 last_free = get_wqe(srq, srq->last_free);
479 *wqe_to_link(get_wqe(srq, srq->last_free)) = ind; 488 *wqe_to_link(last_free) = ind;
480 else 489 last_free->nda_op = htonl((ind << srq->wqe_shift) | 1);
481 srq->first_free = ind;
482
483 *wqe_to_link(get_wqe(srq, ind)) = -1; 490 *wqe_to_link(get_wqe(srq, ind)) = -1;
484 srq->last_free = ind; 491 srq->last_free = ind;
485 492
@@ -506,15 +513,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
506 first_ind = srq->first_free; 513 first_ind = srq->first_free;
507 514
508 for (nreq = 0; wr; wr = wr->next) { 515 for (nreq = 0; wr; wr = wr->next) {
509 ind = srq->first_free; 516 ind = srq->first_free;
510
511 if (unlikely(ind < 0)) {
512 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
513 err = -ENOMEM;
514 *bad_wr = wr;
515 break;
516 }
517
518 wqe = get_wqe(srq, ind); 517 wqe = get_wqe(srq, ind);
519 next_ind = *wqe_to_link(wqe); 518 next_ind = *wqe_to_link(wqe);
520 519
@@ -528,7 +527,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
528 prev_wqe = srq->last; 527 prev_wqe = srq->last;
529 srq->last = wqe; 528 srq->last = wqe;
530 529
531 ((struct mthca_next_seg *) wqe)->nda_op = 0;
532 ((struct mthca_next_seg *) wqe)->ee_nds = 0; 530 ((struct mthca_next_seg *) wqe)->ee_nds = 0;
533 /* flags field will always remain 0 */ 531 /* flags field will always remain 0 */
534 532
@@ -549,9 +547,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
549 if (i < srq->max_gs) 547 if (i < srq->max_gs)
550 mthca_set_data_seg_inval(wqe); 548 mthca_set_data_seg_inval(wqe);
551 549
552 ((struct mthca_next_seg *) prev_wqe)->nda_op =
553 cpu_to_be32((ind << srq->wqe_shift) | 1);
554 wmb();
555 ((struct mthca_next_seg *) prev_wqe)->ee_nds = 550 ((struct mthca_next_seg *) prev_wqe)->ee_nds =
556 cpu_to_be32(MTHCA_NEXT_DBD); 551 cpu_to_be32(MTHCA_NEXT_DBD);
557 552
@@ -614,15 +609,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
614 spin_lock_irqsave(&srq->lock, flags); 609 spin_lock_irqsave(&srq->lock, flags);
615 610
616 for (nreq = 0; wr; ++nreq, wr = wr->next) { 611 for (nreq = 0; wr; ++nreq, wr = wr->next) {
617 ind = srq->first_free; 612 ind = srq->first_free;
618
619 if (unlikely(ind < 0)) {
620 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
621 err = -ENOMEM;
622 *bad_wr = wr;
623 break;
624 }
625
626 wqe = get_wqe(srq, ind); 613 wqe = get_wqe(srq, ind);
627 next_ind = *wqe_to_link(wqe); 614 next_ind = *wqe_to_link(wqe);
628 615
@@ -633,8 +620,6 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
633 break; 620 break;
634 } 621 }
635 622
636 ((struct mthca_next_seg *) wqe)->nda_op =
637 cpu_to_be32((next_ind << srq->wqe_shift) | 1);
638 ((struct mthca_next_seg *) wqe)->ee_nds = 0; 623 ((struct mthca_next_seg *) wqe)->ee_nds = 0;
639 /* flags field will always remain 0 */ 624 /* flags field will always remain 0 */
640 625