diff options
69 files changed, 2732 insertions, 1424 deletions
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index 10be36731ed7..678a7e097f32 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile | |||
@@ -1,5 +1,3 @@ | |||
1 | EXTRA_CFLAGS += -Idrivers/infiniband/include | ||
2 | |||
3 | obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ | 1 | obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ |
4 | ib_cm.o ib_umad.o ib_ucm.o | 2 | ib_cm.o ib_umad.o ib_ucm.o |
5 | obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o | 3 | obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o |
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index 729f0b0d983a..5ac86f566dc0 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved. |
3 | * Copyright (c) 2004 Infinicon Corporation. All rights reserved. | 3 | * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved. |
4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 5 | * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved. |
6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. | 6 | * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. |
7 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
7 | * | 8 | * |
8 | * This software is available to you under a choice of one of two | 9 | * This software is available to you under a choice of one of two |
9 | * licenses. You may choose to be licensed under the terms of the GNU | 10 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -40,7 +41,7 @@ | |||
40 | 41 | ||
41 | #include <asm/bug.h> | 42 | #include <asm/bug.h> |
42 | 43 | ||
43 | #include <ib_smi.h> | 44 | #include <rdma/ib_smi.h> |
44 | 45 | ||
45 | #include "smi.h" | 46 | #include "smi.h" |
46 | #include "agent_priv.h" | 47 | #include "agent_priv.h" |
diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h index 17435af1e914..2ec6d7f1b7d0 100644 --- a/drivers/infiniband/core/agent_priv.h +++ b/drivers/infiniband/core/agent_priv.h | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved. |
3 | * Copyright (c) 2004 Infinicon Corporation. All rights reserved. | 3 | * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved. |
4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 5 | * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved. |
6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. | 6 | * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. |
7 | * | 7 | * |
8 | * 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 |
9 | * 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 |
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 3042360c97e1..f014e639088c 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c | |||
@@ -1,5 +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 Intel Corporation. All rights reserved. | ||
4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
5 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. | ||
3 | * | 6 | * |
4 | * 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 |
5 | * 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 |
@@ -32,12 +35,11 @@ | |||
32 | * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $ | 35 | * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $ |
33 | */ | 36 | */ |
34 | 37 | ||
35 | #include <linux/version.h> | ||
36 | #include <linux/module.h> | 38 | #include <linux/module.h> |
37 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
38 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
39 | 41 | ||
40 | #include <ib_cache.h> | 42 | #include <rdma/ib_cache.h> |
41 | 43 | ||
42 | #include "core_priv.h" | 44 | #include "core_priv.h" |
43 | 45 | ||
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 403ed125d8f4..4de93ba274a6 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -43,8 +43,8 @@ | |||
43 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
44 | #include <linux/workqueue.h> | 44 | #include <linux/workqueue.h> |
45 | 45 | ||
46 | #include <ib_cache.h> | 46 | #include <rdma/ib_cache.h> |
47 | #include <ib_cm.h> | 47 | #include <rdma/ib_cm.h> |
48 | #include "cm_msgs.h" | 48 | #include "cm_msgs.h" |
49 | 49 | ||
50 | MODULE_AUTHOR("Sean Hefty"); | 50 | MODULE_AUTHOR("Sean Hefty"); |
@@ -83,7 +83,7 @@ struct cm_port { | |||
83 | struct cm_device { | 83 | struct cm_device { |
84 | struct list_head list; | 84 | struct list_head list; |
85 | struct ib_device *device; | 85 | struct ib_device *device; |
86 | u64 ca_guid; | 86 | __be64 ca_guid; |
87 | struct cm_port port[0]; | 87 | struct cm_port port[0]; |
88 | }; | 88 | }; |
89 | 89 | ||
@@ -100,8 +100,8 @@ struct cm_work { | |||
100 | struct list_head list; | 100 | struct list_head list; |
101 | struct cm_port *port; | 101 | struct cm_port *port; |
102 | struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */ | 102 | struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */ |
103 | u32 local_id; /* Established / timewait */ | 103 | __be32 local_id; /* Established / timewait */ |
104 | u32 remote_id; | 104 | __be32 remote_id; |
105 | struct ib_cm_event cm_event; | 105 | struct ib_cm_event cm_event; |
106 | struct ib_sa_path_rec path[0]; | 106 | struct ib_sa_path_rec path[0]; |
107 | }; | 107 | }; |
@@ -110,8 +110,8 @@ struct cm_timewait_info { | |||
110 | struct cm_work work; /* Must be first. */ | 110 | struct cm_work work; /* Must be first. */ |
111 | struct rb_node remote_qp_node; | 111 | struct rb_node remote_qp_node; |
112 | struct rb_node remote_id_node; | 112 | struct rb_node remote_id_node; |
113 | u64 remote_ca_guid; | 113 | __be64 remote_ca_guid; |
114 | u32 remote_qpn; | 114 | __be32 remote_qpn; |
115 | u8 inserted_remote_qp; | 115 | u8 inserted_remote_qp; |
116 | u8 inserted_remote_id; | 116 | u8 inserted_remote_id; |
117 | }; | 117 | }; |
@@ -132,11 +132,11 @@ struct cm_id_private { | |||
132 | struct cm_av alt_av; | 132 | struct cm_av alt_av; |
133 | 133 | ||
134 | void *private_data; | 134 | void *private_data; |
135 | u64 tid; | 135 | __be64 tid; |
136 | u32 local_qpn; | 136 | __be32 local_qpn; |
137 | u32 remote_qpn; | 137 | __be32 remote_qpn; |
138 | u32 sq_psn; | 138 | __be32 sq_psn; |
139 | u32 rq_psn; | 139 | __be32 rq_psn; |
140 | int timeout_ms; | 140 | int timeout_ms; |
141 | enum ib_mtu path_mtu; | 141 | enum ib_mtu path_mtu; |
142 | u8 private_data_len; | 142 | u8 private_data_len; |
@@ -253,7 +253,7 @@ static void cm_set_ah_attr(struct ib_ah_attr *ah_attr, u8 port_num, | |||
253 | u16 dlid, u8 sl, u16 src_path_bits) | 253 | u16 dlid, u8 sl, u16 src_path_bits) |
254 | { | 254 | { |
255 | memset(ah_attr, 0, sizeof ah_attr); | 255 | memset(ah_attr, 0, sizeof ah_attr); |
256 | ah_attr->dlid = be16_to_cpu(dlid); | 256 | ah_attr->dlid = dlid; |
257 | ah_attr->sl = sl; | 257 | ah_attr->sl = sl; |
258 | ah_attr->src_path_bits = src_path_bits; | 258 | ah_attr->src_path_bits = src_path_bits; |
259 | ah_attr->port_num = port_num; | 259 | ah_attr->port_num = port_num; |
@@ -264,7 +264,7 @@ static void cm_init_av_for_response(struct cm_port *port, | |||
264 | { | 264 | { |
265 | av->port = port; | 265 | av->port = port; |
266 | av->pkey_index = wc->pkey_index; | 266 | av->pkey_index = wc->pkey_index; |
267 | cm_set_ah_attr(&av->ah_attr, port->port_num, cpu_to_be16(wc->slid), | 267 | cm_set_ah_attr(&av->ah_attr, port->port_num, wc->slid, |
268 | wc->sl, wc->dlid_path_bits); | 268 | wc->sl, wc->dlid_path_bits); |
269 | } | 269 | } |
270 | 270 | ||
@@ -295,8 +295,9 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) | |||
295 | return ret; | 295 | return ret; |
296 | 296 | ||
297 | av->port = port; | 297 | av->port = port; |
298 | cm_set_ah_attr(&av->ah_attr, av->port->port_num, path->dlid, | 298 | cm_set_ah_attr(&av->ah_attr, av->port->port_num, |
299 | path->sl, path->slid & 0x7F); | 299 | be16_to_cpu(path->dlid), path->sl, |
300 | be16_to_cpu(path->slid) & 0x7F); | ||
300 | av->packet_life_time = path->packet_life_time; | 301 | av->packet_life_time = path->packet_life_time; |
301 | return 0; | 302 | return 0; |
302 | } | 303 | } |
@@ -309,26 +310,26 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv) | |||
309 | do { | 310 | do { |
310 | spin_lock_irqsave(&cm.lock, flags); | 311 | spin_lock_irqsave(&cm.lock, flags); |
311 | ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, | 312 | ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, |
312 | (int *) &cm_id_priv->id.local_id); | 313 | (__force int *) &cm_id_priv->id.local_id); |
313 | spin_unlock_irqrestore(&cm.lock, flags); | 314 | spin_unlock_irqrestore(&cm.lock, flags); |
314 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); | 315 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); |
315 | return ret; | 316 | return ret; |
316 | } | 317 | } |
317 | 318 | ||
318 | static void cm_free_id(u32 local_id) | 319 | static void cm_free_id(__be32 local_id) |
319 | { | 320 | { |
320 | unsigned long flags; | 321 | unsigned long flags; |
321 | 322 | ||
322 | spin_lock_irqsave(&cm.lock, flags); | 323 | spin_lock_irqsave(&cm.lock, flags); |
323 | idr_remove(&cm.local_id_table, (int) local_id); | 324 | idr_remove(&cm.local_id_table, (__force int) local_id); |
324 | spin_unlock_irqrestore(&cm.lock, flags); | 325 | spin_unlock_irqrestore(&cm.lock, flags); |
325 | } | 326 | } |
326 | 327 | ||
327 | static struct cm_id_private * cm_get_id(u32 local_id, u32 remote_id) | 328 | static struct cm_id_private * cm_get_id(__be32 local_id, __be32 remote_id) |
328 | { | 329 | { |
329 | struct cm_id_private *cm_id_priv; | 330 | struct cm_id_private *cm_id_priv; |
330 | 331 | ||
331 | cm_id_priv = idr_find(&cm.local_id_table, (int) local_id); | 332 | cm_id_priv = idr_find(&cm.local_id_table, (__force int) local_id); |
332 | if (cm_id_priv) { | 333 | if (cm_id_priv) { |
333 | if (cm_id_priv->id.remote_id == remote_id) | 334 | if (cm_id_priv->id.remote_id == remote_id) |
334 | atomic_inc(&cm_id_priv->refcount); | 335 | atomic_inc(&cm_id_priv->refcount); |
@@ -339,7 +340,7 @@ static struct cm_id_private * cm_get_id(u32 local_id, u32 remote_id) | |||
339 | return cm_id_priv; | 340 | return cm_id_priv; |
340 | } | 341 | } |
341 | 342 | ||
342 | static struct cm_id_private * cm_acquire_id(u32 local_id, u32 remote_id) | 343 | static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id) |
343 | { | 344 | { |
344 | struct cm_id_private *cm_id_priv; | 345 | struct cm_id_private *cm_id_priv; |
345 | unsigned long flags; | 346 | unsigned long flags; |
@@ -356,8 +357,8 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) | |||
356 | struct rb_node **link = &cm.listen_service_table.rb_node; | 357 | struct rb_node **link = &cm.listen_service_table.rb_node; |
357 | struct rb_node *parent = NULL; | 358 | struct rb_node *parent = NULL; |
358 | struct cm_id_private *cur_cm_id_priv; | 359 | struct cm_id_private *cur_cm_id_priv; |
359 | u64 service_id = cm_id_priv->id.service_id; | 360 | __be64 service_id = cm_id_priv->id.service_id; |
360 | u64 service_mask = cm_id_priv->id.service_mask; | 361 | __be64 service_mask = cm_id_priv->id.service_mask; |
361 | 362 | ||
362 | while (*link) { | 363 | while (*link) { |
363 | parent = *link; | 364 | parent = *link; |
@@ -376,7 +377,7 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) | |||
376 | return NULL; | 377 | return NULL; |
377 | } | 378 | } |
378 | 379 | ||
379 | static struct cm_id_private * cm_find_listen(u64 service_id) | 380 | static struct cm_id_private * cm_find_listen(__be64 service_id) |
380 | { | 381 | { |
381 | struct rb_node *node = cm.listen_service_table.rb_node; | 382 | struct rb_node *node = cm.listen_service_table.rb_node; |
382 | struct cm_id_private *cm_id_priv; | 383 | struct cm_id_private *cm_id_priv; |
@@ -400,8 +401,8 @@ static struct cm_timewait_info * cm_insert_remote_id(struct cm_timewait_info | |||
400 | struct rb_node **link = &cm.remote_id_table.rb_node; | 401 | struct rb_node **link = &cm.remote_id_table.rb_node; |
401 | struct rb_node *parent = NULL; | 402 | struct rb_node *parent = NULL; |
402 | struct cm_timewait_info *cur_timewait_info; | 403 | struct cm_timewait_info *cur_timewait_info; |
403 | u64 remote_ca_guid = timewait_info->remote_ca_guid; | 404 | __be64 remote_ca_guid = timewait_info->remote_ca_guid; |
404 | u32 remote_id = timewait_info->work.remote_id; | 405 | __be32 remote_id = timewait_info->work.remote_id; |
405 | 406 | ||
406 | while (*link) { | 407 | while (*link) { |
407 | parent = *link; | 408 | parent = *link; |
@@ -424,8 +425,8 @@ static struct cm_timewait_info * cm_insert_remote_id(struct cm_timewait_info | |||
424 | return NULL; | 425 | return NULL; |
425 | } | 426 | } |
426 | 427 | ||
427 | static struct cm_timewait_info * cm_find_remote_id(u64 remote_ca_guid, | 428 | static struct cm_timewait_info * cm_find_remote_id(__be64 remote_ca_guid, |
428 | u32 remote_id) | 429 | __be32 remote_id) |
429 | { | 430 | { |
430 | struct rb_node *node = cm.remote_id_table.rb_node; | 431 | struct rb_node *node = cm.remote_id_table.rb_node; |
431 | struct cm_timewait_info *timewait_info; | 432 | struct cm_timewait_info *timewait_info; |
@@ -453,8 +454,8 @@ static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info | |||
453 | struct rb_node **link = &cm.remote_qp_table.rb_node; | 454 | struct rb_node **link = &cm.remote_qp_table.rb_node; |
454 | struct rb_node *parent = NULL; | 455 | struct rb_node *parent = NULL; |
455 | struct cm_timewait_info *cur_timewait_info; | 456 | struct cm_timewait_info *cur_timewait_info; |
456 | u64 remote_ca_guid = timewait_info->remote_ca_guid; | 457 | __be64 remote_ca_guid = timewait_info->remote_ca_guid; |
457 | u32 remote_qpn = timewait_info->remote_qpn; | 458 | __be32 remote_qpn = timewait_info->remote_qpn; |
458 | 459 | ||
459 | while (*link) { | 460 | while (*link) { |
460 | parent = *link; | 461 | parent = *link; |
@@ -484,7 +485,7 @@ static struct cm_id_private * cm_insert_remote_sidr(struct cm_id_private | |||
484 | struct rb_node *parent = NULL; | 485 | struct rb_node *parent = NULL; |
485 | struct cm_id_private *cur_cm_id_priv; | 486 | struct cm_id_private *cur_cm_id_priv; |
486 | union ib_gid *port_gid = &cm_id_priv->av.dgid; | 487 | union ib_gid *port_gid = &cm_id_priv->av.dgid; |
487 | u32 remote_id = cm_id_priv->id.remote_id; | 488 | __be32 remote_id = cm_id_priv->id.remote_id; |
488 | 489 | ||
489 | while (*link) { | 490 | while (*link) { |
490 | parent = *link; | 491 | parent = *link; |
@@ -598,7 +599,7 @@ static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info) | |||
598 | spin_unlock_irqrestore(&cm.lock, flags); | 599 | spin_unlock_irqrestore(&cm.lock, flags); |
599 | } | 600 | } |
600 | 601 | ||
601 | static struct cm_timewait_info * cm_create_timewait_info(u32 local_id) | 602 | static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id) |
602 | { | 603 | { |
603 | struct cm_timewait_info *timewait_info; | 604 | struct cm_timewait_info *timewait_info; |
604 | 605 | ||
@@ -715,14 +716,15 @@ retest: | |||
715 | EXPORT_SYMBOL(ib_destroy_cm_id); | 716 | EXPORT_SYMBOL(ib_destroy_cm_id); |
716 | 717 | ||
717 | int ib_cm_listen(struct ib_cm_id *cm_id, | 718 | int ib_cm_listen(struct ib_cm_id *cm_id, |
718 | u64 service_id, | 719 | __be64 service_id, |
719 | u64 service_mask) | 720 | __be64 service_mask) |
720 | { | 721 | { |
721 | struct cm_id_private *cm_id_priv, *cur_cm_id_priv; | 722 | struct cm_id_private *cm_id_priv, *cur_cm_id_priv; |
722 | unsigned long flags; | 723 | unsigned long flags; |
723 | int ret = 0; | 724 | int ret = 0; |
724 | 725 | ||
725 | service_mask = service_mask ? service_mask : ~0ULL; | 726 | service_mask = service_mask ? service_mask : |
727 | __constant_cpu_to_be64(~0ULL); | ||
726 | service_id &= service_mask; | 728 | service_id &= service_mask; |
727 | if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID && | 729 | if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID && |
728 | (service_id != IB_CM_ASSIGN_SERVICE_ID)) | 730 | (service_id != IB_CM_ASSIGN_SERVICE_ID)) |
@@ -735,8 +737,8 @@ int ib_cm_listen(struct ib_cm_id *cm_id, | |||
735 | 737 | ||
736 | spin_lock_irqsave(&cm.lock, flags); | 738 | spin_lock_irqsave(&cm.lock, flags); |
737 | if (service_id == IB_CM_ASSIGN_SERVICE_ID) { | 739 | if (service_id == IB_CM_ASSIGN_SERVICE_ID) { |
738 | cm_id->service_id = __cpu_to_be64(cm.listen_service_id++); | 740 | cm_id->service_id = cpu_to_be64(cm.listen_service_id++); |
739 | cm_id->service_mask = ~0ULL; | 741 | cm_id->service_mask = __constant_cpu_to_be64(~0ULL); |
740 | } else { | 742 | } else { |
741 | cm_id->service_id = service_id; | 743 | cm_id->service_id = service_id; |
742 | cm_id->service_mask = service_mask; | 744 | cm_id->service_mask = service_mask; |
@@ -752,18 +754,19 @@ int ib_cm_listen(struct ib_cm_id *cm_id, | |||
752 | } | 754 | } |
753 | EXPORT_SYMBOL(ib_cm_listen); | 755 | EXPORT_SYMBOL(ib_cm_listen); |
754 | 756 | ||
755 | static u64 cm_form_tid(struct cm_id_private *cm_id_priv, | 757 | static __be64 cm_form_tid(struct cm_id_private *cm_id_priv, |
756 | enum cm_msg_sequence msg_seq) | 758 | enum cm_msg_sequence msg_seq) |
757 | { | 759 | { |
758 | u64 hi_tid, low_tid; | 760 | u64 hi_tid, low_tid; |
759 | 761 | ||
760 | hi_tid = ((u64) cm_id_priv->av.port->mad_agent->hi_tid) << 32; | 762 | hi_tid = ((u64) cm_id_priv->av.port->mad_agent->hi_tid) << 32; |
761 | low_tid = (u64) (cm_id_priv->id.local_id | (msg_seq << 30)); | 763 | low_tid = (u64) ((__force u32)cm_id_priv->id.local_id | |
764 | (msg_seq << 30)); | ||
762 | return cpu_to_be64(hi_tid | low_tid); | 765 | return cpu_to_be64(hi_tid | low_tid); |
763 | } | 766 | } |
764 | 767 | ||
765 | static void cm_format_mad_hdr(struct ib_mad_hdr *hdr, | 768 | static void cm_format_mad_hdr(struct ib_mad_hdr *hdr, |
766 | enum cm_msg_attr_id attr_id, u64 tid) | 769 | __be16 attr_id, __be64 tid) |
767 | { | 770 | { |
768 | hdr->base_version = IB_MGMT_BASE_VERSION; | 771 | hdr->base_version = IB_MGMT_BASE_VERSION; |
769 | hdr->mgmt_class = IB_MGMT_CLASS_CM; | 772 | hdr->mgmt_class = IB_MGMT_CLASS_CM; |
@@ -896,7 +899,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, | |||
896 | goto error1; | 899 | goto error1; |
897 | } | 900 | } |
898 | cm_id->service_id = param->service_id; | 901 | cm_id->service_id = param->service_id; |
899 | cm_id->service_mask = ~0ULL; | 902 | cm_id->service_mask = __constant_cpu_to_be64(~0ULL); |
900 | cm_id_priv->timeout_ms = cm_convert_to_ms( | 903 | cm_id_priv->timeout_ms = cm_convert_to_ms( |
901 | param->primary_path->packet_life_time) * 2 + | 904 | param->primary_path->packet_life_time) * 2 + |
902 | cm_convert_to_ms( | 905 | cm_convert_to_ms( |
@@ -963,7 +966,7 @@ static int cm_issue_rej(struct cm_port *port, | |||
963 | rej_msg->remote_comm_id = rcv_msg->local_comm_id; | 966 | rej_msg->remote_comm_id = rcv_msg->local_comm_id; |
964 | rej_msg->local_comm_id = rcv_msg->remote_comm_id; | 967 | rej_msg->local_comm_id = rcv_msg->remote_comm_id; |
965 | cm_rej_set_msg_rejected(rej_msg, msg_rejected); | 968 | cm_rej_set_msg_rejected(rej_msg, msg_rejected); |
966 | rej_msg->reason = reason; | 969 | rej_msg->reason = cpu_to_be16(reason); |
967 | 970 | ||
968 | if (ari && ari_length) { | 971 | if (ari && ari_length) { |
969 | cm_rej_set_reject_info_len(rej_msg, ari_length); | 972 | cm_rej_set_reject_info_len(rej_msg, ari_length); |
@@ -977,8 +980,8 @@ static int cm_issue_rej(struct cm_port *port, | |||
977 | return ret; | 980 | return ret; |
978 | } | 981 | } |
979 | 982 | ||
980 | static inline int cm_is_active_peer(u64 local_ca_guid, u64 remote_ca_guid, | 983 | static inline int cm_is_active_peer(__be64 local_ca_guid, __be64 remote_ca_guid, |
981 | u32 local_qpn, u32 remote_qpn) | 984 | __be32 local_qpn, __be32 remote_qpn) |
982 | { | 985 | { |
983 | return (be64_to_cpu(local_ca_guid) > be64_to_cpu(remote_ca_guid) || | 986 | return (be64_to_cpu(local_ca_guid) > be64_to_cpu(remote_ca_guid) || |
984 | ((local_ca_guid == remote_ca_guid) && | 987 | ((local_ca_guid == remote_ca_guid) && |
@@ -1137,7 +1140,7 @@ static void cm_format_rej(struct cm_rej_msg *rej_msg, | |||
1137 | break; | 1140 | break; |
1138 | } | 1141 | } |
1139 | 1142 | ||
1140 | rej_msg->reason = reason; | 1143 | rej_msg->reason = cpu_to_be16(reason); |
1141 | if (ari && ari_length) { | 1144 | if (ari && ari_length) { |
1142 | cm_rej_set_reject_info_len(rej_msg, ari_length); | 1145 | cm_rej_set_reject_info_len(rej_msg, ari_length); |
1143 | memcpy(rej_msg->ari, ari, ari_length); | 1146 | memcpy(rej_msg->ari, ari, ari_length); |
@@ -1276,7 +1279,7 @@ static int cm_req_handler(struct cm_work *work) | |||
1276 | cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; | 1279 | cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; |
1277 | cm_id_priv->id.context = listen_cm_id_priv->id.context; | 1280 | cm_id_priv->id.context = listen_cm_id_priv->id.context; |
1278 | cm_id_priv->id.service_id = req_msg->service_id; | 1281 | cm_id_priv->id.service_id = req_msg->service_id; |
1279 | cm_id_priv->id.service_mask = ~0ULL; | 1282 | cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL); |
1280 | 1283 | ||
1281 | cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); | 1284 | cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); |
1282 | ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); | 1285 | ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); |
@@ -1969,7 +1972,7 @@ static void cm_format_rej_event(struct cm_work *work) | |||
1969 | param = &work->cm_event.param.rej_rcvd; | 1972 | param = &work->cm_event.param.rej_rcvd; |
1970 | param->ari = rej_msg->ari; | 1973 | param->ari = rej_msg->ari; |
1971 | param->ari_length = cm_rej_get_reject_info_len(rej_msg); | 1974 | param->ari_length = cm_rej_get_reject_info_len(rej_msg); |
1972 | param->reason = rej_msg->reason; | 1975 | param->reason = __be16_to_cpu(rej_msg->reason); |
1973 | work->cm_event.private_data = &rej_msg->private_data; | 1976 | work->cm_event.private_data = &rej_msg->private_data; |
1974 | } | 1977 | } |
1975 | 1978 | ||
@@ -1978,20 +1981,20 @@ static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg) | |||
1978 | struct cm_timewait_info *timewait_info; | 1981 | struct cm_timewait_info *timewait_info; |
1979 | struct cm_id_private *cm_id_priv; | 1982 | struct cm_id_private *cm_id_priv; |
1980 | unsigned long flags; | 1983 | unsigned long flags; |
1981 | u32 remote_id; | 1984 | __be32 remote_id; |
1982 | 1985 | ||
1983 | remote_id = rej_msg->local_comm_id; | 1986 | remote_id = rej_msg->local_comm_id; |
1984 | 1987 | ||
1985 | if (rej_msg->reason == IB_CM_REJ_TIMEOUT) { | 1988 | if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_TIMEOUT) { |
1986 | spin_lock_irqsave(&cm.lock, flags); | 1989 | spin_lock_irqsave(&cm.lock, flags); |
1987 | timewait_info = cm_find_remote_id( *((u64 *) rej_msg->ari), | 1990 | timewait_info = cm_find_remote_id( *((__be64 *) rej_msg->ari), |
1988 | remote_id); | 1991 | remote_id); |
1989 | if (!timewait_info) { | 1992 | if (!timewait_info) { |
1990 | spin_unlock_irqrestore(&cm.lock, flags); | 1993 | spin_unlock_irqrestore(&cm.lock, flags); |
1991 | return NULL; | 1994 | return NULL; |
1992 | } | 1995 | } |
1993 | cm_id_priv = idr_find(&cm.local_id_table, | 1996 | cm_id_priv = idr_find(&cm.local_id_table, |
1994 | (int) timewait_info->work.local_id); | 1997 | (__force int) timewait_info->work.local_id); |
1995 | if (cm_id_priv) { | 1998 | if (cm_id_priv) { |
1996 | if (cm_id_priv->id.remote_id == remote_id) | 1999 | if (cm_id_priv->id.remote_id == remote_id) |
1997 | atomic_inc(&cm_id_priv->refcount); | 2000 | atomic_inc(&cm_id_priv->refcount); |
@@ -2032,7 +2035,7 @@ static int cm_rej_handler(struct cm_work *work) | |||
2032 | /* fall through */ | 2035 | /* fall through */ |
2033 | case IB_CM_REQ_RCVD: | 2036 | case IB_CM_REQ_RCVD: |
2034 | case IB_CM_MRA_REQ_SENT: | 2037 | case IB_CM_MRA_REQ_SENT: |
2035 | if (rej_msg->reason == IB_CM_REJ_STALE_CONN) | 2038 | if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_STALE_CONN) |
2036 | cm_enter_timewait(cm_id_priv); | 2039 | cm_enter_timewait(cm_id_priv); |
2037 | else | 2040 | else |
2038 | cm_reset_to_idle(cm_id_priv); | 2041 | cm_reset_to_idle(cm_id_priv); |
@@ -2553,7 +2556,7 @@ static void cm_format_sidr_req(struct cm_sidr_req_msg *sidr_req_msg, | |||
2553 | cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID, | 2556 | cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID, |
2554 | cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_SIDR)); | 2557 | cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_SIDR)); |
2555 | sidr_req_msg->request_id = cm_id_priv->id.local_id; | 2558 | sidr_req_msg->request_id = cm_id_priv->id.local_id; |
2556 | sidr_req_msg->pkey = param->pkey; | 2559 | sidr_req_msg->pkey = cpu_to_be16(param->pkey); |
2557 | sidr_req_msg->service_id = param->service_id; | 2560 | sidr_req_msg->service_id = param->service_id; |
2558 | 2561 | ||
2559 | if (param->private_data && param->private_data_len) | 2562 | if (param->private_data && param->private_data_len) |
@@ -2580,7 +2583,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, | |||
2580 | goto out; | 2583 | goto out; |
2581 | 2584 | ||
2582 | cm_id->service_id = param->service_id; | 2585 | cm_id->service_id = param->service_id; |
2583 | cm_id->service_mask = ~0ULL; | 2586 | cm_id->service_mask = __constant_cpu_to_be64(~0ULL); |
2584 | cm_id_priv->timeout_ms = param->timeout_ms; | 2587 | cm_id_priv->timeout_ms = param->timeout_ms; |
2585 | cm_id_priv->max_cm_retries = param->max_cm_retries; | 2588 | cm_id_priv->max_cm_retries = param->max_cm_retries; |
2586 | ret = cm_alloc_msg(cm_id_priv, &msg); | 2589 | ret = cm_alloc_msg(cm_id_priv, &msg); |
@@ -2621,7 +2624,7 @@ static void cm_format_sidr_req_event(struct cm_work *work, | |||
2621 | sidr_req_msg = (struct cm_sidr_req_msg *) | 2624 | sidr_req_msg = (struct cm_sidr_req_msg *) |
2622 | work->mad_recv_wc->recv_buf.mad; | 2625 | work->mad_recv_wc->recv_buf.mad; |
2623 | param = &work->cm_event.param.sidr_req_rcvd; | 2626 | param = &work->cm_event.param.sidr_req_rcvd; |
2624 | param->pkey = sidr_req_msg->pkey; | 2627 | param->pkey = __be16_to_cpu(sidr_req_msg->pkey); |
2625 | param->listen_id = listen_id; | 2628 | param->listen_id = listen_id; |
2626 | param->device = work->port->mad_agent->device; | 2629 | param->device = work->port->mad_agent->device; |
2627 | param->port = work->port->port_num; | 2630 | param->port = work->port->port_num; |
@@ -2645,7 +2648,7 @@ static int cm_sidr_req_handler(struct cm_work *work) | |||
2645 | sidr_req_msg = (struct cm_sidr_req_msg *) | 2648 | sidr_req_msg = (struct cm_sidr_req_msg *) |
2646 | work->mad_recv_wc->recv_buf.mad; | 2649 | work->mad_recv_wc->recv_buf.mad; |
2647 | wc = work->mad_recv_wc->wc; | 2650 | wc = work->mad_recv_wc->wc; |
2648 | cm_id_priv->av.dgid.global.subnet_prefix = wc->slid; | 2651 | cm_id_priv->av.dgid.global.subnet_prefix = cpu_to_be64(wc->slid); |
2649 | cm_id_priv->av.dgid.global.interface_id = 0; | 2652 | cm_id_priv->av.dgid.global.interface_id = 0; |
2650 | cm_init_av_for_response(work->port, work->mad_recv_wc->wc, | 2653 | cm_init_av_for_response(work->port, work->mad_recv_wc->wc, |
2651 | &cm_id_priv->av); | 2654 | &cm_id_priv->av); |
@@ -2673,7 +2676,7 @@ static int cm_sidr_req_handler(struct cm_work *work) | |||
2673 | cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler; | 2676 | cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler; |
2674 | cm_id_priv->id.context = cur_cm_id_priv->id.context; | 2677 | cm_id_priv->id.context = cur_cm_id_priv->id.context; |
2675 | cm_id_priv->id.service_id = sidr_req_msg->service_id; | 2678 | cm_id_priv->id.service_id = sidr_req_msg->service_id; |
2676 | cm_id_priv->id.service_mask = ~0ULL; | 2679 | cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL); |
2677 | 2680 | ||
2678 | cm_format_sidr_req_event(work, &cur_cm_id_priv->id); | 2681 | cm_format_sidr_req_event(work, &cur_cm_id_priv->id); |
2679 | cm_process_work(cm_id_priv, work); | 2682 | cm_process_work(cm_id_priv, work); |
@@ -3175,10 +3178,10 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id, | |||
3175 | } | 3178 | } |
3176 | EXPORT_SYMBOL(ib_cm_init_qp_attr); | 3179 | EXPORT_SYMBOL(ib_cm_init_qp_attr); |
3177 | 3180 | ||
3178 | static u64 cm_get_ca_guid(struct ib_device *device) | 3181 | static __be64 cm_get_ca_guid(struct ib_device *device) |
3179 | { | 3182 | { |
3180 | struct ib_device_attr *device_attr; | 3183 | struct ib_device_attr *device_attr; |
3181 | u64 guid; | 3184 | __be64 guid; |
3182 | int ret; | 3185 | int ret; |
3183 | 3186 | ||
3184 | device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); | 3187 | device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); |
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h index 15a309a77b2b..813ab70bf6d5 100644 --- a/drivers/infiniband/core/cm_msgs.h +++ b/drivers/infiniband/core/cm_msgs.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #if !defined(CM_MSGS_H) | 34 | #if !defined(CM_MSGS_H) |
35 | #define CM_MSGS_H | 35 | #define CM_MSGS_H |
36 | 36 | ||
37 | #include <ib_mad.h> | 37 | #include <rdma/ib_mad.h> |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Parameters to routines below should be in network-byte order, and values | 40 | * Parameters to routines below should be in network-byte order, and values |
@@ -43,19 +43,17 @@ | |||
43 | 43 | ||
44 | #define IB_CM_CLASS_VERSION 2 /* IB specification 1.2 */ | 44 | #define IB_CM_CLASS_VERSION 2 /* IB specification 1.2 */ |
45 | 45 | ||
46 | enum cm_msg_attr_id { | 46 | #define CM_REQ_ATTR_ID __constant_htons(0x0010) |
47 | CM_REQ_ATTR_ID = __constant_htons(0x0010), | 47 | #define CM_MRA_ATTR_ID __constant_htons(0x0011) |
48 | CM_MRA_ATTR_ID = __constant_htons(0x0011), | 48 | #define CM_REJ_ATTR_ID __constant_htons(0x0012) |
49 | CM_REJ_ATTR_ID = __constant_htons(0x0012), | 49 | #define CM_REP_ATTR_ID __constant_htons(0x0013) |
50 | CM_REP_ATTR_ID = __constant_htons(0x0013), | 50 | #define CM_RTU_ATTR_ID __constant_htons(0x0014) |
51 | CM_RTU_ATTR_ID = __constant_htons(0x0014), | 51 | #define CM_DREQ_ATTR_ID __constant_htons(0x0015) |
52 | CM_DREQ_ATTR_ID = __constant_htons(0x0015), | 52 | #define CM_DREP_ATTR_ID __constant_htons(0x0016) |
53 | CM_DREP_ATTR_ID = __constant_htons(0x0016), | 53 | #define CM_SIDR_REQ_ATTR_ID __constant_htons(0x0017) |
54 | CM_SIDR_REQ_ATTR_ID = __constant_htons(0x0017), | 54 | #define CM_SIDR_REP_ATTR_ID __constant_htons(0x0018) |
55 | CM_SIDR_REP_ATTR_ID = __constant_htons(0x0018), | 55 | #define CM_LAP_ATTR_ID __constant_htons(0x0019) |
56 | CM_LAP_ATTR_ID = __constant_htons(0x0019), | 56 | #define CM_APR_ATTR_ID __constant_htons(0x001A) |
57 | CM_APR_ATTR_ID = __constant_htons(0x001A) | ||
58 | }; | ||
59 | 57 | ||
60 | enum cm_msg_sequence { | 58 | enum cm_msg_sequence { |
61 | CM_MSG_SEQUENCE_REQ, | 59 | CM_MSG_SEQUENCE_REQ, |
@@ -67,35 +65,35 @@ enum cm_msg_sequence { | |||
67 | struct cm_req_msg { | 65 | struct cm_req_msg { |
68 | struct ib_mad_hdr hdr; | 66 | struct ib_mad_hdr hdr; |
69 | 67 | ||
70 | u32 local_comm_id; | 68 | __be32 local_comm_id; |
71 | u32 rsvd4; | 69 | __be32 rsvd4; |
72 | u64 service_id; | 70 | __be64 service_id; |
73 | u64 local_ca_guid; | 71 | __be64 local_ca_guid; |
74 | u32 rsvd24; | 72 | __be32 rsvd24; |
75 | u32 local_qkey; | 73 | __be32 local_qkey; |
76 | /* local QPN:24, responder resources:8 */ | 74 | /* local QPN:24, responder resources:8 */ |
77 | u32 offset32; | 75 | __be32 offset32; |
78 | /* local EECN:24, initiator depth:8 */ | 76 | /* local EECN:24, initiator depth:8 */ |
79 | u32 offset36; | 77 | __be32 offset36; |
80 | /* | 78 | /* |
81 | * remote EECN:24, remote CM response timeout:5, | 79 | * remote EECN:24, remote CM response timeout:5, |
82 | * transport service type:2, end-to-end flow control:1 | 80 | * transport service type:2, end-to-end flow control:1 |
83 | */ | 81 | */ |
84 | u32 offset40; | 82 | __be32 offset40; |
85 | /* starting PSN:24, local CM response timeout:5, retry count:3 */ | 83 | /* starting PSN:24, local CM response timeout:5, retry count:3 */ |
86 | u32 offset44; | 84 | __be32 offset44; |
87 | u16 pkey; | 85 | __be16 pkey; |
88 | /* path MTU:4, RDC exists:1, RNR retry count:3. */ | 86 | /* path MTU:4, RDC exists:1, RNR retry count:3. */ |
89 | u8 offset50; | 87 | u8 offset50; |
90 | /* max CM Retries:4, SRQ:1, rsvd:3 */ | 88 | /* max CM Retries:4, SRQ:1, rsvd:3 */ |
91 | u8 offset51; | 89 | u8 offset51; |
92 | 90 | ||
93 | u16 primary_local_lid; | 91 | __be16 primary_local_lid; |
94 | u16 primary_remote_lid; | 92 | __be16 primary_remote_lid; |
95 | union ib_gid primary_local_gid; | 93 | union ib_gid primary_local_gid; |
96 | union ib_gid primary_remote_gid; | 94 | union ib_gid primary_remote_gid; |
97 | /* flow label:20, rsvd:6, packet rate:6 */ | 95 | /* flow label:20, rsvd:6, packet rate:6 */ |
98 | u32 primary_offset88; | 96 | __be32 primary_offset88; |
99 | u8 primary_traffic_class; | 97 | u8 primary_traffic_class; |
100 | u8 primary_hop_limit; | 98 | u8 primary_hop_limit; |
101 | /* SL:4, subnet local:1, rsvd:3 */ | 99 | /* SL:4, subnet local:1, rsvd:3 */ |
@@ -103,12 +101,12 @@ struct cm_req_msg { | |||
103 | /* local ACK timeout:5, rsvd:3 */ | 101 | /* local ACK timeout:5, rsvd:3 */ |
104 | u8 primary_offset95; | 102 | u8 primary_offset95; |
105 | 103 | ||
106 | u16 alt_local_lid; | 104 | __be16 alt_local_lid; |
107 | u16 alt_remote_lid; | 105 | __be16 alt_remote_lid; |
108 | union ib_gid alt_local_gid; | 106 | union ib_gid alt_local_gid; |
109 | union ib_gid alt_remote_gid; | 107 | union ib_gid alt_remote_gid; |
110 | /* flow label:20, rsvd:6, packet rate:6 */ | 108 | /* flow label:20, rsvd:6, packet rate:6 */ |
111 | u32 alt_offset132; | 109 | __be32 alt_offset132; |
112 | u8 alt_traffic_class; | 110 | u8 alt_traffic_class; |
113 | u8 alt_hop_limit; | 111 | u8 alt_hop_limit; |
114 | /* SL:4, subnet local:1, rsvd:3 */ | 112 | /* SL:4, subnet local:1, rsvd:3 */ |
@@ -120,12 +118,12 @@ struct cm_req_msg { | |||
120 | 118 | ||
121 | } __attribute__ ((packed)); | 119 | } __attribute__ ((packed)); |
122 | 120 | ||
123 | static inline u32 cm_req_get_local_qpn(struct cm_req_msg *req_msg) | 121 | static inline __be32 cm_req_get_local_qpn(struct cm_req_msg *req_msg) |
124 | { | 122 | { |
125 | return cpu_to_be32(be32_to_cpu(req_msg->offset32) >> 8); | 123 | return cpu_to_be32(be32_to_cpu(req_msg->offset32) >> 8); |
126 | } | 124 | } |
127 | 125 | ||
128 | static inline void cm_req_set_local_qpn(struct cm_req_msg *req_msg, u32 qpn) | 126 | static inline void cm_req_set_local_qpn(struct cm_req_msg *req_msg, __be32 qpn) |
129 | { | 127 | { |
130 | req_msg->offset32 = cpu_to_be32((be32_to_cpu(qpn) << 8) | | 128 | req_msg->offset32 = cpu_to_be32((be32_to_cpu(qpn) << 8) | |
131 | (be32_to_cpu(req_msg->offset32) & | 129 | (be32_to_cpu(req_msg->offset32) & |
@@ -208,13 +206,13 @@ static inline void cm_req_set_flow_ctrl(struct cm_req_msg *req_msg, | |||
208 | 0xFFFFFFFE)); | 206 | 0xFFFFFFFE)); |
209 | } | 207 | } |
210 | 208 | ||
211 | static inline u32 cm_req_get_starting_psn(struct cm_req_msg *req_msg) | 209 | static inline __be32 cm_req_get_starting_psn(struct cm_req_msg *req_msg) |
212 | { | 210 | { |
213 | return cpu_to_be32(be32_to_cpu(req_msg->offset44) >> 8); | 211 | return cpu_to_be32(be32_to_cpu(req_msg->offset44) >> 8); |
214 | } | 212 | } |
215 | 213 | ||
216 | static inline void cm_req_set_starting_psn(struct cm_req_msg *req_msg, | 214 | static inline void cm_req_set_starting_psn(struct cm_req_msg *req_msg, |
217 | u32 starting_psn) | 215 | __be32 starting_psn) |
218 | { | 216 | { |
219 | req_msg->offset44 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) | | 217 | req_msg->offset44 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) | |
220 | (be32_to_cpu(req_msg->offset44) & 0x000000FF)); | 218 | (be32_to_cpu(req_msg->offset44) & 0x000000FF)); |
@@ -288,13 +286,13 @@ static inline void cm_req_set_srq(struct cm_req_msg *req_msg, u8 srq) | |||
288 | ((srq & 0x1) << 3)); | 286 | ((srq & 0x1) << 3)); |
289 | } | 287 | } |
290 | 288 | ||
291 | static inline u32 cm_req_get_primary_flow_label(struct cm_req_msg *req_msg) | 289 | static inline __be32 cm_req_get_primary_flow_label(struct cm_req_msg *req_msg) |
292 | { | 290 | { |
293 | return cpu_to_be32((be32_to_cpu(req_msg->primary_offset88) >> 12)); | 291 | return cpu_to_be32(be32_to_cpu(req_msg->primary_offset88) >> 12); |
294 | } | 292 | } |
295 | 293 | ||
296 | static inline void cm_req_set_primary_flow_label(struct cm_req_msg *req_msg, | 294 | static inline void cm_req_set_primary_flow_label(struct cm_req_msg *req_msg, |
297 | u32 flow_label) | 295 | __be32 flow_label) |
298 | { | 296 | { |
299 | req_msg->primary_offset88 = cpu_to_be32( | 297 | req_msg->primary_offset88 = cpu_to_be32( |
300 | (be32_to_cpu(req_msg->primary_offset88) & | 298 | (be32_to_cpu(req_msg->primary_offset88) & |
@@ -350,13 +348,13 @@ static inline void cm_req_set_primary_local_ack_timeout(struct cm_req_msg *req_m | |||
350 | (local_ack_timeout << 3)); | 348 | (local_ack_timeout << 3)); |
351 | } | 349 | } |
352 | 350 | ||
353 | static inline u32 cm_req_get_alt_flow_label(struct cm_req_msg *req_msg) | 351 | static inline __be32 cm_req_get_alt_flow_label(struct cm_req_msg *req_msg) |
354 | { | 352 | { |
355 | return cpu_to_be32((be32_to_cpu(req_msg->alt_offset132) >> 12)); | 353 | return cpu_to_be32(be32_to_cpu(req_msg->alt_offset132) >> 12); |
356 | } | 354 | } |
357 | 355 | ||
358 | static inline void cm_req_set_alt_flow_label(struct cm_req_msg *req_msg, | 356 | static inline void cm_req_set_alt_flow_label(struct cm_req_msg *req_msg, |
359 | u32 flow_label) | 357 | __be32 flow_label) |
360 | { | 358 | { |
361 | req_msg->alt_offset132 = cpu_to_be32( | 359 | req_msg->alt_offset132 = cpu_to_be32( |
362 | (be32_to_cpu(req_msg->alt_offset132) & | 360 | (be32_to_cpu(req_msg->alt_offset132) & |
@@ -422,8 +420,8 @@ enum cm_msg_response { | |||
422 | struct cm_mra_msg { | 420 | struct cm_mra_msg { |
423 | struct ib_mad_hdr hdr; | 421 | struct ib_mad_hdr hdr; |
424 | 422 | ||
425 | u32 local_comm_id; | 423 | __be32 local_comm_id; |
426 | u32 remote_comm_id; | 424 | __be32 remote_comm_id; |
427 | /* message MRAed:2, rsvd:6 */ | 425 | /* message MRAed:2, rsvd:6 */ |
428 | u8 offset8; | 426 | u8 offset8; |
429 | /* service timeout:5, rsvd:3 */ | 427 | /* service timeout:5, rsvd:3 */ |
@@ -458,13 +456,13 @@ static inline void cm_mra_set_service_timeout(struct cm_mra_msg *mra_msg, | |||
458 | struct cm_rej_msg { | 456 | struct cm_rej_msg { |
459 | struct ib_mad_hdr hdr; | 457 | struct ib_mad_hdr hdr; |
460 | 458 | ||
461 | u32 local_comm_id; | 459 | __be32 local_comm_id; |
462 | u32 remote_comm_id; | 460 | __be32 remote_comm_id; |
463 | /* message REJected:2, rsvd:6 */ | 461 | /* message REJected:2, rsvd:6 */ |
464 | u8 offset8; | 462 | u8 offset8; |
465 | /* reject info length:7, rsvd:1. */ | 463 | /* reject info length:7, rsvd:1. */ |
466 | u8 offset9; | 464 | u8 offset9; |
467 | u16 reason; | 465 | __be16 reason; |
468 | u8 ari[IB_CM_REJ_ARI_LENGTH]; | 466 | u8 ari[IB_CM_REJ_ARI_LENGTH]; |
469 | 467 | ||
470 | u8 private_data[IB_CM_REJ_PRIVATE_DATA_SIZE]; | 468 | u8 private_data[IB_CM_REJ_PRIVATE_DATA_SIZE]; |
@@ -495,45 +493,45 @@ static inline void cm_rej_set_reject_info_len(struct cm_rej_msg *rej_msg, | |||
495 | struct cm_rep_msg { | 493 | struct cm_rep_msg { |
496 | struct ib_mad_hdr hdr; | 494 | struct ib_mad_hdr hdr; |
497 | 495 | ||
498 | u32 local_comm_id; | 496 | __be32 local_comm_id; |
499 | u32 remote_comm_id; | 497 | __be32 remote_comm_id; |
500 | u32 local_qkey; | 498 | __be32 local_qkey; |
501 | /* local QPN:24, rsvd:8 */ | 499 | /* local QPN:24, rsvd:8 */ |
502 | u32 offset12; | 500 | __be32 offset12; |
503 | /* local EECN:24, rsvd:8 */ | 501 | /* local EECN:24, rsvd:8 */ |
504 | u32 offset16; | 502 | __be32 offset16; |
505 | /* starting PSN:24 rsvd:8 */ | 503 | /* starting PSN:24 rsvd:8 */ |
506 | u32 offset20; | 504 | __be32 offset20; |
507 | u8 resp_resources; | 505 | u8 resp_resources; |
508 | u8 initiator_depth; | 506 | u8 initiator_depth; |
509 | /* target ACK delay:5, failover accepted:2, end-to-end flow control:1 */ | 507 | /* target ACK delay:5, failover accepted:2, end-to-end flow control:1 */ |
510 | u8 offset26; | 508 | u8 offset26; |
511 | /* RNR retry count:3, SRQ:1, rsvd:5 */ | 509 | /* RNR retry count:3, SRQ:1, rsvd:5 */ |
512 | u8 offset27; | 510 | u8 offset27; |
513 | u64 local_ca_guid; | 511 | __be64 local_ca_guid; |
514 | 512 | ||
515 | u8 private_data[IB_CM_REP_PRIVATE_DATA_SIZE]; | 513 | u8 private_data[IB_CM_REP_PRIVATE_DATA_SIZE]; |
516 | 514 | ||
517 | } __attribute__ ((packed)); | 515 | } __attribute__ ((packed)); |
518 | 516 | ||
519 | static inline u32 cm_rep_get_local_qpn(struct cm_rep_msg *rep_msg) | 517 | static inline __be32 cm_rep_get_local_qpn(struct cm_rep_msg *rep_msg) |
520 | { | 518 | { |
521 | return cpu_to_be32(be32_to_cpu(rep_msg->offset12) >> 8); | 519 | return cpu_to_be32(be32_to_cpu(rep_msg->offset12) >> 8); |
522 | } | 520 | } |
523 | 521 | ||
524 | static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, u32 qpn) | 522 | static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, __be32 qpn) |
525 | { | 523 | { |
526 | rep_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) | | 524 | rep_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) | |
527 | (be32_to_cpu(rep_msg->offset12) & 0x000000FF)); | 525 | (be32_to_cpu(rep_msg->offset12) & 0x000000FF)); |
528 | } | 526 | } |
529 | 527 | ||
530 | static inline u32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg) | 528 | static inline __be32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg) |
531 | { | 529 | { |
532 | return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8); | 530 | return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8); |
533 | } | 531 | } |
534 | 532 | ||
535 | static inline void cm_rep_set_starting_psn(struct cm_rep_msg *rep_msg, | 533 | static inline void cm_rep_set_starting_psn(struct cm_rep_msg *rep_msg, |
536 | u32 starting_psn) | 534 | __be32 starting_psn) |
537 | { | 535 | { |
538 | rep_msg->offset20 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) | | 536 | rep_msg->offset20 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) | |
539 | (be32_to_cpu(rep_msg->offset20) & 0x000000FF)); | 537 | (be32_to_cpu(rep_msg->offset20) & 0x000000FF)); |
@@ -600,8 +598,8 @@ static inline void cm_rep_set_srq(struct cm_rep_msg *rep_msg, u8 srq) | |||
600 | struct cm_rtu_msg { | 598 | struct cm_rtu_msg { |
601 | struct ib_mad_hdr hdr; | 599 | struct ib_mad_hdr hdr; |
602 | 600 | ||
603 | u32 local_comm_id; | 601 | __be32 local_comm_id; |
604 | u32 remote_comm_id; | 602 | __be32 remote_comm_id; |
605 | 603 | ||
606 | u8 private_data[IB_CM_RTU_PRIVATE_DATA_SIZE]; | 604 | u8 private_data[IB_CM_RTU_PRIVATE_DATA_SIZE]; |
607 | 605 | ||
@@ -610,21 +608,21 @@ struct cm_rtu_msg { | |||
610 | struct cm_dreq_msg { | 608 | struct cm_dreq_msg { |
611 | struct ib_mad_hdr hdr; | 609 | struct ib_mad_hdr hdr; |
612 | 610 | ||
613 | u32 local_comm_id; | 611 | __be32 local_comm_id; |
614 | u32 remote_comm_id; | 612 | __be32 remote_comm_id; |
615 | /* remote QPN/EECN:24, rsvd:8 */ | 613 | /* remote QPN/EECN:24, rsvd:8 */ |
616 | u32 offset8; | 614 | __be32 offset8; |
617 | 615 | ||
618 | u8 private_data[IB_CM_DREQ_PRIVATE_DATA_SIZE]; | 616 | u8 private_data[IB_CM_DREQ_PRIVATE_DATA_SIZE]; |
619 | 617 | ||
620 | } __attribute__ ((packed)); | 618 | } __attribute__ ((packed)); |
621 | 619 | ||
622 | static inline u32 cm_dreq_get_remote_qpn(struct cm_dreq_msg *dreq_msg) | 620 | static inline __be32 cm_dreq_get_remote_qpn(struct cm_dreq_msg *dreq_msg) |
623 | { | 621 | { |
624 | return cpu_to_be32(be32_to_cpu(dreq_msg->offset8) >> 8); | 622 | return cpu_to_be32(be32_to_cpu(dreq_msg->offset8) >> 8); |
625 | } | 623 | } |
626 | 624 | ||
627 | static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, u32 qpn) | 625 | static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, __be32 qpn) |
628 | { | 626 | { |
629 | dreq_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) | | 627 | dreq_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) | |
630 | (be32_to_cpu(dreq_msg->offset8) & 0x000000FF)); | 628 | (be32_to_cpu(dreq_msg->offset8) & 0x000000FF)); |
@@ -633,8 +631,8 @@ static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, u32 qpn) | |||
633 | struct cm_drep_msg { | 631 | struct cm_drep_msg { |
634 | struct ib_mad_hdr hdr; | 632 | struct ib_mad_hdr hdr; |
635 | 633 | ||
636 | u32 local_comm_id; | 634 | __be32 local_comm_id; |
637 | u32 remote_comm_id; | 635 | __be32 remote_comm_id; |
638 | 636 | ||
639 | u8 private_data[IB_CM_DREP_PRIVATE_DATA_SIZE]; | 637 | u8 private_data[IB_CM_DREP_PRIVATE_DATA_SIZE]; |
640 | 638 | ||
@@ -643,37 +641,37 @@ struct cm_drep_msg { | |||
643 | struct cm_lap_msg { | 641 | struct cm_lap_msg { |
644 | struct ib_mad_hdr hdr; | 642 | struct ib_mad_hdr hdr; |
645 | 643 | ||
646 | u32 local_comm_id; | 644 | __be32 local_comm_id; |
647 | u32 remote_comm_id; | 645 | __be32 remote_comm_id; |
648 | 646 | ||
649 | u32 rsvd8; | 647 | __be32 rsvd8; |
650 | /* remote QPN/EECN:24, remote CM response timeout:5, rsvd:3 */ | 648 | /* remote QPN/EECN:24, remote CM response timeout:5, rsvd:3 */ |
651 | u32 offset12; | 649 | __be32 offset12; |
652 | u32 rsvd16; | 650 | __be32 rsvd16; |
653 | 651 | ||
654 | u16 alt_local_lid; | 652 | __be16 alt_local_lid; |
655 | u16 alt_remote_lid; | 653 | __be16 alt_remote_lid; |
656 | union ib_gid alt_local_gid; | 654 | union ib_gid alt_local_gid; |
657 | union ib_gid alt_remote_gid; | 655 | union ib_gid alt_remote_gid; |
658 | /* flow label:20, rsvd:4, traffic class:8 */ | 656 | /* flow label:20, rsvd:4, traffic class:8 */ |
659 | u32 offset56; | 657 | __be32 offset56; |
660 | u8 alt_hop_limit; | 658 | u8 alt_hop_limit; |
661 | /* rsvd:2, packet rate:6 */ | 659 | /* rsvd:2, packet rate:6 */ |
662 | uint8_t offset61; | 660 | u8 offset61; |
663 | /* SL:4, subnet local:1, rsvd:3 */ | 661 | /* SL:4, subnet local:1, rsvd:3 */ |
664 | uint8_t offset62; | 662 | u8 offset62; |
665 | /* local ACK timeout:5, rsvd:3 */ | 663 | /* local ACK timeout:5, rsvd:3 */ |
666 | uint8_t offset63; | 664 | u8 offset63; |
667 | 665 | ||
668 | u8 private_data[IB_CM_LAP_PRIVATE_DATA_SIZE]; | 666 | u8 private_data[IB_CM_LAP_PRIVATE_DATA_SIZE]; |
669 | } __attribute__ ((packed)); | 667 | } __attribute__ ((packed)); |
670 | 668 | ||
671 | static inline u32 cm_lap_get_remote_qpn(struct cm_lap_msg *lap_msg) | 669 | static inline __be32 cm_lap_get_remote_qpn(struct cm_lap_msg *lap_msg) |
672 | { | 670 | { |
673 | return cpu_to_be32(be32_to_cpu(lap_msg->offset12) >> 8); | 671 | return cpu_to_be32(be32_to_cpu(lap_msg->offset12) >> 8); |
674 | } | 672 | } |
675 | 673 | ||
676 | static inline void cm_lap_set_remote_qpn(struct cm_lap_msg *lap_msg, u32 qpn) | 674 | static inline void cm_lap_set_remote_qpn(struct cm_lap_msg *lap_msg, __be32 qpn) |
677 | { | 675 | { |
678 | lap_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) | | 676 | lap_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) | |
679 | (be32_to_cpu(lap_msg->offset12) & | 677 | (be32_to_cpu(lap_msg->offset12) & |
@@ -693,17 +691,17 @@ static inline void cm_lap_set_remote_resp_timeout(struct cm_lap_msg *lap_msg, | |||
693 | 0xFFFFFF07)); | 691 | 0xFFFFFF07)); |
694 | } | 692 | } |
695 | 693 | ||
696 | static inline u32 cm_lap_get_flow_label(struct cm_lap_msg *lap_msg) | 694 | static inline __be32 cm_lap_get_flow_label(struct cm_lap_msg *lap_msg) |
697 | { | 695 | { |
698 | return be32_to_cpu(lap_msg->offset56) >> 12; | 696 | return cpu_to_be32(be32_to_cpu(lap_msg->offset56) >> 12); |
699 | } | 697 | } |
700 | 698 | ||
701 | static inline void cm_lap_set_flow_label(struct cm_lap_msg *lap_msg, | 699 | static inline void cm_lap_set_flow_label(struct cm_lap_msg *lap_msg, |
702 | u32 flow_label) | 700 | __be32 flow_label) |
703 | { | 701 | { |
704 | lap_msg->offset56 = cpu_to_be32((flow_label << 12) | | 702 | lap_msg->offset56 = cpu_to_be32( |
705 | (be32_to_cpu(lap_msg->offset56) & | 703 | (be32_to_cpu(lap_msg->offset56) & 0x00000FFF) | |
706 | 0x00000FFF)); | 704 | (be32_to_cpu(flow_label) << 12)); |
707 | } | 705 | } |
708 | 706 | ||
709 | static inline u8 cm_lap_get_traffic_class(struct cm_lap_msg *lap_msg) | 707 | static inline u8 cm_lap_get_traffic_class(struct cm_lap_msg *lap_msg) |
@@ -766,8 +764,8 @@ static inline void cm_lap_set_local_ack_timeout(struct cm_lap_msg *lap_msg, | |||
766 | struct cm_apr_msg { | 764 | struct cm_apr_msg { |
767 | struct ib_mad_hdr hdr; | 765 | struct ib_mad_hdr hdr; |
768 | 766 | ||
769 | u32 local_comm_id; | 767 | __be32 local_comm_id; |
770 | u32 remote_comm_id; | 768 | __be32 remote_comm_id; |
771 | 769 | ||
772 | u8 info_length; | 770 | u8 info_length; |
773 | u8 ap_status; | 771 | u8 ap_status; |
@@ -779,10 +777,10 @@ struct cm_apr_msg { | |||
779 | struct cm_sidr_req_msg { | 777 | struct cm_sidr_req_msg { |
780 | struct ib_mad_hdr hdr; | 778 | struct ib_mad_hdr hdr; |
781 | 779 | ||
782 | u32 request_id; | 780 | __be32 request_id; |
783 | u16 pkey; | 781 | __be16 pkey; |
784 | u16 rsvd; | 782 | __be16 rsvd; |
785 | u64 service_id; | 783 | __be64 service_id; |
786 | 784 | ||
787 | u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE]; | 785 | u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE]; |
788 | } __attribute__ ((packed)); | 786 | } __attribute__ ((packed)); |
@@ -790,26 +788,26 @@ struct cm_sidr_req_msg { | |||
790 | struct cm_sidr_rep_msg { | 788 | struct cm_sidr_rep_msg { |
791 | struct ib_mad_hdr hdr; | 789 | struct ib_mad_hdr hdr; |
792 | 790 | ||
793 | u32 request_id; | 791 | __be32 request_id; |
794 | u8 status; | 792 | u8 status; |
795 | u8 info_length; | 793 | u8 info_length; |
796 | u16 rsvd; | 794 | __be16 rsvd; |
797 | /* QPN:24, rsvd:8 */ | 795 | /* QPN:24, rsvd:8 */ |
798 | u32 offset8; | 796 | __be32 offset8; |
799 | u64 service_id; | 797 | __be64 service_id; |
800 | u32 qkey; | 798 | __be32 qkey; |
801 | u8 info[IB_CM_SIDR_REP_INFO_LENGTH]; | 799 | u8 info[IB_CM_SIDR_REP_INFO_LENGTH]; |
802 | 800 | ||
803 | u8 private_data[IB_CM_SIDR_REP_PRIVATE_DATA_SIZE]; | 801 | u8 private_data[IB_CM_SIDR_REP_PRIVATE_DATA_SIZE]; |
804 | } __attribute__ ((packed)); | 802 | } __attribute__ ((packed)); |
805 | 803 | ||
806 | static inline u32 cm_sidr_rep_get_qpn(struct cm_sidr_rep_msg *sidr_rep_msg) | 804 | static inline __be32 cm_sidr_rep_get_qpn(struct cm_sidr_rep_msg *sidr_rep_msg) |
807 | { | 805 | { |
808 | return cpu_to_be32(be32_to_cpu(sidr_rep_msg->offset8) >> 8); | 806 | return cpu_to_be32(be32_to_cpu(sidr_rep_msg->offset8) >> 8); |
809 | } | 807 | } |
810 | 808 | ||
811 | static inline void cm_sidr_rep_set_qpn(struct cm_sidr_rep_msg *sidr_rep_msg, | 809 | static inline void cm_sidr_rep_set_qpn(struct cm_sidr_rep_msg *sidr_rep_msg, |
812 | u32 qpn) | 810 | __be32 qpn) |
813 | { | 811 | { |
814 | sidr_rep_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) | | 812 | sidr_rep_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) | |
815 | (be32_to_cpu(sidr_rep_msg->offset8) & | 813 | (be32_to_cpu(sidr_rep_msg->offset8) & |
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 797049626ff6..7ad47a4b166b 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/list.h> | 38 | #include <linux/list.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | 40 | ||
41 | #include <ib_verbs.h> | 41 | #include <rdma/ib_verbs.h> |
42 | 42 | ||
43 | int ib_device_register_sysfs(struct ib_device *device); | 43 | int ib_device_register_sysfs(struct ib_device *device); |
44 | void ib_device_unregister_sysfs(struct ib_device *device); | 44 | void ib_device_unregister_sysfs(struct ib_device *device); |
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 9197e92d708a..d3cf84e01587 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.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 Sun Microsystems, Inc. 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/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index 7763b31abba7..d34a6f1c4f4c 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/jhash.h> | 39 | #include <linux/jhash.h> |
40 | #include <linux/kthread.h> | 40 | #include <linux/kthread.h> |
41 | 41 | ||
42 | #include <ib_fmr_pool.h> | 42 | #include <rdma/ib_fmr_pool.h> |
43 | 43 | ||
44 | #include "core_priv.h" | 44 | #include "core_priv.h" |
45 | 45 | ||
@@ -334,6 +334,7 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) | |||
334 | { | 334 | { |
335 | struct ib_pool_fmr *fmr; | 335 | struct ib_pool_fmr *fmr; |
336 | struct ib_pool_fmr *tmp; | 336 | struct ib_pool_fmr *tmp; |
337 | LIST_HEAD(fmr_list); | ||
337 | int i; | 338 | int i; |
338 | 339 | ||
339 | kthread_stop(pool->thread); | 340 | kthread_stop(pool->thread); |
@@ -341,6 +342,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) | |||
341 | 342 | ||
342 | i = 0; | 343 | i = 0; |
343 | list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { | 344 | list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { |
345 | if (fmr->remap_count) { | ||
346 | INIT_LIST_HEAD(&fmr_list); | ||
347 | list_add_tail(&fmr->fmr->list, &fmr_list); | ||
348 | ib_unmap_fmr(&fmr_list); | ||
349 | } | ||
344 | ib_dealloc_fmr(fmr->fmr); | 350 | ib_dealloc_fmr(fmr->fmr); |
345 | list_del(&fmr->list); | 351 | list_del(&fmr->list); |
346 | kfree(fmr); | 352 | kfree(fmr); |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index b97e210ce9c8..a4a4d9c1eef3 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -693,7 +693,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
693 | goto out; | 693 | goto out; |
694 | } | 694 | } |
695 | 695 | ||
696 | build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index, | 696 | build_smp_wc(send_wr->wr_id, be16_to_cpu(smp->dr_slid), |
697 | send_wr->wr.ud.pkey_index, | ||
697 | send_wr->wr.ud.port_num, &mad_wc); | 698 | send_wr->wr.ud.port_num, &mad_wc); |
698 | 699 | ||
699 | /* No GRH for DR SMP */ | 700 | /* No GRH for DR SMP */ |
@@ -1554,7 +1555,7 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv, | |||
1554 | } | 1555 | } |
1555 | 1556 | ||
1556 | struct ib_mad_send_wr_private* | 1557 | struct ib_mad_send_wr_private* |
1557 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid) | 1558 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid) |
1558 | { | 1559 | { |
1559 | struct ib_mad_send_wr_private *mad_send_wr; | 1560 | struct ib_mad_send_wr_private *mad_send_wr; |
1560 | 1561 | ||
@@ -1597,7 +1598,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, | |||
1597 | struct ib_mad_send_wr_private *mad_send_wr; | 1598 | struct ib_mad_send_wr_private *mad_send_wr; |
1598 | struct ib_mad_send_wc mad_send_wc; | 1599 | struct ib_mad_send_wc mad_send_wc; |
1599 | unsigned long flags; | 1600 | unsigned long flags; |
1600 | u64 tid; | 1601 | __be64 tid; |
1601 | 1602 | ||
1602 | INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); | 1603 | INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); |
1603 | list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); | 1604 | list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); |
@@ -2165,7 +2166,8 @@ static void local_completions(void *data) | |||
2165 | * Defined behavior is to complete response | 2166 | * Defined behavior is to complete response |
2166 | * before request | 2167 | * before request |
2167 | */ | 2168 | */ |
2168 | build_smp_wc(local->wr_id, IB_LID_PERMISSIVE, | 2169 | build_smp_wc(local->wr_id, |
2170 | be16_to_cpu(IB_LID_PERMISSIVE), | ||
2169 | 0 /* pkey index */, | 2171 | 0 /* pkey index */, |
2170 | recv_mad_agent->agent.port_num, &wc); | 2172 | recv_mad_agent->agent.port_num, &wc); |
2171 | 2173 | ||
@@ -2294,7 +2296,7 @@ static void timeout_sends(void *data) | |||
2294 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 2296 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
2295 | } | 2297 | } |
2296 | 2298 | ||
2297 | static void ib_mad_thread_completion_handler(struct ib_cq *cq) | 2299 | static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg) |
2298 | { | 2300 | { |
2299 | struct ib_mad_port_private *port_priv = cq->cq_context; | 2301 | struct ib_mad_port_private *port_priv = cq->cq_context; |
2300 | 2302 | ||
@@ -2574,8 +2576,7 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2574 | 2576 | ||
2575 | cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2; | 2577 | cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2; |
2576 | port_priv->cq = ib_create_cq(port_priv->device, | 2578 | port_priv->cq = ib_create_cq(port_priv->device, |
2577 | (ib_comp_handler) | 2579 | ib_mad_thread_completion_handler, |
2578 | ib_mad_thread_completion_handler, | ||
2579 | NULL, port_priv, cq_size); | 2580 | NULL, port_priv, cq_size); |
2580 | if (IS_ERR(port_priv->cq)) { | 2581 | if (IS_ERR(port_priv->cq)) { |
2581 | printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n"); | 2582 | printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n"); |
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index 568da10b05ab..f1ba794e0daa 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h | |||
@@ -40,8 +40,8 @@ | |||
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/kthread.h> | 41 | #include <linux/kthread.h> |
42 | #include <linux/workqueue.h> | 42 | #include <linux/workqueue.h> |
43 | #include <ib_mad.h> | 43 | #include <rdma/ib_mad.h> |
44 | #include <ib_smi.h> | 44 | #include <rdma/ib_smi.h> |
45 | 45 | ||
46 | 46 | ||
47 | #define PFX "ib_mad: " | 47 | #define PFX "ib_mad: " |
@@ -121,7 +121,7 @@ struct ib_mad_send_wr_private { | |||
121 | struct ib_send_wr send_wr; | 121 | struct ib_send_wr send_wr; |
122 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; | 122 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; |
123 | u64 wr_id; /* client WR ID */ | 123 | u64 wr_id; /* client WR ID */ |
124 | u64 tid; | 124 | __be64 tid; |
125 | unsigned long timeout; | 125 | unsigned long timeout; |
126 | int retries; | 126 | int retries; |
127 | int retry; | 127 | int retry; |
@@ -144,7 +144,7 @@ struct ib_mad_local_private { | |||
144 | struct ib_send_wr send_wr; | 144 | struct ib_send_wr send_wr; |
145 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; | 145 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; |
146 | u64 wr_id; /* client WR ID */ | 146 | u64 wr_id; /* client WR ID */ |
147 | u64 tid; | 147 | __be64 tid; |
148 | }; | 148 | }; |
149 | 149 | ||
150 | struct ib_mad_mgmt_method_table { | 150 | struct ib_mad_mgmt_method_table { |
@@ -210,7 +210,7 @@ extern kmem_cache_t *ib_mad_cache; | |||
210 | int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); | 210 | int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); |
211 | 211 | ||
212 | struct ib_mad_send_wr_private * | 212 | struct ib_mad_send_wr_private * |
213 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid); | 213 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid); |
214 | 214 | ||
215 | void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, | 215 | void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, |
216 | struct ib_mad_send_wc *mad_send_wc); | 216 | struct ib_mad_send_wc *mad_send_wc); |
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 8f1eb80e421f..43fd805e0265 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
@@ -61,7 +61,7 @@ struct mad_rmpp_recv { | |||
61 | int seg_num; | 61 | int seg_num; |
62 | int newwin; | 62 | int newwin; |
63 | 63 | ||
64 | u64 tid; | 64 | __be64 tid; |
65 | u32 src_qp; | 65 | u32 src_qp; |
66 | u16 slid; | 66 | u16 slid; |
67 | u8 mgmt_class; | 67 | u8 mgmt_class; |
@@ -100,6 +100,121 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent) | |||
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | static int data_offset(u8 mgmt_class) | ||
104 | { | ||
105 | if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) | ||
106 | return offsetof(struct ib_sa_mad, data); | ||
107 | else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
108 | (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) | ||
109 | return offsetof(struct ib_vendor_mad, data); | ||
110 | else | ||
111 | return offsetof(struct ib_rmpp_mad, data); | ||
112 | } | ||
113 | |||
114 | static void format_ack(struct ib_rmpp_mad *ack, | ||
115 | struct ib_rmpp_mad *data, | ||
116 | struct mad_rmpp_recv *rmpp_recv) | ||
117 | { | ||
118 | unsigned long flags; | ||
119 | |||
120 | memcpy(&ack->mad_hdr, &data->mad_hdr, | ||
121 | data_offset(data->mad_hdr.mgmt_class)); | ||
122 | |||
123 | ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP; | ||
124 | ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK; | ||
125 | ib_set_rmpp_flags(&ack->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); | ||
126 | |||
127 | spin_lock_irqsave(&rmpp_recv->lock, flags); | ||
128 | rmpp_recv->last_ack = rmpp_recv->seg_num; | ||
129 | ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num); | ||
130 | ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin); | ||
131 | spin_unlock_irqrestore(&rmpp_recv->lock, flags); | ||
132 | } | ||
133 | |||
134 | static void ack_recv(struct mad_rmpp_recv *rmpp_recv, | ||
135 | struct ib_mad_recv_wc *recv_wc) | ||
136 | { | ||
137 | struct ib_mad_send_buf *msg; | ||
138 | struct ib_send_wr *bad_send_wr; | ||
139 | int hdr_len, ret; | ||
140 | |||
141 | hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr); | ||
142 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, | ||
143 | recv_wc->wc->pkey_index, rmpp_recv->ah, 1, | ||
144 | hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len, | ||
145 | GFP_KERNEL); | ||
146 | if (!msg) | ||
147 | return; | ||
148 | |||
149 | format_ack((struct ib_rmpp_mad *) msg->mad, | ||
150 | (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); | ||
151 | ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr, | ||
152 | &bad_send_wr); | ||
153 | if (ret) | ||
154 | ib_free_send_mad(msg); | ||
155 | } | ||
156 | |||
157 | static int alloc_response_msg(struct ib_mad_agent *agent, | ||
158 | struct ib_mad_recv_wc *recv_wc, | ||
159 | struct ib_mad_send_buf **msg) | ||
160 | { | ||
161 | struct ib_mad_send_buf *m; | ||
162 | struct ib_ah *ah; | ||
163 | int hdr_len; | ||
164 | |||
165 | ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc, | ||
166 | recv_wc->recv_buf.grh, agent->port_num); | ||
167 | if (IS_ERR(ah)) | ||
168 | return PTR_ERR(ah); | ||
169 | |||
170 | hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr); | ||
171 | m = ib_create_send_mad(agent, recv_wc->wc->src_qp, | ||
172 | recv_wc->wc->pkey_index, ah, 1, hdr_len, | ||
173 | sizeof(struct ib_rmpp_mad) - hdr_len, | ||
174 | GFP_KERNEL); | ||
175 | if (IS_ERR(m)) { | ||
176 | ib_destroy_ah(ah); | ||
177 | return PTR_ERR(m); | ||
178 | } | ||
179 | *msg = m; | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static void free_msg(struct ib_mad_send_buf *msg) | ||
184 | { | ||
185 | ib_destroy_ah(msg->send_wr.wr.ud.ah); | ||
186 | ib_free_send_mad(msg); | ||
187 | } | ||
188 | |||
189 | static void nack_recv(struct ib_mad_agent_private *agent, | ||
190 | struct ib_mad_recv_wc *recv_wc, u8 rmpp_status) | ||
191 | { | ||
192 | struct ib_mad_send_buf *msg; | ||
193 | struct ib_rmpp_mad *rmpp_mad; | ||
194 | struct ib_send_wr *bad_send_wr; | ||
195 | int ret; | ||
196 | |||
197 | ret = alloc_response_msg(&agent->agent, recv_wc, &msg); | ||
198 | if (ret) | ||
199 | return; | ||
200 | |||
201 | rmpp_mad = (struct ib_rmpp_mad *) msg->mad; | ||
202 | memcpy(rmpp_mad, recv_wc->recv_buf.mad, | ||
203 | data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class)); | ||
204 | |||
205 | rmpp_mad->mad_hdr.method ^= IB_MGMT_METHOD_RESP; | ||
206 | rmpp_mad->rmpp_hdr.rmpp_version = IB_MGMT_RMPP_VERSION; | ||
207 | rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ABORT; | ||
208 | ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); | ||
209 | rmpp_mad->rmpp_hdr.rmpp_status = rmpp_status; | ||
210 | rmpp_mad->rmpp_hdr.seg_num = 0; | ||
211 | rmpp_mad->rmpp_hdr.paylen_newwin = 0; | ||
212 | |||
213 | ret = ib_post_send_mad(&agent->agent, &msg->send_wr, &bad_send_wr); | ||
214 | if (ret) | ||
215 | free_msg(msg); | ||
216 | } | ||
217 | |||
103 | static void recv_timeout_handler(void *data) | 218 | static void recv_timeout_handler(void *data) |
104 | { | 219 | { |
105 | struct mad_rmpp_recv *rmpp_recv = data; | 220 | struct mad_rmpp_recv *rmpp_recv = data; |
@@ -115,8 +230,8 @@ static void recv_timeout_handler(void *data) | |||
115 | list_del(&rmpp_recv->list); | 230 | list_del(&rmpp_recv->list); |
116 | spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); | 231 | spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); |
117 | 232 | ||
118 | /* TODO: send abort. */ | ||
119 | rmpp_wc = rmpp_recv->rmpp_wc; | 233 | rmpp_wc = rmpp_recv->rmpp_wc; |
234 | nack_recv(rmpp_recv->agent, rmpp_wc, IB_MGMT_RMPP_STATUS_T2L); | ||
120 | destroy_rmpp_recv(rmpp_recv); | 235 | destroy_rmpp_recv(rmpp_recv); |
121 | ib_free_recv_mad(rmpp_wc); | 236 | ib_free_recv_mad(rmpp_wc); |
122 | } | 237 | } |
@@ -230,60 +345,6 @@ insert_rmpp_recv(struct ib_mad_agent_private *agent, | |||
230 | return cur_rmpp_recv; | 345 | return cur_rmpp_recv; |
231 | } | 346 | } |
232 | 347 | ||
233 | static int data_offset(u8 mgmt_class) | ||
234 | { | ||
235 | if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) | ||
236 | return offsetof(struct ib_sa_mad, data); | ||
237 | else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
238 | (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) | ||
239 | return offsetof(struct ib_vendor_mad, data); | ||
240 | else | ||
241 | return offsetof(struct ib_rmpp_mad, data); | ||
242 | } | ||
243 | |||
244 | static void format_ack(struct ib_rmpp_mad *ack, | ||
245 | struct ib_rmpp_mad *data, | ||
246 | struct mad_rmpp_recv *rmpp_recv) | ||
247 | { | ||
248 | unsigned long flags; | ||
249 | |||
250 | memcpy(&ack->mad_hdr, &data->mad_hdr, | ||
251 | data_offset(data->mad_hdr.mgmt_class)); | ||
252 | |||
253 | ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP; | ||
254 | ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK; | ||
255 | ib_set_rmpp_flags(&ack->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); | ||
256 | |||
257 | spin_lock_irqsave(&rmpp_recv->lock, flags); | ||
258 | rmpp_recv->last_ack = rmpp_recv->seg_num; | ||
259 | ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num); | ||
260 | ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin); | ||
261 | spin_unlock_irqrestore(&rmpp_recv->lock, flags); | ||
262 | } | ||
263 | |||
264 | static void ack_recv(struct mad_rmpp_recv *rmpp_recv, | ||
265 | struct ib_mad_recv_wc *recv_wc) | ||
266 | { | ||
267 | struct ib_mad_send_buf *msg; | ||
268 | struct ib_send_wr *bad_send_wr; | ||
269 | int hdr_len, ret; | ||
270 | |||
271 | hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr); | ||
272 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, | ||
273 | recv_wc->wc->pkey_index, rmpp_recv->ah, 1, | ||
274 | hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len, | ||
275 | GFP_KERNEL); | ||
276 | if (!msg) | ||
277 | return; | ||
278 | |||
279 | format_ack((struct ib_rmpp_mad *) msg->mad, | ||
280 | (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); | ||
281 | ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr, | ||
282 | &bad_send_wr); | ||
283 | if (ret) | ||
284 | ib_free_send_mad(msg); | ||
285 | } | ||
286 | |||
287 | static inline int get_last_flag(struct ib_mad_recv_buf *seg) | 348 | static inline int get_last_flag(struct ib_mad_recv_buf *seg) |
288 | { | 349 | { |
289 | struct ib_rmpp_mad *rmpp_mad; | 350 | struct ib_rmpp_mad *rmpp_mad; |
@@ -559,6 +620,34 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) | |||
559 | return ib_send_mad(mad_send_wr); | 620 | return ib_send_mad(mad_send_wr); |
560 | } | 621 | } |
561 | 622 | ||
623 | static void abort_send(struct ib_mad_agent_private *agent, __be64 tid, | ||
624 | u8 rmpp_status) | ||
625 | { | ||
626 | struct ib_mad_send_wr_private *mad_send_wr; | ||
627 | struct ib_mad_send_wc wc; | ||
628 | unsigned long flags; | ||
629 | |||
630 | spin_lock_irqsave(&agent->lock, flags); | ||
631 | mad_send_wr = ib_find_send_mad(agent, tid); | ||
632 | if (!mad_send_wr) | ||
633 | goto out; /* Unmatched send */ | ||
634 | |||
635 | if ((mad_send_wr->last_ack == mad_send_wr->total_seg) || | ||
636 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) | ||
637 | goto out; /* Send is already done */ | ||
638 | |||
639 | ib_mark_mad_done(mad_send_wr); | ||
640 | spin_unlock_irqrestore(&agent->lock, flags); | ||
641 | |||
642 | wc.status = IB_WC_REM_ABORT_ERR; | ||
643 | wc.vendor_err = rmpp_status; | ||
644 | wc.wr_id = mad_send_wr->wr_id; | ||
645 | ib_mad_complete_send_wr(mad_send_wr, &wc); | ||
646 | return; | ||
647 | out: | ||
648 | spin_unlock_irqrestore(&agent->lock, flags); | ||
649 | } | ||
650 | |||
562 | static void process_rmpp_ack(struct ib_mad_agent_private *agent, | 651 | static void process_rmpp_ack(struct ib_mad_agent_private *agent, |
563 | struct ib_mad_recv_wc *mad_recv_wc) | 652 | struct ib_mad_recv_wc *mad_recv_wc) |
564 | { | 653 | { |
@@ -568,11 +657,21 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
568 | int seg_num, newwin, ret; | 657 | int seg_num, newwin, ret; |
569 | 658 | ||
570 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; | 659 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; |
571 | if (rmpp_mad->rmpp_hdr.rmpp_status) | 660 | if (rmpp_mad->rmpp_hdr.rmpp_status) { |
661 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
662 | IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
663 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
572 | return; | 664 | return; |
665 | } | ||
573 | 666 | ||
574 | seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); | 667 | seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); |
575 | newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); | 668 | newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); |
669 | if (newwin < seg_num) { | ||
670 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
671 | IB_MGMT_RMPP_STATUS_W2S); | ||
672 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); | ||
673 | return; | ||
674 | } | ||
576 | 675 | ||
577 | spin_lock_irqsave(&agent->lock, flags); | 676 | spin_lock_irqsave(&agent->lock, flags); |
578 | mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid); | 677 | mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid); |
@@ -583,8 +682,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
583 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) | 682 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) |
584 | goto out; /* Send is already done */ | 683 | goto out; /* Send is already done */ |
585 | 684 | ||
586 | if (seg_num > mad_send_wr->total_seg) | 685 | if (seg_num > mad_send_wr->total_seg || seg_num > mad_send_wr->newwin) { |
587 | goto out; /* Bad ACK */ | 686 | spin_unlock_irqrestore(&agent->lock, flags); |
687 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
688 | IB_MGMT_RMPP_STATUS_S2B); | ||
689 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); | ||
690 | return; | ||
691 | } | ||
588 | 692 | ||
589 | if (newwin < mad_send_wr->newwin || seg_num < mad_send_wr->last_ack) | 693 | if (newwin < mad_send_wr->newwin || seg_num < mad_send_wr->last_ack) |
590 | goto out; /* Old ACK */ | 694 | goto out; /* Old ACK */ |
@@ -628,6 +732,72 @@ out: | |||
628 | spin_unlock_irqrestore(&agent->lock, flags); | 732 | spin_unlock_irqrestore(&agent->lock, flags); |
629 | } | 733 | } |
630 | 734 | ||
735 | static struct ib_mad_recv_wc * | ||
736 | process_rmpp_data(struct ib_mad_agent_private *agent, | ||
737 | struct ib_mad_recv_wc *mad_recv_wc) | ||
738 | { | ||
739 | struct ib_rmpp_hdr *rmpp_hdr; | ||
740 | u8 rmpp_status; | ||
741 | |||
742 | rmpp_hdr = &((struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad)->rmpp_hdr; | ||
743 | |||
744 | if (rmpp_hdr->rmpp_status) { | ||
745 | rmpp_status = IB_MGMT_RMPP_STATUS_BAD_STATUS; | ||
746 | goto bad; | ||
747 | } | ||
748 | |||
749 | if (rmpp_hdr->seg_num == __constant_htonl(1)) { | ||
750 | if (!(ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST)) { | ||
751 | rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG; | ||
752 | goto bad; | ||
753 | } | ||
754 | return start_rmpp(agent, mad_recv_wc); | ||
755 | } else { | ||
756 | if (ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST) { | ||
757 | rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG; | ||
758 | goto bad; | ||
759 | } | ||
760 | return continue_rmpp(agent, mad_recv_wc); | ||
761 | } | ||
762 | bad: | ||
763 | nack_recv(agent, mad_recv_wc, rmpp_status); | ||
764 | ib_free_recv_mad(mad_recv_wc); | ||
765 | return NULL; | ||
766 | } | ||
767 | |||
768 | static void process_rmpp_stop(struct ib_mad_agent_private *agent, | ||
769 | struct ib_mad_recv_wc *mad_recv_wc) | ||
770 | { | ||
771 | struct ib_rmpp_mad *rmpp_mad; | ||
772 | |||
773 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; | ||
774 | |||
775 | if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) { | ||
776 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
777 | IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
778 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
779 | } else | ||
780 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
781 | rmpp_mad->rmpp_hdr.rmpp_status); | ||
782 | } | ||
783 | |||
784 | static void process_rmpp_abort(struct ib_mad_agent_private *agent, | ||
785 | struct ib_mad_recv_wc *mad_recv_wc) | ||
786 | { | ||
787 | struct ib_rmpp_mad *rmpp_mad; | ||
788 | |||
789 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; | ||
790 | |||
791 | if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN || | ||
792 | rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) { | ||
793 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
794 | IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
795 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
796 | } else | ||
797 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
798 | rmpp_mad->rmpp_hdr.rmpp_status); | ||
799 | } | ||
800 | |||
631 | struct ib_mad_recv_wc * | 801 | struct ib_mad_recv_wc * |
632 | ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, | 802 | ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, |
633 | struct ib_mad_recv_wc *mad_recv_wc) | 803 | struct ib_mad_recv_wc *mad_recv_wc) |
@@ -638,23 +808,29 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, | |||
638 | if (!(rmpp_mad->rmpp_hdr.rmpp_rtime_flags & IB_MGMT_RMPP_FLAG_ACTIVE)) | 808 | if (!(rmpp_mad->rmpp_hdr.rmpp_rtime_flags & IB_MGMT_RMPP_FLAG_ACTIVE)) |
639 | return mad_recv_wc; | 809 | return mad_recv_wc; |
640 | 810 | ||
641 | if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) | 811 | if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) { |
812 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
813 | IB_MGMT_RMPP_STATUS_UNV); | ||
814 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); | ||
642 | goto out; | 815 | goto out; |
816 | } | ||
643 | 817 | ||
644 | switch (rmpp_mad->rmpp_hdr.rmpp_type) { | 818 | switch (rmpp_mad->rmpp_hdr.rmpp_type) { |
645 | case IB_MGMT_RMPP_TYPE_DATA: | 819 | case IB_MGMT_RMPP_TYPE_DATA: |
646 | if (rmpp_mad->rmpp_hdr.seg_num == __constant_htonl(1)) | 820 | return process_rmpp_data(agent, mad_recv_wc); |
647 | return start_rmpp(agent, mad_recv_wc); | ||
648 | else | ||
649 | return continue_rmpp(agent, mad_recv_wc); | ||
650 | case IB_MGMT_RMPP_TYPE_ACK: | 821 | case IB_MGMT_RMPP_TYPE_ACK: |
651 | process_rmpp_ack(agent, mad_recv_wc); | 822 | process_rmpp_ack(agent, mad_recv_wc); |
652 | break; | 823 | break; |
653 | case IB_MGMT_RMPP_TYPE_STOP: | 824 | case IB_MGMT_RMPP_TYPE_STOP: |
825 | process_rmpp_stop(agent, mad_recv_wc); | ||
826 | break; | ||
654 | case IB_MGMT_RMPP_TYPE_ABORT: | 827 | case IB_MGMT_RMPP_TYPE_ABORT: |
655 | /* TODO: process_rmpp_nack(agent, mad_recv_wc); */ | 828 | process_rmpp_abort(agent, mad_recv_wc); |
656 | break; | 829 | break; |
657 | default: | 830 | default: |
831 | abort_send(agent, rmpp_mad->mad_hdr.tid, | ||
832 | IB_MGMT_RMPP_STATUS_BADT); | ||
833 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); | ||
658 | break; | 834 | break; |
659 | } | 835 | } |
660 | out: | 836 | out: |
@@ -714,7 +890,10 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr, | |||
714 | if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) { | 890 | if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) { |
715 | msg = (struct ib_mad_send_buf *) (unsigned long) | 891 | msg = (struct ib_mad_send_buf *) (unsigned long) |
716 | mad_send_wc->wr_id; | 892 | mad_send_wc->wr_id; |
717 | ib_free_send_mad(msg); | 893 | if (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_ACK) |
894 | ib_free_send_mad(msg); | ||
895 | else | ||
896 | free_msg(msg); | ||
718 | return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */ | 897 | return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */ |
719 | } | 898 | } |
720 | 899 | ||
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c index eb5ff54c10d7..35df5010e723 100644 --- a/drivers/infiniband/core/packer.c +++ b/drivers/infiniband/core/packer.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 2 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. 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 |
@@ -32,7 +33,7 @@ | |||
32 | * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $ | 33 | * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $ |
33 | */ | 34 | */ |
34 | 35 | ||
35 | #include <ib_pack.h> | 36 | #include <rdma/ib_pack.h> |
36 | 37 | ||
37 | static u64 value_read(int offset, int size, void *structure) | 38 | static u64 value_read(int offset, int size, void *structure) |
38 | { | 39 | { |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 795184931c83..126ac80db7b8 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -1,6 +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 Voltaire, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * 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 |
6 | * 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 |
@@ -44,8 +44,8 @@ | |||
44 | #include <linux/kref.h> | 44 | #include <linux/kref.h> |
45 | #include <linux/idr.h> | 45 | #include <linux/idr.h> |
46 | 46 | ||
47 | #include <ib_pack.h> | 47 | #include <rdma/ib_pack.h> |
48 | #include <ib_sa.h> | 48 | #include <rdma/ib_sa.h> |
49 | 49 | ||
50 | MODULE_AUTHOR("Roland Dreier"); | 50 | MODULE_AUTHOR("Roland Dreier"); |
51 | MODULE_DESCRIPTION("InfiniBand subnet administration query support"); | 51 | MODULE_DESCRIPTION("InfiniBand subnet administration query support"); |
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c index b4b284324a33..35852e794e26 100644 --- a/drivers/infiniband/core/smi.c +++ b/drivers/infiniband/core/smi.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved. |
3 | * Copyright (c) 2004 Infinicon Corporation. All rights reserved. | 3 | * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved. |
4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 5 | * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved. |
6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. | 6 | * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. |
7 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
7 | * | 8 | * |
8 | * This software is available to you under a choice of one of two | 9 | * This software is available to you under a choice of one of two |
9 | * licenses. You may choose to be licensed under the terms of the GNU | 10 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -36,7 +37,7 @@ | |||
36 | * $Id: smi.c 1389 2004-12-27 22:56:47Z roland $ | 37 | * $Id: smi.c 1389 2004-12-27 22:56:47Z roland $ |
37 | */ | 38 | */ |
38 | 39 | ||
39 | #include <ib_smi.h> | 40 | #include <rdma/ib_smi.h> |
40 | #include "smi.h" | 41 | #include "smi.h" |
41 | 42 | ||
42 | /* | 43 | /* |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 90d51b179abe..fae1c2dcee51 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -1,5 +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 Mellanox Technologies Ltd. All rights reserved. | ||
4 | * Copyright (c) 2005 Sun Microsystems, 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 |
@@ -34,7 +36,7 @@ | |||
34 | 36 | ||
35 | #include "core_priv.h" | 37 | #include "core_priv.h" |
36 | 38 | ||
37 | #include <ib_mad.h> | 39 | #include <rdma/ib_mad.h> |
38 | 40 | ||
39 | struct ib_port { | 41 | struct ib_port { |
40 | struct kobject kobj; | 42 | struct kobject kobj; |
@@ -253,14 +255,14 @@ static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr, | |||
253 | return ret; | 255 | return ret; |
254 | 256 | ||
255 | return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", | 257 | return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", |
256 | be16_to_cpu(((u16 *) gid.raw)[0]), | 258 | be16_to_cpu(((__be16 *) gid.raw)[0]), |
257 | be16_to_cpu(((u16 *) gid.raw)[1]), | 259 | be16_to_cpu(((__be16 *) gid.raw)[1]), |
258 | be16_to_cpu(((u16 *) gid.raw)[2]), | 260 | be16_to_cpu(((__be16 *) gid.raw)[2]), |
259 | be16_to_cpu(((u16 *) gid.raw)[3]), | 261 | be16_to_cpu(((__be16 *) gid.raw)[3]), |
260 | be16_to_cpu(((u16 *) gid.raw)[4]), | 262 | be16_to_cpu(((__be16 *) gid.raw)[4]), |
261 | be16_to_cpu(((u16 *) gid.raw)[5]), | 263 | be16_to_cpu(((__be16 *) gid.raw)[5]), |
262 | be16_to_cpu(((u16 *) gid.raw)[6]), | 264 | be16_to_cpu(((__be16 *) gid.raw)[6]), |
263 | be16_to_cpu(((u16 *) gid.raw)[7])); | 265 | be16_to_cpu(((__be16 *) gid.raw)[7])); |
264 | } | 266 | } |
265 | 267 | ||
266 | static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr, | 268 | static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr, |
@@ -332,11 +334,11 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr, | |||
332 | break; | 334 | break; |
333 | case 16: | 335 | case 16: |
334 | ret = sprintf(buf, "%u\n", | 336 | ret = sprintf(buf, "%u\n", |
335 | be16_to_cpup((u16 *)(out_mad->data + 40 + offset / 8))); | 337 | be16_to_cpup((__be16 *)(out_mad->data + 40 + offset / 8))); |
336 | break; | 338 | break; |
337 | case 32: | 339 | case 32: |
338 | ret = sprintf(buf, "%u\n", | 340 | ret = sprintf(buf, "%u\n", |
339 | be32_to_cpup((u32 *)(out_mad->data + 40 + offset / 8))); | 341 | be32_to_cpup((__be32 *)(out_mad->data + 40 + offset / 8))); |
340 | break; | 342 | break; |
341 | default: | 343 | default: |
342 | ret = 0; | 344 | ret = 0; |
@@ -598,10 +600,10 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf) | |||
598 | return ret; | 600 | return ret; |
599 | 601 | ||
600 | return sprintf(buf, "%04x:%04x:%04x:%04x\n", | 602 | return sprintf(buf, "%04x:%04x:%04x:%04x\n", |
601 | be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]), | 603 | be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]), |
602 | be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]), | 604 | be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]), |
603 | be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]), | 605 | be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]), |
604 | be16_to_cpu(((u16 *) &attr.sys_image_guid)[3])); | 606 | be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3])); |
605 | } | 607 | } |
606 | 608 | ||
607 | static ssize_t show_node_guid(struct class_device *cdev, char *buf) | 609 | static ssize_t show_node_guid(struct class_device *cdev, char *buf) |
@@ -615,10 +617,10 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf) | |||
615 | return ret; | 617 | return ret; |
616 | 618 | ||
617 | return sprintf(buf, "%04x:%04x:%04x:%04x\n", | 619 | return sprintf(buf, "%04x:%04x:%04x:%04x\n", |
618 | be16_to_cpu(((u16 *) &attr.node_guid)[0]), | 620 | be16_to_cpu(((__be16 *) &attr.node_guid)[0]), |
619 | be16_to_cpu(((u16 *) &attr.node_guid)[1]), | 621 | be16_to_cpu(((__be16 *) &attr.node_guid)[1]), |
620 | be16_to_cpu(((u16 *) &attr.node_guid)[2]), | 622 | be16_to_cpu(((__be16 *) &attr.node_guid)[2]), |
621 | be16_to_cpu(((u16 *) &attr.node_guid)[3])); | 623 | be16_to_cpu(((__be16 *) &attr.node_guid)[3])); |
622 | } | 624 | } |
623 | 625 | ||
624 | static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); | 626 | static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 61d07c732f49..79595826ccc7 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Intel Corporation. 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 |
@@ -73,14 +74,18 @@ static struct semaphore ctx_id_mutex; | |||
73 | static struct idr ctx_id_table; | 74 | static struct idr ctx_id_table; |
74 | static int ctx_id_rover = 0; | 75 | static int ctx_id_rover = 0; |
75 | 76 | ||
76 | static struct ib_ucm_context *ib_ucm_ctx_get(int id) | 77 | static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) |
77 | { | 78 | { |
78 | struct ib_ucm_context *ctx; | 79 | struct ib_ucm_context *ctx; |
79 | 80 | ||
80 | down(&ctx_id_mutex); | 81 | down(&ctx_id_mutex); |
81 | ctx = idr_find(&ctx_id_table, id); | 82 | ctx = idr_find(&ctx_id_table, id); |
82 | if (ctx) | 83 | if (!ctx) |
83 | ctx->ref++; | 84 | ctx = ERR_PTR(-ENOENT); |
85 | else if (ctx->file != file) | ||
86 | ctx = ERR_PTR(-EINVAL); | ||
87 | else | ||
88 | atomic_inc(&ctx->ref); | ||
84 | up(&ctx_id_mutex); | 89 | up(&ctx_id_mutex); |
85 | 90 | ||
86 | return ctx; | 91 | return ctx; |
@@ -88,21 +93,37 @@ static struct ib_ucm_context *ib_ucm_ctx_get(int id) | |||
88 | 93 | ||
89 | static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) | 94 | static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) |
90 | { | 95 | { |
96 | if (atomic_dec_and_test(&ctx->ref)) | ||
97 | wake_up(&ctx->wait); | ||
98 | } | ||
99 | |||
100 | static ssize_t ib_ucm_destroy_ctx(struct ib_ucm_file *file, int id) | ||
101 | { | ||
102 | struct ib_ucm_context *ctx; | ||
91 | struct ib_ucm_event *uevent; | 103 | struct ib_ucm_event *uevent; |
92 | 104 | ||
93 | down(&ctx_id_mutex); | 105 | down(&ctx_id_mutex); |
94 | 106 | ctx = idr_find(&ctx_id_table, id); | |
95 | ctx->ref--; | 107 | if (!ctx) |
96 | if (!ctx->ref) | 108 | ctx = ERR_PTR(-ENOENT); |
109 | else if (ctx->file != file) | ||
110 | ctx = ERR_PTR(-EINVAL); | ||
111 | else | ||
97 | idr_remove(&ctx_id_table, ctx->id); | 112 | idr_remove(&ctx_id_table, ctx->id); |
98 | |||
99 | up(&ctx_id_mutex); | 113 | up(&ctx_id_mutex); |
100 | 114 | ||
101 | if (ctx->ref) | 115 | if (IS_ERR(ctx)) |
102 | return; | 116 | return PTR_ERR(ctx); |
103 | 117 | ||
104 | down(&ctx->file->mutex); | 118 | atomic_dec(&ctx->ref); |
119 | wait_event(ctx->wait, !atomic_read(&ctx->ref)); | ||
120 | |||
121 | /* No new events will be generated after destroying the cm_id. */ | ||
122 | if (!IS_ERR(ctx->cm_id)) | ||
123 | ib_destroy_cm_id(ctx->cm_id); | ||
105 | 124 | ||
125 | /* Cleanup events not yet reported to the user. */ | ||
126 | down(&file->mutex); | ||
106 | list_del(&ctx->file_list); | 127 | list_del(&ctx->file_list); |
107 | while (!list_empty(&ctx->events)) { | 128 | while (!list_empty(&ctx->events)) { |
108 | 129 | ||
@@ -117,13 +138,10 @@ static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) | |||
117 | 138 | ||
118 | kfree(uevent); | 139 | kfree(uevent); |
119 | } | 140 | } |
141 | up(&file->mutex); | ||
120 | 142 | ||
121 | up(&ctx->file->mutex); | ||
122 | |||
123 | ucm_dbg("Destroyed CM ID <%d>\n", ctx->id); | ||
124 | |||
125 | ib_destroy_cm_id(ctx->cm_id); | ||
126 | kfree(ctx); | 143 | kfree(ctx); |
144 | return 0; | ||
127 | } | 145 | } |
128 | 146 | ||
129 | static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) | 147 | static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) |
@@ -135,11 +153,11 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) | |||
135 | if (!ctx) | 153 | if (!ctx) |
136 | return NULL; | 154 | return NULL; |
137 | 155 | ||
138 | ctx->ref = 1; /* user reference */ | 156 | atomic_set(&ctx->ref, 1); |
157 | init_waitqueue_head(&ctx->wait); | ||
139 | ctx->file = file; | 158 | ctx->file = file; |
140 | 159 | ||
141 | INIT_LIST_HEAD(&ctx->events); | 160 | INIT_LIST_HEAD(&ctx->events); |
142 | init_MUTEX(&ctx->mutex); | ||
143 | 161 | ||
144 | list_add_tail(&ctx->file_list, &file->ctxs); | 162 | list_add_tail(&ctx->file_list, &file->ctxs); |
145 | 163 | ||
@@ -177,8 +195,8 @@ static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath, | |||
177 | if (!kpath || !upath) | 195 | if (!kpath || !upath) |
178 | return; | 196 | return; |
179 | 197 | ||
180 | memcpy(upath->dgid, kpath->dgid.raw, sizeof(union ib_gid)); | 198 | memcpy(upath->dgid, kpath->dgid.raw, sizeof *upath->dgid); |
181 | memcpy(upath->sgid, kpath->sgid.raw, sizeof(union ib_gid)); | 199 | memcpy(upath->sgid, kpath->sgid.raw, sizeof *upath->sgid); |
182 | 200 | ||
183 | upath->dlid = kpath->dlid; | 201 | upath->dlid = kpath->dlid; |
184 | upath->slid = kpath->slid; | 202 | upath->slid = kpath->slid; |
@@ -201,10 +219,11 @@ static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath, | |||
201 | kpath->packet_life_time_selector; | 219 | kpath->packet_life_time_selector; |
202 | } | 220 | } |
203 | 221 | ||
204 | static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, | 222 | static void ib_ucm_event_req_get(struct ib_ucm_context *ctx, |
223 | struct ib_ucm_req_event_resp *ureq, | ||
205 | struct ib_cm_req_event_param *kreq) | 224 | struct ib_cm_req_event_param *kreq) |
206 | { | 225 | { |
207 | ureq->listen_id = (long)kreq->listen_id->context; | 226 | ureq->listen_id = ctx->id; |
208 | 227 | ||
209 | ureq->remote_ca_guid = kreq->remote_ca_guid; | 228 | ureq->remote_ca_guid = kreq->remote_ca_guid; |
210 | ureq->remote_qkey = kreq->remote_qkey; | 229 | ureq->remote_qkey = kreq->remote_qkey; |
@@ -240,34 +259,11 @@ static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep, | |||
240 | urep->srq = krep->srq; | 259 | urep->srq = krep->srq; |
241 | } | 260 | } |
242 | 261 | ||
243 | static void ib_ucm_event_rej_get(struct ib_ucm_rej_event_resp *urej, | 262 | static void ib_ucm_event_sidr_req_get(struct ib_ucm_context *ctx, |
244 | struct ib_cm_rej_event_param *krej) | 263 | struct ib_ucm_sidr_req_event_resp *ureq, |
245 | { | ||
246 | urej->reason = krej->reason; | ||
247 | } | ||
248 | |||
249 | static void ib_ucm_event_mra_get(struct ib_ucm_mra_event_resp *umra, | ||
250 | struct ib_cm_mra_event_param *kmra) | ||
251 | { | ||
252 | umra->timeout = kmra->service_timeout; | ||
253 | } | ||
254 | |||
255 | static void ib_ucm_event_lap_get(struct ib_ucm_lap_event_resp *ulap, | ||
256 | struct ib_cm_lap_event_param *klap) | ||
257 | { | ||
258 | ib_ucm_event_path_get(&ulap->path, klap->alternate_path); | ||
259 | } | ||
260 | |||
261 | static void ib_ucm_event_apr_get(struct ib_ucm_apr_event_resp *uapr, | ||
262 | struct ib_cm_apr_event_param *kapr) | ||
263 | { | ||
264 | uapr->status = kapr->ap_status; | ||
265 | } | ||
266 | |||
267 | static void ib_ucm_event_sidr_req_get(struct ib_ucm_sidr_req_event_resp *ureq, | ||
268 | struct ib_cm_sidr_req_event_param *kreq) | 264 | struct ib_cm_sidr_req_event_param *kreq) |
269 | { | 265 | { |
270 | ureq->listen_id = (long)kreq->listen_id->context; | 266 | ureq->listen_id = ctx->id; |
271 | ureq->pkey = kreq->pkey; | 267 | ureq->pkey = kreq->pkey; |
272 | } | 268 | } |
273 | 269 | ||
@@ -279,19 +275,18 @@ static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep, | |||
279 | urep->qpn = krep->qpn; | 275 | urep->qpn = krep->qpn; |
280 | }; | 276 | }; |
281 | 277 | ||
282 | static int ib_ucm_event_process(struct ib_cm_event *evt, | 278 | static int ib_ucm_event_process(struct ib_ucm_context *ctx, |
279 | struct ib_cm_event *evt, | ||
283 | struct ib_ucm_event *uvt) | 280 | struct ib_ucm_event *uvt) |
284 | { | 281 | { |
285 | void *info = NULL; | 282 | void *info = NULL; |
286 | int result; | ||
287 | 283 | ||
288 | switch (evt->event) { | 284 | switch (evt->event) { |
289 | case IB_CM_REQ_RECEIVED: | 285 | case IB_CM_REQ_RECEIVED: |
290 | ib_ucm_event_req_get(&uvt->resp.u.req_resp, | 286 | ib_ucm_event_req_get(ctx, &uvt->resp.u.req_resp, |
291 | &evt->param.req_rcvd); | 287 | &evt->param.req_rcvd); |
292 | uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE; | 288 | uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE; |
293 | uvt->resp.present |= (evt->param.req_rcvd.primary_path ? | 289 | uvt->resp.present = IB_UCM_PRES_PRIMARY; |
294 | IB_UCM_PRES_PRIMARY : 0); | ||
295 | uvt->resp.present |= (evt->param.req_rcvd.alternate_path ? | 290 | uvt->resp.present |= (evt->param.req_rcvd.alternate_path ? |
296 | IB_UCM_PRES_ALTERNATE : 0); | 291 | IB_UCM_PRES_ALTERNATE : 0); |
297 | break; | 292 | break; |
@@ -299,57 +294,46 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, | |||
299 | ib_ucm_event_rep_get(&uvt->resp.u.rep_resp, | 294 | ib_ucm_event_rep_get(&uvt->resp.u.rep_resp, |
300 | &evt->param.rep_rcvd); | 295 | &evt->param.rep_rcvd); |
301 | uvt->data_len = IB_CM_REP_PRIVATE_DATA_SIZE; | 296 | uvt->data_len = IB_CM_REP_PRIVATE_DATA_SIZE; |
302 | |||
303 | break; | 297 | break; |
304 | case IB_CM_RTU_RECEIVED: | 298 | case IB_CM_RTU_RECEIVED: |
305 | uvt->data_len = IB_CM_RTU_PRIVATE_DATA_SIZE; | 299 | uvt->data_len = IB_CM_RTU_PRIVATE_DATA_SIZE; |
306 | uvt->resp.u.send_status = evt->param.send_status; | 300 | uvt->resp.u.send_status = evt->param.send_status; |
307 | |||
308 | break; | 301 | break; |
309 | case IB_CM_DREQ_RECEIVED: | 302 | case IB_CM_DREQ_RECEIVED: |
310 | uvt->data_len = IB_CM_DREQ_PRIVATE_DATA_SIZE; | 303 | uvt->data_len = IB_CM_DREQ_PRIVATE_DATA_SIZE; |
311 | uvt->resp.u.send_status = evt->param.send_status; | 304 | uvt->resp.u.send_status = evt->param.send_status; |
312 | |||
313 | break; | 305 | break; |
314 | case IB_CM_DREP_RECEIVED: | 306 | case IB_CM_DREP_RECEIVED: |
315 | uvt->data_len = IB_CM_DREP_PRIVATE_DATA_SIZE; | 307 | uvt->data_len = IB_CM_DREP_PRIVATE_DATA_SIZE; |
316 | uvt->resp.u.send_status = evt->param.send_status; | 308 | uvt->resp.u.send_status = evt->param.send_status; |
317 | |||
318 | break; | 309 | break; |
319 | case IB_CM_MRA_RECEIVED: | 310 | case IB_CM_MRA_RECEIVED: |
320 | ib_ucm_event_mra_get(&uvt->resp.u.mra_resp, | 311 | uvt->resp.u.mra_resp.timeout = |
321 | &evt->param.mra_rcvd); | 312 | evt->param.mra_rcvd.service_timeout; |
322 | uvt->data_len = IB_CM_MRA_PRIVATE_DATA_SIZE; | 313 | uvt->data_len = IB_CM_MRA_PRIVATE_DATA_SIZE; |
323 | |||
324 | break; | 314 | break; |
325 | case IB_CM_REJ_RECEIVED: | 315 | case IB_CM_REJ_RECEIVED: |
326 | ib_ucm_event_rej_get(&uvt->resp.u.rej_resp, | 316 | uvt->resp.u.rej_resp.reason = evt->param.rej_rcvd.reason; |
327 | &evt->param.rej_rcvd); | ||
328 | uvt->data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; | 317 | uvt->data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; |
329 | uvt->info_len = evt->param.rej_rcvd.ari_length; | 318 | uvt->info_len = evt->param.rej_rcvd.ari_length; |
330 | info = evt->param.rej_rcvd.ari; | 319 | info = evt->param.rej_rcvd.ari; |
331 | |||
332 | break; | 320 | break; |
333 | case IB_CM_LAP_RECEIVED: | 321 | case IB_CM_LAP_RECEIVED: |
334 | ib_ucm_event_lap_get(&uvt->resp.u.lap_resp, | 322 | ib_ucm_event_path_get(&uvt->resp.u.lap_resp.path, |
335 | &evt->param.lap_rcvd); | 323 | evt->param.lap_rcvd.alternate_path); |
336 | uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; | 324 | uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; |
337 | uvt->resp.present |= (evt->param.lap_rcvd.alternate_path ? | 325 | uvt->resp.present = IB_UCM_PRES_ALTERNATE; |
338 | IB_UCM_PRES_ALTERNATE : 0); | ||
339 | break; | 326 | break; |
340 | case IB_CM_APR_RECEIVED: | 327 | case IB_CM_APR_RECEIVED: |
341 | ib_ucm_event_apr_get(&uvt->resp.u.apr_resp, | 328 | uvt->resp.u.apr_resp.status = evt->param.apr_rcvd.ap_status; |
342 | &evt->param.apr_rcvd); | ||
343 | uvt->data_len = IB_CM_APR_PRIVATE_DATA_SIZE; | 329 | uvt->data_len = IB_CM_APR_PRIVATE_DATA_SIZE; |
344 | uvt->info_len = evt->param.apr_rcvd.info_len; | 330 | uvt->info_len = evt->param.apr_rcvd.info_len; |
345 | info = evt->param.apr_rcvd.apr_info; | 331 | info = evt->param.apr_rcvd.apr_info; |
346 | |||
347 | break; | 332 | break; |
348 | case IB_CM_SIDR_REQ_RECEIVED: | 333 | case IB_CM_SIDR_REQ_RECEIVED: |
349 | ib_ucm_event_sidr_req_get(&uvt->resp.u.sidr_req_resp, | 334 | ib_ucm_event_sidr_req_get(ctx, &uvt->resp.u.sidr_req_resp, |
350 | &evt->param.sidr_req_rcvd); | 335 | &evt->param.sidr_req_rcvd); |
351 | uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE; | 336 | uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE; |
352 | |||
353 | break; | 337 | break; |
354 | case IB_CM_SIDR_REP_RECEIVED: | 338 | case IB_CM_SIDR_REP_RECEIVED: |
355 | ib_ucm_event_sidr_rep_get(&uvt->resp.u.sidr_rep_resp, | 339 | ib_ucm_event_sidr_rep_get(&uvt->resp.u.sidr_rep_resp, |
@@ -357,43 +341,35 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, | |||
357 | uvt->data_len = IB_CM_SIDR_REP_PRIVATE_DATA_SIZE; | 341 | uvt->data_len = IB_CM_SIDR_REP_PRIVATE_DATA_SIZE; |
358 | uvt->info_len = evt->param.sidr_rep_rcvd.info_len; | 342 | uvt->info_len = evt->param.sidr_rep_rcvd.info_len; |
359 | info = evt->param.sidr_rep_rcvd.info; | 343 | info = evt->param.sidr_rep_rcvd.info; |
360 | |||
361 | break; | 344 | break; |
362 | default: | 345 | default: |
363 | uvt->resp.u.send_status = evt->param.send_status; | 346 | uvt->resp.u.send_status = evt->param.send_status; |
364 | |||
365 | break; | 347 | break; |
366 | } | 348 | } |
367 | 349 | ||
368 | if (uvt->data_len && evt->private_data) { | 350 | if (uvt->data_len) { |
369 | |||
370 | uvt->data = kmalloc(uvt->data_len, GFP_KERNEL); | 351 | uvt->data = kmalloc(uvt->data_len, GFP_KERNEL); |
371 | if (!uvt->data) { | 352 | if (!uvt->data) |
372 | result = -ENOMEM; | 353 | goto err1; |
373 | goto error; | ||
374 | } | ||
375 | 354 | ||
376 | memcpy(uvt->data, evt->private_data, uvt->data_len); | 355 | memcpy(uvt->data, evt->private_data, uvt->data_len); |
377 | uvt->resp.present |= IB_UCM_PRES_DATA; | 356 | uvt->resp.present |= IB_UCM_PRES_DATA; |
378 | } | 357 | } |
379 | 358 | ||
380 | if (uvt->info_len && info) { | 359 | if (uvt->info_len) { |
381 | |||
382 | uvt->info = kmalloc(uvt->info_len, GFP_KERNEL); | 360 | uvt->info = kmalloc(uvt->info_len, GFP_KERNEL); |
383 | if (!uvt->info) { | 361 | if (!uvt->info) |
384 | result = -ENOMEM; | 362 | goto err2; |
385 | goto error; | ||
386 | } | ||
387 | 363 | ||
388 | memcpy(uvt->info, info, uvt->info_len); | 364 | memcpy(uvt->info, info, uvt->info_len); |
389 | uvt->resp.present |= IB_UCM_PRES_INFO; | 365 | uvt->resp.present |= IB_UCM_PRES_INFO; |
390 | } | 366 | } |
391 | |||
392 | return 0; | 367 | return 0; |
393 | error: | 368 | |
394 | kfree(uvt->info); | 369 | err2: |
395 | kfree(uvt->data); | 370 | kfree(uvt->data); |
396 | return result; | 371 | err1: |
372 | return -ENOMEM; | ||
397 | } | 373 | } |
398 | 374 | ||
399 | static int ib_ucm_event_handler(struct ib_cm_id *cm_id, | 375 | static int ib_ucm_event_handler(struct ib_cm_id *cm_id, |
@@ -403,63 +379,42 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id, | |||
403 | struct ib_ucm_context *ctx; | 379 | struct ib_ucm_context *ctx; |
404 | int result = 0; | 380 | int result = 0; |
405 | int id; | 381 | int id; |
406 | /* | ||
407 | * lookup correct context based on event type. | ||
408 | */ | ||
409 | switch (event->event) { | ||
410 | case IB_CM_REQ_RECEIVED: | ||
411 | id = (long)event->param.req_rcvd.listen_id->context; | ||
412 | break; | ||
413 | case IB_CM_SIDR_REQ_RECEIVED: | ||
414 | id = (long)event->param.sidr_req_rcvd.listen_id->context; | ||
415 | break; | ||
416 | default: | ||
417 | id = (long)cm_id->context; | ||
418 | break; | ||
419 | } | ||
420 | 382 | ||
421 | ucm_dbg("Event. CM ID <%d> event <%d>\n", id, event->event); | 383 | ctx = cm_id->context; |
422 | |||
423 | ctx = ib_ucm_ctx_get(id); | ||
424 | if (!ctx) | ||
425 | return -ENOENT; | ||
426 | 384 | ||
427 | if (event->event == IB_CM_REQ_RECEIVED || | 385 | if (event->event == IB_CM_REQ_RECEIVED || |
428 | event->event == IB_CM_SIDR_REQ_RECEIVED) | 386 | event->event == IB_CM_SIDR_REQ_RECEIVED) |
429 | id = IB_UCM_CM_ID_INVALID; | 387 | id = IB_UCM_CM_ID_INVALID; |
388 | else | ||
389 | id = ctx->id; | ||
430 | 390 | ||
431 | uevent = kmalloc(sizeof(*uevent), GFP_KERNEL); | 391 | uevent = kmalloc(sizeof(*uevent), GFP_KERNEL); |
432 | if (!uevent) { | 392 | if (!uevent) |
433 | result = -ENOMEM; | 393 | goto err1; |
434 | goto done; | ||
435 | } | ||
436 | 394 | ||
437 | memset(uevent, 0, sizeof(*uevent)); | 395 | memset(uevent, 0, sizeof(*uevent)); |
438 | |||
439 | uevent->resp.id = id; | 396 | uevent->resp.id = id; |
440 | uevent->resp.event = event->event; | 397 | uevent->resp.event = event->event; |
441 | 398 | ||
442 | result = ib_ucm_event_process(event, uevent); | 399 | result = ib_ucm_event_process(ctx, event, uevent); |
443 | if (result) | 400 | if (result) |
444 | goto done; | 401 | goto err2; |
445 | 402 | ||
446 | uevent->ctx = ctx; | 403 | uevent->ctx = ctx; |
447 | uevent->cm_id = ((event->event == IB_CM_REQ_RECEIVED || | 404 | uevent->cm_id = (id == IB_UCM_CM_ID_INVALID) ? cm_id : NULL; |
448 | event->event == IB_CM_SIDR_REQ_RECEIVED ) ? | ||
449 | cm_id : NULL); | ||
450 | 405 | ||
451 | down(&ctx->file->mutex); | 406 | down(&ctx->file->mutex); |
452 | |||
453 | list_add_tail(&uevent->file_list, &ctx->file->events); | 407 | list_add_tail(&uevent->file_list, &ctx->file->events); |
454 | list_add_tail(&uevent->ctx_list, &ctx->events); | 408 | list_add_tail(&uevent->ctx_list, &ctx->events); |
455 | |||
456 | wake_up_interruptible(&ctx->file->poll_wait); | 409 | wake_up_interruptible(&ctx->file->poll_wait); |
457 | |||
458 | up(&ctx->file->mutex); | 410 | up(&ctx->file->mutex); |
459 | done: | 411 | return 0; |
460 | ctx->error = result; | 412 | |
461 | ib_ucm_ctx_put(ctx); /* func reference */ | 413 | err2: |
462 | return result; | 414 | kfree(uevent); |
415 | err1: | ||
416 | /* Destroy new cm_id's */ | ||
417 | return (id == IB_UCM_CM_ID_INVALID); | ||
463 | } | 418 | } |
464 | 419 | ||
465 | static ssize_t ib_ucm_event(struct ib_ucm_file *file, | 420 | static ssize_t ib_ucm_event(struct ib_ucm_file *file, |
@@ -517,9 +472,8 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file, | |||
517 | goto done; | 472 | goto done; |
518 | } | 473 | } |
519 | 474 | ||
520 | ctx->cm_id = uevent->cm_id; | 475 | ctx->cm_id = uevent->cm_id; |
521 | ctx->cm_id->cm_handler = ib_ucm_event_handler; | 476 | ctx->cm_id->context = ctx; |
522 | ctx->cm_id->context = (void *)(unsigned long)ctx->id; | ||
523 | 477 | ||
524 | uevent->resp.id = ctx->id; | 478 | uevent->resp.id = ctx->id; |
525 | 479 | ||
@@ -585,30 +539,29 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, | |||
585 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 539 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
586 | return -EFAULT; | 540 | return -EFAULT; |
587 | 541 | ||
542 | down(&file->mutex); | ||
588 | ctx = ib_ucm_ctx_alloc(file); | 543 | ctx = ib_ucm_ctx_alloc(file); |
544 | up(&file->mutex); | ||
589 | if (!ctx) | 545 | if (!ctx) |
590 | return -ENOMEM; | 546 | return -ENOMEM; |
591 | 547 | ||
592 | ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, | 548 | ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx); |
593 | (void *)(unsigned long)ctx->id); | 549 | if (IS_ERR(ctx->cm_id)) { |
594 | if (!ctx->cm_id) { | 550 | result = PTR_ERR(ctx->cm_id); |
595 | result = -ENOMEM; | 551 | goto err; |
596 | goto err_cm; | ||
597 | } | 552 | } |
598 | 553 | ||
599 | resp.id = ctx->id; | 554 | resp.id = ctx->id; |
600 | if (copy_to_user((void __user *)(unsigned long)cmd.response, | 555 | if (copy_to_user((void __user *)(unsigned long)cmd.response, |
601 | &resp, sizeof(resp))) { | 556 | &resp, sizeof(resp))) { |
602 | result = -EFAULT; | 557 | result = -EFAULT; |
603 | goto err_ret; | 558 | goto err; |
604 | } | 559 | } |
605 | 560 | ||
606 | return 0; | 561 | return 0; |
607 | err_ret: | ||
608 | ib_destroy_cm_id(ctx->cm_id); | ||
609 | err_cm: | ||
610 | ib_ucm_ctx_put(ctx); /* user reference */ | ||
611 | 562 | ||
563 | err: | ||
564 | ib_ucm_destroy_ctx(file, ctx->id); | ||
612 | return result; | 565 | return result; |
613 | } | 566 | } |
614 | 567 | ||
@@ -617,19 +570,11 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, | |||
617 | int in_len, int out_len) | 570 | int in_len, int out_len) |
618 | { | 571 | { |
619 | struct ib_ucm_destroy_id cmd; | 572 | struct ib_ucm_destroy_id cmd; |
620 | struct ib_ucm_context *ctx; | ||
621 | 573 | ||
622 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 574 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
623 | return -EFAULT; | 575 | return -EFAULT; |
624 | 576 | ||
625 | ctx = ib_ucm_ctx_get(cmd.id); | 577 | return ib_ucm_destroy_ctx(file, cmd.id); |
626 | if (!ctx) | ||
627 | return -ENOENT; | ||
628 | |||
629 | ib_ucm_ctx_put(ctx); /* user reference */ | ||
630 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
631 | |||
632 | return 0; | ||
633 | } | 578 | } |
634 | 579 | ||
635 | static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, | 580 | static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, |
@@ -647,15 +592,9 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, | |||
647 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 592 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
648 | return -EFAULT; | 593 | return -EFAULT; |
649 | 594 | ||
650 | ctx = ib_ucm_ctx_get(cmd.id); | 595 | ctx = ib_ucm_ctx_get(file, cmd.id); |
651 | if (!ctx) | 596 | if (IS_ERR(ctx)) |
652 | return -ENOENT; | 597 | return PTR_ERR(ctx); |
653 | |||
654 | down(&ctx->file->mutex); | ||
655 | if (ctx->file != file) { | ||
656 | result = -EINVAL; | ||
657 | goto done; | ||
658 | } | ||
659 | 598 | ||
660 | resp.service_id = ctx->cm_id->service_id; | 599 | resp.service_id = ctx->cm_id->service_id; |
661 | resp.service_mask = ctx->cm_id->service_mask; | 600 | resp.service_mask = ctx->cm_id->service_mask; |
@@ -666,9 +605,7 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, | |||
666 | &resp, sizeof(resp))) | 605 | &resp, sizeof(resp))) |
667 | result = -EFAULT; | 606 | result = -EFAULT; |
668 | 607 | ||
669 | done: | 608 | ib_ucm_ctx_put(ctx); |
670 | up(&ctx->file->mutex); | ||
671 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
672 | return result; | 609 | return result; |
673 | } | 610 | } |
674 | 611 | ||
@@ -683,19 +620,12 @@ static ssize_t ib_ucm_listen(struct ib_ucm_file *file, | |||
683 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 620 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
684 | return -EFAULT; | 621 | return -EFAULT; |
685 | 622 | ||
686 | ctx = ib_ucm_ctx_get(cmd.id); | 623 | ctx = ib_ucm_ctx_get(file, cmd.id); |
687 | if (!ctx) | 624 | if (IS_ERR(ctx)) |
688 | return -ENOENT; | 625 | return PTR_ERR(ctx); |
689 | 626 | ||
690 | down(&ctx->file->mutex); | 627 | result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask); |
691 | if (ctx->file != file) | 628 | ib_ucm_ctx_put(ctx); |
692 | result = -EINVAL; | ||
693 | else | ||
694 | result = ib_cm_listen(ctx->cm_id, cmd.service_id, | ||
695 | cmd.service_mask); | ||
696 | |||
697 | up(&ctx->file->mutex); | ||
698 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
699 | return result; | 629 | return result; |
700 | } | 630 | } |
701 | 631 | ||
@@ -710,18 +640,12 @@ static ssize_t ib_ucm_establish(struct ib_ucm_file *file, | |||
710 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 640 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
711 | return -EFAULT; | 641 | return -EFAULT; |
712 | 642 | ||
713 | ctx = ib_ucm_ctx_get(cmd.id); | 643 | ctx = ib_ucm_ctx_get(file, cmd.id); |
714 | if (!ctx) | 644 | if (IS_ERR(ctx)) |
715 | return -ENOENT; | 645 | return PTR_ERR(ctx); |
716 | |||
717 | down(&ctx->file->mutex); | ||
718 | if (ctx->file != file) | ||
719 | result = -EINVAL; | ||
720 | else | ||
721 | result = ib_cm_establish(ctx->cm_id); | ||
722 | 646 | ||
723 | up(&ctx->file->mutex); | 647 | result = ib_cm_establish(ctx->cm_id); |
724 | ib_ucm_ctx_put(ctx); /* func reference */ | 648 | ib_ucm_ctx_put(ctx); |
725 | return result; | 649 | return result; |
726 | } | 650 | } |
727 | 651 | ||
@@ -768,8 +692,8 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) | |||
768 | return -EFAULT; | 692 | return -EFAULT; |
769 | } | 693 | } |
770 | 694 | ||
771 | memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof(union ib_gid)); | 695 | memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof sa_path->dgid); |
772 | memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof(union ib_gid)); | 696 | memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof sa_path->sgid); |
773 | 697 | ||
774 | sa_path->dlid = ucm_path.dlid; | 698 | sa_path->dlid = ucm_path.dlid; |
775 | sa_path->slid = ucm_path.slid; | 699 | sa_path->slid = ucm_path.slid; |
@@ -839,25 +763,17 @@ static ssize_t ib_ucm_send_req(struct ib_ucm_file *file, | |||
839 | param.max_cm_retries = cmd.max_cm_retries; | 763 | param.max_cm_retries = cmd.max_cm_retries; |
840 | param.srq = cmd.srq; | 764 | param.srq = cmd.srq; |
841 | 765 | ||
842 | ctx = ib_ucm_ctx_get(cmd.id); | 766 | ctx = ib_ucm_ctx_get(file, cmd.id); |
843 | if (!ctx) { | 767 | if (!IS_ERR(ctx)) { |
844 | result = -ENOENT; | ||
845 | goto done; | ||
846 | } | ||
847 | |||
848 | down(&ctx->file->mutex); | ||
849 | if (ctx->file != file) | ||
850 | result = -EINVAL; | ||
851 | else | ||
852 | result = ib_send_cm_req(ctx->cm_id, ¶m); | 768 | result = ib_send_cm_req(ctx->cm_id, ¶m); |
769 | ib_ucm_ctx_put(ctx); | ||
770 | } else | ||
771 | result = PTR_ERR(ctx); | ||
853 | 772 | ||
854 | up(&ctx->file->mutex); | ||
855 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
856 | done: | 773 | done: |
857 | kfree(param.private_data); | 774 | kfree(param.private_data); |
858 | kfree(param.primary_path); | 775 | kfree(param.primary_path); |
859 | kfree(param.alternate_path); | 776 | kfree(param.alternate_path); |
860 | |||
861 | return result; | 777 | return result; |
862 | } | 778 | } |
863 | 779 | ||
@@ -890,23 +806,14 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file, | |||
890 | param.rnr_retry_count = cmd.rnr_retry_count; | 806 | param.rnr_retry_count = cmd.rnr_retry_count; |
891 | param.srq = cmd.srq; | 807 | param.srq = cmd.srq; |
892 | 808 | ||
893 | ctx = ib_ucm_ctx_get(cmd.id); | 809 | ctx = ib_ucm_ctx_get(file, cmd.id); |
894 | if (!ctx) { | 810 | if (!IS_ERR(ctx)) { |
895 | result = -ENOENT; | ||
896 | goto done; | ||
897 | } | ||
898 | |||
899 | down(&ctx->file->mutex); | ||
900 | if (ctx->file != file) | ||
901 | result = -EINVAL; | ||
902 | else | ||
903 | result = ib_send_cm_rep(ctx->cm_id, ¶m); | 811 | result = ib_send_cm_rep(ctx->cm_id, ¶m); |
812 | ib_ucm_ctx_put(ctx); | ||
813 | } else | ||
814 | result = PTR_ERR(ctx); | ||
904 | 815 | ||
905 | up(&ctx->file->mutex); | ||
906 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
907 | done: | ||
908 | kfree(param.private_data); | 816 | kfree(param.private_data); |
909 | |||
910 | return result; | 817 | return result; |
911 | } | 818 | } |
912 | 819 | ||
@@ -928,23 +835,14 @@ static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file, | |||
928 | if (result) | 835 | if (result) |
929 | return result; | 836 | return result; |
930 | 837 | ||
931 | ctx = ib_ucm_ctx_get(cmd.id); | 838 | ctx = ib_ucm_ctx_get(file, cmd.id); |
932 | if (!ctx) { | 839 | if (!IS_ERR(ctx)) { |
933 | result = -ENOENT; | ||
934 | goto done; | ||
935 | } | ||
936 | |||
937 | down(&ctx->file->mutex); | ||
938 | if (ctx->file != file) | ||
939 | result = -EINVAL; | ||
940 | else | ||
941 | result = func(ctx->cm_id, private_data, cmd.len); | 840 | result = func(ctx->cm_id, private_data, cmd.len); |
841 | ib_ucm_ctx_put(ctx); | ||
842 | } else | ||
843 | result = PTR_ERR(ctx); | ||
942 | 844 | ||
943 | up(&ctx->file->mutex); | ||
944 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
945 | done: | ||
946 | kfree(private_data); | 845 | kfree(private_data); |
947 | |||
948 | return result; | 846 | return result; |
949 | } | 847 | } |
950 | 848 | ||
@@ -995,26 +893,17 @@ static ssize_t ib_ucm_send_info(struct ib_ucm_file *file, | |||
995 | if (result) | 893 | if (result) |
996 | goto done; | 894 | goto done; |
997 | 895 | ||
998 | ctx = ib_ucm_ctx_get(cmd.id); | 896 | ctx = ib_ucm_ctx_get(file, cmd.id); |
999 | if (!ctx) { | 897 | if (!IS_ERR(ctx)) { |
1000 | result = -ENOENT; | 898 | result = func(ctx->cm_id, cmd.status, info, cmd.info_len, |
1001 | goto done; | ||
1002 | } | ||
1003 | |||
1004 | down(&ctx->file->mutex); | ||
1005 | if (ctx->file != file) | ||
1006 | result = -EINVAL; | ||
1007 | else | ||
1008 | result = func(ctx->cm_id, cmd.status, | ||
1009 | info, cmd.info_len, | ||
1010 | data, cmd.data_len); | 899 | data, cmd.data_len); |
900 | ib_ucm_ctx_put(ctx); | ||
901 | } else | ||
902 | result = PTR_ERR(ctx); | ||
1011 | 903 | ||
1012 | up(&ctx->file->mutex); | ||
1013 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
1014 | done: | 904 | done: |
1015 | kfree(data); | 905 | kfree(data); |
1016 | kfree(info); | 906 | kfree(info); |
1017 | |||
1018 | return result; | 907 | return result; |
1019 | } | 908 | } |
1020 | 909 | ||
@@ -1048,24 +937,14 @@ static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file, | |||
1048 | if (result) | 937 | if (result) |
1049 | return result; | 938 | return result; |
1050 | 939 | ||
1051 | ctx = ib_ucm_ctx_get(cmd.id); | 940 | ctx = ib_ucm_ctx_get(file, cmd.id); |
1052 | if (!ctx) { | 941 | if (!IS_ERR(ctx)) { |
1053 | result = -ENOENT; | 942 | result = ib_send_cm_mra(ctx->cm_id, cmd.timeout, data, cmd.len); |
1054 | goto done; | 943 | ib_ucm_ctx_put(ctx); |
1055 | } | 944 | } else |
945 | result = PTR_ERR(ctx); | ||
1056 | 946 | ||
1057 | down(&ctx->file->mutex); | ||
1058 | if (ctx->file != file) | ||
1059 | result = -EINVAL; | ||
1060 | else | ||
1061 | result = ib_send_cm_mra(ctx->cm_id, cmd.timeout, | ||
1062 | data, cmd.len); | ||
1063 | |||
1064 | up(&ctx->file->mutex); | ||
1065 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
1066 | done: | ||
1067 | kfree(data); | 947 | kfree(data); |
1068 | |||
1069 | return result; | 948 | return result; |
1070 | } | 949 | } |
1071 | 950 | ||
@@ -1090,24 +969,16 @@ static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file, | |||
1090 | if (result) | 969 | if (result) |
1091 | goto done; | 970 | goto done; |
1092 | 971 | ||
1093 | ctx = ib_ucm_ctx_get(cmd.id); | 972 | ctx = ib_ucm_ctx_get(file, cmd.id); |
1094 | if (!ctx) { | 973 | if (!IS_ERR(ctx)) { |
1095 | result = -ENOENT; | ||
1096 | goto done; | ||
1097 | } | ||
1098 | |||
1099 | down(&ctx->file->mutex); | ||
1100 | if (ctx->file != file) | ||
1101 | result = -EINVAL; | ||
1102 | else | ||
1103 | result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len); | 974 | result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len); |
975 | ib_ucm_ctx_put(ctx); | ||
976 | } else | ||
977 | result = PTR_ERR(ctx); | ||
1104 | 978 | ||
1105 | up(&ctx->file->mutex); | ||
1106 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
1107 | done: | 979 | done: |
1108 | kfree(data); | 980 | kfree(data); |
1109 | kfree(path); | 981 | kfree(path); |
1110 | |||
1111 | return result; | 982 | return result; |
1112 | } | 983 | } |
1113 | 984 | ||
@@ -1140,24 +1011,16 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file, | |||
1140 | param.max_cm_retries = cmd.max_cm_retries; | 1011 | param.max_cm_retries = cmd.max_cm_retries; |
1141 | param.pkey = cmd.pkey; | 1012 | param.pkey = cmd.pkey; |
1142 | 1013 | ||
1143 | ctx = ib_ucm_ctx_get(cmd.id); | 1014 | ctx = ib_ucm_ctx_get(file, cmd.id); |
1144 | if (!ctx) { | 1015 | if (!IS_ERR(ctx)) { |
1145 | result = -ENOENT; | ||
1146 | goto done; | ||
1147 | } | ||
1148 | |||
1149 | down(&ctx->file->mutex); | ||
1150 | if (ctx->file != file) | ||
1151 | result = -EINVAL; | ||
1152 | else | ||
1153 | result = ib_send_cm_sidr_req(ctx->cm_id, ¶m); | 1016 | result = ib_send_cm_sidr_req(ctx->cm_id, ¶m); |
1017 | ib_ucm_ctx_put(ctx); | ||
1018 | } else | ||
1019 | result = PTR_ERR(ctx); | ||
1154 | 1020 | ||
1155 | up(&ctx->file->mutex); | ||
1156 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
1157 | done: | 1021 | done: |
1158 | kfree(param.private_data); | 1022 | kfree(param.private_data); |
1159 | kfree(param.path); | 1023 | kfree(param.path); |
1160 | |||
1161 | return result; | 1024 | return result; |
1162 | } | 1025 | } |
1163 | 1026 | ||
@@ -1184,30 +1047,22 @@ static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file, | |||
1184 | if (result) | 1047 | if (result) |
1185 | goto done; | 1048 | goto done; |
1186 | 1049 | ||
1187 | param.qp_num = cmd.qpn; | 1050 | param.qp_num = cmd.qpn; |
1188 | param.qkey = cmd.qkey; | 1051 | param.qkey = cmd.qkey; |
1189 | param.status = cmd.status; | 1052 | param.status = cmd.status; |
1190 | param.info_length = cmd.info_len; | 1053 | param.info_length = cmd.info_len; |
1191 | param.private_data_len = cmd.data_len; | 1054 | param.private_data_len = cmd.data_len; |
1192 | |||
1193 | ctx = ib_ucm_ctx_get(cmd.id); | ||
1194 | if (!ctx) { | ||
1195 | result = -ENOENT; | ||
1196 | goto done; | ||
1197 | } | ||
1198 | 1055 | ||
1199 | down(&ctx->file->mutex); | 1056 | ctx = ib_ucm_ctx_get(file, cmd.id); |
1200 | if (ctx->file != file) | 1057 | if (!IS_ERR(ctx)) { |
1201 | result = -EINVAL; | ||
1202 | else | ||
1203 | result = ib_send_cm_sidr_rep(ctx->cm_id, ¶m); | 1058 | result = ib_send_cm_sidr_rep(ctx->cm_id, ¶m); |
1059 | ib_ucm_ctx_put(ctx); | ||
1060 | } else | ||
1061 | result = PTR_ERR(ctx); | ||
1204 | 1062 | ||
1205 | up(&ctx->file->mutex); | ||
1206 | ib_ucm_ctx_put(ctx); /* func reference */ | ||
1207 | done: | 1063 | done: |
1208 | kfree(param.private_data); | 1064 | kfree(param.private_data); |
1209 | kfree(param.info); | 1065 | kfree(param.info); |
1210 | |||
1211 | return result; | 1066 | return result; |
1212 | } | 1067 | } |
1213 | 1068 | ||
@@ -1305,22 +1160,17 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) | |||
1305 | struct ib_ucm_context *ctx; | 1160 | struct ib_ucm_context *ctx; |
1306 | 1161 | ||
1307 | down(&file->mutex); | 1162 | down(&file->mutex); |
1308 | |||
1309 | while (!list_empty(&file->ctxs)) { | 1163 | while (!list_empty(&file->ctxs)) { |
1310 | 1164 | ||
1311 | ctx = list_entry(file->ctxs.next, | 1165 | ctx = list_entry(file->ctxs.next, |
1312 | struct ib_ucm_context, file_list); | 1166 | struct ib_ucm_context, file_list); |
1313 | 1167 | ||
1314 | up(&ctx->file->mutex); | 1168 | up(&file->mutex); |
1315 | ib_ucm_ctx_put(ctx); /* user reference */ | 1169 | ib_ucm_destroy_ctx(file, ctx->id); |
1316 | down(&file->mutex); | 1170 | down(&file->mutex); |
1317 | } | 1171 | } |
1318 | |||
1319 | up(&file->mutex); | 1172 | up(&file->mutex); |
1320 | |||
1321 | kfree(file); | 1173 | kfree(file); |
1322 | |||
1323 | ucm_dbg("Deleted struct\n"); | ||
1324 | return 0; | 1174 | return 0; |
1325 | } | 1175 | } |
1326 | 1176 | ||
diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h index 6d36606151b2..c8819b928a1b 100644 --- a/drivers/infiniband/core/ucm.h +++ b/drivers/infiniband/core/ucm.h | |||
@@ -40,17 +40,15 @@ | |||
40 | #include <linux/cdev.h> | 40 | #include <linux/cdev.h> |
41 | #include <linux/idr.h> | 41 | #include <linux/idr.h> |
42 | 42 | ||
43 | #include <ib_cm.h> | 43 | #include <rdma/ib_cm.h> |
44 | #include <ib_user_cm.h> | 44 | #include <rdma/ib_user_cm.h> |
45 | 45 | ||
46 | #define IB_UCM_CM_ID_INVALID 0xffffffff | 46 | #define IB_UCM_CM_ID_INVALID 0xffffffff |
47 | 47 | ||
48 | struct ib_ucm_file { | 48 | struct ib_ucm_file { |
49 | struct semaphore mutex; | 49 | struct semaphore mutex; |
50 | struct file *filp; | 50 | struct file *filp; |
51 | /* | 51 | |
52 | * list of pending events | ||
53 | */ | ||
54 | struct list_head ctxs; /* list of active connections */ | 52 | struct list_head ctxs; /* list of active connections */ |
55 | struct list_head events; /* list of pending events */ | 53 | struct list_head events; /* list of pending events */ |
56 | wait_queue_head_t poll_wait; | 54 | wait_queue_head_t poll_wait; |
@@ -58,12 +56,11 @@ struct ib_ucm_file { | |||
58 | 56 | ||
59 | struct ib_ucm_context { | 57 | struct ib_ucm_context { |
60 | int id; | 58 | int id; |
61 | int ref; | 59 | wait_queue_head_t wait; |
62 | int error; | 60 | atomic_t ref; |
63 | 61 | ||
64 | struct ib_ucm_file *file; | 62 | struct ib_ucm_file *file; |
65 | struct ib_cm_id *cm_id; | 63 | struct ib_cm_id *cm_id; |
66 | struct semaphore mutex; | ||
67 | 64 | ||
68 | struct list_head events; /* list of pending events. */ | 65 | struct list_head events; /* list of pending events. */ |
69 | struct list_head file_list; /* member in file ctx list */ | 66 | struct list_head file_list; /* member in file ctx list */ |
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c index dc4eb1db5e96..527b23450ab3 100644 --- a/drivers/infiniband/core/ud_header.c +++ b/drivers/infiniband/core/ud_header.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 2 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. 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 |
@@ -34,7 +35,7 @@ | |||
34 | 35 | ||
35 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
36 | 37 | ||
37 | #include <ib_pack.h> | 38 | #include <rdma/ib_pack.h> |
38 | 39 | ||
39 | #define STRUCT_FIELD(header, field) \ | 40 | #define STRUCT_FIELD(header, field) \ |
40 | .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \ | 41 | .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \ |
@@ -194,6 +195,7 @@ void ib_ud_header_init(int payload_bytes, | |||
194 | struct ib_ud_header *header) | 195 | struct ib_ud_header *header) |
195 | { | 196 | { |
196 | int header_len; | 197 | int header_len; |
198 | u16 packet_length; | ||
197 | 199 | ||
198 | memset(header, 0, sizeof *header); | 200 | memset(header, 0, sizeof *header); |
199 | 201 | ||
@@ -208,7 +210,7 @@ void ib_ud_header_init(int payload_bytes, | |||
208 | header->lrh.link_version = 0; | 210 | header->lrh.link_version = 0; |
209 | header->lrh.link_next_header = | 211 | header->lrh.link_next_header = |
210 | grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL; | 212 | grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL; |
211 | header->lrh.packet_length = (IB_LRH_BYTES + | 213 | packet_length = (IB_LRH_BYTES + |
212 | IB_BTH_BYTES + | 214 | IB_BTH_BYTES + |
213 | IB_DETH_BYTES + | 215 | IB_DETH_BYTES + |
214 | payload_bytes + | 216 | payload_bytes + |
@@ -217,8 +219,7 @@ void ib_ud_header_init(int payload_bytes, | |||
217 | 219 | ||
218 | header->grh_present = grh_present; | 220 | header->grh_present = grh_present; |
219 | if (grh_present) { | 221 | if (grh_present) { |
220 | header->lrh.packet_length += IB_GRH_BYTES / 4; | 222 | packet_length += IB_GRH_BYTES / 4; |
221 | |||
222 | header->grh.ip_version = 6; | 223 | header->grh.ip_version = 6; |
223 | header->grh.payload_length = | 224 | header->grh.payload_length = |
224 | cpu_to_be16((IB_BTH_BYTES + | 225 | cpu_to_be16((IB_BTH_BYTES + |
@@ -229,7 +230,7 @@ void ib_ud_header_init(int payload_bytes, | |||
229 | header->grh.next_header = 0x1b; | 230 | header->grh.next_header = 0x1b; |
230 | } | 231 | } |
231 | 232 | ||
232 | cpu_to_be16s(&header->lrh.packet_length); | 233 | header->lrh.packet_length = cpu_to_be16(packet_length); |
233 | 234 | ||
234 | if (header->immediate_present) | 235 | if (header->immediate_present) |
235 | header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE; | 236 | header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE; |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 2e38792df533..7c2f03057ddb 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -1,6 +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 Voltaire, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. |
4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | 4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. |
5 | * | 5 | * |
6 | * 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 |
@@ -49,8 +49,8 @@ | |||
49 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
50 | #include <asm/semaphore.h> | 50 | #include <asm/semaphore.h> |
51 | 51 | ||
52 | #include <ib_mad.h> | 52 | #include <rdma/ib_mad.h> |
53 | #include <ib_user_mad.h> | 53 | #include <rdma/ib_user_mad.h> |
54 | 54 | ||
55 | MODULE_AUTHOR("Roland Dreier"); | 55 | MODULE_AUTHOR("Roland Dreier"); |
56 | MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); | 56 | MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); |
@@ -271,7 +271,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
271 | struct ib_send_wr *bad_wr; | 271 | struct ib_send_wr *bad_wr; |
272 | struct ib_rmpp_mad *rmpp_mad; | 272 | struct ib_rmpp_mad *rmpp_mad; |
273 | u8 method; | 273 | u8 method; |
274 | u64 *tid; | 274 | __be64 *tid; |
275 | int ret, length, hdr_len, data_len, rmpp_hdr_size; | 275 | int ret, length, hdr_len, data_len, rmpp_hdr_size; |
276 | int rmpp_active = 0; | 276 | int rmpp_active = 0; |
277 | 277 | ||
@@ -316,7 +316,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
316 | if (packet->mad.hdr.grh_present) { | 316 | if (packet->mad.hdr.grh_present) { |
317 | ah_attr.ah_flags = IB_AH_GRH; | 317 | ah_attr.ah_flags = IB_AH_GRH; |
318 | memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); | 318 | memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); |
319 | ah_attr.grh.flow_label = packet->mad.hdr.flow_label; | 319 | ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label); |
320 | ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; | 320 | ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; |
321 | ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; | 321 | ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; |
322 | } | 322 | } |
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 7696022f9a4e..180b3d4765e4 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 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. | ||
5 | * Copyright (c) 2005 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 |
@@ -43,8 +45,8 @@ | |||
43 | #include <linux/kref.h> | 45 | #include <linux/kref.h> |
44 | #include <linux/idr.h> | 46 | #include <linux/idr.h> |
45 | 47 | ||
46 | #include <ib_verbs.h> | 48 | #include <rdma/ib_verbs.h> |
47 | #include <ib_user_verbs.h> | 49 | #include <rdma/ib_user_verbs.h> |
48 | 50 | ||
49 | struct ib_uverbs_device { | 51 | struct ib_uverbs_device { |
50 | int devnum; | 52 | int devnum; |
@@ -97,10 +99,12 @@ extern struct idr ib_uverbs_mw_idr; | |||
97 | extern struct idr ib_uverbs_ah_idr; | 99 | extern struct idr ib_uverbs_ah_idr; |
98 | extern struct idr ib_uverbs_cq_idr; | 100 | extern struct idr ib_uverbs_cq_idr; |
99 | extern struct idr ib_uverbs_qp_idr; | 101 | extern struct idr ib_uverbs_qp_idr; |
102 | extern struct idr ib_uverbs_srq_idr; | ||
100 | 103 | ||
101 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); | 104 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); |
102 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); | 105 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); |
103 | void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); | 106 | void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); |
107 | void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr); | ||
104 | 108 | ||
105 | int ib_umem_get(struct ib_device *dev, struct ib_umem *mem, | 109 | int ib_umem_get(struct ib_device *dev, struct ib_umem *mem, |
106 | void *addr, size_t size, int write); | 110 | void *addr, size_t size, int write); |
@@ -129,5 +133,8 @@ IB_UVERBS_DECLARE_CMD(modify_qp); | |||
129 | IB_UVERBS_DECLARE_CMD(destroy_qp); | 133 | IB_UVERBS_DECLARE_CMD(destroy_qp); |
130 | IB_UVERBS_DECLARE_CMD(attach_mcast); | 134 | IB_UVERBS_DECLARE_CMD(attach_mcast); |
131 | IB_UVERBS_DECLARE_CMD(detach_mcast); | 135 | IB_UVERBS_DECLARE_CMD(detach_mcast); |
136 | IB_UVERBS_DECLARE_CMD(create_srq); | ||
137 | IB_UVERBS_DECLARE_CMD(modify_srq); | ||
138 | IB_UVERBS_DECLARE_CMD(destroy_srq); | ||
132 | 139 | ||
133 | #endif /* UVERBS_H */ | 140 | #endif /* UVERBS_H */ |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 5f2bbcda4c73..ebccf9f38af9 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -724,6 +724,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
724 | struct ib_uobject *uobj; | 724 | struct ib_uobject *uobj; |
725 | struct ib_pd *pd; | 725 | struct ib_pd *pd; |
726 | struct ib_cq *scq, *rcq; | 726 | struct ib_cq *scq, *rcq; |
727 | struct ib_srq *srq; | ||
727 | struct ib_qp *qp; | 728 | struct ib_qp *qp; |
728 | struct ib_qp_init_attr attr; | 729 | struct ib_qp_init_attr attr; |
729 | int ret; | 730 | int ret; |
@@ -747,10 +748,12 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
747 | pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); | 748 | pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); |
748 | scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); | 749 | scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); |
749 | rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle); | 750 | rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle); |
751 | srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL; | ||
750 | 752 | ||
751 | if (!pd || pd->uobject->context != file->ucontext || | 753 | if (!pd || pd->uobject->context != file->ucontext || |
752 | !scq || scq->uobject->context != file->ucontext || | 754 | !scq || scq->uobject->context != file->ucontext || |
753 | !rcq || rcq->uobject->context != file->ucontext) { | 755 | !rcq || rcq->uobject->context != file->ucontext || |
756 | (cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) { | ||
754 | ret = -EINVAL; | 757 | ret = -EINVAL; |
755 | goto err_up; | 758 | goto err_up; |
756 | } | 759 | } |
@@ -759,7 +762,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
759 | attr.qp_context = file; | 762 | attr.qp_context = file; |
760 | attr.send_cq = scq; | 763 | attr.send_cq = scq; |
761 | attr.recv_cq = rcq; | 764 | attr.recv_cq = rcq; |
762 | attr.srq = NULL; | 765 | attr.srq = srq; |
763 | attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; | 766 | attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; |
764 | attr.qp_type = cmd.qp_type; | 767 | attr.qp_type = cmd.qp_type; |
765 | 768 | ||
@@ -1004,3 +1007,178 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, | |||
1004 | 1007 | ||
1005 | return ret ? ret : in_len; | 1008 | return ret ? ret : in_len; |
1006 | } | 1009 | } |
1010 | |||
1011 | ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, | ||
1012 | const char __user *buf, int in_len, | ||
1013 | int out_len) | ||
1014 | { | ||
1015 | struct ib_uverbs_create_srq cmd; | ||
1016 | struct ib_uverbs_create_srq_resp resp; | ||
1017 | struct ib_udata udata; | ||
1018 | struct ib_uobject *uobj; | ||
1019 | struct ib_pd *pd; | ||
1020 | struct ib_srq *srq; | ||
1021 | struct ib_srq_init_attr attr; | ||
1022 | int ret; | ||
1023 | |||
1024 | if (out_len < sizeof resp) | ||
1025 | return -ENOSPC; | ||
1026 | |||
1027 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
1028 | return -EFAULT; | ||
1029 | |||
1030 | INIT_UDATA(&udata, buf + sizeof cmd, | ||
1031 | (unsigned long) cmd.response + sizeof resp, | ||
1032 | in_len - sizeof cmd, out_len - sizeof resp); | ||
1033 | |||
1034 | uobj = kmalloc(sizeof *uobj, GFP_KERNEL); | ||
1035 | if (!uobj) | ||
1036 | return -ENOMEM; | ||
1037 | |||
1038 | down(&ib_uverbs_idr_mutex); | ||
1039 | |||
1040 | pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); | ||
1041 | |||
1042 | if (!pd || pd->uobject->context != file->ucontext) { | ||
1043 | ret = -EINVAL; | ||
1044 | goto err_up; | ||
1045 | } | ||
1046 | |||
1047 | attr.event_handler = ib_uverbs_srq_event_handler; | ||
1048 | attr.srq_context = file; | ||
1049 | attr.attr.max_wr = cmd.max_wr; | ||
1050 | attr.attr.max_sge = cmd.max_sge; | ||
1051 | attr.attr.srq_limit = cmd.srq_limit; | ||
1052 | |||
1053 | uobj->user_handle = cmd.user_handle; | ||
1054 | uobj->context = file->ucontext; | ||
1055 | |||
1056 | srq = pd->device->create_srq(pd, &attr, &udata); | ||
1057 | if (IS_ERR(srq)) { | ||
1058 | ret = PTR_ERR(srq); | ||
1059 | goto err_up; | ||
1060 | } | ||
1061 | |||
1062 | srq->device = pd->device; | ||
1063 | srq->pd = pd; | ||
1064 | srq->uobject = uobj; | ||
1065 | srq->event_handler = attr.event_handler; | ||
1066 | srq->srq_context = attr.srq_context; | ||
1067 | atomic_inc(&pd->usecnt); | ||
1068 | atomic_set(&srq->usecnt, 0); | ||
1069 | |||
1070 | memset(&resp, 0, sizeof resp); | ||
1071 | |||
1072 | retry: | ||
1073 | if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) { | ||
1074 | ret = -ENOMEM; | ||
1075 | goto err_destroy; | ||
1076 | } | ||
1077 | |||
1078 | ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->id); | ||
1079 | |||
1080 | if (ret == -EAGAIN) | ||
1081 | goto retry; | ||
1082 | if (ret) | ||
1083 | goto err_destroy; | ||
1084 | |||
1085 | resp.srq_handle = uobj->id; | ||
1086 | |||
1087 | spin_lock_irq(&file->ucontext->lock); | ||
1088 | list_add_tail(&uobj->list, &file->ucontext->srq_list); | ||
1089 | spin_unlock_irq(&file->ucontext->lock); | ||
1090 | |||
1091 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | ||
1092 | &resp, sizeof resp)) { | ||
1093 | ret = -EFAULT; | ||
1094 | goto err_list; | ||
1095 | } | ||
1096 | |||
1097 | up(&ib_uverbs_idr_mutex); | ||
1098 | |||
1099 | return in_len; | ||
1100 | |||
1101 | err_list: | ||
1102 | spin_lock_irq(&file->ucontext->lock); | ||
1103 | list_del(&uobj->list); | ||
1104 | spin_unlock_irq(&file->ucontext->lock); | ||
1105 | |||
1106 | err_destroy: | ||
1107 | ib_destroy_srq(srq); | ||
1108 | |||
1109 | err_up: | ||
1110 | up(&ib_uverbs_idr_mutex); | ||
1111 | |||
1112 | kfree(uobj); | ||
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, | ||
1117 | const char __user *buf, int in_len, | ||
1118 | int out_len) | ||
1119 | { | ||
1120 | struct ib_uverbs_modify_srq cmd; | ||
1121 | struct ib_srq *srq; | ||
1122 | struct ib_srq_attr attr; | ||
1123 | int ret; | ||
1124 | |||
1125 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
1126 | return -EFAULT; | ||
1127 | |||
1128 | down(&ib_uverbs_idr_mutex); | ||
1129 | |||
1130 | srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); | ||
1131 | if (!srq || srq->uobject->context != file->ucontext) { | ||
1132 | ret = -EINVAL; | ||
1133 | goto out; | ||
1134 | } | ||
1135 | |||
1136 | attr.max_wr = cmd.max_wr; | ||
1137 | attr.max_sge = cmd.max_sge; | ||
1138 | attr.srq_limit = cmd.srq_limit; | ||
1139 | |||
1140 | ret = ib_modify_srq(srq, &attr, cmd.attr_mask); | ||
1141 | |||
1142 | out: | ||
1143 | up(&ib_uverbs_idr_mutex); | ||
1144 | |||
1145 | return ret ? ret : in_len; | ||
1146 | } | ||
1147 | |||
1148 | ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | ||
1149 | const char __user *buf, int in_len, | ||
1150 | int out_len) | ||
1151 | { | ||
1152 | struct ib_uverbs_destroy_srq cmd; | ||
1153 | struct ib_srq *srq; | ||
1154 | struct ib_uobject *uobj; | ||
1155 | int ret = -EINVAL; | ||
1156 | |||
1157 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
1158 | return -EFAULT; | ||
1159 | |||
1160 | down(&ib_uverbs_idr_mutex); | ||
1161 | |||
1162 | srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); | ||
1163 | if (!srq || srq->uobject->context != file->ucontext) | ||
1164 | goto out; | ||
1165 | |||
1166 | uobj = srq->uobject; | ||
1167 | |||
1168 | ret = ib_destroy_srq(srq); | ||
1169 | if (ret) | ||
1170 | goto out; | ||
1171 | |||
1172 | idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); | ||
1173 | |||
1174 | spin_lock_irq(&file->ucontext->lock); | ||
1175 | list_del(&uobj->list); | ||
1176 | spin_unlock_irq(&file->ucontext->lock); | ||
1177 | |||
1178 | kfree(uobj); | ||
1179 | |||
1180 | out: | ||
1181 | up(&ib_uverbs_idr_mutex); | ||
1182 | |||
1183 | return ret ? ret : in_len; | ||
1184 | } | ||
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 5f6e9ea29cd7..09caf5b1ef36 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 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. | ||
5 | * Copyright (c) 2005 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 |
@@ -67,6 +69,7 @@ DEFINE_IDR(ib_uverbs_mw_idr); | |||
67 | DEFINE_IDR(ib_uverbs_ah_idr); | 69 | DEFINE_IDR(ib_uverbs_ah_idr); |
68 | DEFINE_IDR(ib_uverbs_cq_idr); | 70 | DEFINE_IDR(ib_uverbs_cq_idr); |
69 | DEFINE_IDR(ib_uverbs_qp_idr); | 71 | DEFINE_IDR(ib_uverbs_qp_idr); |
72 | DEFINE_IDR(ib_uverbs_srq_idr); | ||
70 | 73 | ||
71 | static spinlock_t map_lock; | 74 | static spinlock_t map_lock; |
72 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); | 75 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); |
@@ -91,6 +94,9 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
91 | [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, | 94 | [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, |
92 | [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, | 95 | [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, |
93 | [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, | 96 | [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, |
97 | [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, | ||
98 | [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, | ||
99 | [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, | ||
94 | }; | 100 | }; |
95 | 101 | ||
96 | static struct vfsmount *uverbs_event_mnt; | 102 | static struct vfsmount *uverbs_event_mnt; |
@@ -125,7 +131,14 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) | |||
125 | kfree(uobj); | 131 | kfree(uobj); |
126 | } | 132 | } |
127 | 133 | ||
128 | /* XXX Free SRQs */ | 134 | list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { |
135 | struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id); | ||
136 | idr_remove(&ib_uverbs_srq_idr, uobj->id); | ||
137 | ib_destroy_srq(srq); | ||
138 | list_del(&uobj->list); | ||
139 | kfree(uobj); | ||
140 | } | ||
141 | |||
129 | /* XXX Free MWs */ | 142 | /* XXX Free MWs */ |
130 | 143 | ||
131 | list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { | 144 | list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { |
@@ -344,6 +357,13 @@ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr) | |||
344 | event->event); | 357 | event->event); |
345 | } | 358 | } |
346 | 359 | ||
360 | void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr) | ||
361 | { | ||
362 | ib_uverbs_async_handler(context_ptr, | ||
363 | event->element.srq->uobject->user_handle, | ||
364 | event->event); | ||
365 | } | ||
366 | |||
347 | static void ib_uverbs_event_handler(struct ib_event_handler *handler, | 367 | static void ib_uverbs_event_handler(struct ib_event_handler *handler, |
348 | struct ib_event *event) | 368 | struct ib_event *event) |
349 | { | 369 | { |
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c index ed550f6595bd..36a32c315668 100644 --- a/drivers/infiniband/core/uverbs_mem.c +++ b/drivers/infiniband/core/uverbs_mem.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 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 |
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 506fdf1f2a26..5081d903e561 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. |
6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. | 6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. |
7 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
7 | * Copyright (c) 2005 Cisco Systems. All rights reserved. | 8 | * Copyright (c) 2005 Cisco Systems. All rights reserved. |
8 | * | 9 | * |
9 | * This software is available to you under a choice of one of two | 10 | * This software is available to you under a choice of one of two |
@@ -40,8 +41,8 @@ | |||
40 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
41 | #include <linux/err.h> | 42 | #include <linux/err.h> |
42 | 43 | ||
43 | #include <ib_verbs.h> | 44 | #include <rdma/ib_verbs.h> |
44 | #include <ib_cache.h> | 45 | #include <rdma/ib_cache.h> |
45 | 46 | ||
46 | /* Protection domains */ | 47 | /* Protection domains */ |
47 | 48 | ||
@@ -153,6 +154,66 @@ int ib_destroy_ah(struct ib_ah *ah) | |||
153 | } | 154 | } |
154 | EXPORT_SYMBOL(ib_destroy_ah); | 155 | EXPORT_SYMBOL(ib_destroy_ah); |
155 | 156 | ||
157 | /* Shared receive queues */ | ||
158 | |||
159 | struct ib_srq *ib_create_srq(struct ib_pd *pd, | ||
160 | struct ib_srq_init_attr *srq_init_attr) | ||
161 | { | ||
162 | struct ib_srq *srq; | ||
163 | |||
164 | if (!pd->device->create_srq) | ||
165 | return ERR_PTR(-ENOSYS); | ||
166 | |||
167 | srq = pd->device->create_srq(pd, srq_init_attr, NULL); | ||
168 | |||
169 | if (!IS_ERR(srq)) { | ||
170 | srq->device = pd->device; | ||
171 | srq->pd = pd; | ||
172 | srq->uobject = NULL; | ||
173 | srq->event_handler = srq_init_attr->event_handler; | ||
174 | srq->srq_context = srq_init_attr->srq_context; | ||
175 | atomic_inc(&pd->usecnt); | ||
176 | atomic_set(&srq->usecnt, 0); | ||
177 | } | ||
178 | |||
179 | return srq; | ||
180 | } | ||
181 | EXPORT_SYMBOL(ib_create_srq); | ||
182 | |||
183 | int ib_modify_srq(struct ib_srq *srq, | ||
184 | struct ib_srq_attr *srq_attr, | ||
185 | enum ib_srq_attr_mask srq_attr_mask) | ||
186 | { | ||
187 | return srq->device->modify_srq(srq, srq_attr, srq_attr_mask); | ||
188 | } | ||
189 | EXPORT_SYMBOL(ib_modify_srq); | ||
190 | |||
191 | int ib_query_srq(struct ib_srq *srq, | ||
192 | struct ib_srq_attr *srq_attr) | ||
193 | { | ||
194 | return srq->device->query_srq ? | ||
195 | srq->device->query_srq(srq, srq_attr) : -ENOSYS; | ||
196 | } | ||
197 | EXPORT_SYMBOL(ib_query_srq); | ||
198 | |||
199 | int ib_destroy_srq(struct ib_srq *srq) | ||
200 | { | ||
201 | struct ib_pd *pd; | ||
202 | int ret; | ||
203 | |||
204 | if (atomic_read(&srq->usecnt)) | ||
205 | return -EBUSY; | ||
206 | |||
207 | pd = srq->pd; | ||
208 | |||
209 | ret = srq->device->destroy_srq(srq); | ||
210 | if (!ret) | ||
211 | atomic_dec(&pd->usecnt); | ||
212 | |||
213 | return ret; | ||
214 | } | ||
215 | EXPORT_SYMBOL(ib_destroy_srq); | ||
216 | |||
156 | /* Queue pairs */ | 217 | /* Queue pairs */ |
157 | 218 | ||
158 | struct ib_qp *ib_create_qp(struct ib_pd *pd, | 219 | struct ib_qp *ib_create_qp(struct ib_pd *pd, |
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 */ | ||
diff --git a/drivers/infiniband/ulp/ipoib/Makefile b/drivers/infiniband/ulp/ipoib/Makefile index 394bc08abc6f..8935e74ae3f8 100644 --- a/drivers/infiniband/ulp/ipoib/Makefile +++ b/drivers/infiniband/ulp/ipoib/Makefile | |||
@@ -1,5 +1,3 @@ | |||
1 | EXTRA_CFLAGS += -Idrivers/infiniband/include | ||
2 | |||
3 | obj-$(CONFIG_INFINIBAND_IPOIB) += ib_ipoib.o | 1 | obj-$(CONFIG_INFINIBAND_IPOIB) += ib_ipoib.o |
4 | 2 | ||
5 | ib_ipoib-y := ipoib_main.o \ | 3 | ib_ipoib-y := ipoib_main.o \ |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 04c98f54e9c4..bea960b8191f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -1,5 +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. | ||
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 |
@@ -49,9 +51,9 @@ | |||
49 | #include <asm/atomic.h> | 51 | #include <asm/atomic.h> |
50 | #include <asm/semaphore.h> | 52 | #include <asm/semaphore.h> |
51 | 53 | ||
52 | #include <ib_verbs.h> | 54 | #include <rdma/ib_verbs.h> |
53 | #include <ib_pack.h> | 55 | #include <rdma/ib_pack.h> |
54 | #include <ib_sa.h> | 56 | #include <rdma/ib_sa.h> |
55 | 57 | ||
56 | /* constants */ | 58 | /* constants */ |
57 | 59 | ||
@@ -88,8 +90,8 @@ enum { | |||
88 | /* structs */ | 90 | /* structs */ |
89 | 91 | ||
90 | struct ipoib_header { | 92 | struct ipoib_header { |
91 | u16 proto; | 93 | __be16 proto; |
92 | u16 reserved; | 94 | u16 reserved; |
93 | }; | 95 | }; |
94 | 96 | ||
95 | struct ipoib_pseudoheader { | 97 | struct ipoib_pseudoheader { |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index a84e5fe0f193..38b150f775e7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
@@ -97,7 +97,7 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr) | |||
97 | 97 | ||
98 | for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { | 98 | for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { |
99 | n += sprintf(gid_buf + n, "%x", | 99 | n += sprintf(gid_buf + n, "%x", |
100 | be16_to_cpu(((u16 *)mgid.raw)[i])); | 100 | be16_to_cpu(((__be16 *) mgid.raw)[i])); |
101 | if (i < sizeof mgid / 2 - 1) | 101 | if (i < sizeof mgid / 2 - 1) |
102 | gid_buf[n++] = ':'; | 102 | gid_buf[n++] = ':'; |
103 | } | 103 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index eee82363167d..ef0e3894863c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -1,5 +1,8 @@ | |||
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. | ||
4 | * Copyright (c) 2005 Mellanox Technologies. All rights reserved. | ||
5 | * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved. | ||
3 | * | 6 | * |
4 | * 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 |
5 | * 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,7 +38,7 @@ | |||
35 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
36 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
37 | 40 | ||
38 | #include <ib_cache.h> | 41 | #include <rdma/ib_cache.h> |
39 | 42 | ||
40 | #include "ipoib.h" | 43 | #include "ipoib.h" |
41 | 44 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index fa00816a3cf7..0e8ac138e355 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.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 Sun Microsystems, Inc. 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 |
@@ -34,7 +36,6 @@ | |||
34 | 36 | ||
35 | #include "ipoib.h" | 37 | #include "ipoib.h" |
36 | 38 | ||
37 | #include <linux/version.h> | ||
38 | #include <linux/module.h> | 39 | #include <linux/module.h> |
39 | 40 | ||
40 | #include <linux/init.h> | 41 | #include <linux/init.h> |
@@ -607,8 +608,8 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
607 | ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x " | 608 | ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x " |
608 | IPOIB_GID_FMT "\n", | 609 | IPOIB_GID_FMT "\n", |
609 | skb->dst ? "neigh" : "dst", | 610 | skb->dst ? "neigh" : "dst", |
610 | be16_to_cpup((u16 *) skb->data), | 611 | be16_to_cpup((__be16 *) skb->data), |
611 | be32_to_cpup((u32 *) phdr->hwaddr), | 612 | be32_to_cpup((__be32 *) phdr->hwaddr), |
612 | IPOIB_GID_ARG(*(union ib_gid *) (phdr->hwaddr + 4))); | 613 | IPOIB_GID_ARG(*(union ib_gid *) (phdr->hwaddr + 4))); |
613 | dev_kfree_skb_any(skb); | 614 | dev_kfree_skb_any(skb); |
614 | ++priv->stats.tx_dropped; | 615 | ++priv->stats.tx_dropped; |
@@ -671,7 +672,7 @@ static void ipoib_set_mcast_list(struct net_device *dev) | |||
671 | { | 672 | { |
672 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 673 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
673 | 674 | ||
674 | schedule_work(&priv->restart_task); | 675 | queue_work(ipoib_workqueue, &priv->restart_task); |
675 | } | 676 | } |
676 | 677 | ||
677 | static void ipoib_neigh_destructor(struct neighbour *n) | 678 | static void ipoib_neigh_destructor(struct neighbour *n) |
@@ -780,15 +781,11 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
780 | 781 | ||
781 | ipoib_ib_dev_cleanup(dev); | 782 | ipoib_ib_dev_cleanup(dev); |
782 | 783 | ||
783 | if (priv->rx_ring) { | 784 | kfree(priv->rx_ring); |
784 | kfree(priv->rx_ring); | 785 | kfree(priv->tx_ring); |
785 | priv->rx_ring = NULL; | ||
786 | } | ||
787 | 786 | ||
788 | if (priv->tx_ring) { | 787 | priv->rx_ring = NULL; |
789 | kfree(priv->tx_ring); | 788 | priv->tx_ring = NULL; |
790 | priv->tx_ring = NULL; | ||
791 | } | ||
792 | } | 789 | } |
793 | 790 | ||
794 | static void ipoib_setup(struct net_device *dev) | 791 | static void ipoib_setup(struct net_device *dev) |
@@ -886,6 +883,12 @@ static ssize_t create_child(struct class_device *cdev, | |||
886 | if (pkey < 0 || pkey > 0xffff) | 883 | if (pkey < 0 || pkey > 0xffff) |
887 | return -EINVAL; | 884 | return -EINVAL; |
888 | 885 | ||
886 | /* | ||
887 | * Set the full membership bit, so that we join the right | ||
888 | * broadcast group, etc. | ||
889 | */ | ||
890 | pkey |= 0x8000; | ||
891 | |||
889 | ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev), | 892 | ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev), |
890 | pkey); | 893 | pkey); |
891 | 894 | ||
@@ -938,6 +941,12 @@ static struct net_device *ipoib_add_port(const char *format, | |||
938 | goto alloc_mem_failed; | 941 | goto alloc_mem_failed; |
939 | } | 942 | } |
940 | 943 | ||
944 | /* | ||
945 | * Set the full membership bit, so that we join the right | ||
946 | * broadcast group, etc. | ||
947 | */ | ||
948 | priv->pkey |= 0x8000; | ||
949 | |||
941 | priv->dev->broadcast[8] = priv->pkey >> 8; | 950 | priv->dev->broadcast[8] = priv->pkey >> 8; |
942 | priv->dev->broadcast[9] = priv->pkey & 0xff; | 951 | priv->dev->broadcast[9] = priv->pkey & 0xff; |
943 | 952 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 70208c3d21e2..aca7aea18a69 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -1,5 +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. | ||
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 |
@@ -357,7 +359,7 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) | |||
357 | 359 | ||
358 | rec.mgid = mcast->mcmember.mgid; | 360 | rec.mgid = mcast->mcmember.mgid; |
359 | rec.port_gid = priv->local_gid; | 361 | rec.port_gid = priv->local_gid; |
360 | rec.pkey = be16_to_cpu(priv->pkey); | 362 | rec.pkey = cpu_to_be16(priv->pkey); |
361 | 363 | ||
362 | ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, | 364 | ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, |
363 | IB_SA_MCMEMBER_REC_MGID | | 365 | IB_SA_MCMEMBER_REC_MGID | |
@@ -457,7 +459,7 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, | |||
457 | 459 | ||
458 | rec.mgid = mcast->mcmember.mgid; | 460 | rec.mgid = mcast->mcmember.mgid; |
459 | rec.port_gid = priv->local_gid; | 461 | rec.port_gid = priv->local_gid; |
460 | rec.pkey = be16_to_cpu(priv->pkey); | 462 | rec.pkey = cpu_to_be16(priv->pkey); |
461 | 463 | ||
462 | comp_mask = | 464 | comp_mask = |
463 | IB_SA_MCMEMBER_REC_MGID | | 465 | IB_SA_MCMEMBER_REC_MGID | |
@@ -646,7 +648,7 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) | |||
646 | 648 | ||
647 | rec.mgid = mcast->mcmember.mgid; | 649 | rec.mgid = mcast->mcmember.mgid; |
648 | rec.port_gid = priv->local_gid; | 650 | rec.port_gid = priv->local_gid; |
649 | rec.pkey = be16_to_cpu(priv->pkey); | 651 | rec.pkey = cpu_to_be16(priv->pkey); |
650 | 652 | ||
651 | /* Remove ourselves from the multicast group */ | 653 | /* Remove ourselves from the multicast group */ |
652 | ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid), | 654 | ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid), |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 4933edf062c2..79f59d0563ed 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.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 |
@@ -32,7 +33,7 @@ | |||
32 | * $Id: ipoib_verbs.c 1349 2004-12-16 21:09:43Z roland $ | 33 | * $Id: ipoib_verbs.c 1349 2004-12-16 21:09:43Z roland $ |
33 | */ | 34 | */ |
34 | 35 | ||
35 | #include <ib_cache.h> | 36 | #include <rdma/ib_cache.h> |
36 | 37 | ||
37 | #include "ipoib.h" | 38 | #include "ipoib.h" |
38 | 39 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 94b8ea812fef..332d730e60c2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
@@ -32,7 +32,6 @@ | |||
32 | * $Id: ipoib_vlan.c 1349 2004-12-16 21:09:43Z roland $ | 32 | * $Id: ipoib_vlan.c 1349 2004-12-16 21:09:43Z roland $ |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/version.h> | ||
36 | #include <linux/module.h> | 35 | #include <linux/module.h> |
37 | 36 | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
diff --git a/drivers/infiniband/include/ib_cache.h b/include/rdma/ib_cache.h index 44ef6bb9b9df..5bf9834f7dca 100644 --- a/drivers/infiniband/include/ib_cache.h +++ b/include/rdma/ib_cache.h | |||
@@ -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 Intel Corporation. All rights reserved. | ||
4 | * Copyright (c) 2005 Sun Microsystems, 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 |
@@ -35,7 +37,7 @@ | |||
35 | #ifndef _IB_CACHE_H | 37 | #ifndef _IB_CACHE_H |
36 | #define _IB_CACHE_H | 38 | #define _IB_CACHE_H |
37 | 39 | ||
38 | #include <ib_verbs.h> | 40 | #include <rdma/ib_verbs.h> |
39 | 41 | ||
40 | /** | 42 | /** |
41 | * ib_get_cached_gid - Returns a cached GID table entry | 43 | * ib_get_cached_gid - Returns a cached GID table entry |
diff --git a/drivers/infiniband/include/ib_cm.h b/include/rdma/ib_cm.h index da650115e79a..77fe9039209b 100644 --- a/drivers/infiniband/include/ib_cm.h +++ b/include/rdma/ib_cm.h | |||
@@ -37,8 +37,8 @@ | |||
37 | #if !defined(IB_CM_H) | 37 | #if !defined(IB_CM_H) |
38 | #define IB_CM_H | 38 | #define IB_CM_H |
39 | 39 | ||
40 | #include <ib_mad.h> | 40 | #include <rdma/ib_mad.h> |
41 | #include <ib_sa.h> | 41 | #include <rdma/ib_sa.h> |
42 | 42 | ||
43 | enum ib_cm_state { | 43 | enum ib_cm_state { |
44 | IB_CM_IDLE, | 44 | IB_CM_IDLE, |
@@ -115,7 +115,7 @@ struct ib_cm_req_event_param { | |||
115 | struct ib_sa_path_rec *primary_path; | 115 | struct ib_sa_path_rec *primary_path; |
116 | struct ib_sa_path_rec *alternate_path; | 116 | struct ib_sa_path_rec *alternate_path; |
117 | 117 | ||
118 | u64 remote_ca_guid; | 118 | __be64 remote_ca_guid; |
119 | u32 remote_qkey; | 119 | u32 remote_qkey; |
120 | u32 remote_qpn; | 120 | u32 remote_qpn; |
121 | enum ib_qp_type qp_type; | 121 | enum ib_qp_type qp_type; |
@@ -132,7 +132,7 @@ struct ib_cm_req_event_param { | |||
132 | }; | 132 | }; |
133 | 133 | ||
134 | struct ib_cm_rep_event_param { | 134 | struct ib_cm_rep_event_param { |
135 | u64 remote_ca_guid; | 135 | __be64 remote_ca_guid; |
136 | u32 remote_qkey; | 136 | u32 remote_qkey; |
137 | u32 remote_qpn; | 137 | u32 remote_qpn; |
138 | u32 starting_psn; | 138 | u32 starting_psn; |
@@ -146,39 +146,39 @@ struct ib_cm_rep_event_param { | |||
146 | }; | 146 | }; |
147 | 147 | ||
148 | enum ib_cm_rej_reason { | 148 | enum ib_cm_rej_reason { |
149 | IB_CM_REJ_NO_QP = __constant_htons(1), | 149 | IB_CM_REJ_NO_QP = 1, |
150 | IB_CM_REJ_NO_EEC = __constant_htons(2), | 150 | IB_CM_REJ_NO_EEC = 2, |
151 | IB_CM_REJ_NO_RESOURCES = __constant_htons(3), | 151 | IB_CM_REJ_NO_RESOURCES = 3, |
152 | IB_CM_REJ_TIMEOUT = __constant_htons(4), | 152 | IB_CM_REJ_TIMEOUT = 4, |
153 | IB_CM_REJ_UNSUPPORTED = __constant_htons(5), | 153 | IB_CM_REJ_UNSUPPORTED = 5, |
154 | IB_CM_REJ_INVALID_COMM_ID = __constant_htons(6), | 154 | IB_CM_REJ_INVALID_COMM_ID = 6, |
155 | IB_CM_REJ_INVALID_COMM_INSTANCE = __constant_htons(7), | 155 | IB_CM_REJ_INVALID_COMM_INSTANCE = 7, |
156 | IB_CM_REJ_INVALID_SERVICE_ID = __constant_htons(8), | 156 | IB_CM_REJ_INVALID_SERVICE_ID = 8, |
157 | IB_CM_REJ_INVALID_TRANSPORT_TYPE = __constant_htons(9), | 157 | IB_CM_REJ_INVALID_TRANSPORT_TYPE = 9, |
158 | IB_CM_REJ_STALE_CONN = __constant_htons(10), | 158 | IB_CM_REJ_STALE_CONN = 10, |
159 | IB_CM_REJ_RDC_NOT_EXIST = __constant_htons(11), | 159 | IB_CM_REJ_RDC_NOT_EXIST = 11, |
160 | IB_CM_REJ_INVALID_GID = __constant_htons(12), | 160 | IB_CM_REJ_INVALID_GID = 12, |
161 | IB_CM_REJ_INVALID_LID = __constant_htons(13), | 161 | IB_CM_REJ_INVALID_LID = 13, |
162 | IB_CM_REJ_INVALID_SL = __constant_htons(14), | 162 | IB_CM_REJ_INVALID_SL = 14, |
163 | IB_CM_REJ_INVALID_TRAFFIC_CLASS = __constant_htons(15), | 163 | IB_CM_REJ_INVALID_TRAFFIC_CLASS = 15, |
164 | IB_CM_REJ_INVALID_HOP_LIMIT = __constant_htons(16), | 164 | IB_CM_REJ_INVALID_HOP_LIMIT = 16, |
165 | IB_CM_REJ_INVALID_PACKET_RATE = __constant_htons(17), | 165 | IB_CM_REJ_INVALID_PACKET_RATE = 17, |
166 | IB_CM_REJ_INVALID_ALT_GID = __constant_htons(18), | 166 | IB_CM_REJ_INVALID_ALT_GID = 18, |
167 | IB_CM_REJ_INVALID_ALT_LID = __constant_htons(19), | 167 | IB_CM_REJ_INVALID_ALT_LID = 19, |
168 | IB_CM_REJ_INVALID_ALT_SL = __constant_htons(20), | 168 | IB_CM_REJ_INVALID_ALT_SL = 20, |
169 | IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS = __constant_htons(21), | 169 | IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS = 21, |
170 | IB_CM_REJ_INVALID_ALT_HOP_LIMIT = __constant_htons(22), | 170 | IB_CM_REJ_INVALID_ALT_HOP_LIMIT = 22, |
171 | IB_CM_REJ_INVALID_ALT_PACKET_RATE = __constant_htons(23), | 171 | IB_CM_REJ_INVALID_ALT_PACKET_RATE = 23, |
172 | IB_CM_REJ_PORT_CM_REDIRECT = __constant_htons(24), | 172 | IB_CM_REJ_PORT_CM_REDIRECT = 24, |
173 | IB_CM_REJ_PORT_REDIRECT = __constant_htons(25), | 173 | IB_CM_REJ_PORT_REDIRECT = 25, |
174 | IB_CM_REJ_INVALID_MTU = __constant_htons(26), | 174 | IB_CM_REJ_INVALID_MTU = 26, |
175 | IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES = __constant_htons(27), | 175 | IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES = 27, |
176 | IB_CM_REJ_CONSUMER_DEFINED = __constant_htons(28), | 176 | IB_CM_REJ_CONSUMER_DEFINED = 28, |
177 | IB_CM_REJ_INVALID_RNR_RETRY = __constant_htons(29), | 177 | IB_CM_REJ_INVALID_RNR_RETRY = 29, |
178 | IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID = __constant_htons(30), | 178 | IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID = 30, |
179 | IB_CM_REJ_INVALID_CLASS_VERSION = __constant_htons(31), | 179 | IB_CM_REJ_INVALID_CLASS_VERSION = 31, |
180 | IB_CM_REJ_INVALID_FLOW_LABEL = __constant_htons(32), | 180 | IB_CM_REJ_INVALID_FLOW_LABEL = 32, |
181 | IB_CM_REJ_INVALID_ALT_FLOW_LABEL = __constant_htons(33) | 181 | IB_CM_REJ_INVALID_ALT_FLOW_LABEL = 33 |
182 | }; | 182 | }; |
183 | 183 | ||
184 | struct ib_cm_rej_event_param { | 184 | struct ib_cm_rej_event_param { |
@@ -222,8 +222,7 @@ struct ib_cm_sidr_req_event_param { | |||
222 | struct ib_cm_id *listen_id; | 222 | struct ib_cm_id *listen_id; |
223 | struct ib_device *device; | 223 | struct ib_device *device; |
224 | u8 port; | 224 | u8 port; |
225 | 225 | u16 pkey; | |
226 | u16 pkey; | ||
227 | }; | 226 | }; |
228 | 227 | ||
229 | enum ib_cm_sidr_status { | 228 | enum ib_cm_sidr_status { |
@@ -285,12 +284,12 @@ typedef int (*ib_cm_handler)(struct ib_cm_id *cm_id, | |||
285 | struct ib_cm_id { | 284 | struct ib_cm_id { |
286 | ib_cm_handler cm_handler; | 285 | ib_cm_handler cm_handler; |
287 | void *context; | 286 | void *context; |
288 | u64 service_id; | 287 | __be64 service_id; |
289 | u64 service_mask; | 288 | __be64 service_mask; |
290 | enum ib_cm_state state; /* internal CM/debug use */ | 289 | enum ib_cm_state state; /* internal CM/debug use */ |
291 | enum ib_cm_lap_state lap_state; /* internal CM/debug use */ | 290 | enum ib_cm_lap_state lap_state; /* internal CM/debug use */ |
292 | u32 local_id; | 291 | __be32 local_id; |
293 | u32 remote_id; | 292 | __be32 remote_id; |
294 | }; | 293 | }; |
295 | 294 | ||
296 | /** | 295 | /** |
@@ -330,13 +329,13 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id); | |||
330 | * IB_CM_ASSIGN_SERVICE_ID. | 329 | * IB_CM_ASSIGN_SERVICE_ID. |
331 | */ | 330 | */ |
332 | int ib_cm_listen(struct ib_cm_id *cm_id, | 331 | int ib_cm_listen(struct ib_cm_id *cm_id, |
333 | u64 service_id, | 332 | __be64 service_id, |
334 | u64 service_mask); | 333 | __be64 service_mask); |
335 | 334 | ||
336 | struct ib_cm_req_param { | 335 | struct ib_cm_req_param { |
337 | struct ib_sa_path_rec *primary_path; | 336 | struct ib_sa_path_rec *primary_path; |
338 | struct ib_sa_path_rec *alternate_path; | 337 | struct ib_sa_path_rec *alternate_path; |
339 | u64 service_id; | 338 | __be64 service_id; |
340 | u32 qp_num; | 339 | u32 qp_num; |
341 | enum ib_qp_type qp_type; | 340 | enum ib_qp_type qp_type; |
342 | u32 starting_psn; | 341 | u32 starting_psn; |
@@ -528,7 +527,7 @@ int ib_send_cm_apr(struct ib_cm_id *cm_id, | |||
528 | 527 | ||
529 | struct ib_cm_sidr_req_param { | 528 | struct ib_cm_sidr_req_param { |
530 | struct ib_sa_path_rec *path; | 529 | struct ib_sa_path_rec *path; |
531 | u64 service_id; | 530 | __be64 service_id; |
532 | int timeout_ms; | 531 | int timeout_ms; |
533 | const void *private_data; | 532 | const void *private_data; |
534 | u8 private_data_len; | 533 | u8 private_data_len; |
diff --git a/drivers/infiniband/include/ib_fmr_pool.h b/include/rdma/ib_fmr_pool.h index 6c9e24d6e144..86b7e93f198b 100644 --- a/drivers/infiniband/include/ib_fmr_pool.h +++ b/include/rdma/ib_fmr_pool.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #if !defined(IB_FMR_POOL_H) | 36 | #if !defined(IB_FMR_POOL_H) |
37 | #define IB_FMR_POOL_H | 37 | #define IB_FMR_POOL_H |
38 | 38 | ||
39 | #include <ib_verbs.h> | 39 | #include <rdma/ib_verbs.h> |
40 | 40 | ||
41 | struct ib_fmr_pool; | 41 | struct ib_fmr_pool; |
42 | 42 | ||
diff --git a/drivers/infiniband/include/ib_mad.h b/include/rdma/ib_mad.h index 491b6f25b3b8..fc6b1c18ffc6 100644 --- a/drivers/infiniband/include/ib_mad.h +++ b/include/rdma/ib_mad.h | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
43 | 43 | ||
44 | #include <ib_verbs.h> | 44 | #include <rdma/ib_verbs.h> |
45 | 45 | ||
46 | /* Management base version */ | 46 | /* Management base version */ |
47 | #define IB_MGMT_BASE_VERSION 1 | 47 | #define IB_MGMT_BASE_VERSION 1 |
@@ -90,6 +90,7 @@ | |||
90 | 90 | ||
91 | #define IB_MGMT_RMPP_STATUS_SUCCESS 0 | 91 | #define IB_MGMT_RMPP_STATUS_SUCCESS 0 |
92 | #define IB_MGMT_RMPP_STATUS_RESX 1 | 92 | #define IB_MGMT_RMPP_STATUS_RESX 1 |
93 | #define IB_MGMT_RMPP_STATUS_ABORT_MIN 118 | ||
93 | #define IB_MGMT_RMPP_STATUS_T2L 118 | 94 | #define IB_MGMT_RMPP_STATUS_T2L 118 |
94 | #define IB_MGMT_RMPP_STATUS_BAD_LEN 119 | 95 | #define IB_MGMT_RMPP_STATUS_BAD_LEN 119 |
95 | #define IB_MGMT_RMPP_STATUS_BAD_SEG 120 | 96 | #define IB_MGMT_RMPP_STATUS_BAD_SEG 120 |
@@ -100,6 +101,7 @@ | |||
100 | #define IB_MGMT_RMPP_STATUS_UNV 125 | 101 | #define IB_MGMT_RMPP_STATUS_UNV 125 |
101 | #define IB_MGMT_RMPP_STATUS_TMR 126 | 102 | #define IB_MGMT_RMPP_STATUS_TMR 126 |
102 | #define IB_MGMT_RMPP_STATUS_UNSPEC 127 | 103 | #define IB_MGMT_RMPP_STATUS_UNSPEC 127 |
104 | #define IB_MGMT_RMPP_STATUS_ABORT_MAX 127 | ||
103 | 105 | ||
104 | #define IB_QP0 0 | 106 | #define IB_QP0 0 |
105 | #define IB_QP1 __constant_htonl(1) | 107 | #define IB_QP1 __constant_htonl(1) |
@@ -111,12 +113,12 @@ struct ib_mad_hdr { | |||
111 | u8 mgmt_class; | 113 | u8 mgmt_class; |
112 | u8 class_version; | 114 | u8 class_version; |
113 | u8 method; | 115 | u8 method; |
114 | u16 status; | 116 | __be16 status; |
115 | u16 class_specific; | 117 | __be16 class_specific; |
116 | u64 tid; | 118 | __be64 tid; |
117 | u16 attr_id; | 119 | __be16 attr_id; |
118 | u16 resv; | 120 | __be16 resv; |
119 | u32 attr_mod; | 121 | __be32 attr_mod; |
120 | }; | 122 | }; |
121 | 123 | ||
122 | struct ib_rmpp_hdr { | 124 | struct ib_rmpp_hdr { |
@@ -124,8 +126,8 @@ struct ib_rmpp_hdr { | |||
124 | u8 rmpp_type; | 126 | u8 rmpp_type; |
125 | u8 rmpp_rtime_flags; | 127 | u8 rmpp_rtime_flags; |
126 | u8 rmpp_status; | 128 | u8 rmpp_status; |
127 | u32 seg_num; | 129 | __be32 seg_num; |
128 | u32 paylen_newwin; | 130 | __be32 paylen_newwin; |
129 | }; | 131 | }; |
130 | 132 | ||
131 | typedef u64 __bitwise ib_sa_comp_mask; | 133 | typedef u64 __bitwise ib_sa_comp_mask; |
@@ -139,9 +141,9 @@ typedef u64 __bitwise ib_sa_comp_mask; | |||
139 | * the wire so we can't change the layout) | 141 | * the wire so we can't change the layout) |
140 | */ | 142 | */ |
141 | struct ib_sa_hdr { | 143 | struct ib_sa_hdr { |
142 | u64 sm_key; | 144 | __be64 sm_key; |
143 | u16 attr_offset; | 145 | __be16 attr_offset; |
144 | u16 reserved; | 146 | __be16 reserved; |
145 | ib_sa_comp_mask comp_mask; | 147 | ib_sa_comp_mask comp_mask; |
146 | } __attribute__ ((packed)); | 148 | } __attribute__ ((packed)); |
147 | 149 | ||
diff --git a/drivers/infiniband/include/ib_pack.h b/include/rdma/ib_pack.h index fe480f3e8654..f926020d6331 100644 --- a/drivers/infiniband/include/ib_pack.h +++ b/include/rdma/ib_pack.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #ifndef IB_PACK_H | 35 | #ifndef IB_PACK_H |
36 | #define IB_PACK_H | 36 | #define IB_PACK_H |
37 | 37 | ||
38 | #include <ib_verbs.h> | 38 | #include <rdma/ib_verbs.h> |
39 | 39 | ||
40 | enum { | 40 | enum { |
41 | IB_LRH_BYTES = 8, | 41 | IB_LRH_BYTES = 8, |
diff --git a/drivers/infiniband/include/ib_sa.h b/include/rdma/ib_sa.h index 6d999f7b5d93..c022edfc49da 100644 --- a/drivers/infiniband/include/ib_sa.h +++ b/include/rdma/ib_sa.h | |||
@@ -38,8 +38,8 @@ | |||
38 | 38 | ||
39 | #include <linux/compiler.h> | 39 | #include <linux/compiler.h> |
40 | 40 | ||
41 | #include <ib_verbs.h> | 41 | #include <rdma/ib_verbs.h> |
42 | #include <ib_mad.h> | 42 | #include <rdma/ib_mad.h> |
43 | 43 | ||
44 | enum { | 44 | enum { |
45 | IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */ | 45 | IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */ |
@@ -133,16 +133,16 @@ struct ib_sa_path_rec { | |||
133 | /* reserved */ | 133 | /* reserved */ |
134 | union ib_gid dgid; | 134 | union ib_gid dgid; |
135 | union ib_gid sgid; | 135 | union ib_gid sgid; |
136 | u16 dlid; | 136 | __be16 dlid; |
137 | u16 slid; | 137 | __be16 slid; |
138 | int raw_traffic; | 138 | int raw_traffic; |
139 | /* reserved */ | 139 | /* reserved */ |
140 | u32 flow_label; | 140 | __be32 flow_label; |
141 | u8 hop_limit; | 141 | u8 hop_limit; |
142 | u8 traffic_class; | 142 | u8 traffic_class; |
143 | int reversible; | 143 | int reversible; |
144 | u8 numb_path; | 144 | u8 numb_path; |
145 | u16 pkey; | 145 | __be16 pkey; |
146 | /* reserved */ | 146 | /* reserved */ |
147 | u8 sl; | 147 | u8 sl; |
148 | u8 mtu_selector; | 148 | u8 mtu_selector; |
@@ -176,18 +176,18 @@ struct ib_sa_path_rec { | |||
176 | struct ib_sa_mcmember_rec { | 176 | struct ib_sa_mcmember_rec { |
177 | union ib_gid mgid; | 177 | union ib_gid mgid; |
178 | union ib_gid port_gid; | 178 | union ib_gid port_gid; |
179 | u32 qkey; | 179 | __be32 qkey; |
180 | u16 mlid; | 180 | __be16 mlid; |
181 | u8 mtu_selector; | 181 | u8 mtu_selector; |
182 | u8 mtu; | 182 | u8 mtu; |
183 | u8 traffic_class; | 183 | u8 traffic_class; |
184 | u16 pkey; | 184 | __be16 pkey; |
185 | u8 rate_selector; | 185 | u8 rate_selector; |
186 | u8 rate; | 186 | u8 rate; |
187 | u8 packet_life_time_selector; | 187 | u8 packet_life_time_selector; |
188 | u8 packet_life_time; | 188 | u8 packet_life_time; |
189 | u8 sl; | 189 | u8 sl; |
190 | u32 flow_label; | 190 | __be32 flow_label; |
191 | u8 hop_limit; | 191 | u8 hop_limit; |
192 | u8 scope; | 192 | u8 scope; |
193 | u8 join_state; | 193 | u8 join_state; |
@@ -238,7 +238,7 @@ struct ib_sa_mcmember_rec { | |||
238 | struct ib_sa_service_rec { | 238 | struct ib_sa_service_rec { |
239 | u64 id; | 239 | u64 id; |
240 | union ib_gid gid; | 240 | union ib_gid gid; |
241 | u16 pkey; | 241 | __be16 pkey; |
242 | /* reserved */ | 242 | /* reserved */ |
243 | u32 lease; | 243 | u32 lease; |
244 | u8 key[16]; | 244 | u8 key[16]; |
diff --git a/drivers/infiniband/include/ib_smi.h b/include/rdma/ib_smi.h index ca8216514963..87f60737f695 100644 --- a/drivers/infiniband/include/ib_smi.h +++ b/include/rdma/ib_smi.h | |||
@@ -39,9 +39,7 @@ | |||
39 | #if !defined( IB_SMI_H ) | 39 | #if !defined( IB_SMI_H ) |
40 | #define IB_SMI_H | 40 | #define IB_SMI_H |
41 | 41 | ||
42 | #include <ib_mad.h> | 42 | #include <rdma/ib_mad.h> |
43 | |||
44 | #define IB_LID_PERMISSIVE 0xFFFF | ||
45 | 43 | ||
46 | #define IB_SMP_DATA_SIZE 64 | 44 | #define IB_SMP_DATA_SIZE 64 |
47 | #define IB_SMP_MAX_PATH_HOPS 64 | 45 | #define IB_SMP_MAX_PATH_HOPS 64 |
@@ -51,16 +49,16 @@ struct ib_smp { | |||
51 | u8 mgmt_class; | 49 | u8 mgmt_class; |
52 | u8 class_version; | 50 | u8 class_version; |
53 | u8 method; | 51 | u8 method; |
54 | u16 status; | 52 | __be16 status; |
55 | u8 hop_ptr; | 53 | u8 hop_ptr; |
56 | u8 hop_cnt; | 54 | u8 hop_cnt; |
57 | u64 tid; | 55 | __be64 tid; |
58 | u16 attr_id; | 56 | __be16 attr_id; |
59 | u16 resv; | 57 | __be16 resv; |
60 | u32 attr_mod; | 58 | __be32 attr_mod; |
61 | u64 mkey; | 59 | __be64 mkey; |
62 | u16 dr_slid; | 60 | __be16 dr_slid; |
63 | u16 dr_dlid; | 61 | __be16 dr_dlid; |
64 | u8 reserved[28]; | 62 | u8 reserved[28]; |
65 | u8 data[IB_SMP_DATA_SIZE]; | 63 | u8 data[IB_SMP_DATA_SIZE]; |
66 | u8 initial_path[IB_SMP_MAX_PATH_HOPS]; | 64 | u8 initial_path[IB_SMP_MAX_PATH_HOPS]; |
diff --git a/drivers/infiniband/include/ib_user_cm.h b/include/rdma/ib_user_cm.h index 500b1af6ff77..72182d16778b 100644 --- a/drivers/infiniband/include/ib_user_cm.h +++ b/include/rdma/ib_user_cm.h | |||
@@ -88,15 +88,15 @@ struct ib_ucm_attr_id { | |||
88 | }; | 88 | }; |
89 | 89 | ||
90 | struct ib_ucm_attr_id_resp { | 90 | struct ib_ucm_attr_id_resp { |
91 | __u64 service_id; | 91 | __be64 service_id; |
92 | __u64 service_mask; | 92 | __be64 service_mask; |
93 | __u32 local_id; | 93 | __be32 local_id; |
94 | __u32 remote_id; | 94 | __be32 remote_id; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | struct ib_ucm_listen { | 97 | struct ib_ucm_listen { |
98 | __u64 service_id; | 98 | __be64 service_id; |
99 | __u64 service_mask; | 99 | __be64 service_mask; |
100 | __u32 id; | 100 | __u32 id; |
101 | }; | 101 | }; |
102 | 102 | ||
@@ -114,13 +114,13 @@ struct ib_ucm_private_data { | |||
114 | struct ib_ucm_path_rec { | 114 | struct ib_ucm_path_rec { |
115 | __u8 dgid[16]; | 115 | __u8 dgid[16]; |
116 | __u8 sgid[16]; | 116 | __u8 sgid[16]; |
117 | __u16 dlid; | 117 | __be16 dlid; |
118 | __u16 slid; | 118 | __be16 slid; |
119 | __u32 raw_traffic; | 119 | __u32 raw_traffic; |
120 | __u32 flow_label; | 120 | __be32 flow_label; |
121 | __u32 reversible; | 121 | __u32 reversible; |
122 | __u32 mtu; | 122 | __u32 mtu; |
123 | __u16 pkey; | 123 | __be16 pkey; |
124 | __u8 hop_limit; | 124 | __u8 hop_limit; |
125 | __u8 traffic_class; | 125 | __u8 traffic_class; |
126 | __u8 numb_path; | 126 | __u8 numb_path; |
@@ -138,7 +138,7 @@ struct ib_ucm_req { | |||
138 | __u32 qpn; | 138 | __u32 qpn; |
139 | __u32 qp_type; | 139 | __u32 qp_type; |
140 | __u32 psn; | 140 | __u32 psn; |
141 | __u64 sid; | 141 | __be64 sid; |
142 | __u64 data; | 142 | __u64 data; |
143 | __u64 primary_path; | 143 | __u64 primary_path; |
144 | __u64 alternate_path; | 144 | __u64 alternate_path; |
@@ -200,7 +200,7 @@ struct ib_ucm_lap { | |||
200 | struct ib_ucm_sidr_req { | 200 | struct ib_ucm_sidr_req { |
201 | __u32 id; | 201 | __u32 id; |
202 | __u32 timeout; | 202 | __u32 timeout; |
203 | __u64 sid; | 203 | __be64 sid; |
204 | __u64 data; | 204 | __u64 data; |
205 | __u64 path; | 205 | __u64 path; |
206 | __u16 pkey; | 206 | __u16 pkey; |
@@ -237,7 +237,7 @@ struct ib_ucm_req_event_resp { | |||
237 | /* port */ | 237 | /* port */ |
238 | struct ib_ucm_path_rec primary_path; | 238 | struct ib_ucm_path_rec primary_path; |
239 | struct ib_ucm_path_rec alternate_path; | 239 | struct ib_ucm_path_rec alternate_path; |
240 | __u64 remote_ca_guid; | 240 | __be64 remote_ca_guid; |
241 | __u32 remote_qkey; | 241 | __u32 remote_qkey; |
242 | __u32 remote_qpn; | 242 | __u32 remote_qpn; |
243 | __u32 qp_type; | 243 | __u32 qp_type; |
@@ -253,7 +253,7 @@ struct ib_ucm_req_event_resp { | |||
253 | }; | 253 | }; |
254 | 254 | ||
255 | struct ib_ucm_rep_event_resp { | 255 | struct ib_ucm_rep_event_resp { |
256 | __u64 remote_ca_guid; | 256 | __be64 remote_ca_guid; |
257 | __u32 remote_qkey; | 257 | __u32 remote_qkey; |
258 | __u32 remote_qpn; | 258 | __u32 remote_qpn; |
259 | __u32 starting_psn; | 259 | __u32 starting_psn; |
diff --git a/drivers/infiniband/include/ib_user_mad.h b/include/rdma/ib_user_mad.h index a9a56b50aacc..44537aa32e62 100644 --- a/drivers/infiniband/include/ib_user_mad.h +++ b/include/rdma/ib_user_mad.h | |||
@@ -70,8 +70,6 @@ | |||
70 | * @traffic_class - Traffic class in GRH | 70 | * @traffic_class - Traffic class in GRH |
71 | * @gid - Remote GID in GRH | 71 | * @gid - Remote GID in GRH |
72 | * @flow_label - Flow label in GRH | 72 | * @flow_label - Flow label in GRH |
73 | * | ||
74 | * All multi-byte quantities are stored in network (big endian) byte order. | ||
75 | */ | 73 | */ |
76 | struct ib_user_mad_hdr { | 74 | struct ib_user_mad_hdr { |
77 | __u32 id; | 75 | __u32 id; |
@@ -79,9 +77,9 @@ struct ib_user_mad_hdr { | |||
79 | __u32 timeout_ms; | 77 | __u32 timeout_ms; |
80 | __u32 retries; | 78 | __u32 retries; |
81 | __u32 length; | 79 | __u32 length; |
82 | __u32 qpn; | 80 | __be32 qpn; |
83 | __u32 qkey; | 81 | __be32 qkey; |
84 | __u16 lid; | 82 | __be16 lid; |
85 | __u8 sl; | 83 | __u8 sl; |
86 | __u8 path_bits; | 84 | __u8 path_bits; |
87 | __u8 grh_present; | 85 | __u8 grh_present; |
@@ -89,7 +87,7 @@ struct ib_user_mad_hdr { | |||
89 | __u8 hop_limit; | 87 | __u8 hop_limit; |
90 | __u8 traffic_class; | 88 | __u8 traffic_class; |
91 | __u8 gid[16]; | 89 | __u8 gid[16]; |
92 | __u32 flow_label; | 90 | __be32 flow_label; |
93 | }; | 91 | }; |
94 | 92 | ||
95 | /** | 93 | /** |
diff --git a/drivers/infiniband/include/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 7c613706af72..7ebb01c8f996 100644 --- a/drivers/infiniband/include/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h | |||
@@ -78,7 +78,12 @@ enum { | |||
78 | IB_USER_VERBS_CMD_POST_SEND, | 78 | IB_USER_VERBS_CMD_POST_SEND, |
79 | IB_USER_VERBS_CMD_POST_RECV, | 79 | IB_USER_VERBS_CMD_POST_RECV, |
80 | IB_USER_VERBS_CMD_ATTACH_MCAST, | 80 | IB_USER_VERBS_CMD_ATTACH_MCAST, |
81 | IB_USER_VERBS_CMD_DETACH_MCAST | 81 | IB_USER_VERBS_CMD_DETACH_MCAST, |
82 | IB_USER_VERBS_CMD_CREATE_SRQ, | ||
83 | IB_USER_VERBS_CMD_MODIFY_SRQ, | ||
84 | IB_USER_VERBS_CMD_QUERY_SRQ, | ||
85 | IB_USER_VERBS_CMD_DESTROY_SRQ, | ||
86 | IB_USER_VERBS_CMD_POST_SRQ_RECV | ||
82 | }; | 87 | }; |
83 | 88 | ||
84 | /* | 89 | /* |
@@ -143,8 +148,8 @@ struct ib_uverbs_query_device { | |||
143 | 148 | ||
144 | struct ib_uverbs_query_device_resp { | 149 | struct ib_uverbs_query_device_resp { |
145 | __u64 fw_ver; | 150 | __u64 fw_ver; |
146 | __u64 node_guid; | 151 | __be64 node_guid; |
147 | __u64 sys_image_guid; | 152 | __be64 sys_image_guid; |
148 | __u64 max_mr_size; | 153 | __u64 max_mr_size; |
149 | __u64 page_size_cap; | 154 | __u64 page_size_cap; |
150 | __u32 vendor_id; | 155 | __u32 vendor_id; |
@@ -386,4 +391,32 @@ struct ib_uverbs_detach_mcast { | |||
386 | __u64 driver_data[0]; | 391 | __u64 driver_data[0]; |
387 | }; | 392 | }; |
388 | 393 | ||
394 | struct ib_uverbs_create_srq { | ||
395 | __u64 response; | ||
396 | __u64 user_handle; | ||
397 | __u32 pd_handle; | ||
398 | __u32 max_wr; | ||
399 | __u32 max_sge; | ||
400 | __u32 srq_limit; | ||
401 | __u64 driver_data[0]; | ||
402 | }; | ||
403 | |||
404 | struct ib_uverbs_create_srq_resp { | ||
405 | __u32 srq_handle; | ||
406 | }; | ||
407 | |||
408 | struct ib_uverbs_modify_srq { | ||
409 | __u32 srq_handle; | ||
410 | __u32 attr_mask; | ||
411 | __u32 max_wr; | ||
412 | __u32 max_sge; | ||
413 | __u32 srq_limit; | ||
414 | __u32 reserved; | ||
415 | __u64 driver_data[0]; | ||
416 | }; | ||
417 | |||
418 | struct ib_uverbs_destroy_srq { | ||
419 | __u32 srq_handle; | ||
420 | }; | ||
421 | |||
389 | #endif /* IB_USER_VERBS_H */ | 422 | #endif /* IB_USER_VERBS_H */ |
diff --git a/drivers/infiniband/include/ib_verbs.h b/include/rdma/ib_verbs.h index 5d24edaa66e6..e16cf94870f2 100644 --- a/drivers/infiniband/include/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2004 Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 5 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. |
6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. | 6 | * Copyright (c) 2004 Voltaire Corporation. All rights reserved. |
7 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | ||
7 | * Copyright (c) 2005 Cisco Systems. All rights reserved. | 8 | * Copyright (c) 2005 Cisco Systems. All rights reserved. |
8 | * | 9 | * |
9 | * This software is available to you under a choice of one of two | 10 | * This software is available to you under a choice of one of two |
@@ -50,8 +51,8 @@ | |||
50 | union ib_gid { | 51 | union ib_gid { |
51 | u8 raw[16]; | 52 | u8 raw[16]; |
52 | struct { | 53 | struct { |
53 | u64 subnet_prefix; | 54 | __be64 subnet_prefix; |
54 | u64 interface_id; | 55 | __be64 interface_id; |
55 | } global; | 56 | } global; |
56 | }; | 57 | }; |
57 | 58 | ||
@@ -87,8 +88,8 @@ enum ib_atomic_cap { | |||
87 | 88 | ||
88 | struct ib_device_attr { | 89 | struct ib_device_attr { |
89 | u64 fw_ver; | 90 | u64 fw_ver; |
90 | u64 node_guid; | 91 | __be64 node_guid; |
91 | u64 sys_image_guid; | 92 | __be64 sys_image_guid; |
92 | u64 max_mr_size; | 93 | u64 max_mr_size; |
93 | u64 page_size_cap; | 94 | u64 page_size_cap; |
94 | u32 vendor_id; | 95 | u32 vendor_id; |
@@ -255,7 +256,10 @@ enum ib_event_type { | |||
255 | IB_EVENT_PORT_ERR, | 256 | IB_EVENT_PORT_ERR, |
256 | IB_EVENT_LID_CHANGE, | 257 | IB_EVENT_LID_CHANGE, |
257 | IB_EVENT_PKEY_CHANGE, | 258 | IB_EVENT_PKEY_CHANGE, |
258 | IB_EVENT_SM_CHANGE | 259 | IB_EVENT_SM_CHANGE, |
260 | IB_EVENT_SRQ_ERR, | ||
261 | IB_EVENT_SRQ_LIMIT_REACHED, | ||
262 | IB_EVENT_QP_LAST_WQE_REACHED | ||
259 | }; | 263 | }; |
260 | 264 | ||
261 | struct ib_event { | 265 | struct ib_event { |
@@ -263,6 +267,7 @@ struct ib_event { | |||
263 | union { | 267 | union { |
264 | struct ib_cq *cq; | 268 | struct ib_cq *cq; |
265 | struct ib_qp *qp; | 269 | struct ib_qp *qp; |
270 | struct ib_srq *srq; | ||
266 | u8 port_num; | 271 | u8 port_num; |
267 | } element; | 272 | } element; |
268 | enum ib_event_type event; | 273 | enum ib_event_type event; |
@@ -290,8 +295,8 @@ struct ib_global_route { | |||
290 | }; | 295 | }; |
291 | 296 | ||
292 | struct ib_grh { | 297 | struct ib_grh { |
293 | u32 version_tclass_flow; | 298 | __be32 version_tclass_flow; |
294 | u16 paylen; | 299 | __be16 paylen; |
295 | u8 next_hdr; | 300 | u8 next_hdr; |
296 | u8 hop_limit; | 301 | u8 hop_limit; |
297 | union ib_gid sgid; | 302 | union ib_gid sgid; |
@@ -302,6 +307,8 @@ enum { | |||
302 | IB_MULTICAST_QPN = 0xffffff | 307 | IB_MULTICAST_QPN = 0xffffff |
303 | }; | 308 | }; |
304 | 309 | ||
310 | #define IB_LID_PERMISSIVE __constant_htons(0xFFFF) | ||
311 | |||
305 | enum ib_ah_flags { | 312 | enum ib_ah_flags { |
306 | IB_AH_GRH = 1 | 313 | IB_AH_GRH = 1 |
307 | }; | 314 | }; |
@@ -383,6 +390,23 @@ enum ib_cq_notify { | |||
383 | IB_CQ_NEXT_COMP | 390 | IB_CQ_NEXT_COMP |
384 | }; | 391 | }; |
385 | 392 | ||
393 | enum ib_srq_attr_mask { | ||
394 | IB_SRQ_MAX_WR = 1 << 0, | ||
395 | IB_SRQ_LIMIT = 1 << 1, | ||
396 | }; | ||
397 | |||
398 | struct ib_srq_attr { | ||
399 | u32 max_wr; | ||
400 | u32 max_sge; | ||
401 | u32 srq_limit; | ||
402 | }; | ||
403 | |||
404 | struct ib_srq_init_attr { | ||
405 | void (*event_handler)(struct ib_event *, void *); | ||
406 | void *srq_context; | ||
407 | struct ib_srq_attr attr; | ||
408 | }; | ||
409 | |||
386 | struct ib_qp_cap { | 410 | struct ib_qp_cap { |
387 | u32 max_send_wr; | 411 | u32 max_send_wr; |
388 | u32 max_recv_wr; | 412 | u32 max_recv_wr; |
@@ -710,10 +734,11 @@ struct ib_cq { | |||
710 | }; | 734 | }; |
711 | 735 | ||
712 | struct ib_srq { | 736 | struct ib_srq { |
713 | struct ib_device *device; | 737 | struct ib_device *device; |
714 | struct ib_uobject *uobject; | 738 | struct ib_pd *pd; |
715 | struct ib_pd *pd; | 739 | struct ib_uobject *uobject; |
716 | void *srq_context; | 740 | void (*event_handler)(struct ib_event *, void *); |
741 | void *srq_context; | ||
717 | atomic_t usecnt; | 742 | atomic_t usecnt; |
718 | }; | 743 | }; |
719 | 744 | ||
@@ -827,6 +852,18 @@ struct ib_device { | |||
827 | int (*query_ah)(struct ib_ah *ah, | 852 | int (*query_ah)(struct ib_ah *ah, |
828 | struct ib_ah_attr *ah_attr); | 853 | struct ib_ah_attr *ah_attr); |
829 | int (*destroy_ah)(struct ib_ah *ah); | 854 | int (*destroy_ah)(struct ib_ah *ah); |
855 | struct ib_srq * (*create_srq)(struct ib_pd *pd, | ||
856 | struct ib_srq_init_attr *srq_init_attr, | ||
857 | struct ib_udata *udata); | ||
858 | int (*modify_srq)(struct ib_srq *srq, | ||
859 | struct ib_srq_attr *srq_attr, | ||
860 | enum ib_srq_attr_mask srq_attr_mask); | ||
861 | int (*query_srq)(struct ib_srq *srq, | ||
862 | struct ib_srq_attr *srq_attr); | ||
863 | int (*destroy_srq)(struct ib_srq *srq); | ||
864 | int (*post_srq_recv)(struct ib_srq *srq, | ||
865 | struct ib_recv_wr *recv_wr, | ||
866 | struct ib_recv_wr **bad_recv_wr); | ||
830 | struct ib_qp * (*create_qp)(struct ib_pd *pd, | 867 | struct ib_qp * (*create_qp)(struct ib_pd *pd, |
831 | struct ib_qp_init_attr *qp_init_attr, | 868 | struct ib_qp_init_attr *qp_init_attr, |
832 | struct ib_udata *udata); | 869 | struct ib_udata *udata); |
@@ -1039,6 +1076,65 @@ int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr); | |||
1039 | int ib_destroy_ah(struct ib_ah *ah); | 1076 | int ib_destroy_ah(struct ib_ah *ah); |
1040 | 1077 | ||
1041 | /** | 1078 | /** |
1079 | * ib_create_srq - Creates a SRQ associated with the specified protection | ||
1080 | * domain. | ||
1081 | * @pd: The protection domain associated with the SRQ. | ||
1082 | * @srq_init_attr: A list of initial attributes required to create the SRQ. | ||
1083 | * | ||
1084 | * srq_attr->max_wr and srq_attr->max_sge are read the determine the | ||
1085 | * requested size of the SRQ, and set to the actual values allocated | ||
1086 | * on return. If ib_create_srq() succeeds, then max_wr and max_sge | ||
1087 | * will always be at least as large as the requested values. | ||
1088 | */ | ||
1089 | struct ib_srq *ib_create_srq(struct ib_pd *pd, | ||
1090 | struct ib_srq_init_attr *srq_init_attr); | ||
1091 | |||
1092 | /** | ||
1093 | * ib_modify_srq - Modifies the attributes for the specified SRQ. | ||
1094 | * @srq: The SRQ to modify. | ||
1095 | * @srq_attr: On input, specifies the SRQ attributes to modify. On output, | ||
1096 | * the current values of selected SRQ attributes are returned. | ||
1097 | * @srq_attr_mask: A bit-mask used to specify which attributes of the SRQ | ||
1098 | * are being modified. | ||
1099 | * | ||
1100 | * The mask may contain IB_SRQ_MAX_WR to resize the SRQ and/or | ||
1101 | * IB_SRQ_LIMIT to set the SRQ's limit and request notification when | ||
1102 | * the number of receives queued drops below the limit. | ||
1103 | */ | ||
1104 | int ib_modify_srq(struct ib_srq *srq, | ||
1105 | struct ib_srq_attr *srq_attr, | ||
1106 | enum ib_srq_attr_mask srq_attr_mask); | ||
1107 | |||
1108 | /** | ||
1109 | * ib_query_srq - Returns the attribute list and current values for the | ||
1110 | * specified SRQ. | ||
1111 | * @srq: The SRQ to query. | ||
1112 | * @srq_attr: The attributes of the specified SRQ. | ||
1113 | */ | ||
1114 | int ib_query_srq(struct ib_srq *srq, | ||
1115 | struct ib_srq_attr *srq_attr); | ||
1116 | |||
1117 | /** | ||
1118 | * ib_destroy_srq - Destroys the specified SRQ. | ||
1119 | * @srq: The SRQ to destroy. | ||
1120 | */ | ||
1121 | int ib_destroy_srq(struct ib_srq *srq); | ||
1122 | |||
1123 | /** | ||
1124 | * ib_post_srq_recv - Posts a list of work requests to the specified SRQ. | ||
1125 | * @srq: The SRQ to post the work request on. | ||
1126 | * @recv_wr: A list of work requests to post on the receive queue. | ||
1127 | * @bad_recv_wr: On an immediate failure, this parameter will reference | ||
1128 | * the work request that failed to be posted on the QP. | ||
1129 | */ | ||
1130 | static inline int ib_post_srq_recv(struct ib_srq *srq, | ||
1131 | struct ib_recv_wr *recv_wr, | ||
1132 | struct ib_recv_wr **bad_recv_wr) | ||
1133 | { | ||
1134 | return srq->device->post_srq_recv(srq, recv_wr, bad_recv_wr); | ||
1135 | } | ||
1136 | |||
1137 | /** | ||
1042 | * ib_create_qp - Creates a QP associated with the specified protection | 1138 | * ib_create_qp - Creates a QP associated with the specified protection |
1043 | * domain. | 1139 | * domain. |
1044 | * @pd: The protection domain associated with the QP. | 1140 | * @pd: The protection domain associated with the QP. |