aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-08-29 19:06:29 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-29 19:06:29 -0400
commit502c7f1dd566e7ca8aabdb755182664c5fdaebf1 (patch)
tree31934a4da45c0cb83acd118a181db4c51967ac8a /drivers/infiniband/hw/mthca
parent2cba582a49f1535c1a12a687cfb3dab713c22cc4 (diff)
parent8f3d17fb7bcb7c255197d11469fb5e9695c9d2f4 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/infiniband/hw/mthca')
-rw-r--r--drivers/infiniband/hw/mthca/Makefile4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_allocator.c116
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c28
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c106
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.h20
-rw-r--r--drivers/infiniband/hw/mthca/mthca_config_reg.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c256
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h52
-rw-r--r--drivers/infiniband/hw/mthca/mthca_doorbell.h13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c63
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c179
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c36
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c35
-rw-r--r--drivers/infiniband/hw/mthca/mthca_pd.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c115
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h54
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c362
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c591
-rw-r--r--drivers/infiniband/hw/mthca/mthca_user.h11
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h114
25 files changed, 1523 insertions, 665 deletions
diff --git a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile
index 5dcbd43073e2..c44f7bae5424 100644
--- a/drivers/infiniband/hw/mthca/Makefile
+++ b/drivers/infiniband/hw/mthca/Makefile
@@ -1,5 +1,3 @@
1EXTRA_CFLAGS += -Idrivers/infiniband/include
2
3ifdef CONFIG_INFINIBAND_MTHCA_DEBUG 1ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
4EXTRA_CFLAGS += -DDEBUG 2EXTRA_CFLAGS += -DDEBUG
5endif 3endif
@@ -9,4 +7,4 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o
9ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \ 7ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
10 mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \ 8 mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \
11 mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \ 9 mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \
12 mthca_provider.o mthca_memfree.o mthca_uar.o 10 mthca_provider.o mthca_memfree.o mthca_uar.o mthca_srq.o
diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c
index b1db48dd91d6..9ba3211cef7c 100644
--- a/drivers/infiniband/hw/mthca/mthca_allocator.c
+++ b/drivers/infiniband/hw/mthca/mthca_allocator.c
@@ -177,3 +177,119 @@ void mthca_array_cleanup(struct mthca_array *array, int nent)
177 177
178 kfree(array->page_list); 178 kfree(array->page_list);
179} 179}
180
181/*
182 * Handling for queue buffers -- we allocate a bunch of memory and
183 * register it in a memory region at HCA virtual address 0. If the
184 * requested size is > max_direct, we split the allocation into
185 * multiple pages, so we don't require too much contiguous memory.
186 */
187
188int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct,
189 union mthca_buf *buf, int *is_direct, struct mthca_pd *pd,
190 int hca_write, struct mthca_mr *mr)
191{
192 int err = -ENOMEM;
193 int npages, shift;
194 u64 *dma_list = NULL;
195 dma_addr_t t;
196 int i;
197
198 if (size <= max_direct) {
199 *is_direct = 1;
200 npages = 1;
201 shift = get_order(size) + PAGE_SHIFT;
202
203 buf->direct.buf = dma_alloc_coherent(&dev->pdev->dev,
204 size, &t, GFP_KERNEL);
205 if (!buf->direct.buf)
206 return -ENOMEM;
207
208 pci_unmap_addr_set(&buf->direct, mapping, t);
209
210 memset(buf->direct.buf, 0, size);
211
212 while (t & ((1 << shift) - 1)) {
213 --shift;
214 npages *= 2;
215 }
216
217 dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
218 if (!dma_list)
219 goto err_free;
220
221 for (i = 0; i < npages; ++i)
222 dma_list[i] = t + i * (1 << shift);
223 } else {
224 *is_direct = 0;
225 npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
226 shift = PAGE_SHIFT;
227
228 dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
229 if (!dma_list)
230 return -ENOMEM;
231
232 buf->page_list = kmalloc(npages * sizeof *buf->page_list,
233 GFP_KERNEL);
234 if (!buf->page_list)
235 goto err_out;
236
237 for (i = 0; i < npages; ++i)
238 buf->page_list[i].buf = NULL;
239
240 for (i = 0; i < npages; ++i) {
241 buf->page_list[i].buf =
242 dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
243 &t, GFP_KERNEL);
244 if (!buf->page_list[i].buf)
245 goto err_free;
246
247 dma_list[i] = t;
248 pci_unmap_addr_set(&buf->page_list[i], mapping, t);
249
250 memset(buf->page_list[i].buf, 0, PAGE_SIZE);
251 }
252 }
253
254 err = mthca_mr_alloc_phys(dev, pd->pd_num,
255 dma_list, shift, npages,
256 0, size,
257 MTHCA_MPT_FLAG_LOCAL_READ |
258 (hca_write ? MTHCA_MPT_FLAG_LOCAL_WRITE : 0),
259 mr);
260 if (err)
261 goto err_free;
262
263 kfree(dma_list);
264
265 return 0;
266
267err_free:
268 mthca_buf_free(dev, size, buf, *is_direct, NULL);
269
270err_out:
271 kfree(dma_list);
272
273 return err;
274}
275
276void mthca_buf_free(struct mthca_dev *dev, int size, union mthca_buf *buf,
277 int is_direct, struct mthca_mr *mr)
278{
279 int i;
280
281 if (mr)
282 mthca_free_mr(dev, mr);
283
284 if (is_direct)
285 dma_free_coherent(&dev->pdev->dev, size, buf->direct.buf,
286 pci_unmap_addr(&buf->direct, mapping));
287 else {
288 for (i = 0; i < (size + PAGE_SIZE - 1) / PAGE_SIZE; ++i)
289 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
290 buf->page_list[i].buf,
291 pci_unmap_addr(&buf->page_list[i],
292 mapping));
293 kfree(buf->page_list);
294 }
295}
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index d58dcbe66488..889e85096736 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -35,22 +35,22 @@
35 35
36#include <linux/init.h> 36#include <linux/init.h>
37 37
38#include <ib_verbs.h> 38#include <rdma/ib_verbs.h>
39#include <ib_cache.h> 39#include <rdma/ib_cache.h>
40 40
41#include "mthca_dev.h" 41#include "mthca_dev.h"
42 42
43struct mthca_av { 43struct mthca_av {
44 u32 port_pd; 44 __be32 port_pd;
45 u8 reserved1; 45 u8 reserved1;
46 u8 g_slid; 46 u8 g_slid;
47 u16 dlid; 47 __be16 dlid;
48 u8 reserved2; 48 u8 reserved2;
49 u8 gid_index; 49 u8 gid_index;
50 u8 msg_sr; 50 u8 msg_sr;
51 u8 hop_limit; 51 u8 hop_limit;
52 u32 sl_tclass_flowlabel; 52 __be32 sl_tclass_flowlabel;
53 u32 dgid[4]; 53 __be32 dgid[4];
54}; 54};
55 55
56int mthca_create_ah(struct mthca_dev *dev, 56int mthca_create_ah(struct mthca_dev *dev,
@@ -128,7 +128,7 @@ on_hca_fail:
128 av, (unsigned long) ah->avdma); 128 av, (unsigned long) ah->avdma);
129 for (j = 0; j < 8; ++j) 129 for (j = 0; j < 8; ++j)
130 printk(KERN_DEBUG " [%2x] %08x\n", 130 printk(KERN_DEBUG " [%2x] %08x\n",
131 j * 4, be32_to_cpu(((u32 *) av)[j])); 131 j * 4, be32_to_cpu(((__be32 *) av)[j]));
132 } 132 }
133 133
134 if (ah->type == MTHCA_AH_ON_HCA) { 134 if (ah->type == MTHCA_AH_ON_HCA) {
@@ -169,7 +169,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
169 169
170 header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; 170 header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28;
171 header->lrh.destination_lid = ah->av->dlid; 171 header->lrh.destination_lid = ah->av->dlid;
172 header->lrh.source_lid = ah->av->g_slid & 0x7f; 172 header->lrh.source_lid = cpu_to_be16(ah->av->g_slid & 0x7f);
173 if (ah->av->g_slid & 0x80) { 173 if (ah->av->g_slid & 0x80) {
174 header->grh_present = 1; 174 header->grh_present = 1;
175 header->grh.traffic_class = 175 header->grh.traffic_class =
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 1557a522d831..cc758a2d2bc6 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -36,7 +37,7 @@
36#include <linux/pci.h> 37#include <linux/pci.h>
37#include <linux/errno.h> 38#include <linux/errno.h>
38#include <asm/io.h> 39#include <asm/io.h>
39#include <ib_mad.h> 40#include <rdma/ib_mad.h>
40 41
41#include "mthca_dev.h" 42#include "mthca_dev.h"
42#include "mthca_config_reg.h" 43#include "mthca_config_reg.h"
@@ -108,6 +109,7 @@ enum {
108 CMD_SW2HW_SRQ = 0x35, 109 CMD_SW2HW_SRQ = 0x35,
109 CMD_HW2SW_SRQ = 0x36, 110 CMD_HW2SW_SRQ = 0x36,
110 CMD_QUERY_SRQ = 0x37, 111 CMD_QUERY_SRQ = 0x37,
112 CMD_ARM_SRQ = 0x40,
111 113
112 /* QP/EE commands */ 114 /* QP/EE commands */
113 CMD_RST2INIT_QPEE = 0x19, 115 CMD_RST2INIT_QPEE = 0x19,
@@ -219,20 +221,20 @@ static int mthca_cmd_post(struct mthca_dev *dev,
219 * (and some architectures such as ia64 implement memcpy_toio 221 * (and some architectures such as ia64 implement memcpy_toio
220 * in terms of writeb). 222 * in terms of writeb).
221 */ 223 */
222 __raw_writel(cpu_to_be32(in_param >> 32), dev->hcr + 0 * 4); 224 __raw_writel((__force u32) cpu_to_be32(in_param >> 32), dev->hcr + 0 * 4);
223 __raw_writel(cpu_to_be32(in_param & 0xfffffffful), dev->hcr + 1 * 4); 225 __raw_writel((__force u32) cpu_to_be32(in_param & 0xfffffffful), dev->hcr + 1 * 4);
224 __raw_writel(cpu_to_be32(in_modifier), dev->hcr + 2 * 4); 226 __raw_writel((__force u32) cpu_to_be32(in_modifier), dev->hcr + 2 * 4);
225 __raw_writel(cpu_to_be32(out_param >> 32), dev->hcr + 3 * 4); 227 __raw_writel((__force u32) cpu_to_be32(out_param >> 32), dev->hcr + 3 * 4);
226 __raw_writel(cpu_to_be32(out_param & 0xfffffffful), dev->hcr + 4 * 4); 228 __raw_writel((__force u32) cpu_to_be32(out_param & 0xfffffffful), dev->hcr + 4 * 4);
227 __raw_writel(cpu_to_be32(token << 16), dev->hcr + 5 * 4); 229 __raw_writel((__force u32) cpu_to_be32(token << 16), dev->hcr + 5 * 4);
228 230
229 /* __raw_writel may not order writes. */ 231 /* __raw_writel may not order writes. */
230 wmb(); 232 wmb();
231 233
232 __raw_writel(cpu_to_be32((1 << HCR_GO_BIT) | 234 __raw_writel((__force u32) cpu_to_be32((1 << HCR_GO_BIT) |
233 (event ? (1 << HCA_E_BIT) : 0) | 235 (event ? (1 << HCA_E_BIT) : 0) |
234 (op_modifier << HCR_OPMOD_SHIFT) | 236 (op_modifier << HCR_OPMOD_SHIFT) |
235 op), dev->hcr + 6 * 4); 237 op), dev->hcr + 6 * 4);
236 238
237out: 239out:
238 up(&dev->cmd.hcr_sem); 240 up(&dev->cmd.hcr_sem);
@@ -273,12 +275,14 @@ static int mthca_cmd_poll(struct mthca_dev *dev,
273 goto out; 275 goto out;
274 } 276 }
275 277
276 if (out_is_imm) { 278 if (out_is_imm)
277 memcpy_fromio(out_param, dev->hcr + HCR_OUT_PARAM_OFFSET, sizeof (u64)); 279 *out_param =
278 be64_to_cpus(out_param); 280 (u64) be32_to_cpu((__force __be32)
279 } 281 __raw_readl(dev->hcr + HCR_OUT_PARAM_OFFSET)) << 32 |
282 (u64) be32_to_cpu((__force __be32)
283 __raw_readl(dev->hcr + HCR_OUT_PARAM_OFFSET + 4));
280 284
281 *status = be32_to_cpu(__raw_readl(dev->hcr + HCR_STATUS_OFFSET)) >> 24; 285 *status = be32_to_cpu((__force __be32) __raw_readl(dev->hcr + HCR_STATUS_OFFSET)) >> 24;
282 286
283out: 287out:
284 up(&dev->cmd.poll_sem); 288 up(&dev->cmd.poll_sem);
@@ -1029,6 +1033,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1029 1033
1030 mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", 1034 mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n",
1031 dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); 1035 dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz);
1036 mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n",
1037 dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz);
1032 mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", 1038 mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n",
1033 dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); 1039 dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz);
1034 mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", 1040 mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n",
@@ -1082,6 +1088,34 @@ out:
1082 return err; 1088 return err;
1083} 1089}
1084 1090
1091static void get_board_id(void *vsd, char *board_id)
1092{
1093 int i;
1094
1095#define VSD_OFFSET_SIG1 0x00
1096#define VSD_OFFSET_SIG2 0xde
1097#define VSD_OFFSET_MLX_BOARD_ID 0xd0
1098#define VSD_OFFSET_TS_BOARD_ID 0x20
1099
1100#define VSD_SIGNATURE_TOPSPIN 0x5ad
1101
1102 memset(board_id, 0, MTHCA_BOARD_ID_LEN);
1103
1104 if (be16_to_cpup(vsd + VSD_OFFSET_SIG1) == VSD_SIGNATURE_TOPSPIN &&
1105 be16_to_cpup(vsd + VSD_OFFSET_SIG2) == VSD_SIGNATURE_TOPSPIN) {
1106 strlcpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MTHCA_BOARD_ID_LEN);
1107 } else {
1108 /*
1109 * The board ID is a string but the firmware byte
1110 * swaps each 4-byte word before passing it back to
1111 * us. Therefore we need to swab it before printing.
1112 */
1113 for (i = 0; i < 4; ++i)
1114 ((u32 *) board_id)[i] =
1115 swab32(*(u32 *) (vsd + VSD_OFFSET_MLX_BOARD_ID + i * 4));
1116 }
1117}
1118
1085int mthca_QUERY_ADAPTER(struct mthca_dev *dev, 1119int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
1086 struct mthca_adapter *adapter, u8 *status) 1120 struct mthca_adapter *adapter, u8 *status)
1087{ 1121{
@@ -1094,6 +1128,7 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
1094#define QUERY_ADAPTER_DEVICE_ID_OFFSET 0x04 1128#define QUERY_ADAPTER_DEVICE_ID_OFFSET 0x04
1095#define QUERY_ADAPTER_REVISION_ID_OFFSET 0x08 1129#define QUERY_ADAPTER_REVISION_ID_OFFSET 0x08
1096#define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 1130#define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10
1131#define QUERY_ADAPTER_VSD_OFFSET 0x20
1097 1132
1098 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 1133 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
1099 if (IS_ERR(mailbox)) 1134 if (IS_ERR(mailbox))
@@ -1111,6 +1146,9 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
1111 MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET); 1146 MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET);
1112 MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); 1147 MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET);
1113 1148
1149 get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4,
1150 adapter->board_id);
1151
1114out: 1152out:
1115 mthca_free_mailbox(dev, mailbox); 1153 mthca_free_mailbox(dev, mailbox);
1116 return err; 1154 return err;
@@ -1121,7 +1159,7 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
1121 u8 *status) 1159 u8 *status)
1122{ 1160{
1123 struct mthca_mailbox *mailbox; 1161 struct mthca_mailbox *mailbox;
1124 u32 *inbox; 1162 __be32 *inbox;
1125 int err; 1163 int err;
1126 1164
1127#define INIT_HCA_IN_SIZE 0x200 1165#define INIT_HCA_IN_SIZE 0x200
@@ -1247,10 +1285,8 @@ int mthca_INIT_IB(struct mthca_dev *dev,
1247#define INIT_IB_FLAG_SIG (1 << 18) 1285#define INIT_IB_FLAG_SIG (1 << 18)
1248#define INIT_IB_FLAG_NG (1 << 17) 1286#define INIT_IB_FLAG_NG (1 << 17)
1249#define INIT_IB_FLAG_G0 (1 << 16) 1287#define INIT_IB_FLAG_G0 (1 << 16)
1250#define INIT_IB_FLAG_1X (1 << 8)
1251#define INIT_IB_FLAG_4X (1 << 9)
1252#define INIT_IB_FLAG_12X (1 << 11)
1253#define INIT_IB_VL_SHIFT 4 1288#define INIT_IB_VL_SHIFT 4
1289#define INIT_IB_PORT_WIDTH_SHIFT 8
1254#define INIT_IB_MTU_SHIFT 12 1290#define INIT_IB_MTU_SHIFT 12
1255#define INIT_IB_MAX_GID_OFFSET 0x06 1291#define INIT_IB_MAX_GID_OFFSET 0x06
1256#define INIT_IB_MAX_PKEY_OFFSET 0x0a 1292#define INIT_IB_MAX_PKEY_OFFSET 0x0a
@@ -1266,12 +1302,11 @@ int mthca_INIT_IB(struct mthca_dev *dev,
1266 memset(inbox, 0, INIT_IB_IN_SIZE); 1302 memset(inbox, 0, INIT_IB_IN_SIZE);
1267 1303
1268 flags = 0; 1304 flags = 0;
1269 flags |= param->enable_1x ? INIT_IB_FLAG_1X : 0;
1270 flags |= param->enable_4x ? INIT_IB_FLAG_4X : 0;
1271 flags |= param->set_guid0 ? INIT_IB_FLAG_G0 : 0; 1305 flags |= param->set_guid0 ? INIT_IB_FLAG_G0 : 0;
1272 flags |= param->set_node_guid ? INIT_IB_FLAG_NG : 0; 1306 flags |= param->set_node_guid ? INIT_IB_FLAG_NG : 0;
1273 flags |= param->set_si_guid ? INIT_IB_FLAG_SIG : 0; 1307 flags |= param->set_si_guid ? INIT_IB_FLAG_SIG : 0;
1274 flags |= param->vl_cap << INIT_IB_VL_SHIFT; 1308 flags |= param->vl_cap << INIT_IB_VL_SHIFT;
1309 flags |= param->port_width << INIT_IB_PORT_WIDTH_SHIFT;
1275 flags |= param->mtu_cap << INIT_IB_MTU_SHIFT; 1310 flags |= param->mtu_cap << INIT_IB_MTU_SHIFT;
1276 MTHCA_PUT(inbox, flags, INIT_IB_FLAGS_OFFSET); 1311 MTHCA_PUT(inbox, flags, INIT_IB_FLAGS_OFFSET);
1277 1312
@@ -1342,7 +1377,7 @@ int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *st
1342int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status) 1377int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status)
1343{ 1378{
1344 struct mthca_mailbox *mailbox; 1379 struct mthca_mailbox *mailbox;
1345 u64 *inbox; 1380 __be64 *inbox;
1346 int err; 1381 int err;
1347 1382
1348 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 1383 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
@@ -1468,6 +1503,27 @@ int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
1468 CMD_TIME_CLASS_A, status); 1503 CMD_TIME_CLASS_A, status);
1469} 1504}
1470 1505
1506int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
1507 int srq_num, u8 *status)
1508{
1509 return mthca_cmd(dev, mailbox->dma, srq_num, 0, CMD_SW2HW_SRQ,
1510 CMD_TIME_CLASS_A, status);
1511}
1512
1513int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
1514 int srq_num, u8 *status)
1515{
1516 return mthca_cmd_box(dev, 0, mailbox->dma, srq_num, 0,
1517 CMD_HW2SW_SRQ,
1518 CMD_TIME_CLASS_A, status);
1519}
1520
1521int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status)
1522{
1523 return mthca_cmd(dev, limit, srq_num, 0, CMD_ARM_SRQ,
1524 CMD_TIME_CLASS_B, status);
1525}
1526
1471int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, 1527int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
1472 int is_ee, struct mthca_mailbox *mailbox, u32 optmask, 1528 int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
1473 u8 *status) 1529 u8 *status)
@@ -1513,7 +1569,7 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
1513 if (i % 8 == 0) 1569 if (i % 8 == 0)
1514 printk(" [%02x] ", i * 4); 1570 printk(" [%02x] ", i * 4);
1515 printk(" %08x", 1571 printk(" %08x",
1516 be32_to_cpu(((u32 *) mailbox->buf)[i + 2])); 1572 be32_to_cpu(((__be32 *) mailbox->buf)[i + 2]));
1517 if ((i + 1) % 8 == 0) 1573 if ((i + 1) % 8 == 0)
1518 printk("\n"); 1574 printk("\n");
1519 } 1575 }
@@ -1533,7 +1589,7 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
1533 if (i % 8 == 0) 1589 if (i % 8 == 0)
1534 printk("[%02x] ", i * 4); 1590 printk("[%02x] ", i * 4);
1535 printk(" %08x", 1591 printk(" %08x",
1536 be32_to_cpu(((u32 *) mailbox->buf)[i + 2])); 1592 be32_to_cpu(((__be32 *) mailbox->buf)[i + 2]));
1537 if ((i + 1) % 8 == 0) 1593 if ((i + 1) % 8 == 0)
1538 printk("\n"); 1594 printk("\n");
1539 } 1595 }
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
index ed517f175dd6..65f976a13e02 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -35,7 +36,7 @@
35#ifndef MTHCA_CMD_H 36#ifndef MTHCA_CMD_H
36#define MTHCA_CMD_H 37#define MTHCA_CMD_H
37 38
38#include <ib_verbs.h> 39#include <rdma/ib_verbs.h>
39 40
40#define MTHCA_MAILBOX_SIZE 4096 41#define MTHCA_MAILBOX_SIZE 4096
41 42
@@ -183,10 +184,11 @@ struct mthca_dev_lim {
183}; 184};
184 185
185struct mthca_adapter { 186struct mthca_adapter {
186 u32 vendor_id; 187 u32 vendor_id;
187 u32 device_id; 188 u32 device_id;
188 u32 revision_id; 189 u32 revision_id;
189 u8 inta_pin; 190 char board_id[MTHCA_BOARD_ID_LEN];
191 u8 inta_pin;
190}; 192};
191 193
192struct mthca_init_hca_param { 194struct mthca_init_hca_param {
@@ -218,8 +220,7 @@ struct mthca_init_hca_param {
218}; 220};
219 221
220struct mthca_init_ib_param { 222struct mthca_init_ib_param {
221 int enable_1x; 223 int port_width;
222 int enable_4x;
223 int vl_cap; 224 int vl_cap;
224 int mtu_cap; 225 int mtu_cap;
225 u16 gid_cap; 226 u16 gid_cap;
@@ -297,6 +298,11 @@ int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
297 int cq_num, u8 *status); 298 int cq_num, u8 *status);
298int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, 299int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
299 int cq_num, u8 *status); 300 int cq_num, u8 *status);
301int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
302 int srq_num, u8 *status);
303int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
304 int srq_num, u8 *status);
305int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status);
300int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, 306int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
301 int is_ee, struct mthca_mailbox *mailbox, u32 optmask, 307 int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
302 u8 *status); 308 u8 *status);
diff --git a/drivers/infiniband/hw/mthca/mthca_config_reg.h b/drivers/infiniband/hw/mthca/mthca_config_reg.h
index b4bfbbfe2c3d..afa56bfaab2e 100644
--- a/drivers/infiniband/hw/mthca/mthca_config_reg.h
+++ b/drivers/infiniband/hw/mthca/mthca_config_reg.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 5687c3014522..8600b6c3e0c2 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -2,6 +2,8 @@
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved. 4 * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
5 * 7 *
6 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU 9 * licenses. You may choose to be licensed under the terms of the GNU
@@ -37,7 +39,7 @@
37#include <linux/init.h> 39#include <linux/init.h>
38#include <linux/hardirq.h> 40#include <linux/hardirq.h>
39 41
40#include <ib_pack.h> 42#include <rdma/ib_pack.h>
41 43
42#include "mthca_dev.h" 44#include "mthca_dev.h"
43#include "mthca_cmd.h" 45#include "mthca_cmd.h"
@@ -55,21 +57,21 @@ enum {
55 * Must be packed because start is 64 bits but only aligned to 32 bits. 57 * Must be packed because start is 64 bits but only aligned to 32 bits.
56 */ 58 */
57struct mthca_cq_context { 59struct mthca_cq_context {
58 u32 flags; 60 __be32 flags;
59 u64 start; 61 __be64 start;
60 u32 logsize_usrpage; 62 __be32 logsize_usrpage;
61 u32 error_eqn; /* Tavor only */ 63 __be32 error_eqn; /* Tavor only */
62 u32 comp_eqn; 64 __be32 comp_eqn;
63 u32 pd; 65 __be32 pd;
64 u32 lkey; 66 __be32 lkey;
65 u32 last_notified_index; 67 __be32 last_notified_index;
66 u32 solicit_producer_index; 68 __be32 solicit_producer_index;
67 u32 consumer_index; 69 __be32 consumer_index;
68 u32 producer_index; 70 __be32 producer_index;
69 u32 cqn; 71 __be32 cqn;
70 u32 ci_db; /* Arbel only */ 72 __be32 ci_db; /* Arbel only */
71 u32 state_db; /* Arbel only */ 73 __be32 state_db; /* Arbel only */
72 u32 reserved; 74 u32 reserved;
73} __attribute__((packed)); 75} __attribute__((packed));
74 76
75#define MTHCA_CQ_STATUS_OK ( 0 << 28) 77#define MTHCA_CQ_STATUS_OK ( 0 << 28)
@@ -108,31 +110,31 @@ enum {
108}; 110};
109 111
110struct mthca_cqe { 112struct mthca_cqe {
111 u32 my_qpn; 113 __be32 my_qpn;
112 u32 my_ee; 114 __be32 my_ee;
113 u32 rqpn; 115 __be32 rqpn;
114 u16 sl_g_mlpath; 116 __be16 sl_g_mlpath;
115 u16 rlid; 117 __be16 rlid;
116 u32 imm_etype_pkey_eec; 118 __be32 imm_etype_pkey_eec;
117 u32 byte_cnt; 119 __be32 byte_cnt;
118 u32 wqe; 120 __be32 wqe;
119 u8 opcode; 121 u8 opcode;
120 u8 is_send; 122 u8 is_send;
121 u8 reserved; 123 u8 reserved;
122 u8 owner; 124 u8 owner;
123}; 125};
124 126
125struct mthca_err_cqe { 127struct mthca_err_cqe {
126 u32 my_qpn; 128 __be32 my_qpn;
127 u32 reserved1[3]; 129 u32 reserved1[3];
128 u8 syndrome; 130 u8 syndrome;
129 u8 reserved2; 131 u8 reserved2;
130 u16 db_cnt; 132 __be16 db_cnt;
131 u32 reserved3; 133 u32 reserved3;
132 u32 wqe; 134 __be32 wqe;
133 u8 opcode; 135 u8 opcode;
134 u8 reserved4[2]; 136 u8 reserved4[2];
135 u8 owner; 137 u8 owner;
136}; 138};
137 139
138#define MTHCA_CQ_ENTRY_OWNER_SW (0 << 7) 140#define MTHCA_CQ_ENTRY_OWNER_SW (0 << 7)
@@ -191,7 +193,7 @@ static void dump_cqe(struct mthca_dev *dev, void *cqe_ptr)
191static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq, 193static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
192 int incr) 194 int incr)
193{ 195{
194 u32 doorbell[2]; 196 __be32 doorbell[2];
195 197
196 if (mthca_is_memfree(dev)) { 198 if (mthca_is_memfree(dev)) {
197 *cq->set_ci_db = cpu_to_be32(cq->cons_index); 199 *cq->set_ci_db = cpu_to_be32(cq->cons_index);
@@ -222,7 +224,8 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
222 cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); 224 cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
223} 225}
224 226
225void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn) 227void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
228 struct mthca_srq *srq)
226{ 229{
227 struct mthca_cq *cq; 230 struct mthca_cq *cq;
228 struct mthca_cqe *cqe; 231 struct mthca_cqe *cqe;
@@ -263,8 +266,11 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn)
263 */ 266 */
264 while (prod_index > cq->cons_index) { 267 while (prod_index > cq->cons_index) {
265 cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe); 268 cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe);
266 if (cqe->my_qpn == cpu_to_be32(qpn)) 269 if (cqe->my_qpn == cpu_to_be32(qpn)) {
270 if (srq)
271 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
267 ++nfreed; 272 ++nfreed;
273 }
268 else if (nfreed) 274 else if (nfreed)
269 memcpy(get_cqe(cq, (prod_index - 1 + nfreed) & 275 memcpy(get_cqe(cq, (prod_index - 1 + nfreed) &
270 cq->ibcq.cqe), 276 cq->ibcq.cqe),
@@ -291,7 +297,7 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
291{ 297{
292 int err; 298 int err;
293 int dbd; 299 int dbd;
294 u32 new_wqe; 300 __be32 new_wqe;
295 301
296 if (cqe->syndrome == SYNDROME_LOCAL_QP_OP_ERR) { 302 if (cqe->syndrome == SYNDROME_LOCAL_QP_OP_ERR) {
297 mthca_dbg(dev, "local QP operation err " 303 mthca_dbg(dev, "local QP operation err "
@@ -365,6 +371,13 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
365 break; 371 break;
366 } 372 }
367 373
374 /*
375 * Mem-free HCAs always generate one CQE per WQE, even in the
376 * error case, so we don't have to check the doorbell count, etc.
377 */
378 if (mthca_is_memfree(dev))
379 return 0;
380
368 err = mthca_free_err_wqe(dev, qp, is_send, wqe_index, &dbd, &new_wqe); 381 err = mthca_free_err_wqe(dev, qp, is_send, wqe_index, &dbd, &new_wqe);
369 if (err) 382 if (err)
370 return err; 383 return err;
@@ -373,12 +386,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
373 * If we're at the end of the WQE chain, or we've used up our 386 * If we're at the end of the WQE chain, or we've used up our
374 * doorbell count, free the CQE. Otherwise just update it for 387 * doorbell count, free the CQE. Otherwise just update it for
375 * the next poll operation. 388 * the next poll operation.
376 *
377 * This does not apply to mem-free HCAs: they don't use the
378 * doorbell count field, and so we should always free the CQE.
379 */ 389 */
380 if (mthca_is_memfree(dev) || 390 if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
381 !(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
382 return 0; 391 return 0;
383 392
384 cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd); 393 cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd);
@@ -450,23 +459,27 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
450 >> wq->wqe_shift); 459 >> wq->wqe_shift);
451 entry->wr_id = (*cur_qp)->wrid[wqe_index + 460 entry->wr_id = (*cur_qp)->wrid[wqe_index +
452 (*cur_qp)->rq.max]; 461 (*cur_qp)->rq.max];
462 } else if ((*cur_qp)->ibqp.srq) {
463 struct mthca_srq *srq = to_msrq((*cur_qp)->ibqp.srq);
464 u32 wqe = be32_to_cpu(cqe->wqe);
465 wq = NULL;
466 wqe_index = wqe >> srq->wqe_shift;
467 entry->wr_id = srq->wrid[wqe_index];
468 mthca_free_srq_wqe(srq, wqe);
453 } else { 469 } else {
454 wq = &(*cur_qp)->rq; 470 wq = &(*cur_qp)->rq;
455 wqe_index = be32_to_cpu(cqe->wqe) >> wq->wqe_shift; 471 wqe_index = be32_to_cpu(cqe->wqe) >> wq->wqe_shift;
456 entry->wr_id = (*cur_qp)->wrid[wqe_index]; 472 entry->wr_id = (*cur_qp)->wrid[wqe_index];
457 } 473 }
458 474
459 if (wq->last_comp < wqe_index) 475 if (wq) {
460 wq->tail += wqe_index - wq->last_comp; 476 if (wq->last_comp < wqe_index)
461 else 477 wq->tail += wqe_index - wq->last_comp;
462 wq->tail += wqe_index + wq->max - wq->last_comp; 478 else
463 479 wq->tail += wqe_index + wq->max - wq->last_comp;
464 wq->last_comp = wqe_index;
465 480
466 if (0) 481 wq->last_comp = wqe_index;
467 mthca_dbg(dev, "%s completion for QP %06x, index %d (nr %d)\n", 482 }
468 is_send ? "Send" : "Receive",
469 (*cur_qp)->qpn, wqe_index, wq->max);
470 483
471 if (is_error) { 484 if (is_error) {
472 err = handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send, 485 err = handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
@@ -584,13 +597,13 @@ int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
584 597
585int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify) 598int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify)
586{ 599{
587 u32 doorbell[2]; 600 __be32 doorbell[2];
588 601
589 doorbell[0] = cpu_to_be32((notify == IB_CQ_SOLICITED ? 602 doorbell[0] = cpu_to_be32((notify == IB_CQ_SOLICITED ?
590 MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL : 603 MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
591 MTHCA_TAVOR_CQ_DB_REQ_NOT) | 604 MTHCA_TAVOR_CQ_DB_REQ_NOT) |
592 to_mcq(cq)->cqn); 605 to_mcq(cq)->cqn);
593 doorbell[1] = 0xffffffff; 606 doorbell[1] = (__force __be32) 0xffffffff;
594 607
595 mthca_write64(doorbell, 608 mthca_write64(doorbell,
596 to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL, 609 to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
@@ -602,9 +615,9 @@ int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify)
602int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) 615int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
603{ 616{
604 struct mthca_cq *cq = to_mcq(ibcq); 617 struct mthca_cq *cq = to_mcq(ibcq);
605 u32 doorbell[2]; 618 __be32 doorbell[2];
606 u32 sn; 619 u32 sn;
607 u32 ci; 620 __be32 ci;
608 621
609 sn = cq->arm_sn & 3; 622 sn = cq->arm_sn & 3;
610 ci = cpu_to_be32(cq->cons_index); 623 ci = cpu_to_be32(cq->cons_index);
@@ -637,113 +650,8 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
637 650
638static void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq *cq) 651static void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq *cq)
639{ 652{
640 int i; 653 mthca_buf_free(dev, (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE,
641 int size; 654 &cq->queue, cq->is_direct, &cq->mr);
642
643 if (cq->is_direct)
644 dma_free_coherent(&dev->pdev->dev,
645 (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE,
646 cq->queue.direct.buf,
647 pci_unmap_addr(&cq->queue.direct,
648 mapping));
649 else {
650 size = (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE;
651 for (i = 0; i < (size + PAGE_SIZE - 1) / PAGE_SIZE; ++i)
652 if (cq->queue.page_list[i].buf)
653 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
654 cq->queue.page_list[i].buf,
655 pci_unmap_addr(&cq->queue.page_list[i],
656 mapping));
657
658 kfree(cq->queue.page_list);
659 }
660}
661
662static int mthca_alloc_cq_buf(struct mthca_dev *dev, int size,
663 struct mthca_cq *cq)
664{
665 int err = -ENOMEM;
666 int npages, shift;
667 u64 *dma_list = NULL;
668 dma_addr_t t;
669 int i;
670
671 if (size <= MTHCA_MAX_DIRECT_CQ_SIZE) {
672 cq->is_direct = 1;
673 npages = 1;
674 shift = get_order(size) + PAGE_SHIFT;
675
676 cq->queue.direct.buf = dma_alloc_coherent(&dev->pdev->dev,
677 size, &t, GFP_KERNEL);
678 if (!cq->queue.direct.buf)
679 return -ENOMEM;
680
681 pci_unmap_addr_set(&cq->queue.direct, mapping, t);
682
683 memset(cq->queue.direct.buf, 0, size);
684
685 while (t & ((1 << shift) - 1)) {
686 --shift;
687 npages *= 2;
688 }
689
690 dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
691 if (!dma_list)
692 goto err_free;
693
694 for (i = 0; i < npages; ++i)
695 dma_list[i] = t + i * (1 << shift);
696 } else {
697 cq->is_direct = 0;
698 npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
699 shift = PAGE_SHIFT;
700
701 dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
702 if (!dma_list)
703 return -ENOMEM;
704
705 cq->queue.page_list = kmalloc(npages * sizeof *cq->queue.page_list,
706 GFP_KERNEL);
707 if (!cq->queue.page_list)
708 goto err_out;
709
710 for (i = 0; i < npages; ++i)
711 cq->queue.page_list[i].buf = NULL;
712
713 for (i = 0; i < npages; ++i) {
714 cq->queue.page_list[i].buf =
715 dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
716 &t, GFP_KERNEL);
717 if (!cq->queue.page_list[i].buf)
718 goto err_free;
719
720 dma_list[i] = t;
721 pci_unmap_addr_set(&cq->queue.page_list[i], mapping, t);
722
723 memset(cq->queue.page_list[i].buf, 0, PAGE_SIZE);
724 }
725 }
726
727 err = mthca_mr_alloc_phys(dev, dev->driver_pd.pd_num,
728 dma_list, shift, npages,
729 0, size,
730 MTHCA_MPT_FLAG_LOCAL_WRITE |
731 MTHCA_MPT_FLAG_LOCAL_READ,
732 &cq->mr);
733 if (err)
734 goto err_free;
735
736 kfree(dma_list);
737
738 return 0;
739
740err_free:
741 mthca_free_cq_buf(dev, cq);
742
743err_out:
744 kfree(dma_list);
745
746 return err;
747} 655}
748 656
749int mthca_init_cq(struct mthca_dev *dev, int nent, 657int mthca_init_cq(struct mthca_dev *dev, int nent,
@@ -795,7 +703,9 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
795 cq_context = mailbox->buf; 703 cq_context = mailbox->buf;
796 704
797 if (cq->is_kernel) { 705 if (cq->is_kernel) {
798 err = mthca_alloc_cq_buf(dev, size, cq); 706 err = mthca_buf_alloc(dev, size, MTHCA_MAX_DIRECT_CQ_SIZE,
707 &cq->queue, &cq->is_direct,
708 &dev->driver_pd, 1, &cq->mr);
799 if (err) 709 if (err)
800 goto err_out_mailbox; 710 goto err_out_mailbox;
801 711
@@ -811,7 +721,6 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
811 cq_context->flags = cpu_to_be32(MTHCA_CQ_STATUS_OK | 721 cq_context->flags = cpu_to_be32(MTHCA_CQ_STATUS_OK |
812 MTHCA_CQ_STATE_DISARMED | 722 MTHCA_CQ_STATE_DISARMED |
813 MTHCA_CQ_FLAG_TR); 723 MTHCA_CQ_FLAG_TR);
814 cq_context->start = cpu_to_be64(0);
815 cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24); 724 cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
816 if (ctx) 725 if (ctx)
817 cq_context->logsize_usrpage |= cpu_to_be32(ctx->uar.index); 726 cq_context->logsize_usrpage |= cpu_to_be32(ctx->uar.index);
@@ -857,10 +766,8 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
857 return 0; 766 return 0;
858 767
859err_out_free_mr: 768err_out_free_mr:
860 if (cq->is_kernel) { 769 if (cq->is_kernel)
861 mthca_free_mr(dev, &cq->mr);
862 mthca_free_cq_buf(dev, cq); 770 mthca_free_cq_buf(dev, cq);
863 }
864 771
865err_out_mailbox: 772err_out_mailbox:
866 mthca_free_mailbox(dev, mailbox); 773 mthca_free_mailbox(dev, mailbox);
@@ -904,7 +811,7 @@ void mthca_free_cq(struct mthca_dev *dev,
904 mthca_warn(dev, "HW2SW_CQ returned status 0x%02x\n", status); 811 mthca_warn(dev, "HW2SW_CQ returned status 0x%02x\n", status);
905 812
906 if (0) { 813 if (0) {
907 u32 *ctx = mailbox->buf; 814 __be32 *ctx = mailbox->buf;
908 int j; 815 int j;
909 816
910 printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n", 817 printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
@@ -928,7 +835,6 @@ void mthca_free_cq(struct mthca_dev *dev,
928 wait_event(cq->wait, !atomic_read(&cq->refcount)); 835 wait_event(cq->wait, !atomic_read(&cq->refcount));
929 836
930 if (cq->is_kernel) { 837 if (cq->is_kernel) {
931 mthca_free_mr(dev, &cq->mr);
932 mthca_free_cq_buf(dev, cq); 838 mthca_free_cq_buf(dev, cq);
933 if (mthca_is_memfree(dev)) { 839 if (mthca_is_memfree(dev)) {
934 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); 840 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 5ecdd2eeeb0f..7bff5a8425f4 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -2,6 +2,8 @@
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005 Cisco Systems. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
5 * 7 *
6 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU 9 * licenses. You may choose to be licensed under the terms of the GNU
@@ -67,6 +69,10 @@ enum {
67}; 69};
68 70
69enum { 71enum {
72 MTHCA_BOARD_ID_LEN = 64
73};
74
75enum {
70 MTHCA_EQ_CONTEXT_SIZE = 0x40, 76 MTHCA_EQ_CONTEXT_SIZE = 0x40,
71 MTHCA_CQ_CONTEXT_SIZE = 0x40, 77 MTHCA_CQ_CONTEXT_SIZE = 0x40,
72 MTHCA_QP_CONTEXT_SIZE = 0x200, 78 MTHCA_QP_CONTEXT_SIZE = 0x200,
@@ -142,6 +148,7 @@ struct mthca_limits {
142 int reserved_mcgs; 148 int reserved_mcgs;
143 int num_pds; 149 int num_pds;
144 int reserved_pds; 150 int reserved_pds;
151 u8 port_width_cap;
145}; 152};
146 153
147struct mthca_alloc { 154struct mthca_alloc {
@@ -211,6 +218,13 @@ struct mthca_cq_table {
211 struct mthca_icm_table *table; 218 struct mthca_icm_table *table;
212}; 219};
213 220
221struct mthca_srq_table {
222 struct mthca_alloc alloc;
223 spinlock_t lock;
224 struct mthca_array srq;
225 struct mthca_icm_table *table;
226};
227
214struct mthca_qp_table { 228struct mthca_qp_table {
215 struct mthca_alloc alloc; 229 struct mthca_alloc alloc;
216 u32 rdb_base; 230 u32 rdb_base;
@@ -246,6 +260,7 @@ struct mthca_dev {
246 unsigned long device_cap_flags; 260 unsigned long device_cap_flags;
247 261
248 u32 rev_id; 262 u32 rev_id;
263 char board_id[MTHCA_BOARD_ID_LEN];
249 264
250 /* firmware info */ 265 /* firmware info */
251 u64 fw_ver; 266 u64 fw_ver;
@@ -291,6 +306,7 @@ struct mthca_dev {
291 struct mthca_mr_table mr_table; 306 struct mthca_mr_table mr_table;
292 struct mthca_eq_table eq_table; 307 struct mthca_eq_table eq_table;
293 struct mthca_cq_table cq_table; 308 struct mthca_cq_table cq_table;
309 struct mthca_srq_table srq_table;
294 struct mthca_qp_table qp_table; 310 struct mthca_qp_table qp_table;
295 struct mthca_av_table av_table; 311 struct mthca_av_table av_table;
296 struct mthca_mcg_table mcg_table; 312 struct mthca_mcg_table mcg_table;
@@ -331,14 +347,13 @@ extern void __buggy_use_of_MTHCA_PUT(void);
331 347
332#define MTHCA_PUT(dest, source, offset) \ 348#define MTHCA_PUT(dest, source, offset) \
333 do { \ 349 do { \
334 __typeof__(source) *__p = \ 350 void *__d = ((char *) (dest) + (offset)); \
335 (__typeof__(source) *) ((char *) (dest) + (offset)); \
336 switch (sizeof(source)) { \ 351 switch (sizeof(source)) { \
337 case 1: *__p = (source); break; \ 352 case 1: *(u8 *) __d = (source); break; \
338 case 2: *__p = cpu_to_be16(source); break; \ 353 case 2: *(__be16 *) __d = cpu_to_be16(source); break; \
339 case 4: *__p = cpu_to_be32(source); break; \ 354 case 4: *(__be32 *) __d = cpu_to_be32(source); break; \
340 case 8: *__p = cpu_to_be64(source); break; \ 355 case 8: *(__be64 *) __d = cpu_to_be64(source); break; \
341 default: __buggy_use_of_MTHCA_PUT(); \ 356 default: __buggy_use_of_MTHCA_PUT(); \
342 } \ 357 } \
343 } while (0) 358 } while (0)
344 359
@@ -354,12 +369,18 @@ int mthca_array_set(struct mthca_array *array, int index, void *value);
354void mthca_array_clear(struct mthca_array *array, int index); 369void mthca_array_clear(struct mthca_array *array, int index);
355int mthca_array_init(struct mthca_array *array, int nent); 370int mthca_array_init(struct mthca_array *array, int nent);
356void mthca_array_cleanup(struct mthca_array *array, int nent); 371void mthca_array_cleanup(struct mthca_array *array, int nent);
372int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct,
373 union mthca_buf *buf, int *is_direct, struct mthca_pd *pd,
374 int hca_write, struct mthca_mr *mr);
375void mthca_buf_free(struct mthca_dev *dev, int size, union mthca_buf *buf,
376 int is_direct, struct mthca_mr *mr);
357 377
358int mthca_init_uar_table(struct mthca_dev *dev); 378int mthca_init_uar_table(struct mthca_dev *dev);
359int mthca_init_pd_table(struct mthca_dev *dev); 379int mthca_init_pd_table(struct mthca_dev *dev);
360int mthca_init_mr_table(struct mthca_dev *dev); 380int mthca_init_mr_table(struct mthca_dev *dev);
361int mthca_init_eq_table(struct mthca_dev *dev); 381int mthca_init_eq_table(struct mthca_dev *dev);
362int mthca_init_cq_table(struct mthca_dev *dev); 382int mthca_init_cq_table(struct mthca_dev *dev);
383int mthca_init_srq_table(struct mthca_dev *dev);
363int mthca_init_qp_table(struct mthca_dev *dev); 384int mthca_init_qp_table(struct mthca_dev *dev);
364int mthca_init_av_table(struct mthca_dev *dev); 385int mthca_init_av_table(struct mthca_dev *dev);
365int mthca_init_mcg_table(struct mthca_dev *dev); 386int mthca_init_mcg_table(struct mthca_dev *dev);
@@ -369,6 +390,7 @@ void mthca_cleanup_pd_table(struct mthca_dev *dev);
369void mthca_cleanup_mr_table(struct mthca_dev *dev); 390void mthca_cleanup_mr_table(struct mthca_dev *dev);
370void mthca_cleanup_eq_table(struct mthca_dev *dev); 391void mthca_cleanup_eq_table(struct mthca_dev *dev);
371void mthca_cleanup_cq_table(struct mthca_dev *dev); 392void mthca_cleanup_cq_table(struct mthca_dev *dev);
393void mthca_cleanup_srq_table(struct mthca_dev *dev);
372void mthca_cleanup_qp_table(struct mthca_dev *dev); 394void mthca_cleanup_qp_table(struct mthca_dev *dev);
373void mthca_cleanup_av_table(struct mthca_dev *dev); 395void mthca_cleanup_av_table(struct mthca_dev *dev);
374void mthca_cleanup_mcg_table(struct mthca_dev *dev); 396void mthca_cleanup_mcg_table(struct mthca_dev *dev);
@@ -419,7 +441,19 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
419void mthca_free_cq(struct mthca_dev *dev, 441void mthca_free_cq(struct mthca_dev *dev,
420 struct mthca_cq *cq); 442 struct mthca_cq *cq);
421void mthca_cq_event(struct mthca_dev *dev, u32 cqn); 443void mthca_cq_event(struct mthca_dev *dev, u32 cqn);
422void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn); 444void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
445 struct mthca_srq *srq);
446
447int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
448 struct ib_srq_attr *attr, struct mthca_srq *srq);
449void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
450void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
451 enum ib_event_type event_type);
452void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
453int mthca_tavor_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr,
454 struct ib_recv_wr **bad_wr);
455int mthca_arbel_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr,
456 struct ib_recv_wr **bad_wr);
423 457
424void mthca_qp_event(struct mthca_dev *dev, u32 qpn, 458void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
425 enum ib_event_type event_type); 459 enum ib_event_type event_type);
@@ -433,7 +467,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
433int mthca_arbel_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, 467int mthca_arbel_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
434 struct ib_recv_wr **bad_wr); 468 struct ib_recv_wr **bad_wr);
435int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send, 469int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
436 int index, int *dbd, u32 *new_wqe); 470 int index, int *dbd, __be32 *new_wqe);
437int mthca_alloc_qp(struct mthca_dev *dev, 471int mthca_alloc_qp(struct mthca_dev *dev,
438 struct mthca_pd *pd, 472 struct mthca_pd *pd,
439 struct mthca_cq *send_cq, 473 struct mthca_cq *send_cq,
diff --git a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h
index 535fad7710fb..dd9a44d170c9 100644
--- a/drivers/infiniband/hw/mthca/mthca_doorbell.h
+++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -57,13 +58,13 @@ static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
57 __raw_writeq((__force u64) val, dest); 58 __raw_writeq((__force u64) val, dest);
58} 59}
59 60
60static inline void mthca_write64(u32 val[2], void __iomem *dest, 61static inline void mthca_write64(__be32 val[2], void __iomem *dest,
61 spinlock_t *doorbell_lock) 62 spinlock_t *doorbell_lock)
62{ 63{
63 __raw_writeq(*(u64 *) val, dest); 64 __raw_writeq(*(u64 *) val, dest);
64} 65}
65 66
66static inline void mthca_write_db_rec(u32 val[2], u32 *db) 67static inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
67{ 68{
68 *(u64 *) db = *(u64 *) val; 69 *(u64 *) db = *(u64 *) val;
69} 70}
@@ -86,18 +87,18 @@ static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
86 __raw_writel(((__force u32 *) &val)[1], dest + 4); 87 __raw_writel(((__force u32 *) &val)[1], dest + 4);
87} 88}
88 89
89static inline void mthca_write64(u32 val[2], void __iomem *dest, 90static inline void mthca_write64(__be32 val[2], void __iomem *dest,
90 spinlock_t *doorbell_lock) 91 spinlock_t *doorbell_lock)
91{ 92{
92 unsigned long flags; 93 unsigned long flags;
93 94
94 spin_lock_irqsave(doorbell_lock, flags); 95 spin_lock_irqsave(doorbell_lock, flags);
95 __raw_writel(val[0], dest); 96 __raw_writel((__force u32) val[0], dest);
96 __raw_writel(val[1], dest + 4); 97 __raw_writel((__force u32) val[1], dest + 4);
97 spin_unlock_irqrestore(doorbell_lock, flags); 98 spin_unlock_irqrestore(doorbell_lock, flags);
98} 99}
99 100
100static inline void mthca_write_db_rec(u32 val[2], u32 *db) 101static inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
101{ 102{
102 db[0] = val[0]; 103 db[0] = val[0];
103 wmb(); 104 wmb();
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index cbcf2b4722e4..18f0981eb0c1 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -51,18 +52,18 @@ enum {
51 * Must be packed because start is 64 bits but only aligned to 32 bits. 52 * Must be packed because start is 64 bits but only aligned to 32 bits.
52 */ 53 */
53struct mthca_eq_context { 54struct mthca_eq_context {
54 u32 flags; 55 __be32 flags;
55 u64 start; 56 __be64 start;
56 u32 logsize_usrpage; 57 __be32 logsize_usrpage;
57 u32 tavor_pd; /* reserved for Arbel */ 58 __be32 tavor_pd; /* reserved for Arbel */
58 u8 reserved1[3]; 59 u8 reserved1[3];
59 u8 intr; 60 u8 intr;
60 u32 arbel_pd; /* lost_count for Tavor */ 61 __be32 arbel_pd; /* lost_count for Tavor */
61 u32 lkey; 62 __be32 lkey;
62 u32 reserved2[2]; 63 u32 reserved2[2];
63 u32 consumer_index; 64 __be32 consumer_index;
64 u32 producer_index; 65 __be32 producer_index;
65 u32 reserved3[4]; 66 u32 reserved3[4];
66} __attribute__((packed)); 67} __attribute__((packed));
67 68
68#define MTHCA_EQ_STATUS_OK ( 0 << 28) 69#define MTHCA_EQ_STATUS_OK ( 0 << 28)
@@ -127,28 +128,28 @@ struct mthca_eqe {
127 union { 128 union {
128 u32 raw[6]; 129 u32 raw[6];
129 struct { 130 struct {
130 u32 cqn; 131 __be32 cqn;
131 } __attribute__((packed)) comp; 132 } __attribute__((packed)) comp;
132 struct { 133 struct {
133 u16 reserved1; 134 u16 reserved1;
134 u16 token; 135 __be16 token;
135 u32 reserved2; 136 u32 reserved2;
136 u8 reserved3[3]; 137 u8 reserved3[3];
137 u8 status; 138 u8 status;
138 u64 out_param; 139 __be64 out_param;
139 } __attribute__((packed)) cmd; 140 } __attribute__((packed)) cmd;
140 struct { 141 struct {
141 u32 qpn; 142 __be32 qpn;
142 } __attribute__((packed)) qp; 143 } __attribute__((packed)) qp;
143 struct { 144 struct {
144 u32 cqn; 145 __be32 cqn;
145 u32 reserved1; 146 u32 reserved1;
146 u8 reserved2[3]; 147 u8 reserved2[3];
147 u8 syndrome; 148 u8 syndrome;
148 } __attribute__((packed)) cq_err; 149 } __attribute__((packed)) cq_err;
149 struct { 150 struct {
150 u32 reserved1[2]; 151 u32 reserved1[2];
151 u32 port; 152 __be32 port;
152 } __attribute__((packed)) port_change; 153 } __attribute__((packed)) port_change;
153 } event; 154 } event;
154 u8 reserved3[3]; 155 u8 reserved3[3];
@@ -167,7 +168,7 @@ static inline u64 async_mask(struct mthca_dev *dev)
167 168
168static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci) 169static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
169{ 170{
170 u32 doorbell[2]; 171 __be32 doorbell[2];
171 172
172 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_SET_CI | eq->eqn); 173 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_SET_CI | eq->eqn);
173 doorbell[1] = cpu_to_be32(ci & (eq->nent - 1)); 174 doorbell[1] = cpu_to_be32(ci & (eq->nent - 1));
@@ -190,8 +191,8 @@ static inline void arbel_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u
190{ 191{
191 /* See comment in tavor_set_eq_ci() above. */ 192 /* See comment in tavor_set_eq_ci() above. */
192 wmb(); 193 wmb();
193 __raw_writel(cpu_to_be32(ci), dev->eq_regs.arbel.eq_set_ci_base + 194 __raw_writel((__force u32) cpu_to_be32(ci),
194 eq->eqn * 8); 195 dev->eq_regs.arbel.eq_set_ci_base + eq->eqn * 8);
195 /* We still want ordering, just not swabbing, so add a barrier */ 196 /* We still want ordering, just not swabbing, so add a barrier */
196 mb(); 197 mb();
197} 198}
@@ -206,7 +207,7 @@ static inline void set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
206 207
207static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn) 208static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn)
208{ 209{
209 u32 doorbell[2]; 210 __be32 doorbell[2];
210 211
211 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_REQ_NOT | eqn); 212 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_REQ_NOT | eqn);
212 doorbell[1] = 0; 213 doorbell[1] = 0;
@@ -224,7 +225,7 @@ static inline void arbel_eq_req_not(struct mthca_dev *dev, u32 eqn_mask)
224static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn) 225static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn)
225{ 226{
226 if (!mthca_is_memfree(dev)) { 227 if (!mthca_is_memfree(dev)) {
227 u32 doorbell[2]; 228 __be32 doorbell[2];
228 229
229 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn); 230 doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn);
230 doorbell[1] = cpu_to_be32(cqn); 231 doorbell[1] = cpu_to_be32(cqn);
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 7df223642015..9804174f7f3c 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
3 * 5 *
4 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -32,9 +34,9 @@
32 * $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $ 34 * $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $
33 */ 35 */
34 36
35#include <ib_verbs.h> 37#include <rdma/ib_verbs.h>
36#include <ib_mad.h> 38#include <rdma/ib_mad.h>
37#include <ib_smi.h> 39#include <rdma/ib_smi.h>
38 40
39#include "mthca_dev.h" 41#include "mthca_dev.h"
40#include "mthca_cmd.h" 42#include "mthca_cmd.h"
@@ -192,7 +194,7 @@ int mthca_process_mad(struct ib_device *ibdev,
192{ 194{
193 int err; 195 int err;
194 u8 status; 196 u8 status;
195 u16 slid = in_wc ? in_wc->slid : IB_LID_PERMISSIVE; 197 u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
196 198
197 /* Forward locally generated traps to the SM */ 199 /* Forward locally generated traps to the SM */
198 if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && 200 if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 2ef916859e17..3241d6c9dc11 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -34,7 +35,6 @@
34 */ 35 */
35 36
36#include <linux/config.h> 37#include <linux/config.h>
37#include <linux/version.h>
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/errno.h> 40#include <linux/errno.h>
@@ -171,6 +171,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
171 mdev->limits.reserved_mrws = dev_lim->reserved_mrws; 171 mdev->limits.reserved_mrws = dev_lim->reserved_mrws;
172 mdev->limits.reserved_uars = dev_lim->reserved_uars; 172 mdev->limits.reserved_uars = dev_lim->reserved_uars;
173 mdev->limits.reserved_pds = dev_lim->reserved_pds; 173 mdev->limits.reserved_pds = dev_lim->reserved_pds;
174 mdev->limits.port_width_cap = dev_lim->max_port_width;
174 175
175 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. 176 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
176 May be doable since hardware supports it for SRQ. 177 May be doable since hardware supports it for SRQ.
@@ -212,7 +213,6 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
212 struct mthca_dev_lim dev_lim; 213 struct mthca_dev_lim dev_lim;
213 struct mthca_profile profile; 214 struct mthca_profile profile;
214 struct mthca_init_hca_param init_hca; 215 struct mthca_init_hca_param init_hca;
215 struct mthca_adapter adapter;
216 216
217 err = mthca_SYS_EN(mdev, &status); 217 err = mthca_SYS_EN(mdev, &status);
218 if (err) { 218 if (err) {
@@ -253,6 +253,8 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
253 profile = default_profile; 253 profile = default_profile;
254 profile.num_uar = dev_lim.uar_size / PAGE_SIZE; 254 profile.num_uar = dev_lim.uar_size / PAGE_SIZE;
255 profile.uarc_size = 0; 255 profile.uarc_size = 0;
256 if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
257 profile.num_srq = dev_lim.max_srqs;
256 258
257 err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); 259 err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
258 if (err < 0) 260 if (err < 0)
@@ -270,26 +272,8 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
270 goto err_disable; 272 goto err_disable;
271 } 273 }
272 274
273 err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
274 if (err) {
275 mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
276 goto err_close;
277 }
278 if (status) {
279 mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
280 "aborting.\n", status);
281 err = -EINVAL;
282 goto err_close;
283 }
284
285 mdev->eq_table.inta_pin = adapter.inta_pin;
286 mdev->rev_id = adapter.revision_id;
287
288 return 0; 275 return 0;
289 276
290err_close:
291 mthca_CLOSE_HCA(mdev, 0, &status);
292
293err_disable: 277err_disable:
294 mthca_SYS_DIS(mdev, &status); 278 mthca_SYS_DIS(mdev, &status);
295 279
@@ -442,15 +426,29 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev,
442 } 426 }
443 427
444 mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base, 428 mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base,
445 dev_lim->cqc_entry_sz, 429 dev_lim->cqc_entry_sz,
446 mdev->limits.num_cqs, 430 mdev->limits.num_cqs,
447 mdev->limits.reserved_cqs, 0); 431 mdev->limits.reserved_cqs, 0);
448 if (!mdev->cq_table.table) { 432 if (!mdev->cq_table.table) {
449 mthca_err(mdev, "Failed to map CQ context memory, aborting.\n"); 433 mthca_err(mdev, "Failed to map CQ context memory, aborting.\n");
450 err = -ENOMEM; 434 err = -ENOMEM;
451 goto err_unmap_rdb; 435 goto err_unmap_rdb;
452 } 436 }
453 437
438 if (mdev->mthca_flags & MTHCA_FLAG_SRQ) {
439 mdev->srq_table.table =
440 mthca_alloc_icm_table(mdev, init_hca->srqc_base,
441 dev_lim->srq_entry_sz,
442 mdev->limits.num_srqs,
443 mdev->limits.reserved_srqs, 0);
444 if (!mdev->srq_table.table) {
445 mthca_err(mdev, "Failed to map SRQ context memory, "
446 "aborting.\n");
447 err = -ENOMEM;
448 goto err_unmap_cq;
449 }
450 }
451
454 /* 452 /*
455 * It's not strictly required, but for simplicity just map the 453 * It's not strictly required, but for simplicity just map the
456 * whole multicast group table now. The table isn't very big 454 * whole multicast group table now. The table isn't very big
@@ -466,11 +464,15 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev,
466 if (!mdev->mcg_table.table) { 464 if (!mdev->mcg_table.table) {
467 mthca_err(mdev, "Failed to map MCG context memory, aborting.\n"); 465 mthca_err(mdev, "Failed to map MCG context memory, aborting.\n");
468 err = -ENOMEM; 466 err = -ENOMEM;
469 goto err_unmap_cq; 467 goto err_unmap_srq;
470 } 468 }
471 469
472 return 0; 470 return 0;
473 471
472err_unmap_srq:
473 if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
474 mthca_free_icm_table(mdev, mdev->srq_table.table);
475
474err_unmap_cq: 476err_unmap_cq:
475 mthca_free_icm_table(mdev, mdev->cq_table.table); 477 mthca_free_icm_table(mdev, mdev->cq_table.table);
476 478
@@ -506,7 +508,6 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
506 struct mthca_dev_lim dev_lim; 508 struct mthca_dev_lim dev_lim;
507 struct mthca_profile profile; 509 struct mthca_profile profile;
508 struct mthca_init_hca_param init_hca; 510 struct mthca_init_hca_param init_hca;
509 struct mthca_adapter adapter;
510 u64 icm_size; 511 u64 icm_size;
511 u8 status; 512 u8 status;
512 int err; 513 int err;
@@ -551,6 +552,8 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
551 profile = default_profile; 552 profile = default_profile;
552 profile.num_uar = dev_lim.uar_size / PAGE_SIZE; 553 profile.num_uar = dev_lim.uar_size / PAGE_SIZE;
553 profile.num_udav = 0; 554 profile.num_udav = 0;
555 if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
556 profile.num_srq = dev_lim.max_srqs;
554 557
555 icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); 558 icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
556 if ((int) icm_size < 0) { 559 if ((int) icm_size < 0) {
@@ -574,24 +577,11 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
574 goto err_free_icm; 577 goto err_free_icm;
575 } 578 }
576 579
577 err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
578 if (err) {
579 mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
580 goto err_free_icm;
581 }
582 if (status) {
583 mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
584 "aborting.\n", status);
585 err = -EINVAL;
586 goto err_free_icm;
587 }
588
589 mdev->eq_table.inta_pin = adapter.inta_pin;
590 mdev->rev_id = adapter.revision_id;
591
592 return 0; 580 return 0;
593 581
594err_free_icm: 582err_free_icm:
583 if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
584 mthca_free_icm_table(mdev, mdev->srq_table.table);
595 mthca_free_icm_table(mdev, mdev->cq_table.table); 585 mthca_free_icm_table(mdev, mdev->cq_table.table);
596 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); 586 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
597 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); 587 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
@@ -614,12 +604,70 @@ err_disable:
614 return err; 604 return err;
615} 605}
616 606
607static void mthca_close_hca(struct mthca_dev *mdev)
608{
609 u8 status;
610
611 mthca_CLOSE_HCA(mdev, 0, &status);
612
613 if (mthca_is_memfree(mdev)) {
614 if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
615 mthca_free_icm_table(mdev, mdev->srq_table.table);
616 mthca_free_icm_table(mdev, mdev->cq_table.table);
617 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
618 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
619 mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
620 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
621 mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
622 mthca_unmap_eq_icm(mdev);
623
624 mthca_UNMAP_ICM_AUX(mdev, &status);
625 mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
626
627 mthca_UNMAP_FA(mdev, &status);
628 mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
629
630 if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
631 mthca_DISABLE_LAM(mdev, &status);
632 } else
633 mthca_SYS_DIS(mdev, &status);
634}
635
617static int __devinit mthca_init_hca(struct mthca_dev *mdev) 636static int __devinit mthca_init_hca(struct mthca_dev *mdev)
618{ 637{
638 u8 status;
639 int err;
640 struct mthca_adapter adapter;
641
619 if (mthca_is_memfree(mdev)) 642 if (mthca_is_memfree(mdev))
620 return mthca_init_arbel(mdev); 643 err = mthca_init_arbel(mdev);
621 else 644 else
622 return mthca_init_tavor(mdev); 645 err = mthca_init_tavor(mdev);
646
647 if (err)
648 return err;
649
650 err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
651 if (err) {
652 mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
653 goto err_close;
654 }
655 if (status) {
656 mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
657 "aborting.\n", status);
658 err = -EINVAL;
659 goto err_close;
660 }
661
662 mdev->eq_table.inta_pin = adapter.inta_pin;
663 mdev->rev_id = adapter.revision_id;
664 memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id);
665
666 return 0;
667
668err_close:
669 mthca_close_hca(mdev);
670 return err;
623} 671}
624 672
625static int __devinit mthca_setup_hca(struct mthca_dev *dev) 673static int __devinit mthca_setup_hca(struct mthca_dev *dev)
@@ -709,11 +757,18 @@ static int __devinit mthca_setup_hca(struct mthca_dev *dev)
709 goto err_cmd_poll; 757 goto err_cmd_poll;
710 } 758 }
711 759
760 err = mthca_init_srq_table(dev);
761 if (err) {
762 mthca_err(dev, "Failed to initialize "
763 "shared receive queue table, aborting.\n");
764 goto err_cq_table_free;
765 }
766
712 err = mthca_init_qp_table(dev); 767 err = mthca_init_qp_table(dev);
713 if (err) { 768 if (err) {
714 mthca_err(dev, "Failed to initialize " 769 mthca_err(dev, "Failed to initialize "
715 "queue pair table, aborting.\n"); 770 "queue pair table, aborting.\n");
716 goto err_cq_table_free; 771 goto err_srq_table_free;
717 } 772 }
718 773
719 err = mthca_init_av_table(dev); 774 err = mthca_init_av_table(dev);
@@ -738,6 +793,9 @@ err_av_table_free:
738err_qp_table_free: 793err_qp_table_free:
739 mthca_cleanup_qp_table(dev); 794 mthca_cleanup_qp_table(dev);
740 795
796err_srq_table_free:
797 mthca_cleanup_srq_table(dev);
798
741err_cq_table_free: 799err_cq_table_free:
742 mthca_cleanup_cq_table(dev); 800 mthca_cleanup_cq_table(dev);
743 801
@@ -844,33 +902,6 @@ static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev)
844 return 0; 902 return 0;
845} 903}
846 904
847static void mthca_close_hca(struct mthca_dev *mdev)
848{
849 u8 status;
850
851 mthca_CLOSE_HCA(mdev, 0, &status);
852
853 if (mthca_is_memfree(mdev)) {
854 mthca_free_icm_table(mdev, mdev->cq_table.table);
855 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
856 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
857 mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
858 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
859 mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
860 mthca_unmap_eq_icm(mdev);
861
862 mthca_UNMAP_ICM_AUX(mdev, &status);
863 mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
864
865 mthca_UNMAP_FA(mdev, &status);
866 mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
867
868 if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
869 mthca_DISABLE_LAM(mdev, &status);
870 } else
871 mthca_SYS_DIS(mdev, &status);
872}
873
874/* Types of supported HCA */ 905/* Types of supported HCA */
875enum { 906enum {
876 TAVOR, /* MT23108 */ 907 TAVOR, /* MT23108 */
@@ -887,9 +918,9 @@ static struct {
887 int is_memfree; 918 int is_memfree;
888 int is_pcie; 919 int is_pcie;
889} mthca_hca_table[] = { 920} mthca_hca_table[] = {
890 [TAVOR] = { .latest_fw = MTHCA_FW_VER(3, 3, 2), .is_memfree = 0, .is_pcie = 0 }, 921 [TAVOR] = { .latest_fw = MTHCA_FW_VER(3, 3, 3), .is_memfree = 0, .is_pcie = 0 },
891 [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 6, 2), .is_memfree = 0, .is_pcie = 1 }, 922 [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 0), .is_memfree = 0, .is_pcie = 1 },
892 [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 0, 1), .is_memfree = 1, .is_pcie = 1 }, 923 [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 0), .is_memfree = 1, .is_pcie = 1 },
893 [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, .is_pcie = 1 } 924 [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, .is_pcie = 1 }
894}; 925};
895 926
@@ -1051,6 +1082,7 @@ err_cleanup:
1051 mthca_cleanup_mcg_table(mdev); 1082 mthca_cleanup_mcg_table(mdev);
1052 mthca_cleanup_av_table(mdev); 1083 mthca_cleanup_av_table(mdev);
1053 mthca_cleanup_qp_table(mdev); 1084 mthca_cleanup_qp_table(mdev);
1085 mthca_cleanup_srq_table(mdev);
1054 mthca_cleanup_cq_table(mdev); 1086 mthca_cleanup_cq_table(mdev);
1055 mthca_cmd_use_polling(mdev); 1087 mthca_cmd_use_polling(mdev);
1056 mthca_cleanup_eq_table(mdev); 1088 mthca_cleanup_eq_table(mdev);
@@ -1100,6 +1132,7 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev)
1100 mthca_cleanup_mcg_table(mdev); 1132 mthca_cleanup_mcg_table(mdev);
1101 mthca_cleanup_av_table(mdev); 1133 mthca_cleanup_av_table(mdev);
1102 mthca_cleanup_qp_table(mdev); 1134 mthca_cleanup_qp_table(mdev);
1135 mthca_cleanup_srq_table(mdev);
1103 mthca_cleanup_cq_table(mdev); 1136 mthca_cleanup_cq_table(mdev);
1104 mthca_cmd_use_polling(mdev); 1137 mthca_cmd_use_polling(mdev);
1105 mthca_cleanup_eq_table(mdev); 1138 mthca_cleanup_eq_table(mdev);
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index 5be7d949dbf6..a2707605f4c8 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -42,10 +42,10 @@ enum {
42}; 42};
43 43
44struct mthca_mgm { 44struct mthca_mgm {
45 u32 next_gid_index; 45 __be32 next_gid_index;
46 u32 reserved[3]; 46 u32 reserved[3];
47 u8 gid[16]; 47 u8 gid[16];
48 u32 qp[MTHCA_QP_PER_MGM]; 48 __be32 qp[MTHCA_QP_PER_MGM];
49}; 49};
50 50
51static const u8 zero_gid[16]; /* automatically initialized to 0 */ 51static const u8 zero_gid[16]; /* automatically initialized to 0 */
@@ -94,10 +94,14 @@ static int find_mgm(struct mthca_dev *dev,
94 if (0) 94 if (0)
95 mthca_dbg(dev, "Hash for %04x:%04x:%04x:%04x:" 95 mthca_dbg(dev, "Hash for %04x:%04x:%04x:%04x:"
96 "%04x:%04x:%04x:%04x is %04x\n", 96 "%04x:%04x:%04x:%04x is %04x\n",
97 be16_to_cpu(((u16 *) gid)[0]), be16_to_cpu(((u16 *) gid)[1]), 97 be16_to_cpu(((__be16 *) gid)[0]),
98 be16_to_cpu(((u16 *) gid)[2]), be16_to_cpu(((u16 *) gid)[3]), 98 be16_to_cpu(((__be16 *) gid)[1]),
99 be16_to_cpu(((u16 *) gid)[4]), be16_to_cpu(((u16 *) gid)[5]), 99 be16_to_cpu(((__be16 *) gid)[2]),
100 be16_to_cpu(((u16 *) gid)[6]), be16_to_cpu(((u16 *) gid)[7]), 100 be16_to_cpu(((__be16 *) gid)[3]),
101 be16_to_cpu(((__be16 *) gid)[4]),
102 be16_to_cpu(((__be16 *) gid)[5]),
103 be16_to_cpu(((__be16 *) gid)[6]),
104 be16_to_cpu(((__be16 *) gid)[7]),
101 *hash); 105 *hash);
102 106
103 *index = *hash; 107 *index = *hash;
@@ -258,14 +262,14 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
258 if (index == -1) { 262 if (index == -1) {
259 mthca_err(dev, "MGID %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x " 263 mthca_err(dev, "MGID %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
260 "not found\n", 264 "not found\n",
261 be16_to_cpu(((u16 *) gid->raw)[0]), 265 be16_to_cpu(((__be16 *) gid->raw)[0]),
262 be16_to_cpu(((u16 *) gid->raw)[1]), 266 be16_to_cpu(((__be16 *) gid->raw)[1]),
263 be16_to_cpu(((u16 *) gid->raw)[2]), 267 be16_to_cpu(((__be16 *) gid->raw)[2]),
264 be16_to_cpu(((u16 *) gid->raw)[3]), 268 be16_to_cpu(((__be16 *) gid->raw)[3]),
265 be16_to_cpu(((u16 *) gid->raw)[4]), 269 be16_to_cpu(((__be16 *) gid->raw)[4]),
266 be16_to_cpu(((u16 *) gid->raw)[5]), 270 be16_to_cpu(((__be16 *) gid->raw)[5]),
267 be16_to_cpu(((u16 *) gid->raw)[6]), 271 be16_to_cpu(((__be16 *) gid->raw)[6]),
268 be16_to_cpu(((u16 *) gid->raw)[7])); 272 be16_to_cpu(((__be16 *) gid->raw)[7]));
269 err = -EINVAL; 273 err = -EINVAL;
270 goto out; 274 goto out;
271 } 275 }
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 2a8646150355..1827400f189b 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -285,6 +286,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
285{ 286{
286 struct mthca_icm_table *table; 287 struct mthca_icm_table *table;
287 int num_icm; 288 int num_icm;
289 unsigned chunk_size;
288 int i; 290 int i;
289 u8 status; 291 u8 status;
290 292
@@ -305,7 +307,11 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
305 table->icm[i] = NULL; 307 table->icm[i] = NULL;
306 308
307 for (i = 0; i * MTHCA_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { 309 for (i = 0; i * MTHCA_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
308 table->icm[i] = mthca_alloc_icm(dev, MTHCA_TABLE_CHUNK_SIZE >> PAGE_SHIFT, 310 chunk_size = MTHCA_TABLE_CHUNK_SIZE;
311 if ((i + 1) * MTHCA_TABLE_CHUNK_SIZE > nobj * obj_size)
312 chunk_size = nobj * obj_size - i * MTHCA_TABLE_CHUNK_SIZE;
313
314 table->icm[i] = mthca_alloc_icm(dev, chunk_size >> PAGE_SHIFT,
309 (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | 315 (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
310 __GFP_NOWARN); 316 __GFP_NOWARN);
311 if (!table->icm[i]) 317 if (!table->icm[i])
@@ -481,7 +487,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
481 } 487 }
482} 488}
483 489
484int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db) 490int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
485{ 491{
486 int group; 492 int group;
487 int start, end, dir; 493 int start, end, dir;
@@ -564,7 +570,7 @@ found:
564 570
565 page->db_rec[j] = cpu_to_be64((qn << 8) | (type << 5)); 571 page->db_rec[j] = cpu_to_be64((qn << 8) | (type << 5));
566 572
567 *db = (u32 *) &page->db_rec[j]; 573 *db = (__be32 *) &page->db_rec[j];
568 574
569out: 575out:
570 up(&dev->db_tab->mutex); 576 up(&dev->db_tab->mutex);
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index 4761d844cb5f..bafa51544aa3 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -137,7 +138,7 @@ enum {
137 138
138struct mthca_db_page { 139struct mthca_db_page {
139 DECLARE_BITMAP(used, MTHCA_DB_REC_PER_PAGE); 140 DECLARE_BITMAP(used, MTHCA_DB_REC_PER_PAGE);
140 u64 *db_rec; 141 __be64 *db_rec;
141 dma_addr_t mapping; 142 dma_addr_t mapping;
142}; 143};
143 144
@@ -172,7 +173,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
172 173
173int mthca_init_db_tab(struct mthca_dev *dev); 174int mthca_init_db_tab(struct mthca_dev *dev);
174void mthca_cleanup_db_tab(struct mthca_dev *dev); 175void mthca_cleanup_db_tab(struct mthca_dev *dev);
175int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db); 176int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db);
176void mthca_free_db(struct mthca_dev *dev, int type, int db_index); 177void mthca_free_db(struct mthca_dev *dev, int type, int db_index);
177 178
178#endif /* MTHCA_MEMFREE_H */ 179#endif /* MTHCA_MEMFREE_H */
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index cbe50feaf680..1f97a44477f5 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -50,18 +51,18 @@ struct mthca_mtt {
50 * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits. 51 * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
51 */ 52 */
52struct mthca_mpt_entry { 53struct mthca_mpt_entry {
53 u32 flags; 54 __be32 flags;
54 u32 page_size; 55 __be32 page_size;
55 u32 key; 56 __be32 key;
56 u32 pd; 57 __be32 pd;
57 u64 start; 58 __be64 start;
58 u64 length; 59 __be64 length;
59 u32 lkey; 60 __be32 lkey;
60 u32 window_count; 61 __be32 window_count;
61 u32 window_count_limit; 62 __be32 window_count_limit;
62 u64 mtt_seg; 63 __be64 mtt_seg;
63 u32 mtt_sz; /* Arbel only */ 64 __be32 mtt_sz; /* Arbel only */
64 u32 reserved[2]; 65 u32 reserved[2];
65} __attribute__((packed)); 66} __attribute__((packed));
66 67
67#define MTHCA_MPT_FLAG_SW_OWNS (0xfUL << 28) 68#define MTHCA_MPT_FLAG_SW_OWNS (0xfUL << 28)
@@ -247,7 +248,7 @@ int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt,
247 int start_index, u64 *buffer_list, int list_len) 248 int start_index, u64 *buffer_list, int list_len)
248{ 249{
249 struct mthca_mailbox *mailbox; 250 struct mthca_mailbox *mailbox;
250 u64 *mtt_entry; 251 __be64 *mtt_entry;
251 int err = 0; 252 int err = 0;
252 u8 status; 253 u8 status;
253 int i; 254 int i;
@@ -389,7 +390,7 @@ int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
389 for (i = 0; i < sizeof (struct mthca_mpt_entry) / 4; ++i) { 390 for (i = 0; i < sizeof (struct mthca_mpt_entry) / 4; ++i) {
390 if (i % 4 == 0) 391 if (i % 4 == 0)
391 printk("[%02x] ", i * 4); 392 printk("[%02x] ", i * 4);
392 printk(" %08x", be32_to_cpu(((u32 *) mpt_entry)[i])); 393 printk(" %08x", be32_to_cpu(((__be32 *) mpt_entry)[i]));
393 if ((i + 1) % 4 == 0) 394 if ((i + 1) % 4 == 0)
394 printk("\n"); 395 printk("\n");
395 } 396 }
@@ -458,7 +459,7 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
458static void mthca_free_region(struct mthca_dev *dev, u32 lkey) 459static void mthca_free_region(struct mthca_dev *dev, u32 lkey)
459{ 460{
460 mthca_table_put(dev, dev->mr_table.mpt_table, 461 mthca_table_put(dev, dev->mr_table.mpt_table,
461 arbel_key_to_hw_index(lkey)); 462 key_to_hw_index(dev, lkey));
462 463
463 mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, lkey)); 464 mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, lkey));
464} 465}
@@ -562,7 +563,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
562 for (i = 0; i < sizeof (struct mthca_mpt_entry) / 4; ++i) { 563 for (i = 0; i < sizeof (struct mthca_mpt_entry) / 4; ++i) {
563 if (i % 4 == 0) 564 if (i % 4 == 0)
564 printk("[%02x] ", i * 4); 565 printk("[%02x] ", i * 4);
565 printk(" %08x", be32_to_cpu(((u32 *) mpt_entry)[i])); 566 printk(" %08x", be32_to_cpu(((__be32 *) mpt_entry)[i]));
566 if ((i + 1) % 4 == 0) 567 if ((i + 1) % 4 == 0)
567 printk("\n"); 568 printk("\n");
568 } 569 }
@@ -669,7 +670,7 @@ int mthca_tavor_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
669 mpt_entry.length = cpu_to_be64(list_len * (1ull << fmr->attr.page_size)); 670 mpt_entry.length = cpu_to_be64(list_len * (1ull << fmr->attr.page_size));
670 mpt_entry.start = cpu_to_be64(iova); 671 mpt_entry.start = cpu_to_be64(iova);
671 672
672 writel(mpt_entry.lkey, &fmr->mem.tavor.mpt->key); 673 __raw_writel((__force u32) mpt_entry.lkey, &fmr->mem.tavor.mpt->key);
673 memcpy_toio(&fmr->mem.tavor.mpt->start, &mpt_entry.start, 674 memcpy_toio(&fmr->mem.tavor.mpt->start, &mpt_entry.start,
674 offsetof(struct mthca_mpt_entry, window_count) - 675 offsetof(struct mthca_mpt_entry, window_count) -
675 offsetof(struct mthca_mpt_entry, start)); 676 offsetof(struct mthca_mpt_entry, start));
diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c
index c2c899844e98..3dbf06a6e6f4 100644
--- a/drivers/infiniband/hw/mthca/mthca_pd.c
+++ b/drivers/infiniband/hw/mthca/mthca_pd.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
index 4fedc32d5871..0576056b34f4 100644
--- a/drivers/infiniband/hw/mthca/mthca_profile.c
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -101,6 +102,7 @@ u64 mthca_make_profile(struct mthca_dev *dev,
101 profile[MTHCA_RES_UARC].size = request->uarc_size; 102 profile[MTHCA_RES_UARC].size = request->uarc_size;
102 103
103 profile[MTHCA_RES_QP].num = request->num_qp; 104 profile[MTHCA_RES_QP].num = request->num_qp;
105 profile[MTHCA_RES_SRQ].num = request->num_srq;
104 profile[MTHCA_RES_EQP].num = request->num_qp; 106 profile[MTHCA_RES_EQP].num = request->num_qp;
105 profile[MTHCA_RES_RDB].num = request->num_qp * request->rdb_per_qp; 107 profile[MTHCA_RES_RDB].num = request->num_qp * request->rdb_per_qp;
106 profile[MTHCA_RES_CQ].num = request->num_cq; 108 profile[MTHCA_RES_CQ].num = request->num_cq;
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.h b/drivers/infiniband/hw/mthca/mthca_profile.h
index 17aef3357661..94641808f97f 100644
--- a/drivers/infiniband/hw/mthca/mthca_profile.h
+++ b/drivers/infiniband/hw/mthca/mthca_profile.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -41,6 +42,7 @@
41struct mthca_profile { 42struct mthca_profile {
42 int num_qp; 43 int num_qp;
43 int rdb_per_qp; 44 int rdb_per_qp;
45 int num_srq;
44 int num_cq; 46 int num_cq;
45 int num_mcg; 47 int num_mcg;
46 int num_mpt; 48 int num_mpt;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 81919a7b4935..1c1c2e230871 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -2,6 +2,8 @@
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005 Cisco Systems. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
5 * 7 *
6 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU 9 * licenses. You may choose to be licensed under the terms of the GNU
@@ -34,7 +36,7 @@
34 * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $ 36 * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $
35 */ 37 */
36 38
37#include <ib_smi.h> 39#include <rdma/ib_smi.h>
38#include <linux/mm.h> 40#include <linux/mm.h>
39 41
40#include "mthca_dev.h" 42#include "mthca_dev.h"
@@ -79,10 +81,10 @@ static int mthca_query_device(struct ib_device *ibdev,
79 } 81 }
80 82
81 props->device_cap_flags = mdev->device_cap_flags; 83 props->device_cap_flags = mdev->device_cap_flags;
82 props->vendor_id = be32_to_cpup((u32 *) (out_mad->data + 36)) & 84 props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
83 0xffffff; 85 0xffffff;
84 props->vendor_part_id = be16_to_cpup((u16 *) (out_mad->data + 30)); 86 props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30));
85 props->hw_ver = be16_to_cpup((u16 *) (out_mad->data + 32)); 87 props->hw_ver = be16_to_cpup((__be16 *) (out_mad->data + 32));
86 memcpy(&props->sys_image_guid, out_mad->data + 4, 8); 88 memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
87 memcpy(&props->node_guid, out_mad->data + 12, 8); 89 memcpy(&props->node_guid, out_mad->data + 12, 8);
88 90
@@ -118,6 +120,8 @@ static int mthca_query_port(struct ib_device *ibdev,
118 if (!in_mad || !out_mad) 120 if (!in_mad || !out_mad)
119 goto out; 121 goto out;
120 122
123 memset(props, 0, sizeof *props);
124
121 memset(in_mad, 0, sizeof *in_mad); 125 memset(in_mad, 0, sizeof *in_mad);
122 in_mad->base_version = 1; 126 in_mad->base_version = 1;
123 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; 127 in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
@@ -136,16 +140,17 @@ static int mthca_query_port(struct ib_device *ibdev,
136 goto out; 140 goto out;
137 } 141 }
138 142
139 props->lid = be16_to_cpup((u16 *) (out_mad->data + 16)); 143 props->lid = be16_to_cpup((__be16 *) (out_mad->data + 16));
140 props->lmc = out_mad->data[34] & 0x7; 144 props->lmc = out_mad->data[34] & 0x7;
141 props->sm_lid = be16_to_cpup((u16 *) (out_mad->data + 18)); 145 props->sm_lid = be16_to_cpup((__be16 *) (out_mad->data + 18));
142 props->sm_sl = out_mad->data[36] & 0xf; 146 props->sm_sl = out_mad->data[36] & 0xf;
143 props->state = out_mad->data[32] & 0xf; 147 props->state = out_mad->data[32] & 0xf;
144 props->phys_state = out_mad->data[33] >> 4; 148 props->phys_state = out_mad->data[33] >> 4;
145 props->port_cap_flags = be32_to_cpup((u32 *) (out_mad->data + 20)); 149 props->port_cap_flags = be32_to_cpup((__be32 *) (out_mad->data + 20));
146 props->gid_tbl_len = to_mdev(ibdev)->limits.gid_table_len; 150 props->gid_tbl_len = to_mdev(ibdev)->limits.gid_table_len;
151 props->max_msg_sz = 0x80000000;
147 props->pkey_tbl_len = to_mdev(ibdev)->limits.pkey_table_len; 152 props->pkey_tbl_len = to_mdev(ibdev)->limits.pkey_table_len;
148 props->qkey_viol_cntr = be16_to_cpup((u16 *) (out_mad->data + 48)); 153 props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48));
149 props->active_width = out_mad->data[31] & 0xf; 154 props->active_width = out_mad->data[31] & 0xf;
150 props->active_speed = out_mad->data[35] >> 4; 155 props->active_speed = out_mad->data[35] >> 4;
151 156
@@ -221,7 +226,7 @@ static int mthca_query_pkey(struct ib_device *ibdev,
221 goto out; 226 goto out;
222 } 227 }
223 228
224 *pkey = be16_to_cpu(((u16 *) out_mad->data)[index % 32]); 229 *pkey = be16_to_cpu(((__be16 *) out_mad->data)[index % 32]);
225 230
226 out: 231 out:
227 kfree(in_mad); 232 kfree(in_mad);
@@ -420,6 +425,77 @@ static int mthca_ah_destroy(struct ib_ah *ah)
420 return 0; 425 return 0;
421} 426}
422 427
428static struct ib_srq *mthca_create_srq(struct ib_pd *pd,
429 struct ib_srq_init_attr *init_attr,
430 struct ib_udata *udata)
431{
432 struct mthca_create_srq ucmd;
433 struct mthca_ucontext *context = NULL;
434 struct mthca_srq *srq;
435 int err;
436
437 srq = kmalloc(sizeof *srq, GFP_KERNEL);
438 if (!srq)
439 return ERR_PTR(-ENOMEM);
440
441 if (pd->uobject) {
442 context = to_mucontext(pd->uobject->context);
443
444 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
445 return ERR_PTR(-EFAULT);
446
447 err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
448 context->db_tab, ucmd.db_index,
449 ucmd.db_page);
450
451 if (err)
452 goto err_free;
453
454 srq->mr.ibmr.lkey = ucmd.lkey;
455 srq->db_index = ucmd.db_index;
456 }
457
458 err = mthca_alloc_srq(to_mdev(pd->device), to_mpd(pd),
459 &init_attr->attr, srq);
460
461 if (err && pd->uobject)
462 mthca_unmap_user_db(to_mdev(pd->device), &context->uar,
463 context->db_tab, ucmd.db_index);
464
465 if (err)
466 goto err_free;
467
468 if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof (__u32))) {
469 mthca_free_srq(to_mdev(pd->device), srq);
470 err = -EFAULT;
471 goto err_free;
472 }
473
474 return &srq->ibsrq;
475
476err_free:
477 kfree(srq);
478
479 return ERR_PTR(err);
480}
481
482static int mthca_destroy_srq(struct ib_srq *srq)
483{
484 struct mthca_ucontext *context;
485
486 if (srq->uobject) {
487 context = to_mucontext(srq->uobject->context);
488
489 mthca_unmap_user_db(to_mdev(srq->device), &context->uar,
490 context->db_tab, to_msrq(srq)->db_index);
491 }
492
493 mthca_free_srq(to_mdev(srq->device), to_msrq(srq));
494 kfree(srq);
495
496 return 0;
497}
498
423static struct ib_qp *mthca_create_qp(struct ib_pd *pd, 499static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
424 struct ib_qp_init_attr *init_attr, 500 struct ib_qp_init_attr *init_attr,
425 struct ib_udata *udata) 501 struct ib_udata *udata)
@@ -956,14 +1032,22 @@ static ssize_t show_hca(struct class_device *cdev, char *buf)
956 } 1032 }
957} 1033}
958 1034
1035static ssize_t show_board(struct class_device *cdev, char *buf)
1036{
1037 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
1038 return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
1039}
1040
959static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 1041static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
960static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); 1042static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
961static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); 1043static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
1044static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
962 1045
963static struct class_device_attribute *mthca_class_attributes[] = { 1046static struct class_device_attribute *mthca_class_attributes[] = {
964 &class_device_attr_hw_rev, 1047 &class_device_attr_hw_rev,
965 &class_device_attr_fw_ver, 1048 &class_device_attr_fw_ver,
966 &class_device_attr_hca_type 1049 &class_device_attr_hca_type,
1050 &class_device_attr_board_id
967}; 1051};
968 1052
969int mthca_register_device(struct mthca_dev *dev) 1053int mthca_register_device(struct mthca_dev *dev)
@@ -990,6 +1074,17 @@ int mthca_register_device(struct mthca_dev *dev)
990 dev->ib_dev.dealloc_pd = mthca_dealloc_pd; 1074 dev->ib_dev.dealloc_pd = mthca_dealloc_pd;
991 dev->ib_dev.create_ah = mthca_ah_create; 1075 dev->ib_dev.create_ah = mthca_ah_create;
992 dev->ib_dev.destroy_ah = mthca_ah_destroy; 1076 dev->ib_dev.destroy_ah = mthca_ah_destroy;
1077
1078 if (dev->mthca_flags & MTHCA_FLAG_SRQ) {
1079 dev->ib_dev.create_srq = mthca_create_srq;
1080 dev->ib_dev.destroy_srq = mthca_destroy_srq;
1081
1082 if (mthca_is_memfree(dev))
1083 dev->ib_dev.post_srq_recv = mthca_arbel_post_srq_recv;
1084 else
1085 dev->ib_dev.post_srq_recv = mthca_tavor_post_srq_recv;
1086 }
1087
993 dev->ib_dev.create_qp = mthca_create_qp; 1088 dev->ib_dev.create_qp = mthca_create_qp;
994 dev->ib_dev.modify_qp = mthca_modify_qp; 1089 dev->ib_dev.modify_qp = mthca_modify_qp;
995 dev->ib_dev.destroy_qp = mthca_destroy_qp; 1090 dev->ib_dev.destroy_qp = mthca_destroy_qp;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index 1d032791cc8b..bcd4b01a339c 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -36,8 +37,8 @@
36#ifndef MTHCA_PROVIDER_H 37#ifndef MTHCA_PROVIDER_H
37#define MTHCA_PROVIDER_H 38#define MTHCA_PROVIDER_H
38 39
39#include <ib_verbs.h> 40#include <rdma/ib_verbs.h>
40#include <ib_pack.h> 41#include <rdma/ib_pack.h>
41 42
42#define MTHCA_MPT_FLAG_ATOMIC (1 << 14) 43#define MTHCA_MPT_FLAG_ATOMIC (1 << 14)
43#define MTHCA_MPT_FLAG_REMOTE_WRITE (1 << 13) 44#define MTHCA_MPT_FLAG_REMOTE_WRITE (1 << 13)
@@ -50,6 +51,11 @@ struct mthca_buf_list {
50 DECLARE_PCI_UNMAP_ADDR(mapping) 51 DECLARE_PCI_UNMAP_ADDR(mapping)
51}; 52};
52 53
54union mthca_buf {
55 struct mthca_buf_list direct;
56 struct mthca_buf_list *page_list;
57};
58
53struct mthca_uar { 59struct mthca_uar {
54 unsigned long pfn; 60 unsigned long pfn;
55 int index; 61 int index;
@@ -181,19 +187,39 @@ struct mthca_cq {
181 187
182 /* Next fields are Arbel only */ 188 /* Next fields are Arbel only */
183 int set_ci_db_index; 189 int set_ci_db_index;
184 u32 *set_ci_db; 190 __be32 *set_ci_db;
185 int arm_db_index; 191 int arm_db_index;
186 u32 *arm_db; 192 __be32 *arm_db;
187 int arm_sn; 193 int arm_sn;
188 194
189 union { 195 union mthca_buf queue;
190 struct mthca_buf_list direct;
191 struct mthca_buf_list *page_list;
192 } queue;
193 struct mthca_mr mr; 196 struct mthca_mr mr;
194 wait_queue_head_t wait; 197 wait_queue_head_t wait;
195}; 198};
196 199
200struct mthca_srq {
201 struct ib_srq ibsrq;
202 spinlock_t lock;
203 atomic_t refcount;
204 int srqn;
205 int max;
206 int max_gs;
207 int wqe_shift;
208 int first_free;
209 int last_free;
210 u16 counter; /* Arbel only */
211 int db_index; /* Arbel only */
212 __be32 *db; /* Arbel only */
213 void *last;
214
215 int is_direct;
216 u64 *wrid;
217 union mthca_buf queue;
218 struct mthca_mr mr;
219
220 wait_queue_head_t wait;
221};
222
197struct mthca_wq { 223struct mthca_wq {
198 spinlock_t lock; 224 spinlock_t lock;
199 int max; 225 int max;
@@ -206,7 +232,7 @@ struct mthca_wq {
206 int wqe_shift; 232 int wqe_shift;
207 233
208 int db_index; /* Arbel only */ 234 int db_index; /* Arbel only */
209 u32 *db; 235 __be32 *db;
210}; 236};
211 237
212struct mthca_qp { 238struct mthca_qp {
@@ -227,10 +253,7 @@ struct mthca_qp {
227 int send_wqe_offset; 253 int send_wqe_offset;
228 254
229 u64 *wrid; 255 u64 *wrid;
230 union { 256 union mthca_buf queue;
231 struct mthca_buf_list direct;
232 struct mthca_buf_list *page_list;
233 } queue;
234 257
235 wait_queue_head_t wait; 258 wait_queue_head_t wait;
236}; 259};
@@ -277,6 +300,11 @@ static inline struct mthca_cq *to_mcq(struct ib_cq *ibcq)
277 return container_of(ibcq, struct mthca_cq, ibcq); 300 return container_of(ibcq, struct mthca_cq, ibcq);
278} 301}
279 302
303static inline struct mthca_srq *to_msrq(struct ib_srq *ibsrq)
304{
305 return container_of(ibsrq, struct mthca_srq, ibsrq);
306}
307
280static inline struct mthca_qp *to_mqp(struct ib_qp *ibqp) 308static inline struct mthca_qp *to_mqp(struct ib_qp *ibqp)
281{ 309{
282 return container_of(ibqp, struct mthca_qp, ibqp); 310 return container_of(ibqp, struct mthca_qp, ibqp);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index f7126b14d5ae..0164b84d4ec6 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
4 * 6 *
5 * This software is available to you under a choice of one of two 7 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 8 * licenses. You may choose to be licensed under the terms of the GNU
@@ -35,13 +37,14 @@
35 37
36#include <linux/init.h> 38#include <linux/init.h>
37 39
38#include <ib_verbs.h> 40#include <rdma/ib_verbs.h>
39#include <ib_cache.h> 41#include <rdma/ib_cache.h>
40#include <ib_pack.h> 42#include <rdma/ib_pack.h>
41 43
42#include "mthca_dev.h" 44#include "mthca_dev.h"
43#include "mthca_cmd.h" 45#include "mthca_cmd.h"
44#include "mthca_memfree.h" 46#include "mthca_memfree.h"
47#include "mthca_wqe.h"
45 48
46enum { 49enum {
47 MTHCA_MAX_DIRECT_QP_SIZE = 4 * PAGE_SIZE, 50 MTHCA_MAX_DIRECT_QP_SIZE = 4 * PAGE_SIZE,
@@ -95,62 +98,62 @@ enum {
95}; 98};
96 99
97struct mthca_qp_path { 100struct mthca_qp_path {
98 u32 port_pkey; 101 __be32 port_pkey;
99 u8 rnr_retry; 102 u8 rnr_retry;
100 u8 g_mylmc; 103 u8 g_mylmc;
101 u16 rlid; 104 __be16 rlid;
102 u8 ackto; 105 u8 ackto;
103 u8 mgid_index; 106 u8 mgid_index;
104 u8 static_rate; 107 u8 static_rate;
105 u8 hop_limit; 108 u8 hop_limit;
106 u32 sl_tclass_flowlabel; 109 __be32 sl_tclass_flowlabel;
107 u8 rgid[16]; 110 u8 rgid[16];
108} __attribute__((packed)); 111} __attribute__((packed));
109 112
110struct mthca_qp_context { 113struct mthca_qp_context {
111 u32 flags; 114 __be32 flags;
112 u32 tavor_sched_queue; /* Reserved on Arbel */ 115 __be32 tavor_sched_queue; /* Reserved on Arbel */
113 u8 mtu_msgmax; 116 u8 mtu_msgmax;
114 u8 rq_size_stride; /* Reserved on Tavor */ 117 u8 rq_size_stride; /* Reserved on Tavor */
115 u8 sq_size_stride; /* Reserved on Tavor */ 118 u8 sq_size_stride; /* Reserved on Tavor */
116 u8 rlkey_arbel_sched_queue; /* Reserved on Tavor */ 119 u8 rlkey_arbel_sched_queue; /* Reserved on Tavor */
117 u32 usr_page; 120 __be32 usr_page;
118 u32 local_qpn; 121 __be32 local_qpn;
119 u32 remote_qpn; 122 __be32 remote_qpn;
120 u32 reserved1[2]; 123 u32 reserved1[2];
121 struct mthca_qp_path pri_path; 124 struct mthca_qp_path pri_path;
122 struct mthca_qp_path alt_path; 125 struct mthca_qp_path alt_path;
123 u32 rdd; 126 __be32 rdd;
124 u32 pd; 127 __be32 pd;
125 u32 wqe_base; 128 __be32 wqe_base;
126 u32 wqe_lkey; 129 __be32 wqe_lkey;
127 u32 params1; 130 __be32 params1;
128 u32 reserved2; 131 __be32 reserved2;
129 u32 next_send_psn; 132 __be32 next_send_psn;
130 u32 cqn_snd; 133 __be32 cqn_snd;
131 u32 snd_wqe_base_l; /* Next send WQE on Tavor */ 134 __be32 snd_wqe_base_l; /* Next send WQE on Tavor */
132 u32 snd_db_index; /* (debugging only entries) */ 135 __be32 snd_db_index; /* (debugging only entries) */
133 u32 last_acked_psn; 136 __be32 last_acked_psn;
134 u32 ssn; 137 __be32 ssn;
135 u32 params2; 138 __be32 params2;
136 u32 rnr_nextrecvpsn; 139 __be32 rnr_nextrecvpsn;
137 u32 ra_buff_indx; 140 __be32 ra_buff_indx;
138 u32 cqn_rcv; 141 __be32 cqn_rcv;
139 u32 rcv_wqe_base_l; /* Next recv WQE on Tavor */ 142 __be32 rcv_wqe_base_l; /* Next recv WQE on Tavor */
140 u32 rcv_db_index; /* (debugging only entries) */ 143 __be32 rcv_db_index; /* (debugging only entries) */
141 u32 qkey; 144 __be32 qkey;
142 u32 srqn; 145 __be32 srqn;
143 u32 rmsn; 146 __be32 rmsn;
144 u16 rq_wqe_counter; /* reserved on Tavor */ 147 __be16 rq_wqe_counter; /* reserved on Tavor */
145 u16 sq_wqe_counter; /* reserved on Tavor */ 148 __be16 sq_wqe_counter; /* reserved on Tavor */
146 u32 reserved3[18]; 149 u32 reserved3[18];
147} __attribute__((packed)); 150} __attribute__((packed));
148 151
149struct mthca_qp_param { 152struct mthca_qp_param {
150 u32 opt_param_mask; 153 __be32 opt_param_mask;
151 u32 reserved1; 154 u32 reserved1;
152 struct mthca_qp_context context; 155 struct mthca_qp_context context;
153 u32 reserved2[62]; 156 u32 reserved2[62];
154} __attribute__((packed)); 157} __attribute__((packed));
155 158
156enum { 159enum {
@@ -173,80 +176,6 @@ enum {
173 MTHCA_QP_OPTPAR_SCHED_QUEUE = 1 << 16 176 MTHCA_QP_OPTPAR_SCHED_QUEUE = 1 << 16
174}; 177};
175 178
176enum {
177 MTHCA_NEXT_DBD = 1 << 7,
178 MTHCA_NEXT_FENCE = 1 << 6,
179 MTHCA_NEXT_CQ_UPDATE = 1 << 3,
180 MTHCA_NEXT_EVENT_GEN = 1 << 2,
181 MTHCA_NEXT_SOLICIT = 1 << 1,
182
183 MTHCA_MLX_VL15 = 1 << 17,
184 MTHCA_MLX_SLR = 1 << 16
185};
186
187enum {
188 MTHCA_INVAL_LKEY = 0x100
189};
190
191struct mthca_next_seg {
192 u32 nda_op; /* [31:6] next WQE [4:0] next opcode */
193 u32 ee_nds; /* [31:8] next EE [7] DBD [6] F [5:0] next WQE size */
194 u32 flags; /* [3] CQ [2] Event [1] Solicit */
195 u32 imm; /* immediate data */
196};
197
198struct mthca_tavor_ud_seg {
199 u32 reserved1;
200 u32 lkey;
201 u64 av_addr;
202 u32 reserved2[4];
203 u32 dqpn;
204 u32 qkey;
205 u32 reserved3[2];
206};
207
208struct mthca_arbel_ud_seg {
209 u32 av[8];
210 u32 dqpn;
211 u32 qkey;
212 u32 reserved[2];
213};
214
215struct mthca_bind_seg {
216 u32 flags; /* [31] Atomic [30] rem write [29] rem read */
217 u32 reserved;
218 u32 new_rkey;
219 u32 lkey;
220 u64 addr;
221 u64 length;
222};
223
224struct mthca_raddr_seg {
225 u64 raddr;
226 u32 rkey;
227 u32 reserved;
228};
229
230struct mthca_atomic_seg {
231 u64 swap_add;
232 u64 compare;
233};
234
235struct mthca_data_seg {
236 u32 byte_count;
237 u32 lkey;
238 u64 addr;
239};
240
241struct mthca_mlx_seg {
242 u32 nda_op;
243 u32 nds;
244 u32 flags; /* [17] VL15 [16] SLR [14:12] static rate
245 [11:8] SL [3] C [2] E */
246 u16 rlid;
247 u16 vcrc;
248};
249
250static const u8 mthca_opcode[] = { 179static const u8 mthca_opcode[] = {
251 [IB_WR_SEND] = MTHCA_OPCODE_SEND, 180 [IB_WR_SEND] = MTHCA_OPCODE_SEND,
252 [IB_WR_SEND_WITH_IMM] = MTHCA_OPCODE_SEND_IMM, 181 [IB_WR_SEND_WITH_IMM] = MTHCA_OPCODE_SEND_IMM,
@@ -573,12 +502,11 @@ static void init_port(struct mthca_dev *dev, int port)
573 502
574 memset(&param, 0, sizeof param); 503 memset(&param, 0, sizeof param);
575 504
576 param.enable_1x = 1; 505 param.port_width = dev->limits.port_width_cap;
577 param.enable_4x = 1; 506 param.vl_cap = dev->limits.vl_cap;
578 param.vl_cap = dev->limits.vl_cap; 507 param.mtu_cap = dev->limits.mtu_cap;
579 param.mtu_cap = dev->limits.mtu_cap; 508 param.gid_cap = dev->limits.gid_table_len;
580 param.gid_cap = dev->limits.gid_table_len; 509 param.pkey_cap = dev->limits.pkey_table_len;
581 param.pkey_cap = dev->limits.pkey_table_len;
582 510
583 err = mthca_INIT_IB(dev, &param, port, &status); 511 err = mthca_INIT_IB(dev, &param, port, &status);
584 if (err) 512 if (err)
@@ -684,10 +612,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
684 qp_context->mtu_msgmax = (attr->path_mtu << 5) | 31; 612 qp_context->mtu_msgmax = (attr->path_mtu << 5) | 31;
685 613
686 if (mthca_is_memfree(dev)) { 614 if (mthca_is_memfree(dev)) {
687 qp_context->rq_size_stride = 615 if (qp->rq.max)
688 ((ffs(qp->rq.max) - 1) << 3) | (qp->rq.wqe_shift - 4); 616 qp_context->rq_size_stride = long_log2(qp->rq.max) << 3;
689 qp_context->sq_size_stride = 617 qp_context->rq_size_stride |= qp->rq.wqe_shift - 4;
690 ((ffs(qp->sq.max) - 1) << 3) | (qp->sq.wqe_shift - 4); 618
619 if (qp->sq.max)
620 qp_context->sq_size_stride = long_log2(qp->sq.max) << 3;
621 qp_context->sq_size_stride |= qp->sq.wqe_shift - 4;
691 } 622 }
692 623
693 /* leave arbel_sched_queue as 0 */ 624 /* leave arbel_sched_queue as 0 */
@@ -856,6 +787,9 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
856 787
857 qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); 788 qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);
858 789
790 if (ibqp->srq)
791 qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RIC);
792
859 if (attr_mask & IB_QP_MIN_RNR_TIMER) { 793 if (attr_mask & IB_QP_MIN_RNR_TIMER) {
860 qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24); 794 qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24);
861 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_TIMEOUT); 795 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_TIMEOUT);
@@ -878,6 +812,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
878 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_Q_KEY); 812 qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_Q_KEY);
879 } 813 }
880 814
815 if (ibqp->srq)
816 qp_context->srqn = cpu_to_be32(1 << 24 |
817 to_msrq(ibqp->srq)->srqn);
818
881 err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans, 819 err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans,
882 qp->qpn, 0, mailbox, 0, &status); 820 qp->qpn, 0, mailbox, 0, &status);
883 if (status) { 821 if (status) {
@@ -925,10 +863,6 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
925 struct mthca_qp *qp) 863 struct mthca_qp *qp)
926{ 864{
927 int size; 865 int size;
928 int i;
929 int npages, shift;
930 dma_addr_t t;
931 u64 *dma_list = NULL;
932 int err = -ENOMEM; 866 int err = -ENOMEM;
933 867
934 size = sizeof (struct mthca_next_seg) + 868 size = sizeof (struct mthca_next_seg) +
@@ -978,116 +912,24 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
978 if (!qp->wrid) 912 if (!qp->wrid)
979 goto err_out; 913 goto err_out;
980 914
981 if (size <= MTHCA_MAX_DIRECT_QP_SIZE) { 915 err = mthca_buf_alloc(dev, size, MTHCA_MAX_DIRECT_QP_SIZE,
982 qp->is_direct = 1; 916 &qp->queue, &qp->is_direct, pd, 0, &qp->mr);
983 npages = 1;
984 shift = get_order(size) + PAGE_SHIFT;
985
986 if (0)
987 mthca_dbg(dev, "Creating direct QP of size %d (shift %d)\n",
988 size, shift);
989
990 qp->queue.direct.buf = dma_alloc_coherent(&dev->pdev->dev, size,
991 &t, GFP_KERNEL);
992 if (!qp->queue.direct.buf)
993 goto err_out;
994
995 pci_unmap_addr_set(&qp->queue.direct, mapping, t);
996
997 memset(qp->queue.direct.buf, 0, size);
998
999 while (t & ((1 << shift) - 1)) {
1000 --shift;
1001 npages *= 2;
1002 }
1003
1004 dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
1005 if (!dma_list)
1006 goto err_out_free;
1007
1008 for (i = 0; i < npages; ++i)
1009 dma_list[i] = t + i * (1 << shift);
1010 } else {
1011 qp->is_direct = 0;
1012 npages = size / PAGE_SIZE;
1013 shift = PAGE_SHIFT;
1014
1015 if (0)
1016 mthca_dbg(dev, "Creating indirect QP with %d pages\n", npages);
1017
1018 dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
1019 if (!dma_list)
1020 goto err_out;
1021
1022 qp->queue.page_list = kmalloc(npages *
1023 sizeof *qp->queue.page_list,
1024 GFP_KERNEL);
1025 if (!qp->queue.page_list)
1026 goto err_out;
1027
1028 for (i = 0; i < npages; ++i) {
1029 qp->queue.page_list[i].buf =
1030 dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
1031 &t, GFP_KERNEL);
1032 if (!qp->queue.page_list[i].buf)
1033 goto err_out_free;
1034
1035 memset(qp->queue.page_list[i].buf, 0, PAGE_SIZE);
1036
1037 pci_unmap_addr_set(&qp->queue.page_list[i], mapping, t);
1038 dma_list[i] = t;
1039 }
1040 }
1041
1042 err = mthca_mr_alloc_phys(dev, pd->pd_num, dma_list, shift,
1043 npages, 0, size,
1044 MTHCA_MPT_FLAG_LOCAL_READ,
1045 &qp->mr);
1046 if (err) 917 if (err)
1047 goto err_out_free; 918 goto err_out;
1048 919
1049 kfree(dma_list);
1050 return 0; 920 return 0;
1051 921
1052 err_out_free: 922err_out:
1053 if (qp->is_direct) {
1054 dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf,
1055 pci_unmap_addr(&qp->queue.direct, mapping));
1056 } else
1057 for (i = 0; i < npages; ++i) {
1058 if (qp->queue.page_list[i].buf)
1059 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
1060 qp->queue.page_list[i].buf,
1061 pci_unmap_addr(&qp->queue.page_list[i],
1062 mapping));
1063
1064 }
1065
1066 err_out:
1067 kfree(qp->wrid); 923 kfree(qp->wrid);
1068 kfree(dma_list);
1069 return err; 924 return err;
1070} 925}
1071 926
1072static void mthca_free_wqe_buf(struct mthca_dev *dev, 927static void mthca_free_wqe_buf(struct mthca_dev *dev,
1073 struct mthca_qp *qp) 928 struct mthca_qp *qp)
1074{ 929{
1075 int i; 930 mthca_buf_free(dev, PAGE_ALIGN(qp->send_wqe_offset +
1076 int size = PAGE_ALIGN(qp->send_wqe_offset + 931 (qp->sq.max << qp->sq.wqe_shift)),
1077 (qp->sq.max << qp->sq.wqe_shift)); 932 &qp->queue, qp->is_direct, &qp->mr);
1078
1079 if (qp->is_direct) {
1080 dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf,
1081 pci_unmap_addr(&qp->queue.direct, mapping));
1082 } else {
1083 for (i = 0; i < size / PAGE_SIZE; ++i) {
1084 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
1085 qp->queue.page_list[i].buf,
1086 pci_unmap_addr(&qp->queue.page_list[i],
1087 mapping));
1088 }
1089 }
1090
1091 kfree(qp->wrid); 933 kfree(qp->wrid);
1092} 934}
1093 935
@@ -1428,11 +1270,12 @@ void mthca_free_qp(struct mthca_dev *dev,
1428 * unref the mem-free tables and free the QPN in our table. 1270 * unref the mem-free tables and free the QPN in our table.
1429 */ 1271 */
1430 if (!qp->ibqp.uobject) { 1272 if (!qp->ibqp.uobject) {
1431 mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn); 1273 mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn,
1274 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
1432 if (qp->ibqp.send_cq != qp->ibqp.recv_cq) 1275 if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
1433 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn); 1276 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn,
1277 qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
1434 1278
1435 mthca_free_mr(dev, &qp->mr);
1436 mthca_free_memfree(dev, qp); 1279 mthca_free_memfree(dev, qp);
1437 mthca_free_wqe_buf(dev, qp); 1280 mthca_free_wqe_buf(dev, qp);
1438 } 1281 }
@@ -1457,6 +1300,7 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
1457{ 1300{
1458 int header_size; 1301 int header_size;
1459 int err; 1302 int err;
1303 u16 pkey;
1460 1304
1461 ib_ud_header_init(256, /* assume a MAD */ 1305 ib_ud_header_init(256, /* assume a MAD */
1462 sqp->ud_header.grh_present, 1306 sqp->ud_header.grh_present,
@@ -1467,8 +1311,8 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
1467 return err; 1311 return err;
1468 mlx->flags &= ~cpu_to_be32(MTHCA_NEXT_SOLICIT | 1); 1312 mlx->flags &= ~cpu_to_be32(MTHCA_NEXT_SOLICIT | 1);
1469 mlx->flags |= cpu_to_be32((!sqp->qp.ibqp.qp_num ? MTHCA_MLX_VL15 : 0) | 1313 mlx->flags |= cpu_to_be32((!sqp->qp.ibqp.qp_num ? MTHCA_MLX_VL15 : 0) |
1470 (sqp->ud_header.lrh.destination_lid == 0xffff ? 1314 (sqp->ud_header.lrh.destination_lid ==
1471 MTHCA_MLX_SLR : 0) | 1315 IB_LID_PERMISSIVE ? MTHCA_MLX_SLR : 0) |
1472 (sqp->ud_header.lrh.service_level << 8)); 1316 (sqp->ud_header.lrh.service_level << 8));
1473 mlx->rlid = sqp->ud_header.lrh.destination_lid; 1317 mlx->rlid = sqp->ud_header.lrh.destination_lid;
1474 mlx->vcrc = 0; 1318 mlx->vcrc = 0;
@@ -1488,18 +1332,16 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
1488 } 1332 }
1489 1333
1490 sqp->ud_header.lrh.virtual_lane = !sqp->qp.ibqp.qp_num ? 15 : 0; 1334 sqp->ud_header.lrh.virtual_lane = !sqp->qp.ibqp.qp_num ? 15 : 0;
1491 if (sqp->ud_header.lrh.destination_lid == 0xffff) 1335 if (sqp->ud_header.lrh.destination_lid == IB_LID_PERMISSIVE)
1492 sqp->ud_header.lrh.source_lid = 0xffff; 1336 sqp->ud_header.lrh.source_lid = IB_LID_PERMISSIVE;
1493 sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED); 1337 sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
1494 if (!sqp->qp.ibqp.qp_num) 1338 if (!sqp->qp.ibqp.qp_num)
1495 ib_get_cached_pkey(&dev->ib_dev, sqp->port, 1339 ib_get_cached_pkey(&dev->ib_dev, sqp->port,
1496 sqp->pkey_index, 1340 sqp->pkey_index, &pkey);
1497 &sqp->ud_header.bth.pkey);
1498 else 1341 else
1499 ib_get_cached_pkey(&dev->ib_dev, sqp->port, 1342 ib_get_cached_pkey(&dev->ib_dev, sqp->port,
1500 wr->wr.ud.pkey_index, 1343 wr->wr.ud.pkey_index, &pkey);
1501 &sqp->ud_header.bth.pkey); 1344 sqp->ud_header.bth.pkey = cpu_to_be16(pkey);
1502 cpu_to_be16s(&sqp->ud_header.bth.pkey);
1503 sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn); 1345 sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);
1504 sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); 1346 sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1));
1505 sqp->ud_header.deth.qkey = cpu_to_be32(wr->wr.ud.remote_qkey & 0x80000000 ? 1347 sqp->ud_header.deth.qkey = cpu_to_be32(wr->wr.ud.remote_qkey & 0x80000000 ?
@@ -1742,7 +1584,7 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1742 1584
1743out: 1585out:
1744 if (likely(nreq)) { 1586 if (likely(nreq)) {
1745 u32 doorbell[2]; 1587 __be32 doorbell[2];
1746 1588
1747 doorbell[0] = cpu_to_be32(((qp->sq.next_ind << qp->sq.wqe_shift) + 1589 doorbell[0] = cpu_to_be32(((qp->sq.next_ind << qp->sq.wqe_shift) +
1748 qp->send_wqe_offset) | f0 | op0); 1590 qp->send_wqe_offset) | f0 | op0);
@@ -1843,7 +1685,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1843 1685
1844out: 1686out:
1845 if (likely(nreq)) { 1687 if (likely(nreq)) {
1846 u32 doorbell[2]; 1688 __be32 doorbell[2];
1847 1689
1848 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); 1690 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1849 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); 1691 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
@@ -2064,7 +1906,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2064 1906
2065out: 1907out:
2066 if (likely(nreq)) { 1908 if (likely(nreq)) {
2067 u32 doorbell[2]; 1909 __be32 doorbell[2];
2068 1910
2069 doorbell[0] = cpu_to_be32((nreq << 24) | 1911 doorbell[0] = cpu_to_be32((nreq << 24) |
2070 ((qp->sq.head & 0xffff) << 8) | 1912 ((qp->sq.head & 0xffff) << 8) |
@@ -2174,19 +2016,25 @@ out:
2174} 2016}
2175 2017
2176int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send, 2018int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
2177 int index, int *dbd, u32 *new_wqe) 2019 int index, int *dbd, __be32 *new_wqe)
2178{ 2020{
2179 struct mthca_next_seg *next; 2021 struct mthca_next_seg *next;
2180 2022
2023 /*
2024 * For SRQs, all WQEs generate a CQE, so we're always at the
2025 * end of the doorbell chain.
2026 */
2027 if (qp->ibqp.srq) {
2028 *new_wqe = 0;
2029 return 0;
2030 }
2031
2181 if (is_send) 2032 if (is_send)
2182 next = get_send_wqe(qp, index); 2033 next = get_send_wqe(qp, index);
2183 else 2034 else
2184 next = get_recv_wqe(qp, index); 2035 next = get_recv_wqe(qp, index);
2185 2036
2186 if (mthca_is_memfree(dev)) 2037 *dbd = !!(next->ee_nds & cpu_to_be32(MTHCA_NEXT_DBD));
2187 *dbd = 1;
2188 else
2189 *dbd = !!(next->ee_nds & cpu_to_be32(MTHCA_NEXT_DBD));
2190 if (next->ee_nds & cpu_to_be32(0x3f)) 2038 if (next->ee_nds & cpu_to_be32(0x3f))
2191 *new_wqe = (next->nda_op & cpu_to_be32(~0x3f)) | 2039 *new_wqe = (next->nda_op & cpu_to_be32(~0x3f)) |
2192 (next->ee_nds & cpu_to_be32(0x3f)); 2040 (next->ee_nds & cpu_to_be32(0x3f));
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
new file mode 100644
index 000000000000..75cd2d84ef12
--- /dev/null
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -0,0 +1,591 @@
1/*
2 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $
33 */
34
35#include "mthca_dev.h"
36#include "mthca_cmd.h"
37#include "mthca_memfree.h"
38#include "mthca_wqe.h"
39
40enum {
41 MTHCA_MAX_DIRECT_SRQ_SIZE = 4 * PAGE_SIZE
42};
43
44struct mthca_tavor_srq_context {
45 __be64 wqe_base_ds; /* low 6 bits is descriptor size */
46 __be32 state_pd;
47 __be32 lkey;
48 __be32 uar;
49 __be32 wqe_cnt;
50 u32 reserved[2];
51};
52
53struct mthca_arbel_srq_context {
54 __be32 state_logsize_srqn;
55 __be32 lkey;
56 __be32 db_index;
57 __be32 logstride_usrpage;
58 __be64 wqe_base;
59 __be32 eq_pd;
60 __be16 limit_watermark;
61 __be16 wqe_cnt;
62 u16 reserved1;
63 __be16 wqe_counter;
64 u32 reserved2[3];
65};
66
67static void *get_wqe(struct mthca_srq *srq, int n)
68{
69 if (srq->is_direct)
70 return srq->queue.direct.buf + (n << srq->wqe_shift);
71 else
72 return srq->queue.page_list[(n << srq->wqe_shift) >> PAGE_SHIFT].buf +
73 ((n << srq->wqe_shift) & (PAGE_SIZE - 1));
74}
75
76/*
77 * Return a pointer to the location within a WQE that we're using as a
78 * link when the WQE is in the free list. We use an offset of 4
79 * because in the Tavor case, posting a WQE may overwrite the first
80 * four bytes of the previous WQE. The offset avoids corrupting our
81 * free list if the WQE has already completed and been put on the free
82 * list when we post the next WQE.
83 */
84static inline int *wqe_to_link(void *wqe)
85{
86 return (int *) (wqe + 4);
87}
88
89static void mthca_tavor_init_srq_context(struct mthca_dev *dev,
90 struct mthca_pd *pd,
91 struct mthca_srq *srq,
92 struct mthca_tavor_srq_context *context)
93{
94 memset(context, 0, sizeof *context);
95
96 context->wqe_base_ds = cpu_to_be64(1 << (srq->wqe_shift - 4));
97 context->state_pd = cpu_to_be32(pd->pd_num);
98 context->lkey = cpu_to_be32(srq->mr.ibmr.lkey);
99
100 if (pd->ibpd.uobject)
101 context->uar =
102 cpu_to_be32(to_mucontext(pd->ibpd.uobject->context)->uar.index);
103 else
104 context->uar = cpu_to_be32(dev->driver_uar.index);
105}
106
107static void mthca_arbel_init_srq_context(struct mthca_dev *dev,
108 struct mthca_pd *pd,
109 struct mthca_srq *srq,
110 struct mthca_arbel_srq_context *context)
111{
112 int logsize;
113
114 memset(context, 0, sizeof *context);
115
116 logsize = long_log2(srq->max) + srq->wqe_shift;
117 context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn);
118 context->lkey = cpu_to_be32(srq->mr.ibmr.lkey);
119 context->db_index = cpu_to_be32(srq->db_index);
120 context->logstride_usrpage = cpu_to_be32((srq->wqe_shift - 4) << 29);
121 if (pd->ibpd.uobject)
122 context->logstride_usrpage |=
123 cpu_to_be32(to_mucontext(pd->ibpd.uobject->context)->uar.index);
124 else
125 context->logstride_usrpage |= cpu_to_be32(dev->driver_uar.index);
126 context->eq_pd = cpu_to_be32(MTHCA_EQ_ASYNC << 24 | pd->pd_num);
127}
128
129static void mthca_free_srq_buf(struct mthca_dev *dev, struct mthca_srq *srq)
130{
131 mthca_buf_free(dev, srq->max << srq->wqe_shift, &srq->queue,
132 srq->is_direct, &srq->mr);
133 kfree(srq->wrid);
134}
135
136static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd,
137 struct mthca_srq *srq)
138{
139 struct mthca_data_seg *scatter;
140 void *wqe;
141 int err;
142 int i;
143
144 if (pd->ibpd.uobject)
145 return 0;
146
147 srq->wrid = kmalloc(srq->max * sizeof (u64), GFP_KERNEL);
148 if (!srq->wrid)
149 return -ENOMEM;
150
151 err = mthca_buf_alloc(dev, srq->max << srq->wqe_shift,
152 MTHCA_MAX_DIRECT_SRQ_SIZE,
153 &srq->queue, &srq->is_direct, pd, 1, &srq->mr);
154 if (err) {
155 kfree(srq->wrid);
156 return err;
157 }
158
159 /*
160 * Now initialize the SRQ buffer so that all of the WQEs are
161 * linked into the list of free WQEs. In addition, set the
162 * scatter list L_Keys to the sentry value of 0x100.
163 */
164 for (i = 0; i < srq->max; ++i) {
165 wqe = get_wqe(srq, i);
166
167 *wqe_to_link(wqe) = i < srq->max - 1 ? i + 1 : -1;
168
169 for (scatter = wqe + sizeof (struct mthca_next_seg);
170 (void *) scatter < wqe + (1 << srq->wqe_shift);
171 ++scatter)
172 scatter->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
173 }
174
175 return 0;
176}
177
178int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
179 struct ib_srq_attr *attr, struct mthca_srq *srq)
180{
181 struct mthca_mailbox *mailbox;
182 u8 status;
183 int ds;
184 int err;
185
186 /* Sanity check SRQ size before proceeding */
187 if (attr->max_wr > 16 << 20 || attr->max_sge > 64)
188 return -EINVAL;
189
190 srq->max = attr->max_wr;
191 srq->max_gs = attr->max_sge;
192 srq->last = NULL;
193 srq->counter = 0;
194
195 if (mthca_is_memfree(dev))
196 srq->max = roundup_pow_of_two(srq->max + 1);
197
198 ds = min(64UL,
199 roundup_pow_of_two(sizeof (struct mthca_next_seg) +
200 srq->max_gs * sizeof (struct mthca_data_seg)));
201 srq->wqe_shift = long_log2(ds);
202
203 srq->srqn = mthca_alloc(&dev->srq_table.alloc);
204 if (srq->srqn == -1)
205 return -ENOMEM;
206
207 if (mthca_is_memfree(dev)) {
208 err = mthca_table_get(dev, dev->srq_table.table, srq->srqn);
209 if (err)
210 goto err_out;
211
212 if (!pd->ibpd.uobject) {
213 srq->db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SRQ,
214 srq->srqn, &srq->db);
215 if (srq->db_index < 0) {
216 err = -ENOMEM;
217 goto err_out_icm;
218 }
219 }
220 }
221
222 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
223 if (IS_ERR(mailbox)) {
224 err = PTR_ERR(mailbox);
225 goto err_out_db;
226 }
227
228 err = mthca_alloc_srq_buf(dev, pd, srq);
229 if (err)
230 goto err_out_mailbox;
231
232 spin_lock_init(&srq->lock);
233 atomic_set(&srq->refcount, 1);
234 init_waitqueue_head(&srq->wait);
235
236 if (mthca_is_memfree(dev))
237 mthca_arbel_init_srq_context(dev, pd, srq, mailbox->buf);
238 else
239 mthca_tavor_init_srq_context(dev, pd, srq, mailbox->buf);
240
241 err = mthca_SW2HW_SRQ(dev, mailbox, srq->srqn, &status);
242
243 if (err) {
244 mthca_warn(dev, "SW2HW_SRQ failed (%d)\n", err);
245 goto err_out_free_buf;
246 }
247 if (status) {
248 mthca_warn(dev, "SW2HW_SRQ returned status 0x%02x\n",
249 status);
250 err = -EINVAL;
251 goto err_out_free_buf;
252 }
253
254 spin_lock_irq(&dev->srq_table.lock);
255 if (mthca_array_set(&dev->srq_table.srq,
256 srq->srqn & (dev->limits.num_srqs - 1),
257 srq)) {
258 spin_unlock_irq(&dev->srq_table.lock);
259 goto err_out_free_srq;
260 }
261 spin_unlock_irq(&dev->srq_table.lock);
262
263 mthca_free_mailbox(dev, mailbox);
264
265 srq->first_free = 0;
266 srq->last_free = srq->max - 1;
267
268 return 0;
269
270err_out_free_srq:
271 err = mthca_HW2SW_SRQ(dev, mailbox, srq->srqn, &status);
272 if (err)
273 mthca_warn(dev, "HW2SW_SRQ failed (%d)\n", err);
274 else if (status)
275 mthca_warn(dev, "HW2SW_SRQ returned status 0x%02x\n", status);
276
277err_out_free_buf:
278 if (!pd->ibpd.uobject)
279 mthca_free_srq_buf(dev, srq);
280
281err_out_mailbox:
282 mthca_free_mailbox(dev, mailbox);
283
284err_out_db:
285 if (!pd->ibpd.uobject && mthca_is_memfree(dev))
286 mthca_free_db(dev, MTHCA_DB_TYPE_SRQ, srq->db_index);
287
288err_out_icm:
289 mthca_table_put(dev, dev->srq_table.table, srq->srqn);
290
291err_out:
292 mthca_free(&dev->srq_table.alloc, srq->srqn);
293
294 return err;
295}
296
297void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq)
298{
299 struct mthca_mailbox *mailbox;
300 int err;
301 u8 status;
302
303 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
304 if (IS_ERR(mailbox)) {
305 mthca_warn(dev, "No memory for mailbox to free SRQ.\n");
306 return;
307 }
308
309 err = mthca_HW2SW_SRQ(dev, mailbox, srq->srqn, &status);
310 if (err)
311 mthca_warn(dev, "HW2SW_SRQ failed (%d)\n", err);
312 else if (status)
313 mthca_warn(dev, "HW2SW_SRQ returned status 0x%02x\n", status);
314
315 spin_lock_irq(&dev->srq_table.lock);
316 mthca_array_clear(&dev->srq_table.srq,
317 srq->srqn & (dev->limits.num_srqs - 1));
318 spin_unlock_irq(&dev->srq_table.lock);
319
320 atomic_dec(&srq->refcount);
321 wait_event(srq->wait, !atomic_read(&srq->refcount));
322
323 if (!srq->ibsrq.uobject) {
324 mthca_free_srq_buf(dev, srq);
325 if (mthca_is_memfree(dev))
326 mthca_free_db(dev, MTHCA_DB_TYPE_SRQ, srq->db_index);
327 }
328
329 mthca_table_put(dev, dev->srq_table.table, srq->srqn);
330 mthca_free(&dev->srq_table.alloc, srq->srqn);
331 mthca_free_mailbox(dev, mailbox);
332}
333
334void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
335 enum ib_event_type event_type)
336{
337 struct mthca_srq *srq;
338 struct ib_event event;
339
340 spin_lock(&dev->srq_table.lock);
341 srq = mthca_array_get(&dev->srq_table.srq, srqn & (dev->limits.num_srqs - 1));
342 if (srq)
343 atomic_inc(&srq->refcount);
344 spin_unlock(&dev->srq_table.lock);
345
346 if (!srq) {
347 mthca_warn(dev, "Async event for bogus SRQ %08x\n", srqn);
348 return;
349 }
350
351 if (!srq->ibsrq.event_handler)
352 goto out;
353
354 event.device = &dev->ib_dev;
355 event.event = event_type;
356 event.element.srq = &srq->ibsrq;
357 srq->ibsrq.event_handler(&event, srq->ibsrq.srq_context);
358
359out:
360 if (atomic_dec_and_test(&srq->refcount))
361 wake_up(&srq->wait);
362}
363
364/*
365 * This function must be called with IRQs disabled.
366 */
367void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr)
368{
369 int ind;
370
371 ind = wqe_addr >> srq->wqe_shift;
372
373 spin_lock(&srq->lock);
374
375 if (likely(srq->first_free >= 0))
376 *wqe_to_link(get_wqe(srq, srq->last_free)) = ind;
377 else
378 srq->first_free = ind;
379
380 *wqe_to_link(get_wqe(srq, ind)) = -1;
381 srq->last_free = ind;
382
383 spin_unlock(&srq->lock);
384}
385
386int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
387 struct ib_recv_wr **bad_wr)
388{
389 struct mthca_dev *dev = to_mdev(ibsrq->device);
390 struct mthca_srq *srq = to_msrq(ibsrq);
391 unsigned long flags;
392 int err = 0;
393 int first_ind;
394 int ind;
395 int next_ind;
396 int nreq;
397 int i;
398 void *wqe;
399 void *prev_wqe;
400
401 spin_lock_irqsave(&srq->lock, flags);
402
403 first_ind = srq->first_free;
404
405 for (nreq = 0; wr; ++nreq, wr = wr->next) {
406 ind = srq->first_free;
407
408 if (ind < 0) {
409 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
410 err = -ENOMEM;
411 *bad_wr = wr;
412 return nreq;
413 }
414
415 wqe = get_wqe(srq, ind);
416 next_ind = *wqe_to_link(wqe);
417 prev_wqe = srq->last;
418 srq->last = wqe;
419
420 ((struct mthca_next_seg *) wqe)->nda_op = 0;
421 ((struct mthca_next_seg *) wqe)->ee_nds = 0;
422 /* flags field will always remain 0 */
423
424 wqe += sizeof (struct mthca_next_seg);
425
426 if (unlikely(wr->num_sge > srq->max_gs)) {
427 err = -EINVAL;
428 *bad_wr = wr;
429 srq->last = prev_wqe;
430 return nreq;
431 }
432
433 for (i = 0; i < wr->num_sge; ++i) {
434 ((struct mthca_data_seg *) wqe)->byte_count =
435 cpu_to_be32(wr->sg_list[i].length);
436 ((struct mthca_data_seg *) wqe)->lkey =
437 cpu_to_be32(wr->sg_list[i].lkey);
438 ((struct mthca_data_seg *) wqe)->addr =
439 cpu_to_be64(wr->sg_list[i].addr);
440 wqe += sizeof (struct mthca_data_seg);
441 }
442
443 if (i < srq->max_gs) {
444 ((struct mthca_data_seg *) wqe)->byte_count = 0;
445 ((struct mthca_data_seg *) wqe)->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
446 ((struct mthca_data_seg *) wqe)->addr = 0;
447 }
448
449 if (likely(prev_wqe)) {
450 ((struct mthca_next_seg *) prev_wqe)->nda_op =
451 cpu_to_be32((ind << srq->wqe_shift) | 1);
452 wmb();
453 ((struct mthca_next_seg *) prev_wqe)->ee_nds =
454 cpu_to_be32(MTHCA_NEXT_DBD);
455 }
456
457 srq->wrid[ind] = wr->wr_id;
458 srq->first_free = next_ind;
459 }
460
461 return nreq;
462
463 if (likely(nreq)) {
464 __be32 doorbell[2];
465
466 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
467 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
468
469 /*
470 * Make sure that descriptors are written before
471 * doorbell is rung.
472 */
473 wmb();
474
475 mthca_write64(doorbell,
476 dev->kar + MTHCA_RECEIVE_DOORBELL,
477 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
478 }
479
480 spin_unlock_irqrestore(&srq->lock, flags);
481 return err;
482}
483
484int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
485 struct ib_recv_wr **bad_wr)
486{
487 struct mthca_dev *dev = to_mdev(ibsrq->device);
488 struct mthca_srq *srq = to_msrq(ibsrq);
489 unsigned long flags;
490 int err = 0;
491 int ind;
492 int next_ind;
493 int nreq;
494 int i;
495 void *wqe;
496
497 spin_lock_irqsave(&srq->lock, flags);
498
499 for (nreq = 0; wr; ++nreq, wr = wr->next) {
500 ind = srq->first_free;
501
502 if (ind < 0) {
503 mthca_err(dev, "SRQ %06x full\n", srq->srqn);
504 err = -ENOMEM;
505 *bad_wr = wr;
506 return nreq;
507 }
508
509 wqe = get_wqe(srq, ind);
510 next_ind = *wqe_to_link(wqe);
511
512 ((struct mthca_next_seg *) wqe)->nda_op =
513 cpu_to_be32((next_ind << srq->wqe_shift) | 1);
514 ((struct mthca_next_seg *) wqe)->ee_nds = 0;
515 /* flags field will always remain 0 */
516
517 wqe += sizeof (struct mthca_next_seg);
518
519 if (unlikely(wr->num_sge > srq->max_gs)) {
520 err = -EINVAL;
521 *bad_wr = wr;
522 return nreq;
523 }
524
525 for (i = 0; i < wr->num_sge; ++i) {
526 ((struct mthca_data_seg *) wqe)->byte_count =
527 cpu_to_be32(wr->sg_list[i].length);
528 ((struct mthca_data_seg *) wqe)->lkey =
529 cpu_to_be32(wr->sg_list[i].lkey);
530 ((struct mthca_data_seg *) wqe)->addr =
531 cpu_to_be64(wr->sg_list[i].addr);
532 wqe += sizeof (struct mthca_data_seg);
533 }
534
535 if (i < srq->max_gs) {
536 ((struct mthca_data_seg *) wqe)->byte_count = 0;
537 ((struct mthca_data_seg *) wqe)->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
538 ((struct mthca_data_seg *) wqe)->addr = 0;
539 }
540
541 srq->wrid[ind] = wr->wr_id;
542 srq->first_free = next_ind;
543 }
544
545 if (likely(nreq)) {
546 srq->counter += nreq;
547
548 /*
549 * Make sure that descriptors are written before
550 * we write doorbell record.
551 */
552 wmb();
553 *srq->db = cpu_to_be32(srq->counter);
554 }
555
556 spin_unlock_irqrestore(&srq->lock, flags);
557 return err;
558}
559
560int __devinit mthca_init_srq_table(struct mthca_dev *dev)
561{
562 int err;
563
564 if (!(dev->mthca_flags & MTHCA_FLAG_SRQ))
565 return 0;
566
567 spin_lock_init(&dev->srq_table.lock);
568
569 err = mthca_alloc_init(&dev->srq_table.alloc,
570 dev->limits.num_srqs,
571 dev->limits.num_srqs - 1,
572 dev->limits.reserved_srqs);
573 if (err)
574 return err;
575
576 err = mthca_array_init(&dev->srq_table.srq,
577 dev->limits.num_srqs);
578 if (err)
579 mthca_alloc_cleanup(&dev->srq_table.alloc);
580
581 return err;
582}
583
584void __devexit mthca_cleanup_srq_table(struct mthca_dev *dev)
585{
586 if (!(dev->mthca_flags & MTHCA_FLAG_SRQ))
587 return;
588
589 mthca_array_cleanup(&dev->srq_table.srq, dev->limits.num_srqs);
590 mthca_alloc_cleanup(&dev->srq_table.alloc);
591}
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
index 3024c1b4547d..41613ec8a04e 100644
--- a/drivers/infiniband/hw/mthca/mthca_user.h
+++ b/drivers/infiniband/hw/mthca/mthca_user.h
@@ -69,6 +69,17 @@ struct mthca_create_cq_resp {
69 __u32 reserved; 69 __u32 reserved;
70}; 70};
71 71
72struct mthca_create_srq {
73 __u32 lkey;
74 __u32 db_index;
75 __u64 db_page;
76};
77
78struct mthca_create_srq_resp {
79 __u32 srqn;
80 __u32 reserved;
81};
82
72struct mthca_create_qp { 83struct mthca_create_qp {
73 __u32 lkey; 84 __u32 lkey;
74 __u32 reserved; 85 __u32 reserved;
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
new file mode 100644
index 000000000000..1f4c0ff28f79
--- /dev/null
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 *
32 * $Id: mthca_wqe.h 3047 2005-08-10 03:59:35Z roland $
33 */
34
35#ifndef MTHCA_WQE_H
36#define MTHCA_WQE_H
37
38#include <linux/types.h>
39
40enum {
41 MTHCA_NEXT_DBD = 1 << 7,
42 MTHCA_NEXT_FENCE = 1 << 6,
43 MTHCA_NEXT_CQ_UPDATE = 1 << 3,
44 MTHCA_NEXT_EVENT_GEN = 1 << 2,
45 MTHCA_NEXT_SOLICIT = 1 << 1,
46
47 MTHCA_MLX_VL15 = 1 << 17,
48 MTHCA_MLX_SLR = 1 << 16
49};
50
51enum {
52 MTHCA_INVAL_LKEY = 0x100
53};
54
55struct mthca_next_seg {
56 __be32 nda_op; /* [31:6] next WQE [4:0] next opcode */
57 __be32 ee_nds; /* [31:8] next EE [7] DBD [6] F [5:0] next WQE size */
58 __be32 flags; /* [3] CQ [2] Event [1] Solicit */
59 __be32 imm; /* immediate data */
60};
61
62struct mthca_tavor_ud_seg {
63 u32 reserved1;
64 __be32 lkey;
65 __be64 av_addr;
66 u32 reserved2[4];
67 __be32 dqpn;
68 __be32 qkey;
69 u32 reserved3[2];
70};
71
72struct mthca_arbel_ud_seg {
73 __be32 av[8];
74 __be32 dqpn;
75 __be32 qkey;
76 u32 reserved[2];
77};
78
79struct mthca_bind_seg {
80 __be32 flags; /* [31] Atomic [30] rem write [29] rem read */
81 u32 reserved;
82 __be32 new_rkey;
83 __be32 lkey;
84 __be64 addr;
85 __be64 length;
86};
87
88struct mthca_raddr_seg {
89 __be64 raddr;
90 __be32 rkey;
91 u32 reserved;
92};
93
94struct mthca_atomic_seg {
95 __be64 swap_add;
96 __be64 compare;
97};
98
99struct mthca_data_seg {
100 __be32 byte_count;
101 __be32 lkey;
102 __be64 addr;
103};
104
105struct mthca_mlx_seg {
106 __be32 nda_op;
107 __be32 nds;
108 __be32 flags; /* [17] VL15 [16] SLR [14:12] static rate
109 [11:8] SL [3] C [2] E */
110 __be16 rlid;
111 __be16 vcrc;
112};
113
114#endif /* MTHCA_WQE_H */