aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:43:13 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:43:13 -0400
commitce9d3c9a6a9aef61525be07fe6ba27d937236aa2 (patch)
tree1b29bcb8f60fc6b59fa0d7b833cc733b8ebe17c9 /drivers/net
parent038a5008b2f395c85e6e71d6ddf3c684e7c405b0 (diff)
parent3d73c2884f45f9a297cbc956cea101405a9703f2 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (87 commits) mlx4_core: Fix section mismatches IPoIB: Allow setting policy to ignore multicast groups IB/mthca: Mark error paths as unlikely() in post_srq_recv functions IB/ipath: Minor fix to ordering of freeing and zeroing of tid pages. IB/ipath: Remove redundant link state checks IB/ipath: Fix IB_EVENT_PORT_ERR event IB/ipath: Better handling of unexpected GPIO interrupts IB/ipath: Maintain active time on all chips IB/ipath: Fix QHT7040 serial number check IB/ipath: Indicate a couple of chip bugs to userspace IB/ipath: iba6110 rev4 no longer needs recv header overrun workaround IB/ipath: Use counters in ipath_poll and cleanup interrupts in ipath_close IB/ipath: Remove duplicate copy of LMC IB/ipath: Add ability to set the LMC via the sysfs debugging interface IB/ipath: Optimize completion queue entry insertion and polling IB/ipath: Implement IB_EVENT_QP_LAST_WQE_REACHED IB/ipath: Generate flush CQE when QP is in error state IB/ipath: Remove redundant code IB/ipath: Future proof eeprom checksum code (contents reading) IB/ipath: UC RDMA WRITE with IMMEDIATE doesn't send the immediate ...
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/mlx4/cmd.c11
-rw-r--r--drivers/net/mlx4/cq.c2
-rw-r--r--drivers/net/mlx4/eq.c13
-rw-r--r--drivers/net/mlx4/fw.c2
-rw-r--r--drivers/net/mlx4/icm.c134
-rw-r--r--drivers/net/mlx4/icm.h9
-rw-r--r--drivers/net/mlx4/main.c130
-rw-r--r--drivers/net/mlx4/mcg.c2
-rw-r--r--drivers/net/mlx4/mlx4.h10
-rw-r--r--drivers/net/mlx4/mr.c242
-rw-r--r--drivers/net/mlx4/pd.c2
-rw-r--r--drivers/net/mlx4/qp.c5
-rw-r--r--drivers/net/mlx4/srq.c4
13 files changed, 415 insertions, 151 deletions
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index a9f31753661..db49051b97b 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -95,7 +95,7 @@ enum {
95}; 95};
96 96
97enum { 97enum {
98 GO_BIT_TIMEOUT = 10000 98 GO_BIT_TIMEOUT_MSECS = 10000
99}; 99};
100 100
101struct mlx4_cmd_context { 101struct mlx4_cmd_context {
@@ -155,7 +155,7 @@ static int mlx4_cmd_post(struct mlx4_dev *dev, u64 in_param, u64 out_param,
155 155
156 end = jiffies; 156 end = jiffies;
157 if (event) 157 if (event)
158 end += HZ * 10; 158 end += msecs_to_jiffies(GO_BIT_TIMEOUT_MSECS);
159 159
160 while (cmd_pending(dev)) { 160 while (cmd_pending(dev)) {
161 if (time_after_eq(jiffies, end)) 161 if (time_after_eq(jiffies, end))
@@ -184,6 +184,13 @@ static int mlx4_cmd_post(struct mlx4_dev *dev, u64 in_param, u64 out_param,
184 (event ? (1 << HCR_E_BIT) : 0) | 184 (event ? (1 << HCR_E_BIT) : 0) |
185 (op_modifier << HCR_OPMOD_SHIFT) | 185 (op_modifier << HCR_OPMOD_SHIFT) |
186 op), hcr + 6); 186 op), hcr + 6);
187
188 /*
189 * Make sure that our HCR writes don't get mixed in with
190 * writes from another CPU starting a FW command.
191 */
192 mmiowb();
193
187 cmd->toggle = cmd->toggle ^ 1; 194 cmd->toggle = cmd->toggle ^ 1;
188 195
189 ret = 0; 196 ret = 0;
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index 39253d0c159..d4441fee3d8 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -231,7 +231,7 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
231} 231}
232EXPORT_SYMBOL_GPL(mlx4_cq_free); 232EXPORT_SYMBOL_GPL(mlx4_cq_free);
233 233
234int __devinit mlx4_init_cq_table(struct mlx4_dev *dev) 234int mlx4_init_cq_table(struct mlx4_dev *dev)
235{ 235{
236 struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table; 236 struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
237 int err; 237 int err;
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 2095c843fa1..9c36c203403 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -300,8 +300,7 @@ static int mlx4_HW2SW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
300 MLX4_CMD_TIME_CLASS_A); 300 MLX4_CMD_TIME_CLASS_A);
301} 301}
302 302
303static void __devinit __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, 303static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq)
304 struct mlx4_eq *eq)
305{ 304{
306 struct mlx4_priv *priv = mlx4_priv(dev); 305 struct mlx4_priv *priv = mlx4_priv(dev);
307 int index; 306 int index;
@@ -323,8 +322,8 @@ static void __devinit __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev,
323 return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4); 322 return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4);
324} 323}
325 324
326static int __devinit mlx4_create_eq(struct mlx4_dev *dev, int nent, 325static int mlx4_create_eq(struct mlx4_dev *dev, int nent,
327 u8 intr, struct mlx4_eq *eq) 326 u8 intr, struct mlx4_eq *eq)
328{ 327{
329 struct mlx4_priv *priv = mlx4_priv(dev); 328 struct mlx4_priv *priv = mlx4_priv(dev);
330 struct mlx4_cmd_mailbox *mailbox; 329 struct mlx4_cmd_mailbox *mailbox;
@@ -485,7 +484,7 @@ static void mlx4_free_irqs(struct mlx4_dev *dev)
485 free_irq(eq_table->eq[i].irq, eq_table->eq + i); 484 free_irq(eq_table->eq[i].irq, eq_table->eq + i);
486} 485}
487 486
488static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev) 487static int mlx4_map_clr_int(struct mlx4_dev *dev)
489{ 488{
490 struct mlx4_priv *priv = mlx4_priv(dev); 489 struct mlx4_priv *priv = mlx4_priv(dev);
491 490
@@ -506,7 +505,7 @@ static void mlx4_unmap_clr_int(struct mlx4_dev *dev)
506 iounmap(priv->clr_base); 505 iounmap(priv->clr_base);
507} 506}
508 507
509int __devinit mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt) 508int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt)
510{ 509{
511 struct mlx4_priv *priv = mlx4_priv(dev); 510 struct mlx4_priv *priv = mlx4_priv(dev);
512 int ret; 511 int ret;
@@ -548,7 +547,7 @@ void mlx4_unmap_eq_icm(struct mlx4_dev *dev)
548 __free_page(priv->eq_table.icm_page); 547 __free_page(priv->eq_table.icm_page);
549} 548}
550 549
551int __devinit mlx4_init_eq_table(struct mlx4_dev *dev) 550int mlx4_init_eq_table(struct mlx4_dev *dev)
552{ 551{
553 struct mlx4_priv *priv = mlx4_priv(dev); 552 struct mlx4_priv *priv = mlx4_priv(dev);
554 int err; 553 int err;
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index c45cbe43a0c..6471d33afb7 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -76,7 +76,7 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags)
76 [ 0] = "RC transport", 76 [ 0] = "RC transport",
77 [ 1] = "UC transport", 77 [ 1] = "UC transport",
78 [ 2] = "UD transport", 78 [ 2] = "UD transport",
79 [ 3] = "SRC transport", 79 [ 3] = "XRC transport",
80 [ 4] = "reliable multicast", 80 [ 4] = "reliable multicast",
81 [ 5] = "FCoIB support", 81 [ 5] = "FCoIB support",
82 [ 6] = "SRQ support", 82 [ 6] = "SRQ support",
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index b7a4aa8476f..4b3c109d5ea 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -34,6 +34,7 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/errno.h> 35#include <linux/errno.h>
36#include <linux/mm.h> 36#include <linux/mm.h>
37#include <linux/scatterlist.h>
37 38
38#include <linux/mlx4/cmd.h> 39#include <linux/mlx4/cmd.h>
39 40
@@ -50,19 +51,41 @@ enum {
50 MLX4_TABLE_CHUNK_SIZE = 1 << 18 51 MLX4_TABLE_CHUNK_SIZE = 1 << 18
51}; 52};
52 53
53void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm) 54static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chunk)
54{ 55{
55 struct mlx4_icm_chunk *chunk, *tmp;
56 int i; 56 int i;
57 57
58 list_for_each_entry_safe(chunk, tmp, &icm->chunk_list, list) { 58 if (chunk->nsg > 0)
59 if (chunk->nsg > 0) 59 pci_unmap_sg(dev->pdev, chunk->mem, chunk->npages,
60 pci_unmap_sg(dev->pdev, chunk->mem, chunk->npages, 60 PCI_DMA_BIDIRECTIONAL);
61 PCI_DMA_BIDIRECTIONAL); 61
62 for (i = 0; i < chunk->npages; ++i)
63 __free_pages(chunk->mem[i].page,
64 get_order(chunk->mem[i].length));
65}
66
67static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *chunk)
68{
69 int i;
70
71 for (i = 0; i < chunk->npages; ++i)
72 dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
73 lowmem_page_address(chunk->mem[i].page),
74 sg_dma_address(&chunk->mem[i]));
75}
76
77void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
78{
79 struct mlx4_icm_chunk *chunk, *tmp;
62 80
63 for (i = 0; i < chunk->npages; ++i) 81 if (!icm)
64 __free_pages(chunk->mem[i].page, 82 return;
65 get_order(chunk->mem[i].length)); 83
84 list_for_each_entry_safe(chunk, tmp, &icm->chunk_list, list) {
85 if (coherent)
86 mlx4_free_icm_coherent(dev, chunk);
87 else
88 mlx4_free_icm_pages(dev, chunk);
66 89
67 kfree(chunk); 90 kfree(chunk);
68 } 91 }
@@ -70,16 +93,45 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm)
70 kfree(icm); 93 kfree(icm);
71} 94}
72 95
96static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
97{
98 mem->page = alloc_pages(gfp_mask, order);
99 if (!mem->page)
100 return -ENOMEM;
101
102 mem->length = PAGE_SIZE << order;
103 mem->offset = 0;
104 return 0;
105}
106
107static int mlx4_alloc_icm_coherent(struct device *dev, struct scatterlist *mem,
108 int order, gfp_t gfp_mask)
109{
110 void *buf = dma_alloc_coherent(dev, PAGE_SIZE << order,
111 &sg_dma_address(mem), gfp_mask);
112 if (!buf)
113 return -ENOMEM;
114
115 sg_set_buf(mem, buf, PAGE_SIZE << order);
116 BUG_ON(mem->offset);
117 sg_dma_len(mem) = PAGE_SIZE << order;
118 return 0;
119}
120
73struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, 121struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
74 gfp_t gfp_mask) 122 gfp_t gfp_mask, int coherent)
75{ 123{
76 struct mlx4_icm *icm; 124 struct mlx4_icm *icm;
77 struct mlx4_icm_chunk *chunk = NULL; 125 struct mlx4_icm_chunk *chunk = NULL;
78 int cur_order; 126 int cur_order;
127 int ret;
128
129 /* We use sg_set_buf for coherent allocs, which assumes low memory */
130 BUG_ON(coherent && (gfp_mask & __GFP_HIGHMEM));
79 131
80 icm = kmalloc(sizeof *icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); 132 icm = kmalloc(sizeof *icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
81 if (!icm) 133 if (!icm)
82 return icm; 134 return NULL;
83 135
84 icm->refcount = 0; 136 icm->refcount = 0;
85 INIT_LIST_HEAD(&icm->chunk_list); 137 INIT_LIST_HEAD(&icm->chunk_list);
@@ -101,12 +153,20 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
101 while (1 << cur_order > npages) 153 while (1 << cur_order > npages)
102 --cur_order; 154 --cur_order;
103 155
104 chunk->mem[chunk->npages].page = alloc_pages(gfp_mask, cur_order); 156 if (coherent)
105 if (chunk->mem[chunk->npages].page) { 157 ret = mlx4_alloc_icm_coherent(&dev->pdev->dev,
106 chunk->mem[chunk->npages].length = PAGE_SIZE << cur_order; 158 &chunk->mem[chunk->npages],
107 chunk->mem[chunk->npages].offset = 0; 159 cur_order, gfp_mask);
160 else
161 ret = mlx4_alloc_icm_pages(&chunk->mem[chunk->npages],
162 cur_order, gfp_mask);
163
164 if (!ret) {
165 ++chunk->npages;
108 166
109 if (++chunk->npages == MLX4_ICM_CHUNK_LEN) { 167 if (coherent)
168 ++chunk->nsg;
169 else if (chunk->npages == MLX4_ICM_CHUNK_LEN) {
110 chunk->nsg = pci_map_sg(dev->pdev, chunk->mem, 170 chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
111 chunk->npages, 171 chunk->npages,
112 PCI_DMA_BIDIRECTIONAL); 172 PCI_DMA_BIDIRECTIONAL);
@@ -125,7 +185,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
125 } 185 }
126 } 186 }
127 187
128 if (chunk) { 188 if (!coherent && chunk) {
129 chunk->nsg = pci_map_sg(dev->pdev, chunk->mem, 189 chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
130 chunk->npages, 190 chunk->npages,
131 PCI_DMA_BIDIRECTIONAL); 191 PCI_DMA_BIDIRECTIONAL);
@@ -137,7 +197,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
137 return icm; 197 return icm;
138 198
139fail: 199fail:
140 mlx4_free_icm(dev, icm); 200 mlx4_free_icm(dev, icm, coherent);
141 return NULL; 201 return NULL;
142} 202}
143 203
@@ -202,7 +262,7 @@ int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
202 262
203 table->icm[i] = mlx4_alloc_icm(dev, MLX4_TABLE_CHUNK_SIZE >> PAGE_SHIFT, 263 table->icm[i] = mlx4_alloc_icm(dev, MLX4_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
204 (table->lowmem ? GFP_KERNEL : GFP_HIGHUSER) | 264 (table->lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
205 __GFP_NOWARN); 265 __GFP_NOWARN, table->coherent);
206 if (!table->icm[i]) { 266 if (!table->icm[i]) {
207 ret = -ENOMEM; 267 ret = -ENOMEM;
208 goto out; 268 goto out;
@@ -210,7 +270,7 @@ int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
210 270
211 if (mlx4_MAP_ICM(dev, table->icm[i], table->virt + 271 if (mlx4_MAP_ICM(dev, table->icm[i], table->virt +
212 (u64) i * MLX4_TABLE_CHUNK_SIZE)) { 272 (u64) i * MLX4_TABLE_CHUNK_SIZE)) {
213 mlx4_free_icm(dev, table->icm[i]); 273 mlx4_free_icm(dev, table->icm[i], table->coherent);
214 table->icm[i] = NULL; 274 table->icm[i] = NULL;
215 ret = -ENOMEM; 275 ret = -ENOMEM;
216 goto out; 276 goto out;
@@ -234,16 +294,16 @@ void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
234 if (--table->icm[i]->refcount == 0) { 294 if (--table->icm[i]->refcount == 0) {
235 mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE, 295 mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE,
236 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE); 296 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE);
237 mlx4_free_icm(dev, table->icm[i]); 297 mlx4_free_icm(dev, table->icm[i], table->coherent);
238 table->icm[i] = NULL; 298 table->icm[i] = NULL;
239 } 299 }
240 300
241 mutex_unlock(&table->mutex); 301 mutex_unlock(&table->mutex);
242} 302}
243 303
244void *mlx4_table_find(struct mlx4_icm_table *table, int obj) 304void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle)
245{ 305{
246 int idx, offset, i; 306 int idx, offset, dma_offset, i;
247 struct mlx4_icm_chunk *chunk; 307 struct mlx4_icm_chunk *chunk;
248 struct mlx4_icm *icm; 308 struct mlx4_icm *icm;
249 struct page *page = NULL; 309 struct page *page = NULL;
@@ -253,15 +313,26 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj)
253 313
254 mutex_lock(&table->mutex); 314 mutex_lock(&table->mutex);
255 315
256 idx = obj & (table->num_obj - 1); 316 idx = (obj & (table->num_obj - 1)) * table->obj_size;
257 icm = table->icm[idx / (MLX4_TABLE_CHUNK_SIZE / table->obj_size)]; 317 icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE];
258 offset = idx % (MLX4_TABLE_CHUNK_SIZE / table->obj_size); 318 dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE;
259 319
260 if (!icm) 320 if (!icm)
261 goto out; 321 goto out;
262 322
263 list_for_each_entry(chunk, &icm->chunk_list, list) { 323 list_for_each_entry(chunk, &icm->chunk_list, list) {
264 for (i = 0; i < chunk->npages; ++i) { 324 for (i = 0; i < chunk->npages; ++i) {
325 if (dma_handle && dma_offset >= 0) {
326 if (sg_dma_len(&chunk->mem[i]) > dma_offset)
327 *dma_handle = sg_dma_address(&chunk->mem[i]) +
328 dma_offset;
329 dma_offset -= sg_dma_len(&chunk->mem[i]);
330 }
331 /*
332 * DMA mapping can merge pages but not split them,
333 * so if we found the page, dma_handle has already
334 * been assigned to.
335 */
265 if (chunk->mem[i].length > offset) { 336 if (chunk->mem[i].length > offset) {
266 page = chunk->mem[i].page; 337 page = chunk->mem[i].page;
267 goto out; 338 goto out;
@@ -309,7 +380,7 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
309 380
310int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, 381int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
311 u64 virt, int obj_size, int nobj, int reserved, 382 u64 virt, int obj_size, int nobj, int reserved,
312 int use_lowmem) 383 int use_lowmem, int use_coherent)
313{ 384{
314 int obj_per_chunk; 385 int obj_per_chunk;
315 int num_icm; 386 int num_icm;
@@ -327,6 +398,7 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
327 table->num_obj = nobj; 398 table->num_obj = nobj;
328 table->obj_size = obj_size; 399 table->obj_size = obj_size;
329 table->lowmem = use_lowmem; 400 table->lowmem = use_lowmem;
401 table->coherent = use_coherent;
330 mutex_init(&table->mutex); 402 mutex_init(&table->mutex);
331 403
332 for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { 404 for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
@@ -336,11 +408,11 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
336 408
337 table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, 409 table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT,
338 (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | 410 (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
339 __GFP_NOWARN); 411 __GFP_NOWARN, use_coherent);
340 if (!table->icm[i]) 412 if (!table->icm[i])
341 goto err; 413 goto err;
342 if (mlx4_MAP_ICM(dev, table->icm[i], virt + i * MLX4_TABLE_CHUNK_SIZE)) { 414 if (mlx4_MAP_ICM(dev, table->icm[i], virt + i * MLX4_TABLE_CHUNK_SIZE)) {
343 mlx4_free_icm(dev, table->icm[i]); 415 mlx4_free_icm(dev, table->icm[i], use_coherent);
344 table->icm[i] = NULL; 416 table->icm[i] = NULL;
345 goto err; 417 goto err;
346 } 418 }
@@ -359,7 +431,7 @@ err:
359 if (table->icm[i]) { 431 if (table->icm[i]) {
360 mlx4_UNMAP_ICM(dev, virt + i * MLX4_TABLE_CHUNK_SIZE, 432 mlx4_UNMAP_ICM(dev, virt + i * MLX4_TABLE_CHUNK_SIZE,
361 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE); 433 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE);
362 mlx4_free_icm(dev, table->icm[i]); 434 mlx4_free_icm(dev, table->icm[i], use_coherent);
363 } 435 }
364 436
365 return -ENOMEM; 437 return -ENOMEM;
@@ -373,7 +445,7 @@ void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table)
373 if (table->icm[i]) { 445 if (table->icm[i]) {
374 mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE, 446 mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE,
375 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE); 447 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE);
376 mlx4_free_icm(dev, table->icm[i]); 448 mlx4_free_icm(dev, table->icm[i], table->coherent);
377 } 449 }
378 450
379 kfree(table->icm); 451 kfree(table->icm);
diff --git a/drivers/net/mlx4/icm.h b/drivers/net/mlx4/icm.h
index bea223d879a..6c44edf3584 100644
--- a/drivers/net/mlx4/icm.h
+++ b/drivers/net/mlx4/icm.h
@@ -67,8 +67,9 @@ struct mlx4_icm_iter {
67 67
68struct mlx4_dev; 68struct mlx4_dev;
69 69
70struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, gfp_t gfp_mask); 70struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
71void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm); 71 gfp_t gfp_mask, int coherent);
72void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent);
72 73
73int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); 74int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
74void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); 75void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
@@ -78,11 +79,11 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
78 int start, int end); 79 int start, int end);
79int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, 80int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
80 u64 virt, int obj_size, int nobj, int reserved, 81 u64 virt, int obj_size, int nobj, int reserved,
81 int use_lowmem); 82 int use_lowmem, int use_coherent);
82void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); 83void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table);
83int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); 84int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
84void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); 85void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
85void *mlx4_table_find(struct mlx4_icm_table *table, int obj); 86void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle);
86int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, 87int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
87 int start, int end); 88 int start, int end);
88void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, 89void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 4dc9dc19b71..e029b8afbd3 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -61,7 +61,7 @@ MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
61 61
62#ifdef CONFIG_PCI_MSI 62#ifdef CONFIG_PCI_MSI
63 63
64static int msi_x; 64static int msi_x = 1;
65module_param(msi_x, int, 0444); 65module_param(msi_x, int, 0444);
66MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero"); 66MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero");
67 67
@@ -85,7 +85,7 @@ static struct mlx4_profile default_profile = {
85 .num_mtt = 1 << 20, 85 .num_mtt = 1 << 20,
86}; 86};
87 87
88static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 88static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
89{ 89{
90 int err; 90 int err;
91 int i; 91 int i;
@@ -149,7 +149,8 @@ static int __devinit mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev
149 dev->caps.max_cqes = dev_cap->max_cq_sz - 1; 149 dev->caps.max_cqes = dev_cap->max_cq_sz - 1;
150 dev->caps.reserved_cqs = dev_cap->reserved_cqs; 150 dev->caps.reserved_cqs = dev_cap->reserved_cqs;
151 dev->caps.reserved_eqs = dev_cap->reserved_eqs; 151 dev->caps.reserved_eqs = dev_cap->reserved_eqs;
152 dev->caps.reserved_mtts = dev_cap->reserved_mtts; 152 dev->caps.reserved_mtts = DIV_ROUND_UP(dev_cap->reserved_mtts,
153 MLX4_MTT_ENTRY_PER_SEG);
153 dev->caps.reserved_mrws = dev_cap->reserved_mrws; 154 dev->caps.reserved_mrws = dev_cap->reserved_mrws;
154 dev->caps.reserved_uars = dev_cap->reserved_uars; 155 dev->caps.reserved_uars = dev_cap->reserved_uars;
155 dev->caps.reserved_pds = dev_cap->reserved_pds; 156 dev->caps.reserved_pds = dev_cap->reserved_pds;
@@ -168,7 +169,7 @@ static int __devinit mlx4_load_fw(struct mlx4_dev *dev)
168 int err; 169 int err;
169 170
170 priv->fw.fw_icm = mlx4_alloc_icm(dev, priv->fw.fw_pages, 171 priv->fw.fw_icm = mlx4_alloc_icm(dev, priv->fw.fw_pages,
171 GFP_HIGHUSER | __GFP_NOWARN); 172 GFP_HIGHUSER | __GFP_NOWARN, 0);
172 if (!priv->fw.fw_icm) { 173 if (!priv->fw.fw_icm) {
173 mlx4_err(dev, "Couldn't allocate FW area, aborting.\n"); 174 mlx4_err(dev, "Couldn't allocate FW area, aborting.\n");
174 return -ENOMEM; 175 return -ENOMEM;
@@ -192,7 +193,7 @@ err_unmap_fa:
192 mlx4_UNMAP_FA(dev); 193 mlx4_UNMAP_FA(dev);
193 194
194err_free: 195err_free:
195 mlx4_free_icm(dev, priv->fw.fw_icm); 196 mlx4_free_icm(dev, priv->fw.fw_icm, 0);
196 return err; 197 return err;
197} 198}
198 199
@@ -207,7 +208,7 @@ static int __devinit mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
207 ((u64) (MLX4_CMPT_TYPE_QP * 208 ((u64) (MLX4_CMPT_TYPE_QP *
208 cmpt_entry_sz) << MLX4_CMPT_SHIFT), 209 cmpt_entry_sz) << MLX4_CMPT_SHIFT),
209 cmpt_entry_sz, dev->caps.num_qps, 210 cmpt_entry_sz, dev->caps.num_qps,
210 dev->caps.reserved_qps, 0); 211 dev->caps.reserved_qps, 0, 0);
211 if (err) 212 if (err)
212 goto err; 213 goto err;
213 214
@@ -216,7 +217,7 @@ static int __devinit mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
216 ((u64) (MLX4_CMPT_TYPE_SRQ * 217 ((u64) (MLX4_CMPT_TYPE_SRQ *
217 cmpt_entry_sz) << MLX4_CMPT_SHIFT), 218 cmpt_entry_sz) << MLX4_CMPT_SHIFT),
218 cmpt_entry_sz, dev->caps.num_srqs, 219 cmpt_entry_sz, dev->caps.num_srqs,
219 dev->caps.reserved_srqs, 0); 220 dev->caps.reserved_srqs, 0, 0);
220 if (err) 221 if (err)
221 goto err_qp; 222 goto err_qp;
222 223
@@ -225,7 +226,7 @@ static int __devinit mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
225 ((u64) (MLX4_CMPT_TYPE_CQ * 226 ((u64) (MLX4_CMPT_TYPE_CQ *
226 cmpt_entry_sz) << MLX4_CMPT_SHIFT), 227 cmpt_entry_sz) << MLX4_CMPT_SHIFT),
227 cmpt_entry_sz, dev->caps.num_cqs, 228 cmpt_entry_sz, dev->caps.num_cqs,
228 dev->caps.reserved_cqs, 0); 229 dev->caps.reserved_cqs, 0, 0);
229 if (err) 230 if (err)
230 goto err_srq; 231 goto err_srq;
231 232
@@ -236,7 +237,7 @@ static int __devinit mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base,
236 cmpt_entry_sz, 237 cmpt_entry_sz,
237 roundup_pow_of_two(MLX4_NUM_EQ + 238 roundup_pow_of_two(MLX4_NUM_EQ +
238 dev->caps.reserved_eqs), 239 dev->caps.reserved_eqs),
239 MLX4_NUM_EQ + dev->caps.reserved_eqs, 0); 240 MLX4_NUM_EQ + dev->caps.reserved_eqs, 0, 0);
240 if (err) 241 if (err)
241 goto err_cq; 242 goto err_cq;
242 243
@@ -255,10 +256,8 @@ err:
255 return err; 256 return err;
256} 257}
257 258
258static int __devinit mlx4_init_icm(struct mlx4_dev *dev, 259static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
259 struct mlx4_dev_cap *dev_cap, 260 struct mlx4_init_hca_param *init_hca, u64 icm_size)
260 struct mlx4_init_hca_param *init_hca,
261 u64 icm_size)
262{ 261{
263 struct mlx4_priv *priv = mlx4_priv(dev); 262 struct mlx4_priv *priv = mlx4_priv(dev);
264 u64 aux_pages; 263 u64 aux_pages;
@@ -275,7 +274,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
275 (unsigned long long) aux_pages << 2); 274 (unsigned long long) aux_pages << 2);
276 275
277 priv->fw.aux_icm = mlx4_alloc_icm(dev, aux_pages, 276 priv->fw.aux_icm = mlx4_alloc_icm(dev, aux_pages,
278 GFP_HIGHUSER | __GFP_NOWARN); 277 GFP_HIGHUSER | __GFP_NOWARN, 0);
279 if (!priv->fw.aux_icm) { 278 if (!priv->fw.aux_icm) {
280 mlx4_err(dev, "Couldn't allocate aux memory, aborting.\n"); 279 mlx4_err(dev, "Couldn't allocate aux memory, aborting.\n");
281 return -ENOMEM; 280 return -ENOMEM;
@@ -299,11 +298,22 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
299 goto err_unmap_cmpt; 298 goto err_unmap_cmpt;
300 } 299 }
301 300
301 /*
302 * Reserved MTT entries must be aligned up to a cacheline
303 * boundary, since the FW will write to them, while the driver
304 * writes to all other MTT entries. (The variable
305 * dev->caps.mtt_entry_sz below is really the MTT segment
306 * size, not the raw entry size)
307 */
308 dev->caps.reserved_mtts =
309 ALIGN(dev->caps.reserved_mtts * dev->caps.mtt_entry_sz,
310 dma_get_cache_alignment()) / dev->caps.mtt_entry_sz;
311
302 err = mlx4_init_icm_table(dev, &priv->mr_table.mtt_table, 312 err = mlx4_init_icm_table(dev, &priv->mr_table.mtt_table,
303 init_hca->mtt_base, 313 init_hca->mtt_base,
304 dev->caps.mtt_entry_sz, 314 dev->caps.mtt_entry_sz,
305 dev->caps.num_mtt_segs, 315 dev->caps.num_mtt_segs,
306 dev->caps.reserved_mtts, 1); 316 dev->caps.reserved_mtts, 1, 0);
307 if (err) { 317 if (err) {
308 mlx4_err(dev, "Failed to map MTT context memory, aborting.\n"); 318 mlx4_err(dev, "Failed to map MTT context memory, aborting.\n");
309 goto err_unmap_eq; 319 goto err_unmap_eq;
@@ -313,7 +323,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
313 init_hca->dmpt_base, 323 init_hca->dmpt_base,
314 dev_cap->dmpt_entry_sz, 324 dev_cap->dmpt_entry_sz,
315 dev->caps.num_mpts, 325 dev->caps.num_mpts,
316 dev->caps.reserved_mrws, 1); 326 dev->caps.reserved_mrws, 1, 1);
317 if (err) { 327 if (err) {
318 mlx4_err(dev, "Failed to map dMPT context memory, aborting.\n"); 328 mlx4_err(dev, "Failed to map dMPT context memory, aborting.\n");
319 goto err_unmap_mtt; 329 goto err_unmap_mtt;
@@ -323,7 +333,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
323 init_hca->qpc_base, 333 init_hca->qpc_base,
324 dev_cap->qpc_entry_sz, 334 dev_cap->qpc_entry_sz,
325 dev->caps.num_qps, 335 dev->caps.num_qps,
326 dev->caps.reserved_qps, 0); 336 dev->caps.reserved_qps, 0, 0);
327 if (err) { 337 if (err) {
328 mlx4_err(dev, "Failed to map QP context memory, aborting.\n"); 338 mlx4_err(dev, "Failed to map QP context memory, aborting.\n");
329 goto err_unmap_dmpt; 339 goto err_unmap_dmpt;
@@ -333,7 +343,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
333 init_hca->auxc_base, 343 init_hca->auxc_base,
334 dev_cap->aux_entry_sz, 344 dev_cap->aux_entry_sz,
335 dev->caps.num_qps, 345 dev->caps.num_qps,
336 dev->caps.reserved_qps, 0); 346 dev->caps.reserved_qps, 0, 0);
337 if (err) { 347 if (err) {
338 mlx4_err(dev, "Failed to map AUXC context memory, aborting.\n"); 348 mlx4_err(dev, "Failed to map AUXC context memory, aborting.\n");
339 goto err_unmap_qp; 349 goto err_unmap_qp;
@@ -343,7 +353,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
343 init_hca->altc_base, 353 init_hca->altc_base,
344 dev_cap->altc_entry_sz, 354 dev_cap->altc_entry_sz,
345 dev->caps.num_qps, 355 dev->caps.num_qps,
346 dev->caps.reserved_qps, 0); 356 dev->caps.reserved_qps, 0, 0);
347 if (err) { 357 if (err) {
348 mlx4_err(dev, "Failed to map ALTC context memory, aborting.\n"); 358 mlx4_err(dev, "Failed to map ALTC context memory, aborting.\n");
349 goto err_unmap_auxc; 359 goto err_unmap_auxc;
@@ -353,7 +363,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
353 init_hca->rdmarc_base, 363 init_hca->rdmarc_base,
354 dev_cap->rdmarc_entry_sz << priv->qp_table.rdmarc_shift, 364 dev_cap->rdmarc_entry_sz << priv->qp_table.rdmarc_shift,
355 dev->caps.num_qps, 365 dev->caps.num_qps,
356 dev->caps.reserved_qps, 0); 366 dev->caps.reserved_qps, 0, 0);
357 if (err) { 367 if (err) {
358 mlx4_err(dev, "Failed to map RDMARC context memory, aborting\n"); 368 mlx4_err(dev, "Failed to map RDMARC context memory, aborting\n");
359 goto err_unmap_altc; 369 goto err_unmap_altc;
@@ -363,7 +373,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
363 init_hca->cqc_base, 373 init_hca->cqc_base,
364 dev_cap->cqc_entry_sz, 374 dev_cap->cqc_entry_sz,
365 dev->caps.num_cqs, 375 dev->caps.num_cqs,
366 dev->caps.reserved_cqs, 0); 376 dev->caps.reserved_cqs, 0, 0);
367 if (err) { 377 if (err) {
368 mlx4_err(dev, "Failed to map CQ context memory, aborting.\n"); 378 mlx4_err(dev, "Failed to map CQ context memory, aborting.\n");
369 goto err_unmap_rdmarc; 379 goto err_unmap_rdmarc;
@@ -373,7 +383,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
373 init_hca->srqc_base, 383 init_hca->srqc_base,
374 dev_cap->srq_entry_sz, 384 dev_cap->srq_entry_sz,
375 dev->caps.num_srqs, 385 dev->caps.num_srqs,
376 dev->caps.reserved_srqs, 0); 386 dev->caps.reserved_srqs, 0, 0);
377 if (err) { 387 if (err) {
378 mlx4_err(dev, "Failed to map SRQ context memory, aborting.\n"); 388 mlx4_err(dev, "Failed to map SRQ context memory, aborting.\n");
379 goto err_unmap_cq; 389 goto err_unmap_cq;
@@ -388,7 +398,7 @@ static int __devinit mlx4_init_icm(struct mlx4_dev *dev,
388 init_hca->mc_base, MLX4_MGM_ENTRY_SIZE, 398 init_hca->mc_base, MLX4_MGM_ENTRY_SIZE,
389 dev->caps.num_mgms + dev->caps.num_amgms, 399 dev->caps.num_mgms + dev->caps.num_amgms,
390 dev->caps.num_mgms + dev->caps.num_amgms, 400 dev->caps.num_mgms + dev->caps.num_amgms,
391 0); 401 0, 0);
392 if (err) { 402 if (err) {
393 mlx4_err(dev, "Failed to map MCG context memory, aborting.\n"); 403 mlx4_err(dev, "Failed to map MCG context memory, aborting.\n");
394 goto err_unmap_srq; 404 goto err_unmap_srq;
@@ -433,7 +443,7 @@ err_unmap_aux:
433 mlx4_UNMAP_ICM_AUX(dev); 443 mlx4_UNMAP_ICM_AUX(dev);
434 444
435err_free_aux: 445err_free_aux:
436 mlx4_free_icm(dev, priv->fw.aux_icm); 446 mlx4_free_icm(dev, priv->fw.aux_icm, 0);
437 447
438 return err; 448 return err;
439} 449}
@@ -458,7 +468,7 @@ static void mlx4_free_icms(struct mlx4_dev *dev)
458 mlx4_unmap_eq_icm(dev); 468 mlx4_unmap_eq_icm(dev);
459 469
460 mlx4_UNMAP_ICM_AUX(dev); 470 mlx4_UNMAP_ICM_AUX(dev);
461 mlx4_free_icm(dev, priv->fw.aux_icm); 471 mlx4_free_icm(dev, priv->fw.aux_icm, 0);
462} 472}
463 473
464static void mlx4_close_hca(struct mlx4_dev *dev) 474static void mlx4_close_hca(struct mlx4_dev *dev)
@@ -466,10 +476,10 @@ static void mlx4_close_hca(struct mlx4_dev *dev)
466 mlx4_CLOSE_HCA(dev, 0); 476 mlx4_CLOSE_HCA(dev, 0);
467 mlx4_free_icms(dev); 477 mlx4_free_icms(dev);
468 mlx4_UNMAP_FA(dev); 478 mlx4_UNMAP_FA(dev);
469 mlx4_free_icm(dev, mlx4_priv(dev)->fw.fw_icm); 479 mlx4_free_icm(dev, mlx4_priv(dev)->fw.fw_icm, 0);
470} 480}
471 481
472static int __devinit mlx4_init_hca(struct mlx4_dev *dev) 482static int mlx4_init_hca(struct mlx4_dev *dev)
473{ 483{
474 struct mlx4_priv *priv = mlx4_priv(dev); 484 struct mlx4_priv *priv = mlx4_priv(dev);
475 struct mlx4_adapter adapter; 485 struct mlx4_adapter adapter;
@@ -524,8 +534,8 @@ static int __devinit mlx4_init_hca(struct mlx4_dev *dev)
524 } 534 }
525 535
526 priv->eq_table.inta_pin = adapter.inta_pin; 536 priv->eq_table.inta_pin = adapter.inta_pin;
527 priv->rev_id = adapter.revision_id; 537 dev->rev_id = adapter.revision_id;
528 memcpy(priv->board_id, adapter.board_id, sizeof priv->board_id); 538 memcpy(dev->board_id, adapter.board_id, sizeof dev->board_id);
529 539
530 return 0; 540 return 0;
531 541
@@ -537,12 +547,12 @@ err_free_icm:
537 547
538err_stop_fw: 548err_stop_fw:
539 mlx4_UNMAP_FA(dev); 549 mlx4_UNMAP_FA(dev);
540 mlx4_free_icm(dev, priv->fw.fw_icm); 550 mlx4_free_icm(dev, priv->fw.fw_icm, 0);
541 551
542 return err; 552 return err;
543} 553}
544 554
545static int __devinit mlx4_setup_hca(struct mlx4_dev *dev) 555static int mlx4_setup_hca(struct mlx4_dev *dev)
546{ 556{
547 struct mlx4_priv *priv = mlx4_priv(dev); 557 struct mlx4_priv *priv = mlx4_priv(dev);
548 int err; 558 int err;
@@ -599,13 +609,17 @@ static int __devinit mlx4_setup_hca(struct mlx4_dev *dev)
599 609
600 err = mlx4_NOP(dev); 610 err = mlx4_NOP(dev);
601 if (err) { 611 if (err) {
602 mlx4_err(dev, "NOP command failed to generate interrupt " 612 if (dev->flags & MLX4_FLAG_MSI_X) {
603 "(IRQ %d), aborting.\n", 613 mlx4_warn(dev, "NOP command failed to generate MSI-X "
604 priv->eq_table.eq[MLX4_EQ_ASYNC].irq); 614 "interrupt IRQ %d).\n",
605 if (dev->flags & MLX4_FLAG_MSI_X) 615 priv->eq_table.eq[MLX4_EQ_ASYNC].irq);
606 mlx4_err(dev, "Try again with MSI-X disabled.\n"); 616 mlx4_warn(dev, "Trying again without MSI-X.\n");
607 else 617 } else {
618 mlx4_err(dev, "NOP command failed to generate interrupt "
619 "(IRQ %d), aborting.\n",
620 priv->eq_table.eq[MLX4_EQ_ASYNC].irq);
608 mlx4_err(dev, "BIOS or ACPI interrupt routing problem?\n"); 621 mlx4_err(dev, "BIOS or ACPI interrupt routing problem?\n");
622 }
609 623
610 goto err_cmd_poll; 624 goto err_cmd_poll;
611 } 625 }
@@ -705,19 +719,12 @@ no_msi:
705 priv->eq_table.eq[i].irq = dev->pdev->irq; 719 priv->eq_table.eq[i].irq = dev->pdev->irq;
706} 720}
707 721
708static int __devinit mlx4_init_one(struct pci_dev *pdev, 722static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
709 const struct pci_device_id *id)
710{ 723{
711 static int mlx4_version_printed;
712 struct mlx4_priv *priv; 724 struct mlx4_priv *priv;
713 struct mlx4_dev *dev; 725 struct mlx4_dev *dev;
714 int err; 726 int err;
715 727
716 if (!mlx4_version_printed) {
717 printk(KERN_INFO "%s", mlx4_version);
718 ++mlx4_version_printed;
719 }
720
721 printk(KERN_INFO PFX "Initializing %s\n", 728 printk(KERN_INFO PFX "Initializing %s\n",
722 pci_name(pdev)); 729 pci_name(pdev));
723 730
@@ -803,8 +810,6 @@ static int __devinit mlx4_init_one(struct pci_dev *pdev,
803 goto err_free_dev; 810 goto err_free_dev;
804 } 811 }
805 812
806 mlx4_enable_msi_x(dev);
807
808 if (mlx4_cmd_init(dev)) { 813 if (mlx4_cmd_init(dev)) {
809 mlx4_err(dev, "Failed to init command interface, aborting.\n"); 814 mlx4_err(dev, "Failed to init command interface, aborting.\n");
810 goto err_free_dev; 815 goto err_free_dev;
@@ -814,7 +819,15 @@ static int __devinit mlx4_init_one(struct pci_dev *pdev,
814 if (err) 819 if (err)
815 goto err_cmd; 820 goto err_cmd;
816 821
822 mlx4_enable_msi_x(dev);
823
817 err = mlx4_setup_hca(dev); 824 err = mlx4_setup_hca(dev);
825 if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X)) {
826 dev->flags &= ~MLX4_FLAG_MSI_X;
827 pci_disable_msix(pdev);
828 err = mlx4_setup_hca(dev);
829 }
830
818 if (err) 831 if (err)
819 goto err_close; 832 goto err_close;
820 833
@@ -838,15 +851,15 @@ err_cleanup:
838 mlx4_cleanup_uar_table(dev); 851 mlx4_cleanup_uar_table(dev);
839 852
840err_close: 853err_close:
854 if (dev->flags & MLX4_FLAG_MSI_X)
855 pci_disable_msix(pdev);
856
841 mlx4_close_hca(dev); 857 mlx4_close_hca(dev);
842 858
843err_cmd: 859err_cmd:
844 mlx4_cmd_cleanup(dev); 860 mlx4_cmd_cleanup(dev);
845 861
846err_free_dev: 862err_free_dev:
847 if (dev->flags & MLX4_FLAG_MSI_X)
848 pci_disable_msix(pdev);
849
850 kfree(priv); 863 kfree(priv);
851 864
852err_release_bar2: 865err_release_bar2:
@@ -861,7 +874,20 @@ err_disable_pdev:
861 return err; 874 return err;
862} 875}
863 876
864static void __devexit mlx4_remove_one(struct pci_dev *pdev) 877static int __devinit mlx4_init_one(struct pci_dev *pdev,
878 const struct pci_device_id *id)
879{
880 static int mlx4_version_printed;
881
882 if (!mlx4_version_printed) {
883 printk(KERN_INFO "%s", mlx4_version);
884 ++mlx4_version_printed;
885 }
886
887 return mlx4_init_one(pdev, id);
888}
889
890static void mlx4_remove_one(struct pci_dev *pdev)
865{ 891{
866 struct mlx4_dev *dev = pci_get_drvdata(pdev); 892 struct mlx4_dev *dev = pci_get_drvdata(pdev);
867 struct mlx4_priv *priv = mlx4_priv(dev); 893 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -902,7 +928,7 @@ static void __devexit mlx4_remove_one(struct pci_dev *pdev)
902int mlx4_restart_one(struct pci_dev *pdev) 928int mlx4_restart_one(struct pci_dev *pdev)
903{ 929{
904 mlx4_remove_one(pdev); 930 mlx4_remove_one(pdev);
905 return mlx4_init_one(pdev, NULL); 931 return __mlx4_init_one(pdev, NULL);
906} 932}
907 933
908static struct pci_device_id mlx4_pci_table[] = { 934static struct pci_device_id mlx4_pci_table[] = {
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index 672024a0ee7..a99e7729d33 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -359,7 +359,7 @@ out:
359} 359}
360EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 360EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
361 361
362int __devinit mlx4_init_mcg_table(struct mlx4_dev *dev) 362int mlx4_init_mcg_table(struct mlx4_dev *dev)
363{ 363{
364 struct mlx4_priv *priv = mlx4_priv(dev); 364 struct mlx4_priv *priv = mlx4_priv(dev);
365 int err; 365 int err;
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index be304a7c2c9..53a1cdddfc1 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -56,11 +56,7 @@ enum {
56}; 56};
57 57
58enum { 58enum {
59 MLX4_BOARD_ID_LEN = 64 59 MLX4_MGM_ENTRY_SIZE = 0x100,
60};
61
62enum {
63 MLX4_MGM_ENTRY_SIZE = 0x40,
64 MLX4_QP_PER_MGM = 4 * (MLX4_MGM_ENTRY_SIZE / 16 - 2), 60 MLX4_QP_PER_MGM = 4 * (MLX4_MGM_ENTRY_SIZE / 16 - 2),
65 MLX4_MTT_ENTRY_PER_SEG = 8 61 MLX4_MTT_ENTRY_PER_SEG = 8
66}; 62};
@@ -133,6 +129,7 @@ struct mlx4_icm_table {
133 int num_obj; 129 int num_obj;
134 int obj_size; 130 int obj_size;
135 int lowmem; 131 int lowmem;
132 int coherent;
136 struct mutex mutex; 133 struct mutex mutex;
137 struct mlx4_icm **icm; 134 struct mlx4_icm **icm;
138}; 135};
@@ -277,9 +274,6 @@ struct mlx4_priv {
277 274
278 struct mlx4_uar driver_uar; 275 struct mlx4_uar driver_uar;
279 void __iomem *kar; 276 void __iomem *kar;
280
281 u32 rev_id;
282 char board_id[MLX4_BOARD_ID_LEN];
283}; 277};
284 278
285static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev) 279static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index 5b87183e62c..0c05a10bae3 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -68,6 +68,9 @@ struct mlx4_mpt_entry {
68 68
69#define MLX4_MTT_FLAG_PRESENT 1 69#define MLX4_MTT_FLAG_PRESENT 1
70 70
71#define MLX4_MPT_STATUS_SW 0xF0
72#define MLX4_MPT_STATUS_HW 0x00
73
71static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order) 74static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order)
72{ 75{
73 int o; 76 int o;
@@ -349,58 +352,57 @@ err_table:
349} 352}
350EXPORT_SYMBOL_GPL(mlx4_mr_enable); 353EXPORT_SYMBOL_GPL(mlx4_mr_enable);
351 354
352static int mlx4_WRITE_MTT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, 355static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
353 int num_mtt) 356 int start_index, int npages, u64 *page_list)
354{ 357{
355 return mlx4_cmd(dev, mailbox->dma, num_mtt, 0, MLX4_CMD_WRITE_MTT, 358 struct mlx4_priv *priv = mlx4_priv(dev);
356 MLX4_CMD_TIME_CLASS_B); 359 __be64 *mtts;
360 dma_addr_t dma_handle;
361 int i;
362 int s = start_index * sizeof (u64);
363
364 /* All MTTs must fit in the same page */
365 if (start_index / (PAGE_SIZE / sizeof (u64)) !=
366 (start_index + npages - 1) / (PAGE_SIZE / sizeof (u64)))
367 return -EINVAL;
368
369 if (start_index & (MLX4_MTT_ENTRY_PER_SEG - 1))
370 return -EINVAL;
371
372 mtts = mlx4_table_find(&priv->mr_table.mtt_table, mtt->first_seg +
373 s / dev->caps.mtt_entry_sz, &dma_handle);
374 if (!mtts)
375 return -ENOMEM;
376
377 for (i = 0; i < npages; ++i)
378 mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
379
380 dma_sync_single(&dev->pdev->dev, dma_handle, npages * sizeof (u64), DMA_TO_DEVICE);
381
382 return 0;
357} 383}
358 384
359int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, 385int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
360 int start_index, int npages, u64 *page_list) 386 int start_index, int npages, u64 *page_list)
361{ 387{
362 struct mlx4_cmd_mailbox *mailbox; 388 int chunk;
363 __be64 *mtt_entry; 389 int err;
364 int i;
365 int err = 0;
366 390
367 if (mtt->order < 0) 391 if (mtt->order < 0)
368 return -EINVAL; 392 return -EINVAL;
369 393
370 mailbox = mlx4_alloc_cmd_mailbox(dev);
371 if (IS_ERR(mailbox))
372 return PTR_ERR(mailbox);
373
374 mtt_entry = mailbox->buf;
375
376 while (npages > 0) { 394 while (npages > 0) {
377 mtt_entry[0] = cpu_to_be64(mlx4_mtt_addr(dev, mtt) + start_index * 8); 395 chunk = min_t(int, PAGE_SIZE / sizeof(u64), npages);
378 mtt_entry[1] = 0; 396 err = mlx4_write_mtt_chunk(dev, mtt, start_index, chunk, page_list);
379
380 for (i = 0; i < npages && i < MLX4_MAILBOX_SIZE / 8 - 2; ++i)
381 mtt_entry[i + 2] = cpu_to_be64(page_list[i] |
382 MLX4_MTT_FLAG_PRESENT);
383
384 /*
385 * If we have an odd number of entries to write, add
386 * one more dummy entry for firmware efficiency.
387 */
388 if (i & 1)
389 mtt_entry[i + 2] = 0;
390
391 err = mlx4_WRITE_MTT(dev, mailbox, (i + 1) & ~1);
392 if (err) 397 if (err)
393 goto out; 398 return err;
394 399
395 npages -= i; 400 npages -= chunk;
396 start_index += i; 401 start_index += chunk;
397 page_list += i; 402 page_list += chunk;
398 } 403 }
399 404
400out: 405 return 0;
401 mlx4_free_cmd_mailbox(dev, mailbox);
402
403 return err;
404} 406}
405EXPORT_SYMBOL_GPL(mlx4_write_mtt); 407EXPORT_SYMBOL_GPL(mlx4_write_mtt);
406 408
@@ -428,7 +430,7 @@ int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
428} 430}
429EXPORT_SYMBOL_GPL(mlx4_buf_write_mtt); 431EXPORT_SYMBOL_GPL(mlx4_buf_write_mtt);
430 432
431int __devinit mlx4_init_mr_table(struct mlx4_dev *dev) 433int mlx4_init_mr_table(struct mlx4_dev *dev)
432{ 434{
433 struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table; 435 struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;
434 int err; 436 int err;
@@ -444,7 +446,7 @@ int __devinit mlx4_init_mr_table(struct mlx4_dev *dev)
444 goto err_buddy; 446 goto err_buddy;
445 447
446 if (dev->caps.reserved_mtts) { 448 if (dev->caps.reserved_mtts) {
447 if (mlx4_alloc_mtt_range(dev, ilog2(dev->caps.reserved_mtts)) == -1) { 449 if (mlx4_alloc_mtt_range(dev, fls(dev->caps.reserved_mtts - 1)) == -1) {
448 mlx4_warn(dev, "MTT table of order %d is too small.\n", 450 mlx4_warn(dev, "MTT table of order %d is too small.\n",
449 mr_table->mtt_buddy.max_order); 451 mr_table->mtt_buddy.max_order);
450 err = -ENOMEM; 452 err = -ENOMEM;
@@ -470,3 +472,165 @@ void mlx4_cleanup_mr_table(struct mlx4_dev *dev)
470 mlx4_buddy_cleanup(&mr_table->mtt_buddy); 472 mlx4_buddy_cleanup(&mr_table->mtt_buddy);
471 mlx4_bitmap_cleanup(&mr_table->mpt_bitmap); 473 mlx4_bitmap_cleanup(&mr_table->mpt_bitmap);
472} 474}
475
476static inline int mlx4_check_fmr(struct mlx4_fmr *fmr, u64 *page_list,
477 int npages, u64 iova)
478{
479 int i, page_mask;
480
481 if (npages > fmr->max_pages)
482 return -EINVAL;
483
484 page_mask = (1 << fmr->page_shift) - 1;
485
486 /* We are getting page lists, so va must be page aligned. */
487 if (iova & page_mask)
488 return -EINVAL;
489
490 /* Trust the user not to pass misaligned data in page_list */
491 if (0)
492 for (i = 0; i < npages; ++i) {
493 if (page_list[i] & ~page_mask)
494 return -EINVAL;
495 }
496
497 if (fmr->maps >= fmr->max_maps)
498 return -EINVAL;
499
500 return 0;
501}
502
503int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list,
504 int npages, u64 iova, u32 *lkey, u32 *rkey)
505{
506 u32 key;
507 int i, err;
508
509 err = mlx4_check_fmr(fmr, page_list, npages, iova);
510 if (err)
511 return err;
512
513 ++fmr->maps;
514
515 key = key_to_hw_index(fmr->mr.key);
516 key += dev->caps.num_mpts;
517 *lkey = *rkey = fmr->mr.key = hw_index_to_key(key);
518
519 *(u8 *) fmr->mpt = MLX4_MPT_STATUS_SW;
520
521 /* Make sure MPT status is visible before writing MTT entries */
522 wmb();
523
524 for (i = 0; i < npages; ++i)
525 fmr->mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
526
527 dma_sync_single(&dev->pdev->dev, fmr->dma_handle,
528 npages * sizeof(u64), DMA_TO_DEVICE);
529
530 fmr->mpt->key = cpu_to_be32(key);
531 fmr->mpt->lkey = cpu_to_be32(key);
532 fmr->mpt->length = cpu_to_be64(npages * (1ull << fmr->page_shift));
533 fmr->mpt->start = cpu_to_be64(iova);
534
535 /* Make MTT entries are visible before setting MPT status */
536 wmb();
537
538 *(u8 *) fmr->mpt = MLX4_MPT_STATUS_HW;
539
540 /* Make sure MPT status is visible before consumer can use FMR */
541 wmb();
542
543 return 0;
544}
545EXPORT_SYMBOL_GPL(mlx4_map_phys_fmr);
546
547int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
548 int max_maps, u8 page_shift, struct mlx4_fmr *fmr)
549{
550 struct mlx4_priv *priv = mlx4_priv(dev);
551 u64 mtt_seg;
552 int err = -ENOMEM;
553
554 if (page_shift < 12 || page_shift >= 32)
555 return -EINVAL;
556
557 /* All MTTs must fit in the same page */
558 if (max_pages * sizeof *fmr->mtts > PAGE_SIZE)
559 return -EINVAL;
560
561 fmr->page_shift = page_shift;
562 fmr->max_pages = max_pages;
563 fmr->max_maps = max_maps;
564 fmr->maps = 0;
565
566 err = mlx4_mr_alloc(dev, pd, 0, 0, access, max_pages,
567 page_shift, &fmr->mr);
568 if (err)
569 return err;
570
571 mtt_seg = fmr->mr.mtt.first_seg * dev->caps.mtt_entry_sz;
572
573 fmr->mtts = mlx4_table_find(&priv->mr_table.mtt_table,
574 fmr->mr.mtt.first_seg,
575 &fmr->dma_handle);
576 if (!fmr->mtts) {
577 err = -ENOMEM;
578 goto err_free;
579 }
580
581 fmr->mpt = mlx4_table_find(&priv->mr_table.dmpt_table,
582 key_to_hw_index(fmr->mr.key), NULL);
583 if (!fmr->mpt) {
584 err = -ENOMEM;
585 goto err_free;
586 }
587
588 return 0;
589
590err_free:
591 mlx4_mr_free(dev, &fmr->mr);
592 return err;
593}
594EXPORT_SYMBOL_GPL(mlx4_fmr_alloc);
595
596int mlx4_fmr_enable(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
597{
598 return mlx4_mr_enable(dev, &fmr->mr);
599}
600EXPORT_SYMBOL_GPL(mlx4_fmr_enable);
601
602void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr,
603 u32 *lkey, u32 *rkey)
604{
605 u32 key;
606
607 if (!fmr->maps)
608 return;
609
610 key = key_to_hw_index(fmr->mr.key);
611 key &= dev->caps.num_mpts - 1;
612 *lkey = *rkey = fmr->mr.key = hw_index_to_key(key);
613
614 fmr->maps = 0;
615
616 *(u8 *) fmr->mpt = MLX4_MPT_STATUS_SW;
617}
618EXPORT_SYMBOL_GPL(mlx4_fmr_unmap);
619
620int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
621{
622 if (fmr->maps)
623 return -EBUSY;
624
625 fmr->mr.enabled = 0;
626 mlx4_mr_free(dev, &fmr->mr);
627
628 return 0;
629}
630EXPORT_SYMBOL_GPL(mlx4_fmr_free);
631
632int mlx4_SYNC_TPT(struct mlx4_dev *dev)
633{
634 return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_SYNC_TPT, 1000);
635}
636EXPORT_SYMBOL_GPL(mlx4_SYNC_TPT);
diff --git a/drivers/net/mlx4/pd.c b/drivers/net/mlx4/pd.c
index 23dea1ee775..3a93c5f0f7a 100644
--- a/drivers/net/mlx4/pd.c
+++ b/drivers/net/mlx4/pd.c
@@ -57,7 +57,7 @@ void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn)
57} 57}
58EXPORT_SYMBOL_GPL(mlx4_pd_free); 58EXPORT_SYMBOL_GPL(mlx4_pd_free);
59 59
60int __devinit mlx4_init_pd_table(struct mlx4_dev *dev) 60int mlx4_init_pd_table(struct mlx4_dev *dev)
61{ 61{
62 struct mlx4_priv *priv = mlx4_priv(dev); 62 struct mlx4_priv *priv = mlx4_priv(dev);
63 63
diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c
index 19b48c71cf7..cc4b1be1821 100644
--- a/drivers/net/mlx4/qp.c
+++ b/drivers/net/mlx4/qp.c
@@ -240,7 +240,8 @@ void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
240 mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn); 240 mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
241 mlx4_table_put(dev, &qp_table->qp_table, qp->qpn); 241 mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
242 242
243 mlx4_bitmap_free(&qp_table->bitmap, qp->qpn); 243 if (qp->qpn < dev->caps.sqp_start + 8)
244 mlx4_bitmap_free(&qp_table->bitmap, qp->qpn);
244} 245}
245EXPORT_SYMBOL_GPL(mlx4_qp_free); 246EXPORT_SYMBOL_GPL(mlx4_qp_free);
246 247
@@ -250,7 +251,7 @@ static int mlx4_CONF_SPECIAL_QP(struct mlx4_dev *dev, u32 base_qpn)
250 MLX4_CMD_TIME_CLASS_B); 251 MLX4_CMD_TIME_CLASS_B);
251} 252}
252 253
253int __devinit mlx4_init_qp_table(struct mlx4_dev *dev) 254int mlx4_init_qp_table(struct mlx4_dev *dev)
254{ 255{
255 struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; 256 struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
256 int err; 257 int err;
diff --git a/drivers/net/mlx4/srq.c b/drivers/net/mlx4/srq.c
index b061c86d683..d23f46d692e 100644
--- a/drivers/net/mlx4/srq.c
+++ b/drivers/net/mlx4/srq.c
@@ -227,7 +227,7 @@ int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_waterm
227 err = mlx4_QUERY_SRQ(dev, mailbox, srq->srqn); 227 err = mlx4_QUERY_SRQ(dev, mailbox, srq->srqn);
228 if (err) 228 if (err)
229 goto err_out; 229 goto err_out;
230 *limit_watermark = srq_context->limit_watermark; 230 *limit_watermark = be16_to_cpu(srq_context->limit_watermark);
231 231
232err_out: 232err_out:
233 mlx4_free_cmd_mailbox(dev, mailbox); 233 mlx4_free_cmd_mailbox(dev, mailbox);
@@ -235,7 +235,7 @@ err_out:
235} 235}
236EXPORT_SYMBOL_GPL(mlx4_srq_query); 236EXPORT_SYMBOL_GPL(mlx4_srq_query);
237 237
238int __devinit mlx4_init_srq_table(struct mlx4_dev *dev) 238int mlx4_init_srq_table(struct mlx4_dev *dev)
239{ 239{
240 struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table; 240 struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
241 int err; 241 int err;