Bläddra i källkod

Revert to dev_priv/owner_priv scheme, rather than container_of; it

makes it easier to put the generic allocation code into infiniband.c
tags/v0.9.3
Michael Brown 17 år sedan
förälder
incheckning
b21d4ca21e

+ 18
- 5
src/drivers/net/mlx_ipoib/arbel.h Visa fil

107
 	unsigned long reserved_uars;
107
 	unsigned long reserved_uars;
108
 	/** Number of reserved CQs */
108
 	/** Number of reserved CQs */
109
 	unsigned long reserved_cqs;
109
 	unsigned long reserved_cqs;
110
+	/** Number of reserved QPs */
111
+	unsigned long reserved_qps;
110
 };
112
 };
111
 
113
 
112
 /** Alignment of Arbel send work queue entries */
114
 /** Alignment of Arbel send work queue entries */
143
 	union arbel_recv_wqe *wqe;
145
 	union arbel_recv_wqe *wqe;
144
 };
146
 };
145
 
147
 
148
+/** Maximum number of allocatable queue pairs
149
+ *
150
+ * This is a policy decision, not a device limit.
151
+ */
152
+#define ARBEL_MAX_QPS		8
153
+
154
+/** Base queue pair number */
155
+#define ARBEL_QPN_BASE 0x550000
156
+
146
 /** An Arbel queue pair */
157
 /** An Arbel queue pair */
147
 struct arbel_queue_pair {
158
 struct arbel_queue_pair {
148
 	/** Infiniband queue pair */
159
 	/** Infiniband queue pair */
161
 
172
 
162
 /** An Arbel completion queue */
173
 /** An Arbel completion queue */
163
 struct arbel_completion_queue {
174
 struct arbel_completion_queue {
164
-	/** Infiniband completion queue */
165
-	struct ib_completion_queue cq;
166
-	/** Doorbell record number */
167
-	unsigned int doorbell_idx;
175
+	/** Consumer counter doorbell record number */
176
+	unsigned int ci_doorbell_idx;
177
+	/** Arm queue doorbell record number */
178
+	unsigned int arm_doorbell_idx;
168
 	/** Completion queue entries */
179
 	/** Completion queue entries */
169
 	union arbelprm_completion_entry *cqe;
180
 	union arbelprm_completion_entry *cqe;
170
 };
181
 };
200
 
211
 
201
 	/** Completion queue in-use bitmask */
212
 	/** Completion queue in-use bitmask */
202
 	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
213
 	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
214
+	/** Queue pair in-use bitmask */
215
+	arbel_bitmask_t qp_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_QPS ) ];
203
 	
216
 	
204
 	/** Device limits */
217
 	/** Device limits */
205
 	struct arbel_dev_limits limits;
218
 	struct arbel_dev_limits limits;
301
 }
314
 }
302
 
315
 
303
 /**
316
 /**
304
- * Get commpletion queue consumer counter doorbell index
317
+ * Get completion queue consumer counter doorbell index
305
  *
318
  *
306
  * @v cqn_offset	Completion queue number offset
319
  * @v cqn_offset	Completion queue number offset
307
  * @ret doorbell_idx	Doorbell index
320
  * @ret doorbell_idx	Doorbell index

+ 140
- 96
src/drivers/net/mlx_ipoib/mt25218.c Visa fil

53
 static struct io_buffer *static_ipoib_rx_ring[NUM_IPOIB_RCV_WQES];
53
 static struct io_buffer *static_ipoib_rx_ring[NUM_IPOIB_RCV_WQES];
54
 
54
 
55
 static struct arbel static_arbel;
55
 static struct arbel static_arbel;
56
-static struct arbel_completion_queue static_ipoib_send_cq;
57
-static struct arbel_completion_queue static_ipoib_recv_cq;
58
-
59
-static struct arbel_queue_pair static_ipoib_qp = {
60
-	.qp = {
61
-		.send = {
62
-			.qp = &static_ipoib_qp.qp,
63
-			.is_send = 1,
64
-			.cq = &static_ipoib_send_cq.cq,
65
-			.num_wqes = NUM_IPOIB_SND_WQES,
66
-			.iobufs = static_ipoib_tx_ring,
67
-			.list = LIST_HEAD_INIT (static_ipoib_qp.qp.send.list),
68
-		},
69
-		.recv = {
70
-			.qp = &static_ipoib_qp.qp,
71
-			.is_send = 0,
72
-			.cq = &static_ipoib_recv_cq.cq,
73
-			.num_wqes = NUM_IPOIB_RCV_WQES,
74
-			.iobufs = static_ipoib_rx_ring,
75
-			.list = LIST_HEAD_INIT (static_ipoib_qp.qp.recv.list),
76
-		},
77
-	},
56
+
57
+static struct arbel_completion_queue static_arbel_ipoib_send_cq = {
58
+	.ci_doorbell_idx = IPOIB_SND_CQ_CI_DB_IDX,
59
+};
60
+static struct ib_completion_queue static_ipoib_send_cq = {
61
+	.cqn = 1234, /* Only used for debug messages */
62
+	.num_cqes = NUM_IPOIB_SND_CQES,
63
+	.work_queues = LIST_HEAD_INIT ( static_ipoib_send_cq.work_queues ),
64
+	.dev_priv = &static_arbel_ipoib_send_cq,
65
+};
66
+
67
+static struct arbel_completion_queue static_arbel_ipoib_recv_cq = {
68
+	.ci_doorbell_idx = IPOIB_RCV_CQ_CI_DB_IDX,
69
+};
70
+static struct ib_completion_queue static_ipoib_recv_cq = {
71
+	.cqn = 2345, /* Only used for debug messages */
72
+	.num_cqes = NUM_IPOIB_RCV_CQES,
73
+	.work_queues = LIST_HEAD_INIT ( static_ipoib_recv_cq.work_queues ),
74
+	.dev_priv = &static_arbel_ipoib_recv_cq,
75
+};
76
+
77
+static struct arbel_queue_pair static_arbel_ipoib_qp = {
78
 	.send = {
78
 	.send = {
79
 		.doorbell_idx = IPOIB_SND_QP_DB_IDX,
79
 		.doorbell_idx = IPOIB_SND_QP_DB_IDX,
80
 	},
80
 	},
82
 		.doorbell_idx = IPOIB_RCV_QP_DB_IDX,
82
 		.doorbell_idx = IPOIB_RCV_QP_DB_IDX,
83
 	},
83
 	},
84
 };
84
 };
85
-static struct arbel_completion_queue static_ipoib_send_cq = {
86
-	.cq = {
87
-		.cqn = 1234, /* Only used for debug messages */
88
-		.num_cqes = NUM_IPOIB_SND_CQES,
89
-		.work_queues = LIST_HEAD_INIT (static_ipoib_send_cq.cq.work_queues),
85
+static struct ib_queue_pair static_ipoib_qp = {
86
+	.send = {
87
+		.qp = &static_ipoib_qp,
88
+		.is_send = 1,
89
+		.cq = &static_ipoib_send_cq,
90
+		.num_wqes = NUM_IPOIB_SND_WQES,
91
+		.iobufs = static_ipoib_tx_ring,
92
+		.list = LIST_HEAD_INIT (static_ipoib_qp.send.list),
93
+		.dev_priv = &static_arbel_ipoib_qp.send,
90
 	},
94
 	},
91
-	.doorbell_idx = IPOIB_SND_CQ_CI_DB_IDX,
92
-};
93
-static struct arbel_completion_queue static_ipoib_recv_cq = {
94
-	.cq = {
95
-		.cqn = 2345, /* Only used for debug messages */
96
-		.num_cqes = NUM_IPOIB_RCV_CQES,
97
-		.work_queues = LIST_HEAD_INIT (static_ipoib_recv_cq.cq.work_queues),
95
+	.recv = {
96
+		.qp = &static_ipoib_qp,
97
+		.is_send = 0,
98
+		.cq = &static_ipoib_recv_cq,
99
+		.num_wqes = NUM_IPOIB_RCV_WQES,
100
+		.iobufs = static_ipoib_rx_ring,
101
+		.list = LIST_HEAD_INIT (static_ipoib_qp.recv.list),
102
+		.dev_priv = &static_arbel_ipoib_qp.recv,
98
 	},
103
 	},
99
-	.doorbell_idx = IPOIB_RCV_CQ_CI_DB_IDX,
104
+	.dev_priv = &static_arbel_ipoib_qp,
100
 };
105
 };
106
+
107
+
101
 static struct ib_device static_ibdev = {
108
 static struct ib_device static_ibdev = {
102
-	.priv = &static_arbel,
109
+	.dev_priv = &static_arbel,
103
 };
110
 };
104
 
111
 
105
 
112
 
150
 	};
157
 	};
151
 	memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
158
 	memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
152
 
159
 
153
-	rc = arbel_post_send ( &static_ibdev, &static_ipoib_qp.qp, &av, iobuf );
160
+	rc = arbel_post_send ( &static_ibdev, &static_ipoib_qp, &av, iobuf );
154
 
161
 
155
 	return rc;
162
 	return rc;
156
 }
163
 }
164
 				 struct ib_queue_pair *qp,
171
 				 struct ib_queue_pair *qp,
165
 				 struct ib_completion *completion,
172
 				 struct ib_completion *completion,
166
 				 struct io_buffer *iobuf ) {
173
 				 struct io_buffer *iobuf ) {
167
-	struct net_device *netdev = qp->priv;
174
+	struct net_device *netdev = qp->owner_priv;
168
 
175
 
169
 	DBG ( "Wahey! TX completion\n" );
176
 	DBG ( "Wahey! TX completion\n" );
170
 	netdev_tx_complete_err ( netdev, iobuf,
177
 	netdev_tx_complete_err ( netdev, iobuf,
175
 				 struct ib_queue_pair *qp,
182
 				 struct ib_queue_pair *qp,
176
 				 struct ib_completion *completion,
183
 				 struct ib_completion *completion,
177
 				 struct io_buffer *iobuf ) {
184
 				 struct io_buffer *iobuf ) {
178
-	struct net_device *netdev = qp->priv;
185
+	struct net_device *netdev = qp->owner_priv;
179
 	struct mlx_nic *mlx = netdev->priv;
186
 	struct mlx_nic *mlx = netdev->priv;
180
 
187
 
181
 	DBG ( "Yay! RX completion on %p len %zx:\n", iobuf, completion->len );
188
 	DBG ( "Yay! RX completion on %p len %zx:\n", iobuf, completion->len );
205
 			break;
212
 			break;
206
 		DBG ( "Posting RX buffer %p:\n", iobuf );
213
 		DBG ( "Posting RX buffer %p:\n", iobuf );
207
 		if ( ( rc = arbel_post_recv ( &static_ibdev,
214
 		if ( ( rc = arbel_post_recv ( &static_ibdev,
208
-					      &static_ipoib_qp.qp,
215
+					      &static_ipoib_qp,
209
 					      iobuf ) ) != 0 ) {
216
 					      iobuf ) ) != 0 ) {
210
 			free_iob ( iobuf );
217
 			free_iob ( iobuf );
211
 			break;
218
 			break;
237
 	}
244
 	}
238
 
245
 
239
 	/* Poll completion queues */
246
 	/* Poll completion queues */
240
-	arbel_poll_cq ( &static_ibdev, &static_ipoib_send_cq.cq,
247
+	arbel_poll_cq ( &static_ibdev, &static_ipoib_send_cq,
241
 			temp_complete_send, temp_complete_recv );
248
 			temp_complete_send, temp_complete_recv );
242
-	arbel_poll_cq ( &static_ibdev, &static_ipoib_recv_cq.cq,
249
+	arbel_poll_cq ( &static_ibdev, &static_ipoib_recv_cq,
243
 			temp_complete_send, temp_complete_recv );
250
 			temp_complete_send, temp_complete_recv );
244
-	//	mlx_poll_cq ( netdev, mlx->rcv_cqh, mlx_rx_complete );
245
 
251
 
246
 	mlx_refill_rx ( netdev );
252
 	mlx_refill_rx ( netdev );
247
 }
253
 }
469
  * Create completion queue
475
  * Create completion queue
470
  *
476
  *
471
  * @v ibdev		Infiniband device
477
  * @v ibdev		Infiniband device
472
- * @v log2_num_cqes	Log2 of the number of completion queue entries
473
- * @ret new_cq		New completion queue
478
+ * @v cq		Completion queue
474
  * @ret rc		Return status code
479
  * @ret rc		Return status code
475
  */
480
  */
476
 static int arbel_create_cq ( struct ib_device *ibdev,
481
 static int arbel_create_cq ( struct ib_device *ibdev,
477
-			     unsigned int log2_num_cqes,
478
-			     struct ib_completion_queue **new_cq ) {
479
-	struct arbel *arbel = ibdev->priv;
482
+			     struct ib_completion_queue *cq ) {
483
+	struct arbel *arbel = ibdev->dev_priv;
480
 	struct arbel_completion_queue *arbel_cq;
484
 	struct arbel_completion_queue *arbel_cq;
481
 	struct arbelprm_completion_queue_context cqctx;
485
 	struct arbelprm_completion_queue_context cqctx;
482
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
486
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
483
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
487
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
484
 	int cqn_offset;
488
 	int cqn_offset;
485
-	unsigned int cqn;
486
-	unsigned int num_cqes;
487
 	size_t cqe_size;
489
 	size_t cqe_size;
488
-	unsigned int ci_doorbell_idx;
489
-	unsigned int arm_doorbell_idx;
490
 	unsigned int i;
490
 	unsigned int i;
491
 	int rc;
491
 	int rc;
492
 
492
 
497
 		rc = cqn_offset;
497
 		rc = cqn_offset;
498
 		goto err_cqn_offset;
498
 		goto err_cqn_offset;
499
 	}
499
 	}
500
-	cqn = ( arbel->limits.reserved_cqs + cqn_offset );
501
-	ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
502
-	arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
500
+	cq->cqn = ( arbel->limits.reserved_cqs + cqn_offset );
503
 
501
 
504
 	/* Allocate control structures */
502
 	/* Allocate control structures */
505
 	arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
503
 	arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
507
 		rc = -ENOMEM;
505
 		rc = -ENOMEM;
508
 		goto err_arbel_cq;
506
 		goto err_arbel_cq;
509
 	}
507
 	}
510
-	arbel_cq->cq.cqn = cqn;
511
-	arbel_cq->cq.num_cqes = num_cqes;
512
-	INIT_LIST_HEAD ( &arbel_cq->cq.work_queues );
513
-	arbel_cq->doorbell_idx = ci_doorbell_idx;
508
+	arbel_cq->ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
509
+	arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
514
 
510
 
515
 	/* Allocate completion queue itself */
511
 	/* Allocate completion queue itself */
516
-	num_cqes = ( 1 << log2_num_cqes );
517
-	cqe_size = ( num_cqes * sizeof ( arbel_cq->cqe[0] ) );
512
+	cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
518
 	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
513
 	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
519
 	if ( ! arbel_cq->cqe ) {
514
 	if ( ! arbel_cq->cqe ) {
520
 		rc = -ENOMEM;
515
 		rc = -ENOMEM;
521
 		goto err_cqe;
516
 		goto err_cqe;
522
 	}
517
 	}
523
 	memset ( arbel_cq->cqe, 0, cqe_size );
518
 	memset ( arbel_cq->cqe, 0, cqe_size );
524
-	for ( i = 0 ; i < num_cqes ; i++ ) {
519
+	for ( i = 0 ; i < cq->num_cqes ; i++ ) {
525
 		MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
520
 		MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
526
 	}
521
 	}
527
 	barrier();
522
 	barrier();
528
 
523
 
529
 	/* Initialise doorbell records */
524
 	/* Initialise doorbell records */
530
-	ci_db_rec = &arbel->db_rec[ci_doorbell_idx].cq_ci;
525
+	ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
531
 	MLX_FILL_1 ( ci_db_rec, 0, counter, 0 );
526
 	MLX_FILL_1 ( ci_db_rec, 0, counter, 0 );
532
 	MLX_FILL_2 ( ci_db_rec, 1,
527
 	MLX_FILL_2 ( ci_db_rec, 1,
533
 		     res, ARBEL_UAR_RES_CQ_CI,
528
 		     res, ARBEL_UAR_RES_CQ_CI,
534
-		     cq_number, cqn );
535
-	arm_db_rec = &arbel->db_rec[arm_doorbell_idx].cq_arm;
529
+		     cq_number, cq->cqn );
530
+	arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
536
 	MLX_FILL_1 ( arm_db_rec, 0, counter, 0 );
531
 	MLX_FILL_1 ( arm_db_rec, 0, counter, 0 );
537
 	MLX_FILL_2 ( arm_db_rec, 1,
532
 	MLX_FILL_2 ( arm_db_rec, 1,
538
 		     res, ARBEL_UAR_RES_CQ_ARM,
533
 		     res, ARBEL_UAR_RES_CQ_ARM,
539
-		     cq_number, cqn );
534
+		     cq_number, cq->cqn );
540
 
535
 
541
 	/* Hand queue over to hardware */
536
 	/* Hand queue over to hardware */
542
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
537
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
543
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
538
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
544
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
539
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
545
 		     virt_to_bus ( arbel_cq->cqe ) );
540
 		     virt_to_bus ( arbel_cq->cqe ) );
541
+#if 0
546
 	MLX_FILL_2 ( &cqctx, 3,
542
 	MLX_FILL_2 ( &cqctx, 3,
547
 		     usr_page, arbel->limits.reserved_uars,
543
 		     usr_page, arbel->limits.reserved_uars,
548
 		     log_cq_size, log2_num_cqes );
544
 		     log_cq_size, log2_num_cqes );
545
+#endif
549
 	MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
546
 	MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
550
 	MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
547
 	MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
551
 	MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
548
 	MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
552
-	MLX_FILL_1 ( &cqctx, 12, cqn, cqn );
553
-	MLX_FILL_1 ( &cqctx, 13, cq_ci_db_record, ci_doorbell_idx );
554
-	MLX_FILL_1 ( &cqctx, 14, cq_state_db_record, arm_doorbell_idx );
555
-	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cqn, &cqctx ) ) != 0 ) {
549
+	MLX_FILL_1 ( &cqctx, 12, cqn, cq->cqn );
550
+	MLX_FILL_1 ( &cqctx, 13,
551
+		     cq_ci_db_record, arbel_cq->ci_doorbell_idx );
552
+	MLX_FILL_1 ( &cqctx, 14,
553
+		     cq_state_db_record, arbel_cq->arm_doorbell_idx );
554
+	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
556
 		DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
555
 		DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
557
 		       arbel, strerror ( rc ) );
556
 		       arbel, strerror ( rc ) );
558
 		goto err_sw2hw;
557
 		goto err_sw2hw;
559
 	}
558
 	}
560
 
559
 
561
-	*new_cq = &arbel_cq->cq;
560
+	cq->dev_priv = arbel_cq;
562
 	return 0;
561
 	return 0;
563
 
562
 
564
  err_sw2hw:
563
  err_sw2hw:
581
  */
580
  */
582
 static void arbel_destroy_cq ( struct ib_device *ibdev,
581
 static void arbel_destroy_cq ( struct ib_device *ibdev,
583
 			       struct ib_completion_queue *cq ) {
582
 			       struct ib_completion_queue *cq ) {
584
-	struct arbel *arbel = ibdev->priv;
585
-	struct arbel_completion_queue *arbel_cq =
586
-		container_of ( cq, struct arbel_completion_queue, cq );
583
+	struct arbel *arbel = ibdev->dev_priv;
584
+	struct arbel_completion_queue *arbel_cq = cq->dev_priv;
587
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
585
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
588
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
586
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
589
 	int cqn_offset;
587
 	int cqn_offset;
618
 	arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
616
 	arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
619
 }
617
 }
620
 
618
 
619
+/***************************************************************************
620
+ *
621
+ * Queue pair operations
622
+ *
623
+ ***************************************************************************
624
+ */
625
+
626
+static int arbel_create_qp ( struct ib_device *ibdev,
627
+			     unsigned int log2_num_send_wqes,
628
+			     struct ib_completion_queue *send_cq,
629
+			     unsigned int log2_num_recv_wqes,
630
+			     struct ib_completion_queue *recv_cq,
631
+			     struct ib_queue_pair **new_qp ) {
632
+	struct arbel *arbel = ibdev->dev_priv;
633
+	struct arbel_queue_pair *arbel_qp;
634
+	struct arbelprm_qp_db_record *send_db_rec;
635
+	struct arbelprm_qp_db_record *recv_db_rec;
636
+	int qpn_offset;
637
+	unsigned int qpn;
638
+	unsigned int num_send_wqes;
639
+	unsigned int num_recv_wqes;
640
+	unsigned int send_doorbell_idx;
641
+	unsigned int recv_doorbell_idx;
642
+	int rc;
643
+
644
+	/* Find a free queue pair number */
645
+	qpn_offset = arbel_alloc_qn_offset ( arbel->qp_inuse, ARBEL_MAX_QPS );
646
+	if ( qpn_offset < 0 ) {
647
+		DBGC ( arbel, "Arbel %p out of queue pairs\n", arbel );
648
+		rc = qpn_offset;
649
+		goto err_qpn_offset;
650
+	}
651
+	qpn = ( ARBEL_QPN_BASE + arbel->limits.reserved_qps + qpn_offset );
652
+	send_doorbell_idx = arbel_send_doorbell_idx ( qpn_offset );
653
+	recv_doorbell_idx = arbel_recv_doorbell_idx ( qpn_offset );
654
+
655
+	/* Allocate control structures */
656
+	num_send_wqes = ( 1 << log2_num_send_wqes );
657
+	num_recv_wqes = ( 1 << log2_num_recv_wqes );
658
+	arbel_qp = zalloc ( sizeof ( *arbel_qp ) );
659
+
660
+	return 0;
661
+
662
+ err_qpn_offset:
663
+	return rc;
664
+}
665
+
621
 /***************************************************************************
666
 /***************************************************************************
622
  *
667
  *
623
  * Work request operations
668
  * Work request operations
659
 			     struct ib_queue_pair *qp,
704
 			     struct ib_queue_pair *qp,
660
 			     struct ib_address_vector *av,
705
 			     struct ib_address_vector *av,
661
 			     struct io_buffer *iobuf ) {
706
 			     struct io_buffer *iobuf ) {
662
-	struct arbel *arbel = ibdev->priv;
663
-	struct arbel_queue_pair *arbel_qp
664
-		= container_of ( qp, struct arbel_queue_pair, qp );
707
+	struct arbel *arbel = ibdev->dev_priv;
708
+	struct arbel_queue_pair *arbel_qp = qp->dev_priv;
665
 	struct ib_work_queue *wq = &qp->send;
709
 	struct ib_work_queue *wq = &qp->send;
666
 	struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
710
 	struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
667
 	struct arbelprm_ud_send_wqe *prev_wqe;
711
 	struct arbelprm_ud_send_wqe *prev_wqe;
749
 static int arbel_post_recv ( struct ib_device *ibdev,
793
 static int arbel_post_recv ( struct ib_device *ibdev,
750
 			     struct ib_queue_pair *qp,
794
 			     struct ib_queue_pair *qp,
751
 			     struct io_buffer *iobuf ) {
795
 			     struct io_buffer *iobuf ) {
752
-	struct arbel *arbel = ibdev->priv;
753
-	struct arbel_queue_pair *arbel_qp
754
-		= container_of ( qp, struct arbel_queue_pair, qp );
796
+	struct arbel *arbel = ibdev->dev_priv;
797
+	struct arbel_queue_pair *arbel_qp = qp->dev_priv;
755
 	struct ib_work_queue *wq = &qp->recv;
798
 	struct ib_work_queue *wq = &qp->recv;
756
 	struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
799
 	struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
757
 	struct arbelprm_recv_wqe *wqe;
800
 	struct arbelprm_recv_wqe *wqe;
800
 			    union arbelprm_completion_entry *cqe,
843
 			    union arbelprm_completion_entry *cqe,
801
 			    ib_completer_t complete_send,
844
 			    ib_completer_t complete_send,
802
 			    ib_completer_t complete_recv ) {
845
 			    ib_completer_t complete_recv ) {
803
-	struct arbel *arbel = ibdev->priv;
846
+	struct arbel *arbel = ibdev->dev_priv;
804
 	struct ib_completion completion;
847
 	struct ib_completion completion;
805
 	struct ib_work_queue *wq;
848
 	struct ib_work_queue *wq;
806
 	struct ib_queue_pair *qp;
849
 	struct ib_queue_pair *qp;
842
 		return -EIO;
885
 		return -EIO;
843
 	}
886
 	}
844
 	qp = wq->qp;
887
 	qp = wq->qp;
845
-	arbel_qp = container_of ( qp, struct arbel_queue_pair, qp );
888
+	arbel_qp = qp->dev_priv;
846
 
889
 
847
 	/* Identify work queue entry index */
890
 	/* Identify work queue entry index */
848
 	if ( is_send ) {
891
 	if ( is_send ) {
883
 			    struct ib_completion_queue *cq,
926
 			    struct ib_completion_queue *cq,
884
 			    ib_completer_t complete_send,
927
 			    ib_completer_t complete_send,
885
 			    ib_completer_t complete_recv ) {
928
 			    ib_completer_t complete_recv ) {
886
-	struct arbel *arbel = ibdev->priv;
887
-	struct arbel_completion_queue *arbel_cq
888
-		= container_of ( cq, struct arbel_completion_queue, cq );
929
+	struct arbel *arbel = ibdev->dev_priv;
930
+	struct arbel_completion_queue *arbel_cq = cq->dev_priv;
889
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
931
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
890
 	union arbelprm_completion_entry *cqe;
932
 	union arbelprm_completion_entry *cqe;
891
 	unsigned int cqe_idx_mask;
933
 	unsigned int cqe_idx_mask;
914
 		/* Update completion queue's index */
956
 		/* Update completion queue's index */
915
 		cq->next_idx++;
957
 		cq->next_idx++;
916
 		/* Update doorbell record */
958
 		/* Update doorbell record */
917
-		ci_db_rec = &arbel->db_rec[arbel_cq->doorbell_idx].cq_ci;
959
+		ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
918
 		MLX_FILL_1 ( ci_db_rec, 0,
960
 		MLX_FILL_1 ( ci_db_rec, 0,
919
 			     counter, ( cq->next_idx & 0xffffffffUL ) );
961
 			     counter, ( cq->next_idx & 0xffffffffUL ) );
920
 	}
962
 	}
992
 	arbel->db_rec = dev_ib_data.uar_context_base;
1034
 	arbel->db_rec = dev_ib_data.uar_context_base;
993
 	arbel->reserved_lkey = dev_ib_data.mkey;
1035
 	arbel->reserved_lkey = dev_ib_data.mkey;
994
 	arbel->eqn = dev_ib_data.eq.eqn;
1036
 	arbel->eqn = dev_ib_data.eq.eqn;
995
-	static_ipoib_qp.send.wqe =
1037
+	static_arbel_ipoib_qp.send.wqe =
996
 		( ( struct udqp_st * ) qph )->snd_wq;
1038
 		( ( struct udqp_st * ) qph )->snd_wq;
997
-	static_ipoib_qp.recv.wqe =
1039
+	static_arbel_ipoib_qp.recv.wqe =
998
 		( ( struct udqp_st * ) qph )->rcv_wq;
1040
 		( ( struct udqp_st * ) qph )->rcv_wq;
999
-	static_ipoib_send_cq.cqe =
1041
+	static_arbel_ipoib_send_cq.cqe =
1000
 		( ( struct cq_st * ) ib_data.ipoib_snd_cq )->cq_buf;
1042
 		( ( struct cq_st * ) ib_data.ipoib_snd_cq )->cq_buf;
1001
-	static_ipoib_recv_cq.cqe =
1043
+	static_arbel_ipoib_recv_cq.cqe =
1002
 		( ( struct cq_st * ) ib_data.ipoib_rcv_cq )->cq_buf;
1044
 		( ( struct cq_st * ) ib_data.ipoib_rcv_cq )->cq_buf;
1003
-	static_ipoib_qp.qp.qpn = ib_get_qpn ( qph );
1004
-	static_ipoib_qp.qp.priv = netdev;
1005
-	list_add ( &static_ipoib_qp.qp.send.list,
1006
-		   &static_ipoib_send_cq.cq.work_queues );
1007
-	list_add ( &static_ipoib_qp.qp.recv.list,
1008
-		   &static_ipoib_recv_cq.cq.work_queues );
1045
+	static_ipoib_qp.qpn = ib_get_qpn ( qph );
1046
+	static_ipoib_qp.owner_priv = netdev;
1047
+	list_add ( &static_ipoib_qp.send.list,
1048
+		   &static_ipoib_send_cq.work_queues );
1049
+	list_add ( &static_ipoib_qp.recv.list,
1050
+		   &static_ipoib_recv_cq.work_queues );
1009
 
1051
 
1010
 	/* Get device limits */
1052
 	/* Get device limits */
1011
 	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1053
 	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1016
 	arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1058
 	arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1017
 	arbel->limits.reserved_cqs =
1059
 	arbel->limits.reserved_cqs =
1018
 		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1060
 		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1061
+	arbel->limits.reserved_qps =
1062
+		( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
1019
 	DBG ( "Device limits:\n ");
1063
 	DBG ( "Device limits:\n ");
1020
 	DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
1064
 	DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
1021
 
1065
 

+ 13
- 7
src/include/gpxe/infiniband.h Visa fil

89
 	unsigned long next_idx;
89
 	unsigned long next_idx;
90
 	/** I/O buffers assigned to work queue */
90
 	/** I/O buffers assigned to work queue */
91
 	struct io_buffer **iobufs;
91
 	struct io_buffer **iobufs;
92
+	/** Device private data */
93
+	void *dev_priv;
92
 };
94
 };
93
 
95
 
94
 /** An Infiniband Queue Pair */
96
 /** An Infiniband Queue Pair */
99
 	struct ib_work_queue send;
101
 	struct ib_work_queue send;
100
 	/** Receive queue */
102
 	/** Receive queue */
101
 	struct ib_work_queue recv;
103
 	struct ib_work_queue recv;
104
+	/** Device private data */
105
+	void *dev_priv;
102
 	/** Queue owner private data */
106
 	/** Queue owner private data */
103
-	void *priv;
107
+	void *owner_priv;
104
 };
108
 };
105
 
109
 
106
 /** An Infiniband Completion Queue */
110
 /** An Infiniband Completion Queue */
119
 	unsigned long next_idx;
123
 	unsigned long next_idx;
120
 	/** List of work queues completing to this queue */
124
 	/** List of work queues completing to this queue */
121
 	struct list_head work_queues;
125
 	struct list_head work_queues;
126
+	/** Device private data */
127
+	void *dev_priv;
122
 };
128
 };
123
 
129
 
124
 /** An Infiniband completion */
130
 /** An Infiniband completion */
172
 	 * Create completion queue
178
 	 * Create completion queue
173
 	 *
179
 	 *
174
 	 * @v ibdev		Infiniband device
180
 	 * @v ibdev		Infiniband device
175
-	 * @v log2_num_cqes	Log2 of the number of completion queue entries
176
-	 * @ret new_cq		New completion queue
181
+	 * @v cq		Completion queue
177
 	 * @ret rc		Return status code
182
 	 * @ret rc		Return status code
178
 	 */
183
 	 */
179
 	int ( * create_cq ) ( struct ib_device *ibdev,
184
 	int ( * create_cq ) ( struct ib_device *ibdev,
180
-			      unsigned int log2_num_cqes,
181
-			      struct ib_completion_queue **new_cq );
185
+			      struct ib_completion_queue *cq );
182
 	/**
186
 	/**
183
 	 * Destroy completion queue
187
 	 * Destroy completion queue
184
 	 *
188
 	 *
237
 
241
 
238
 /** An Infiniband device */
242
 /** An Infiniband device */
239
 struct ib_device {	
243
 struct ib_device {	
240
-	/** Driver private data */
241
-	void *priv;
244
+	/** Infiniband operations */
245
+	struct ib_device_operations *op;
246
+	/** Device private data */
247
+	void *dev_priv;
242
 };
248
 };
243
 
249
 
244
 
250
 

+ 51
- 0
src/net/infiniband.c Visa fil

17
  */
17
  */
18
 
18
 
19
 #include <stdint.h>
19
 #include <stdint.h>
20
+#include <stdlib.h>
20
 #include <stdio.h>
21
 #include <stdio.h>
21
 #include <string.h>
22
 #include <string.h>
22
 #include <byteswap.h>
23
 #include <byteswap.h>
23
 #include <errno.h>
24
 #include <errno.h>
24
 #include <assert.h>
25
 #include <assert.h>
26
+#include <gpxe/list.h>
25
 #include <gpxe/if_arp.h>
27
 #include <gpxe/if_arp.h>
26
 #include <gpxe/netdevice.h>
28
 #include <gpxe/netdevice.h>
27
 #include <gpxe/iobuf.h>
29
 #include <gpxe/iobuf.h>
33
  *
35
  *
34
  */
36
  */
35
 
37
 
38
+/**
39
+ * Create completion queue
40
+ *
41
+ * @v ibdev		Infiniband device
42
+ * @v num_cqes		Number of completion queue entries
43
+ * @ret cq		New completion queue
44
+ */
45
+struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
46
+					    unsigned int num_cqes ) {
47
+	struct ib_completion_queue *cq;
48
+	int rc;
49
+
50
+	DBGC ( ibdev, "IBDEV %p creating completion queue\n", ibdev );
51
+
52
+	/* Allocate and initialise data structure */
53
+	cq = zalloc ( sizeof ( *cq ) );
54
+	if ( ! cq )
55
+		return NULL;
56
+	cq->num_cqes = num_cqes;
57
+	INIT_LIST_HEAD ( &cq->work_queues );
58
+
59
+	/* Perform device-specific initialisation and get CQN */
60
+	if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
61
+		DBGC ( ibdev, "IBDEV %p could not initialise CQ: %s\n",
62
+		       ibdev, strerror ( rc ) );
63
+		free ( cq );
64
+		return NULL;
65
+	}
66
+
67
+	DBGC ( ibdev, "IBDEV %p created completion queue %#lx\n",
68
+	       ibdev, cq->cqn );
69
+	return cq;
70
+}
71
+
72
+/**
73
+ * Destroy completion queue
74
+ *
75
+ * @v ibdev		Infiniband device
76
+ * @v cq		Completion queue
77
+ */
78
+void ib_destroy_cq ( struct ib_device *ibdev,
79
+		     struct ib_completion_queue *cq ) {
80
+	DBGC ( ibdev, "IBDEV %p destroying completion queue %#lx\n",
81
+	       ibdev, cq->cqn );
82
+	assert ( list_empty ( &cq->work_queues ) );
83
+	ibdev->op->destroy_cq ( ibdev, cq );
84
+	free ( cq );
85
+}
86
+
36
 /**
87
 /**
37
  * Find work queue belonging to completion queue
88
  * Find work queue belonging to completion queue
38
  *
89
  *

Laddar…
Avbryt
Spara