Browse Source

[infiniband] Add infrastructure for RC queue pairs

Queue pairs are now assumed to be created in the INIT state, with a
call to ib_modify_qp() required to bring the queue pair to the RTS
state.

ib_modify_qp() no longer takes a modification list; callers should
modify the relevant queue pair parameters (e.g. qkey) directly and
then call ib_modify_qp() to synchronise the changes to the hardware.

The packet sequence number is now a property of the queue pair, rather
than of the device.

Each queue pair may have an associated address vector.  For RC queue
pairs, this is the address vector that will be programmed in to the
hardware as the remote address.  For UD queue pairs, it will be used
as the default address vector if none is supplied to ib_post_send().
tags/v0.9.8
Michael Brown 15 years ago
parent
commit
c939bc57ff

+ 2
- 10
src/drivers/infiniband/arbel.c View File

855
 		     ( virt_to_bus ( arbel_qp->recv.wqe ) >> 6 ) );
855
 		     ( virt_to_bus ( arbel_qp->recv.wqe ) >> 6 ) );
856
 	MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.rcv_db_record_index,
856
 	MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.rcv_db_record_index,
857
 		     arbel_qp->recv.doorbell_idx );
857
 		     arbel_qp->recv.doorbell_idx );
858
-	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
859
 	if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
858
 	if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
860
 		DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
859
 		DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
861
 		       arbel, strerror ( rc ) );
860
 		       arbel, strerror ( rc ) );
908
  *
907
  *
909
  * @v ibdev		Infiniband device
908
  * @v ibdev		Infiniband device
910
  * @v qp		Queue pair
909
  * @v qp		Queue pair
911
- * @v mod_list		Modification list
912
  * @ret rc		Return status code
910
  * @ret rc		Return status code
913
  */
911
  */
914
 static int arbel_modify_qp ( struct ib_device *ibdev,
912
 static int arbel_modify_qp ( struct ib_device *ibdev,
915
-			     struct ib_queue_pair *qp,
916
-			     unsigned long mod_list ) {
913
+			     struct ib_queue_pair *qp ) {
917
 	struct arbel *arbel = ib_get_drvdata ( ibdev );
914
 	struct arbel *arbel = ib_get_drvdata ( ibdev );
918
 	struct arbelprm_qp_ee_state_transitions qpctx;
915
 	struct arbelprm_qp_ee_state_transitions qpctx;
919
-	unsigned long optparammask = 0;
920
 	int rc;
916
 	int rc;
921
 
917
 
922
-	/* Construct optparammask */
923
-	if ( mod_list & IB_MODIFY_QKEY )
924
-		optparammask |= ARBEL_QPEE_OPT_PARAM_QKEY;
925
-
926
 	/* Issue RTS2RTS_QP */
918
 	/* Issue RTS2RTS_QP */
927
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
919
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
928
-	MLX_FILL_1 ( &qpctx, 0, opt_param_mask, optparammask );
920
+	MLX_FILL_1 ( &qpctx, 0, opt_param_mask, ARBEL_QPEE_OPT_PARAM_QKEY );
929
 	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
921
 	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
930
 	if ( ( rc = arbel_cmd_rts2rts_qp ( arbel, qp->qpn, &qpctx ) ) != 0 ){
922
 	if ( ( rc = arbel_cmd_rts2rts_qp ( arbel, qp->qpn, &qpctx ) ) != 0 ){
931
 		DBGC ( arbel, "Arbel %p RTS2RTS_QP failed: %s\n",
923
 		DBGC ( arbel, "Arbel %p RTS2RTS_QP failed: %s\n",

+ 2
- 10
src/drivers/infiniband/hermon.c View File

885
 	MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
885
 	MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
886
 	MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.db_record_addr_l,
886
 	MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.db_record_addr_l,
887
 		     ( virt_to_phys ( &hermon_qp->recv.doorbell ) >> 2 ) );
887
 		     ( virt_to_phys ( &hermon_qp->recv.doorbell ) >> 2 ) );
888
-	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
889
 	MLX_FILL_1 ( &qpctx, 53, qpc_eec_data.mtt_base_addr_l,
888
 	MLX_FILL_1 ( &qpctx, 53, qpc_eec_data.mtt_base_addr_l,
890
 		     ( hermon_qp->mtt.mtt_base_addr >> 3 ) );
889
 		     ( hermon_qp->mtt.mtt_base_addr >> 3 ) );
891
 	if ( ( rc = hermon_cmd_rst2init_qp ( hermon, qp->qpn,
890
 	if ( ( rc = hermon_cmd_rst2init_qp ( hermon, qp->qpn,
946
  *
945
  *
947
  * @v ibdev		Infiniband device
946
  * @v ibdev		Infiniband device
948
  * @v qp		Queue pair
947
  * @v qp		Queue pair
949
- * @v mod_list		Modification list
950
  * @ret rc		Return status code
948
  * @ret rc		Return status code
951
  */
949
  */
952
 static int hermon_modify_qp ( struct ib_device *ibdev,
950
 static int hermon_modify_qp ( struct ib_device *ibdev,
953
-			      struct ib_queue_pair *qp,
954
-			      unsigned long mod_list ) {
951
+			      struct ib_queue_pair *qp ) {
955
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
952
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
956
 	struct hermonprm_qp_ee_state_transitions qpctx;
953
 	struct hermonprm_qp_ee_state_transitions qpctx;
957
-	unsigned long optparammask = 0;
958
 	int rc;
954
 	int rc;
959
 
955
 
960
-	/* Construct optparammask */
961
-	if ( mod_list & IB_MODIFY_QKEY )
962
-		optparammask |= HERMON_QP_OPT_PARAM_QKEY;
963
-
964
 	/* Issue RTS2RTS_QP */
956
 	/* Issue RTS2RTS_QP */
965
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
957
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
966
-	MLX_FILL_1 ( &qpctx, 0, opt_param_mask, optparammask );
958
+	MLX_FILL_1 ( &qpctx, 0, opt_param_mask, HERMON_QP_OPT_PARAM_QKEY );
967
 	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
959
 	MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
968
 	if ( ( rc = hermon_cmd_rts2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
960
 	if ( ( rc = hermon_cmd_rts2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
969
 		DBGC ( hermon, "Hermon %p RTS2RTS_QP failed: %s\n",
961
 		DBGC ( hermon, "Hermon %p RTS2RTS_QP failed: %s\n",

+ 14
- 3
src/drivers/infiniband/linda.c View File

268
 	return 0;
268
 	return 0;
269
 }
269
 }
270
 
270
 
271
+/**
272
+ * Set partition key table
273
+ *
274
+ * @v ibdev		Infiniband device
275
+ * @v mad		Set partition key table MAD
276
+ */
277
+static int linda_set_pkey_table ( struct ib_device *ibdev __unused,
278
+				  union ib_mad *mad __unused ) {
279
+	/* Nothing to do */
280
+	return 0;
281
+}
282
+
271
 /***************************************************************************
283
 /***************************************************************************
272
  *
284
  *
273
  * Context allocation
285
  * Context allocation
852
  *
864
  *
853
  * @v ibdev		Infiniband device
865
  * @v ibdev		Infiniband device
854
  * @v qp		Queue pair
866
  * @v qp		Queue pair
855
- * @v mod_list		Modification list
856
  * @ret rc		Return status code
867
  * @ret rc		Return status code
857
  */
868
  */
858
 static int linda_modify_qp ( struct ib_device *ibdev,
869
 static int linda_modify_qp ( struct ib_device *ibdev,
859
-			     struct ib_queue_pair *qp,
860
-			     unsigned long mod_list __unused ) {
870
+			     struct ib_queue_pair *qp ) {
861
 	struct linda *linda = ib_get_drvdata ( ibdev );
871
 	struct linda *linda = ib_get_drvdata ( ibdev );
862
 
872
 
863
 	/* Nothing to do; the hardware doesn't have a notion of queue
873
 	/* Nothing to do; the hardware doesn't have a notion of queue
1456
 	.mcast_attach	= linda_mcast_attach,
1466
 	.mcast_attach	= linda_mcast_attach,
1457
 	.mcast_detach	= linda_mcast_detach,
1467
 	.mcast_detach	= linda_mcast_detach,
1458
 	.set_port_info	= linda_set_port_info,
1468
 	.set_port_info	= linda_set_port_info,
1469
+	.set_pkey_table	= linda_set_pkey_table,
1459
 };
1470
 };
1460
 
1471
 
1461
 /***************************************************************************
1472
 /***************************************************************************

+ 1
- 1
src/drivers/net/ipoib.c View File

521
 	/* Allocate queue pair */
521
 	/* Allocate queue pair */
522
 	ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD,
522
 	ipoib->qp = ib_create_qp ( ibdev, IB_QPT_UD,
523
 				   IPOIB_NUM_SEND_WQES, ipoib->cq,
523
 				   IPOIB_NUM_SEND_WQES, ipoib->cq,
524
-				   IPOIB_NUM_RECV_WQES, ipoib->cq, 0 );
524
+				   IPOIB_NUM_RECV_WQES, ipoib->cq );
525
 	if ( ! ipoib->qp ) {
525
 	if ( ! ipoib->qp ) {
526
 		DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
526
 		DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
527
 		       ipoib );
527
 		       ipoib );

+ 63
- 51
src/include/gpxe/infiniband.h View File

47
 struct ib_completion_queue;
47
 struct ib_completion_queue;
48
 struct ib_gma;
48
 struct ib_gma;
49
 
49
 
50
+/** Infiniband transmission rates */
51
+enum ib_rate {
52
+	IB_RATE_2_5 = 2,
53
+	IB_RATE_10 = 3,
54
+	IB_RATE_30 = 4,
55
+	IB_RATE_5 = 5,
56
+	IB_RATE_20 = 6,
57
+	IB_RATE_40 = 7,
58
+	IB_RATE_60 = 8,
59
+	IB_RATE_80 = 9,
60
+	IB_RATE_120 = 10,
61
+};
62
+
63
+/** An Infiniband Address Vector */
64
+struct ib_address_vector {
65
+	/** Queue Pair Number */
66
+	unsigned long qpn;
67
+	/** Queue key
68
+	 *
69
+	 * Not specified for received packets.
70
+	 */
71
+	unsigned long qkey;
72
+	/** Local ID */
73
+	unsigned int lid;
74
+	/** Rate
75
+	 *
76
+	 * Not specified for received packets.
77
+	 */
78
+	enum ib_rate rate;
79
+	/** Service level */
80
+	unsigned int sl;
81
+	/** GID is present */
82
+	unsigned int gid_present;
83
+	/** GID, if present */
84
+	struct ib_gid gid;
85
+};
86
+
50
 /** An Infiniband Work Queue */
87
 /** An Infiniband Work Queue */
51
 struct ib_work_queue {
88
 struct ib_work_queue {
52
 	/** Containing queue pair */
89
 	/** Containing queue pair */
57
 	struct ib_completion_queue *cq;
94
 	struct ib_completion_queue *cq;
58
 	/** List of work queues on this completion queue */
95
 	/** List of work queues on this completion queue */
59
 	struct list_head list;
96
 	struct list_head list;
97
+	/** Packet sequence number */
98
+	uint32_t psn;
60
 	/** Number of work queue entries */
99
 	/** Number of work queue entries */
61
 	unsigned int num_wqes;
100
 	unsigned int num_wqes;
62
 	/** Number of occupied work queue entries */
101
 	/** Number of occupied work queue entries */
88
 	IB_QPT_SMA,
127
 	IB_QPT_SMA,
89
 	IB_QPT_GMA,
128
 	IB_QPT_GMA,
90
 	IB_QPT_UD,
129
 	IB_QPT_UD,
130
+	IB_QPT_RC,
91
 };
131
 };
92
 
132
 
93
 /** An Infiniband Queue Pair */
133
 /** An Infiniband Queue Pair */
115
 	struct ib_work_queue recv;
155
 	struct ib_work_queue recv;
116
 	/** List of multicast GIDs */
156
 	/** List of multicast GIDs */
117
 	struct list_head mgids;
157
 	struct list_head mgids;
158
+	/** Address vector */
159
+	struct ib_address_vector av;
118
 	/** Driver private data */
160
 	/** Driver private data */
119
 	void *drv_priv;
161
 	void *drv_priv;
120
 	/** Queue owner private data */
162
 	/** Queue owner private data */
121
 	void *owner_priv;
163
 	void *owner_priv;
122
 };
164
 };
123
 
165
 
124
-/** Infiniband queue pair modification flags */
125
-enum ib_queue_pair_mods {
126
-	IB_MODIFY_QKEY = 0x0001,
127
-};
128
-
129
-/** An Infiniband Address Vector */
130
-struct ib_address_vector {
131
-	/** Queue Pair Number */
132
-	unsigned long qpn;
133
-	/** Queue key
134
-	 *
135
-	 * Not specified for received packets.
136
-	 */
137
-	unsigned long qkey;
138
-	/** Local ID */
139
-	unsigned int lid;
140
-	/** Rate
141
-	 *
142
-	 * Not specified for received packets.
143
-	 */
144
-	unsigned int rate;
145
-	/** Service level */
146
-	unsigned int sl;
147
-	/** GID is present */
148
-	unsigned int gid_present;
149
-	/** GID, if present */
150
-	struct ib_gid gid;
151
-};
152
-
153
-/** Infiniband transmission rates */
154
-enum ib_rate {
155
-	IB_RATE_2_5 = 2,
156
-	IB_RATE_10 = 3,
157
-	IB_RATE_30 = 4,
158
-	IB_RATE_5 = 5,
159
-	IB_RATE_20 = 6,
160
-	IB_RATE_40 = 7,
161
-	IB_RATE_60 = 8,
162
-	IB_RATE_80 = 9,
163
-	IB_RATE_120 = 10,
164
-};
165
-
166
 /** Infiniband completion queue operations */
166
 /** Infiniband completion queue operations */
167
 struct ib_completion_queue_operations {
167
 struct ib_completion_queue_operations {
168
 	/**
168
 	/**
250
 	 *
250
 	 *
251
 	 * @v ibdev		Infiniband device
251
 	 * @v ibdev		Infiniband device
252
 	 * @v qp		Queue pair
252
 	 * @v qp		Queue pair
253
-	 * @v mod_list		Modification list
254
 	 * @ret rc		Return status code
253
 	 * @ret rc		Return status code
255
 	 */
254
 	 */
256
 	int ( * modify_qp ) ( struct ib_device *ibdev,
255
 	int ( * modify_qp ) ( struct ib_device *ibdev,
257
-			      struct ib_queue_pair *qp,
258
-			      unsigned long mod_list );
256
+			      struct ib_queue_pair *qp );
259
 	/** Destroy queue pair
257
 	/** Destroy queue pair
260
 	 *
258
 	 *
261
 	 * @v ibdev		Infiniband device
259
 	 * @v ibdev		Infiniband device
352
 	 * an embedded SMA.
350
 	 * an embedded SMA.
353
 	 */
351
 	 */
354
 	int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
352
 	int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
353
+	/** Set partition key table
354
+	 *
355
+	 * @v ibdev		Infiniband device
356
+	 * @v mad		Set partition key table MAD
357
+	 *
358
+	 * This method is required only by adapters that do not have
359
+	 * an embedded SMA.
360
+	 */
361
+	int ( * set_pkey_table ) ( struct ib_device *ibdev,
362
+				   union ib_mad *mad );
355
 };
363
 };
356
 
364
 
357
 /** An Infiniband device */
365
 /** An Infiniband device */
398
 	/** Partition key */
406
 	/** Partition key */
399
 	uint16_t pkey;
407
 	uint16_t pkey;
400
 
408
 
401
-	/** Outbound packet sequence number */
402
-	uint32_t psn;
409
+	/** RDMA key
410
+	 *
411
+	 * This is a single key allowing unrestricted access to
412
+	 * memory.
413
+	 */
414
+	uint32_t rdma_key;
403
 
415
 
404
 	/** Subnet management agent */
416
 	/** Subnet management agent */
405
 	struct ib_gma *sma;
417
 	struct ib_gma *sma;
422
 extern struct ib_queue_pair *
434
 extern struct ib_queue_pair *
423
 ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
435
 ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
424
 	       unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
436
 	       unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
425
-	       unsigned int num_recv_wqes, struct ib_completion_queue *recv_cq,
426
-	       unsigned long qkey );
427
-extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
428
-			  unsigned long mod_list, unsigned long qkey );
437
+	       unsigned int num_recv_wqes,
438
+	       struct ib_completion_queue *recv_cq );
439
+extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
429
 extern void ib_destroy_qp ( struct ib_device *ibdev,
440
 extern void ib_destroy_qp ( struct ib_device *ibdev,
430
 			    struct ib_queue_pair *qp );
441
 			    struct ib_queue_pair *qp );
431
 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
442
 extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
457
 extern int ib_get_hca_info ( struct ib_device *ibdev,
468
 extern int ib_get_hca_info ( struct ib_device *ibdev,
458
 			     struct ib_gid_half *hca_guid );
469
 			     struct ib_gid_half *hca_guid );
459
 extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
470
 extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
471
+extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
460
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
472
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
461
 extern int register_ibdev ( struct ib_device *ibdev );
473
 extern int register_ibdev ( struct ib_device *ibdev );
462
 extern void unregister_ibdev ( struct ib_device *ibdev );
474
 extern void unregister_ibdev ( struct ib_device *ibdev );

+ 43
- 12
src/net/infiniband.c View File

149
  * @v send_cq		Send completion queue
149
  * @v send_cq		Send completion queue
150
  * @v num_recv_wqes	Number of receive work queue entries
150
  * @v num_recv_wqes	Number of receive work queue entries
151
  * @v recv_cq		Receive completion queue
151
  * @v recv_cq		Receive completion queue
152
- * @v qkey		Queue key
153
  * @ret qp		Queue pair
152
  * @ret qp		Queue pair
153
+ *
154
+ * The queue pair will be left in the INIT state; you must call
155
+ * ib_modify_qp() before it is ready to use for sending and receiving.
154
  */
156
  */
155
 struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
157
 struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
156
 				      enum ib_queue_pair_type type,
158
 				      enum ib_queue_pair_type type,
157
 				      unsigned int num_send_wqes,
159
 				      unsigned int num_send_wqes,
158
 				      struct ib_completion_queue *send_cq,
160
 				      struct ib_completion_queue *send_cq,
159
 				      unsigned int num_recv_wqes,
161
 				      unsigned int num_recv_wqes,
160
-				      struct ib_completion_queue *recv_cq,
161
-				      unsigned long qkey ) {
162
+				      struct ib_completion_queue *recv_cq ) {
162
 	struct ib_queue_pair *qp;
163
 	struct ib_queue_pair *qp;
163
 	size_t total_size;
164
 	size_t total_size;
164
 	int rc;
165
 	int rc;
175
 	qp->ibdev = ibdev;
176
 	qp->ibdev = ibdev;
176
 	list_add ( &qp->list, &ibdev->qps );
177
 	list_add ( &qp->list, &ibdev->qps );
177
 	qp->type = type;
178
 	qp->type = type;
178
-	qp->qkey = qkey;
179
 	qp->send.qp = qp;
179
 	qp->send.qp = qp;
180
 	qp->send.is_send = 1;
180
 	qp->send.is_send = 1;
181
 	qp->send.cq = send_cq;
181
 	qp->send.cq = send_cq;
182
 	list_add ( &qp->send.list, &send_cq->work_queues );
182
 	list_add ( &qp->send.list, &send_cq->work_queues );
183
+	qp->send.psn = ( random() & 0xffffffUL );
183
 	qp->send.num_wqes = num_send_wqes;
184
 	qp->send.num_wqes = num_send_wqes;
184
 	qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
185
 	qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
185
 	qp->recv.qp = qp;
186
 	qp->recv.qp = qp;
186
 	qp->recv.cq = recv_cq;
187
 	qp->recv.cq = recv_cq;
187
 	list_add ( &qp->recv.list, &recv_cq->work_queues );
188
 	list_add ( &qp->recv.list, &recv_cq->work_queues );
189
+	qp->recv.psn = ( random() & 0xffffffUL );
188
 	qp->recv.num_wqes = num_recv_wqes;
190
 	qp->recv.num_wqes = num_recv_wqes;
189
 	qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
191
 	qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
190
 			    ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
192
 			    ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
239
  *
241
  *
240
  * @v ibdev		Infiniband device
242
  * @v ibdev		Infiniband device
241
  * @v qp		Queue pair
243
  * @v qp		Queue pair
242
- * @v mod_list		Modification list
243
- * @v qkey		New queue key, if applicable
244
+ * @v av		New address vector, if applicable
244
  * @ret rc		Return status code
245
  * @ret rc		Return status code
245
  */
246
  */
246
-int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
247
-		   unsigned long mod_list, unsigned long qkey ) {
247
+int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
248
 	int rc;
248
 	int rc;
249
 
249
 
250
 	DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn );
250
 	DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn );
251
 
251
 
252
-	if ( mod_list & IB_MODIFY_QKEY )
253
-		qp->qkey = qkey;
254
-
255
-	if ( ( rc = ibdev->op->modify_qp ( ibdev, qp, mod_list ) ) != 0 ) {
252
+	if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) {
256
 		DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n",
253
 		DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n",
257
 		       ibdev, qp->qpn, strerror ( rc ) );
254
 		       ibdev, qp->qpn, strerror ( rc ) );
258
 		return rc;
255
 		return rc;
372
 int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
369
 int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
373
 		   struct ib_address_vector *av,
370
 		   struct ib_address_vector *av,
374
 		   struct io_buffer *iobuf ) {
371
 		   struct io_buffer *iobuf ) {
372
+	struct ib_address_vector av_copy;
375
 	int rc;
373
 	int rc;
376
 
374
 
377
 	/* Check queue fill level */
375
 	/* Check queue fill level */
381
 		return -ENOBUFS;
379
 		return -ENOBUFS;
382
 	}
380
 	}
383
 
381
 
382
+	/* Use default address vector if none specified */
383
+	if ( ! av )
384
+		av = &qp->av;
385
+
386
+	/* Make modifiable copy of address vector */
387
+	memcpy ( &av_copy, av, sizeof ( av_copy ) );
388
+	av = &av_copy;
389
+
384
 	/* Fill in optional parameters in address vector */
390
 	/* Fill in optional parameters in address vector */
385
 	if ( ! av->qkey )
391
 	if ( ! av->qkey )
386
 		av->qkey = qp->qkey;
392
 		av->qkey = qp->qkey;
712
 	return 0;
718
 	return 0;
713
 };
719
 };
714
 
720
 
721
+/**
722
+ * Set partition key table
723
+ *
724
+ * @v ibdev		Infiniband device
725
+ * @v mad		Set partition key table MAD
726
+ */
727
+int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) {
728
+	int rc;
729
+
730
+	/* Adapters with embedded SMAs do not need to support this method */
731
+	if ( ! ibdev->op->set_pkey_table ) {
732
+		DBGC ( ibdev, "IBDEV %p does not support setting partition "
733
+		       "key table\n", ibdev );
734
+		return -ENOTSUP;
735
+	}
736
+
737
+	if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) {
738
+		DBGC ( ibdev, "IBDEV %p could not set partition key table: "
739
+		       "%s\n", ibdev, strerror ( rc ) );
740
+		return rc;
741
+	}
742
+
743
+	return 0;
744
+};
745
+
715
 /***************************************************************************
746
 /***************************************************************************
716
  *
747
  *
717
  * Event queues
748
  * Event queues

+ 20
- 4
src/net/infiniband/ib_gma.c View File

296
 					      union ib_mad *mad ) {
296
 					      union ib_mad *mad ) {
297
 	struct ib_device *ibdev = gma->ibdev;
297
 	struct ib_device *ibdev = gma->ibdev;
298
 	struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
298
 	struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
299
+	int rc;
299
 
300
 
300
 	ibdev->pkey = ntohs ( pkey_table->pkey[0] );
301
 	ibdev->pkey = ntohs ( pkey_table->pkey[0] );
302
+	DBGC ( gma, "GMA %p set pkey %04x\n", gma, ibdev->pkey );
303
+
304
+	if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) {
305
+		DBGC ( gma, "GMA %p could not set pkey table: %s\n",
306
+		       gma, strerror ( rc ) );
307
+		mad->hdr.status =
308
+			htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
309
+	}
301
 
310
 
302
 	return ib_sma_get_pkey_table ( gma, mad );
311
 	return ib_sma_get_pkey_table ( gma, mad );
303
 }
312
 }
618
 struct ib_gma * ib_create_gma ( struct ib_device *ibdev,
627
 struct ib_gma * ib_create_gma ( struct ib_device *ibdev,
619
 				enum ib_queue_pair_type type ) {
628
 				enum ib_queue_pair_type type ) {
620
 	struct ib_gma *gma;
629
 	struct ib_gma *gma;
621
-	unsigned long qkey;
630
+	int rc;
622
 
631
 
623
 	/* Allocate and initialise fields */
632
 	/* Allocate and initialise fields */
624
 	gma = zalloc ( sizeof ( *gma ) );
633
 	gma = zalloc ( sizeof ( *gma ) );
637
 	}
646
 	}
638
 
647
 
639
 	/* Create queue pair */
648
 	/* Create queue pair */
640
-	qkey = ( ( type == IB_QPT_SMA ) ? IB_QKEY_SMA : IB_QKEY_GMA );
641
 	gma->qp = ib_create_qp ( ibdev, type, IB_GMA_NUM_SEND_WQES, gma->cq,
649
 	gma->qp = ib_create_qp ( ibdev, type, IB_GMA_NUM_SEND_WQES, gma->cq,
642
-				 IB_GMA_NUM_RECV_WQES, gma->cq, qkey );
650
+				 IB_GMA_NUM_RECV_WQES, gma->cq );
643
 	if ( ! gma->qp ) {
651
 	if ( ! gma->qp ) {
644
 		DBGC ( gma, "GMA %p could not allocate queue pair\n", gma );
652
 		DBGC ( gma, "GMA %p could not allocate queue pair\n", gma );
645
 		goto err_create_qp;
653
 		goto err_create_qp;
646
 	}
654
 	}
647
 	ib_qp_set_ownerdata ( gma->qp, gma );
655
 	ib_qp_set_ownerdata ( gma->qp, gma );
648
-
649
 	DBGC ( gma, "GMA %p running on QPN %#lx\n", gma, gma->qp->qpn );
656
 	DBGC ( gma, "GMA %p running on QPN %#lx\n", gma, gma->qp->qpn );
650
 
657
 
658
+	/* Set queue key */
659
+	gma->qp->qkey = ( ( type == IB_QPT_SMA ) ? IB_QKEY_SMA : IB_QKEY_GMA );
660
+	if ( ( rc = ib_modify_qp ( ibdev, gma->qp ) ) != 0 ) {
661
+		DBGC ( gma, "GMA %p could not set queue key: %s\n",
662
+		       gma, strerror ( rc ) );
663
+		goto err_modify_qp;
664
+	}
665
+
651
 	/* Fill receive ring */
666
 	/* Fill receive ring */
652
 	ib_refill_recv ( ibdev, gma->qp );
667
 	ib_refill_recv ( ibdev, gma->qp );
653
 	return gma;
668
 	return gma;
654
 
669
 
670
+ err_modify_qp:
655
 	ib_destroy_qp ( ibdev, gma->qp );
671
 	ib_destroy_qp ( ibdev, gma->qp );
656
  err_create_qp:
672
  err_create_qp:
657
 	ib_destroy_cq ( ibdev, gma->cq );
673
 	ib_destroy_cq ( ibdev, gma->cq );

+ 2
- 1
src/net/infiniband/ib_mcast.c View File

178
 	       ntohl ( gid->u.dwords[3] ), qkey );
178
 	       ntohl ( gid->u.dwords[3] ), qkey );
179
 
179
 
180
 	/* Set queue key */
180
 	/* Set queue key */
181
-	if ( ( rc = ib_modify_qp ( ibdev, qp, IB_MODIFY_QKEY, qkey ) ) != 0 ) {
181
+	qp->qkey = qkey;
182
+	if ( ( rc = ib_modify_qp ( ibdev, qp ) ) != 0 ) {
182
 		DBGC ( gma, "GMA %p QPN %lx could not modify qkey: %s\n",
183
 		DBGC ( gma, "GMA %p QPN %lx could not modify qkey: %s\n",
183
 		       gma, qp->qpn, strerror ( rc ) );
184
 		       gma, qp->qpn, strerror ( rc ) );
184
 		return NULL;
185
 		return NULL;

+ 1
- 1
src/net/infiniband/ib_packet.c View File

100
 	bth->se__m__padcnt__tver = ( pad_len << 4 );
100
 	bth->se__m__padcnt__tver = ( pad_len << 4 );
101
 	bth->pkey = htons ( ibdev->pkey );
101
 	bth->pkey = htons ( ibdev->pkey );
102
 	bth->dest_qp = htonl ( av->qpn );
102
 	bth->dest_qp = htonl ( av->qpn );
103
-	bth->ack__psn = htonl ( ( ibdev->psn++ ) & 0xffffffUL );
103
+	bth->ack__psn = htonl ( ( qp->send.psn++ ) & 0xffffffUL );
104
 
104
 
105
 	/* Construct DETH */
105
 	/* Construct DETH */
106
 	deth->qkey = htonl ( av->qkey );
106
 	deth->qkey = htonl ( av->qkey );

Loading…
Cancel
Save