diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 19:06:29 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-29 19:06:29 -0400 |
commit | 502c7f1dd566e7ca8aabdb755182664c5fdaebf1 (patch) | |
tree | 31934a4da45c0cb83acd118a181db4c51967ac8a /drivers/infiniband/hw/mthca | |
parent | 2cba582a49f1535c1a12a687cfb3dab713c22cc4 (diff) | |
parent | 8f3d17fb7bcb7c255197d11469fb5e9695c9d2f4 (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/infiniband/hw/mthca')
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 @@ | |||
1 | EXTRA_CFLAGS += -Idrivers/infiniband/include | ||
2 | |||
3 | ifdef CONFIG_INFINIBAND_MTHCA_DEBUG | 1 | ifdef CONFIG_INFINIBAND_MTHCA_DEBUG |
4 | EXTRA_CFLAGS += -DDEBUG | 2 | EXTRA_CFLAGS += -DDEBUG |
5 | endif | 3 | endif |
@@ -9,4 +7,4 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o | |||
9 | ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \ | 7 | ib_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 | |||
188 | int 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 | |||
267 | err_free: | ||
268 | mthca_buf_free(dev, size, buf, *is_direct, NULL); | ||
269 | |||
270 | err_out: | ||
271 | kfree(dma_list); | ||
272 | |||
273 | return err; | ||
274 | } | ||
275 | |||
276 | void 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 | ||
43 | struct mthca_av { | 43 | struct 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 | ||
56 | int mthca_create_ah(struct mthca_dev *dev, | 56 | int 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 | ||
237 | out: | 239 | out: |
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 | ||
283 | out: | 287 | out: |
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 | ||
1091 | static 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 | |||
1085 | int mthca_QUERY_ADAPTER(struct mthca_dev *dev, | 1119 | int 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 | |||
1114 | out: | 1152 | out: |
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 | |||
1342 | int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status) | 1377 | int 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 | ||
1506 | int 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 | |||
1513 | int 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 | |||
1521 | int 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 | |||
1471 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | 1527 | int 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 | ||
185 | struct mthca_adapter { | 186 | struct 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 | ||
192 | struct mthca_init_hca_param { | 194 | struct mthca_init_hca_param { |
@@ -218,8 +220,7 @@ struct mthca_init_hca_param { | |||
218 | }; | 220 | }; |
219 | 221 | ||
220 | struct mthca_init_ib_param { | 222 | struct 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); |
298 | int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, | 299 | int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, |
299 | int cq_num, u8 *status); | 300 | int cq_num, u8 *status); |
301 | int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, | ||
302 | int srq_num, u8 *status); | ||
303 | int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, | ||
304 | int srq_num, u8 *status); | ||
305 | int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status); | ||
300 | int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, | 306 | int 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 | */ |
57 | struct mthca_cq_context { | 59 | struct 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 | ||
110 | struct mthca_cqe { | 112 | struct 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 | ||
125 | struct mthca_err_cqe { | 127 | struct 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) | |||
191 | static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq, | 193 | static 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 | ||
225 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn) | 227 | void 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 | ||
585 | int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify) | 598 | int 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) | |||
602 | int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) | 615 | int 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 | ||
638 | static void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq *cq) | 651 | static 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 | |||
662 | static 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 | |||
740 | err_free: | ||
741 | mthca_free_cq_buf(dev, cq); | ||
742 | |||
743 | err_out: | ||
744 | kfree(dma_list); | ||
745 | |||
746 | return err; | ||
747 | } | 655 | } |
748 | 656 | ||
749 | int mthca_init_cq(struct mthca_dev *dev, int nent, | 657 | int 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 | ||
859 | err_out_free_mr: | 768 | err_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 | ||
865 | err_out_mailbox: | 772 | err_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 | ||
69 | enum { | 71 | enum { |
72 | MTHCA_BOARD_ID_LEN = 64 | ||
73 | }; | ||
74 | |||
75 | enum { | ||
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 | ||
147 | struct mthca_alloc { | 154 | struct 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 | ||
221 | struct 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 | |||
214 | struct mthca_qp_table { | 228 | struct 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); | |||
354 | void mthca_array_clear(struct mthca_array *array, int index); | 369 | void mthca_array_clear(struct mthca_array *array, int index); |
355 | int mthca_array_init(struct mthca_array *array, int nent); | 370 | int mthca_array_init(struct mthca_array *array, int nent); |
356 | void mthca_array_cleanup(struct mthca_array *array, int nent); | 371 | void mthca_array_cleanup(struct mthca_array *array, int nent); |
372 | int 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); | ||
375 | void mthca_buf_free(struct mthca_dev *dev, int size, union mthca_buf *buf, | ||
376 | int is_direct, struct mthca_mr *mr); | ||
357 | 377 | ||
358 | int mthca_init_uar_table(struct mthca_dev *dev); | 378 | int mthca_init_uar_table(struct mthca_dev *dev); |
359 | int mthca_init_pd_table(struct mthca_dev *dev); | 379 | int mthca_init_pd_table(struct mthca_dev *dev); |
360 | int mthca_init_mr_table(struct mthca_dev *dev); | 380 | int mthca_init_mr_table(struct mthca_dev *dev); |
361 | int mthca_init_eq_table(struct mthca_dev *dev); | 381 | int mthca_init_eq_table(struct mthca_dev *dev); |
362 | int mthca_init_cq_table(struct mthca_dev *dev); | 382 | int mthca_init_cq_table(struct mthca_dev *dev); |
383 | int mthca_init_srq_table(struct mthca_dev *dev); | ||
363 | int mthca_init_qp_table(struct mthca_dev *dev); | 384 | int mthca_init_qp_table(struct mthca_dev *dev); |
364 | int mthca_init_av_table(struct mthca_dev *dev); | 385 | int mthca_init_av_table(struct mthca_dev *dev); |
365 | int mthca_init_mcg_table(struct mthca_dev *dev); | 386 | int mthca_init_mcg_table(struct mthca_dev *dev); |
@@ -369,6 +390,7 @@ void mthca_cleanup_pd_table(struct mthca_dev *dev); | |||
369 | void mthca_cleanup_mr_table(struct mthca_dev *dev); | 390 | void mthca_cleanup_mr_table(struct mthca_dev *dev); |
370 | void mthca_cleanup_eq_table(struct mthca_dev *dev); | 391 | void mthca_cleanup_eq_table(struct mthca_dev *dev); |
371 | void mthca_cleanup_cq_table(struct mthca_dev *dev); | 392 | void mthca_cleanup_cq_table(struct mthca_dev *dev); |
393 | void mthca_cleanup_srq_table(struct mthca_dev *dev); | ||
372 | void mthca_cleanup_qp_table(struct mthca_dev *dev); | 394 | void mthca_cleanup_qp_table(struct mthca_dev *dev); |
373 | void mthca_cleanup_av_table(struct mthca_dev *dev); | 395 | void mthca_cleanup_av_table(struct mthca_dev *dev); |
374 | void mthca_cleanup_mcg_table(struct mthca_dev *dev); | 396 | void mthca_cleanup_mcg_table(struct mthca_dev *dev); |
@@ -419,7 +441,19 @@ int mthca_init_cq(struct mthca_dev *dev, int nent, | |||
419 | void mthca_free_cq(struct mthca_dev *dev, | 441 | void mthca_free_cq(struct mthca_dev *dev, |
420 | struct mthca_cq *cq); | 442 | struct mthca_cq *cq); |
421 | void mthca_cq_event(struct mthca_dev *dev, u32 cqn); | 443 | void mthca_cq_event(struct mthca_dev *dev, u32 cqn); |
422 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn); | 444 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, |
445 | struct mthca_srq *srq); | ||
446 | |||
447 | int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | ||
448 | struct ib_srq_attr *attr, struct mthca_srq *srq); | ||
449 | void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq); | ||
450 | void mthca_srq_event(struct mthca_dev *dev, u32 srqn, | ||
451 | enum ib_event_type event_type); | ||
452 | void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr); | ||
453 | int mthca_tavor_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr, | ||
454 | struct ib_recv_wr **bad_wr); | ||
455 | int mthca_arbel_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr, | ||
456 | struct ib_recv_wr **bad_wr); | ||
423 | 457 | ||
424 | void mthca_qp_event(struct mthca_dev *dev, u32 qpn, | 458 | void 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, | |||
433 | int mthca_arbel_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | 467 | int 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); |
435 | int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send, | 469 | int 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); |
437 | int mthca_alloc_qp(struct mthca_dev *dev, | 471 | int 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 | ||
60 | static inline void mthca_write64(u32 val[2], void __iomem *dest, | 61 | static 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 | ||
66 | static inline void mthca_write_db_rec(u32 val[2], u32 *db) | 67 | static 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 | ||
89 | static inline void mthca_write64(u32 val[2], void __iomem *dest, | 90 | static 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 | ||
100 | static inline void mthca_write_db_rec(u32 val[2], u32 *db) | 101 | static 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 | */ |
53 | struct mthca_eq_context { | 54 | struct 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 | ||
168 | static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci) | 169 | static 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 | ||
207 | static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn) | 208 | static 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) | |||
224 | static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn) | 225 | static 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 | ||
290 | err_close: | ||
291 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
292 | |||
293 | err_disable: | 277 | err_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 | ||
472 | err_unmap_srq: | ||
473 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | ||
474 | mthca_free_icm_table(mdev, mdev->srq_table.table); | ||
475 | |||
474 | err_unmap_cq: | 476 | err_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 | ||
594 | err_free_icm: | 582 | err_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 | ||
607 | static 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 | |||
617 | static int __devinit mthca_init_hca(struct mthca_dev *mdev) | 636 | static 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 | |||
668 | err_close: | ||
669 | mthca_close_hca(mdev); | ||
670 | return err; | ||
623 | } | 671 | } |
624 | 672 | ||
625 | static int __devinit mthca_setup_hca(struct mthca_dev *dev) | 673 | static 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: | |||
738 | err_qp_table_free: | 793 | err_qp_table_free: |
739 | mthca_cleanup_qp_table(dev); | 794 | mthca_cleanup_qp_table(dev); |
740 | 795 | ||
796 | err_srq_table_free: | ||
797 | mthca_cleanup_srq_table(dev); | ||
798 | |||
741 | err_cq_table_free: | 799 | err_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 | ||
847 | static 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 */ |
875 | enum { | 906 | enum { |
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 | ||
44 | struct mthca_mgm { | 44 | struct 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 | ||
51 | static const u8 zero_gid[16]; /* automatically initialized to 0 */ | 51 | static 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 | ||
484 | int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db) | 490 | int 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 | ||
569 | out: | 575 | out: |
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 | ||
138 | struct mthca_db_page { | 139 | struct 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 | ||
173 | int mthca_init_db_tab(struct mthca_dev *dev); | 174 | int mthca_init_db_tab(struct mthca_dev *dev); |
174 | void mthca_cleanup_db_tab(struct mthca_dev *dev); | 175 | void mthca_cleanup_db_tab(struct mthca_dev *dev); |
175 | int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db); | 176 | int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db); |
176 | void mthca_free_db(struct mthca_dev *dev, int type, int db_index); | 177 | void 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 | */ |
52 | struct mthca_mpt_entry { | 53 | struct 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, | |||
458 | static void mthca_free_region(struct mthca_dev *dev, u32 lkey) | 459 | static 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 @@ | |||
41 | struct mthca_profile { | 42 | struct 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 | ||
428 | static 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 | |||
476 | err_free: | ||
477 | kfree(srq); | ||
478 | |||
479 | return ERR_PTR(err); | ||
480 | } | ||
481 | |||
482 | static 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 | |||
423 | static struct ib_qp *mthca_create_qp(struct ib_pd *pd, | 499 | static 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 | ||
1035 | static 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 | |||
959 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); | 1041 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); |
960 | static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); | 1042 | static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); |
961 | static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); | 1043 | static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); |
1044 | static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); | ||
962 | 1045 | ||
963 | static struct class_device_attribute *mthca_class_attributes[] = { | 1046 | static 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 | ||
969 | int mthca_register_device(struct mthca_dev *dev) | 1053 | int 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 | ||
54 | union mthca_buf { | ||
55 | struct mthca_buf_list direct; | ||
56 | struct mthca_buf_list *page_list; | ||
57 | }; | ||
58 | |||
53 | struct mthca_uar { | 59 | struct 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 | ||
200 | struct 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 | |||
197 | struct mthca_wq { | 223 | struct 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 | ||
212 | struct mthca_qp { | 238 | struct 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 | ||
303 | static inline struct mthca_srq *to_msrq(struct ib_srq *ibsrq) | ||
304 | { | ||
305 | return container_of(ibsrq, struct mthca_srq, ibsrq); | ||
306 | } | ||
307 | |||
280 | static inline struct mthca_qp *to_mqp(struct ib_qp *ibqp) | 308 | static 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 | ||
46 | enum { | 49 | enum { |
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 | ||
97 | struct mthca_qp_path { | 100 | struct 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 | ||
110 | struct mthca_qp_context { | 113 | struct 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 | ||
149 | struct mthca_qp_param { | 152 | struct 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 | ||
156 | enum { | 159 | enum { |
@@ -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 | ||
176 | enum { | ||
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 | |||
187 | enum { | ||
188 | MTHCA_INVAL_LKEY = 0x100 | ||
189 | }; | ||
190 | |||
191 | struct 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 | |||
198 | struct 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 | |||
208 | struct mthca_arbel_ud_seg { | ||
209 | u32 av[8]; | ||
210 | u32 dqpn; | ||
211 | u32 qkey; | ||
212 | u32 reserved[2]; | ||
213 | }; | ||
214 | |||
215 | struct 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 | |||
224 | struct mthca_raddr_seg { | ||
225 | u64 raddr; | ||
226 | u32 rkey; | ||
227 | u32 reserved; | ||
228 | }; | ||
229 | |||
230 | struct mthca_atomic_seg { | ||
231 | u64 swap_add; | ||
232 | u64 compare; | ||
233 | }; | ||
234 | |||
235 | struct mthca_data_seg { | ||
236 | u32 byte_count; | ||
237 | u32 lkey; | ||
238 | u64 addr; | ||
239 | }; | ||
240 | |||
241 | struct 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 | |||
250 | static const u8 mthca_opcode[] = { | 179 | static 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(¶m, 0, sizeof param); | 503 | memset(¶m, 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, ¶m, port, &status); | 511 | err = mthca_INIT_IB(dev, ¶m, 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: | 922 | err_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 | ||
1072 | static void mthca_free_wqe_buf(struct mthca_dev *dev, | 927 | static 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 | ||
1743 | out: | 1585 | out: |
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 | ||
1844 | out: | 1686 | out: |
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 | ||
2065 | out: | 1907 | out: |
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 | ||
2176 | int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send, | 2018 | int 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 | |||
40 | enum { | ||
41 | MTHCA_MAX_DIRECT_SRQ_SIZE = 4 * PAGE_SIZE | ||
42 | }; | ||
43 | |||
44 | struct 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 | |||
53 | struct 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 | |||
67 | static 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 | */ | ||
84 | static inline int *wqe_to_link(void *wqe) | ||
85 | { | ||
86 | return (int *) (wqe + 4); | ||
87 | } | ||
88 | |||
89 | static 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 | |||
107 | static 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 | |||
129 | static 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 | |||
136 | static 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 | |||
178 | int 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 | |||
270 | err_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 | |||
277 | err_out_free_buf: | ||
278 | if (!pd->ibpd.uobject) | ||
279 | mthca_free_srq_buf(dev, srq); | ||
280 | |||
281 | err_out_mailbox: | ||
282 | mthca_free_mailbox(dev, mailbox); | ||
283 | |||
284 | err_out_db: | ||
285 | if (!pd->ibpd.uobject && mthca_is_memfree(dev)) | ||
286 | mthca_free_db(dev, MTHCA_DB_TYPE_SRQ, srq->db_index); | ||
287 | |||
288 | err_out_icm: | ||
289 | mthca_table_put(dev, dev->srq_table.table, srq->srqn); | ||
290 | |||
291 | err_out: | ||
292 | mthca_free(&dev->srq_table.alloc, srq->srqn); | ||
293 | |||
294 | return err; | ||
295 | } | ||
296 | |||
297 | void 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 | |||
334 | void 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 | |||
359 | out: | ||
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 | */ | ||
367 | void 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 | |||
386 | int 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 | |||
484 | int 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 | |||
560 | int __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 | |||
584 | void __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 | ||
72 | struct mthca_create_srq { | ||
73 | __u32 lkey; | ||
74 | __u32 db_index; | ||
75 | __u64 db_page; | ||
76 | }; | ||
77 | |||
78 | struct mthca_create_srq_resp { | ||
79 | __u32 srqn; | ||
80 | __u32 reserved; | ||
81 | }; | ||
82 | |||
72 | struct mthca_create_qp { | 83 | struct 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 | |||
40 | enum { | ||
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 | |||
51 | enum { | ||
52 | MTHCA_INVAL_LKEY = 0x100 | ||
53 | }; | ||
54 | |||
55 | struct 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 | |||
62 | struct 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 | |||
72 | struct mthca_arbel_ud_seg { | ||
73 | __be32 av[8]; | ||
74 | __be32 dqpn; | ||
75 | __be32 qkey; | ||
76 | u32 reserved[2]; | ||
77 | }; | ||
78 | |||
79 | struct 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 | |||
88 | struct mthca_raddr_seg { | ||
89 | __be64 raddr; | ||
90 | __be32 rkey; | ||
91 | u32 reserved; | ||
92 | }; | ||
93 | |||
94 | struct mthca_atomic_seg { | ||
95 | __be64 swap_add; | ||
96 | __be64 compare; | ||
97 | }; | ||
98 | |||
99 | struct mthca_data_seg { | ||
100 | __be32 byte_count; | ||
101 | __be32 lkey; | ||
102 | __be64 addr; | ||
103 | }; | ||
104 | |||
105 | struct 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 */ | ||