Browse Source

Started to add code for CQ creation

tags/v0.9.3
Michael Brown 16 years ago
parent
commit
5a43293c38

+ 85
- 0
src/drivers/net/mlx_ipoib/arbel.h View File

@@ -85,6 +85,12 @@ union arbelprm_doorbell_register {
85 85
  *
86 86
  */
87 87
 
88
+/** Arbel device limits */
89
+struct arbel_dev_limits {
90
+	/** Number of reserved CQs */
91
+	unsigned long reserved_cqs;
92
+};
93
+
88 94
 /** Alignment of Arbel send work queue entries */
89 95
 #define ARBEL_SEND_WQE_ALIGN 128
90 96
 
@@ -129,6 +135,12 @@ struct arbel_queue_pair {
129 135
 	struct arbel_recv_work_queue recv;
130 136
 };
131 137
 
138
+/** Maximum number of allocatable completion queues
139
+ *
140
+ * This is a policy decision, not a device limit.
141
+ */
142
+#define ARBEL_MAX_CQS		8
143
+
132 144
 /** An Arbel completion queue */
133 145
 struct arbel_completion_queue {
134 146
 	/** Infiniband completion queue */
@@ -139,6 +151,14 @@ struct arbel_completion_queue {
139 151
 	union arbelprm_completion_entry *cqe;
140 152
 };
141 153
 
154
+/** An Arbel resource bitmask */
155
+typedef uint32_t arbel_bitmask_t;
156
+
157
+/** Size of an Arbel resource bitmask */
158
+#define ARBEL_BITMASK_SIZE(max_entries)					     \
159
+	( ( (max_entries) + ( 8 * sizeof ( arbel_bitmask_t ) ) - 1 ) /	     \
160
+	  ( 8 * sizeof ( arbel_bitmask_t ) ) )
161
+
142 162
 /** An Arbel device */
143 163
 struct arbel {
144 164
 	/** Configuration registers */
@@ -157,7 +177,12 @@ struct arbel {
157 177
 	 * Used to get unrestricted memory access.
158 178
 	 */
159 179
 	unsigned long reserved_lkey;
180
+
181
+	/** Completion queue in-use bitmask */
182
+	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
160 183
 	
184
+	/** Device limits */
185
+	struct arbel_dev_limits limits;
161 186
 };
162 187
 
163 188
 /*
@@ -203,4 +228,64 @@ struct arbel {
203 228
 #define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len )		     \
204 229
 	ARBEL_HCR_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
205 230
 
231
+/*
232
+ * Doorbell record allocation
233
+ *
234
+ * The doorbell record map looks like:
235
+ *
236
+ *    ARBEL_MAX_CQS * Arm completion queue doorbell
237
+ *    ARBEL_MAX_QPS * Send work request doorbell
238
+ *    Group separator
239
+ *    ...(empty space)...
240
+ *    ARBEL_MAX_QPS * Receive work request doorbell
241
+ *    ARBEL_MAX_CQS * Completion queue consumer counter update doorbell
242
+ */
243
+
244
+#define ARBEL_MAX_DOORBELL_RECORDS 512
245
+#define ARBEL_GROUP_SEPARATOR_DOORBELL ( ARBEL_MAX_CQS + ARBEL_MAX_QPS )
246
+
247
+/**
248
+ * Get arm completion queue doorbell index
249
+ *
250
+ * @v cqn_offset	Completion queue number offset
251
+ * @ret doorbell_idx	Doorbell index
252
+ */
253
+static inline unsigned int
254
+arbel_arm_cq_doorbell_idx ( unsigned int cqn_offset ) {
255
+	return cqn_offset;
256
+}
257
+
258
+/**
259
+ * Get send work request doorbell index
260
+ *
261
+ * @v qpn_offset	Queue pair number offset
262
+ * @ret doorbell_idx	Doorbell index
263
+ */
264
+static inline unsigned int
265
+arbel_send_doorbell_idx ( unsigned int qpn_offset ) {
266
+	return ( ARBEL_MAX_CQS + qpn_offset );
267
+}
268
+
269
+/**
270
+ * Get receive work request doorbell index
271
+ *
272
+ * @v qpn_offset	Queue pair number offset
273
+ * @ret doorbell_idx	Doorbell index
274
+ */
275
+static inline unsigned int
276
+arbel_recv_doorbell_idx ( unsigned int qpn_offset ) {
277
+	return ( ARBEL_MAX_DOORBELL_RECORDS - ARBEL_MAX_CQS - qpn_offset - 1 );
278
+}
279
+
280
+/**
281
+ * Get commpletion queue consumer counter doorbell index
282
+ *
283
+ * @v cqn_offset	Completion queue number offset
284
+ * @ret doorbell_idx	Doorbell index
285
+ */
286
+static inline unsigned int
287
+arbel_cq_ci_doorbell_idx ( unsigned int cqn_offset ) {
288
+	return ( ARBEL_MAX_DOORBELL_RECORDS - cqn_offset - 1 );
289
+}
290
+
206 291
 #endif /* _ARBEL_H */

+ 119
- 13
src/drivers/net/mlx_ipoib/mt25218.c View File

@@ -12,6 +12,7 @@ Skeleton NIC driver for Etherboot
12 12
 
13 13
 #include <errno.h>
14 14
 #include <gpxe/pci.h>
15
+#include <gpxe/malloc.h>
15 16
 #include <gpxe/iobuf.h>
16 17
 #include <gpxe/netdevice.h>
17 18
 #include <gpxe/infiniband.h>
@@ -266,6 +267,50 @@ static struct net_device_operations mlx_operations = {
266 267
 	.irq		= mlx_irq,
267 268
 };
268 269
 
270
+
271
+
272
+
273
+/**
274
+ * Allocate queue number
275
+ *
276
+ * @v q_inuse		Queue usage bitmask
277
+ * @v max_inuse		Maximum number of in-use queues
278
+ * @ret qn_offset	Free queue number offset, or negative error
279
+ */
280
+static int arbel_alloc_qn_offset ( arbel_bitmask_t *q_inuse,
281
+				   unsigned int max_inuse ) {
282
+	unsigned int qn_offset = 0;
283
+	arbel_bitmask_t mask = 1;
284
+
285
+	while ( qn_offset < max_inuse ) {
286
+		if ( ( mask & *q_inuse ) == 0 ) {
287
+			*q_inuse |= mask;
288
+			return qn_offset;
289
+		}
290
+		qn_offset++;
291
+		mask <<= 1;
292
+		if ( ! mask ) {
293
+			mask = 1;
294
+			q_inuse++;
295
+		}
296
+	}
297
+	return -ENFILE;
298
+}
299
+
300
+/**
301
+ * Free queue number
302
+ *
303
+ * @v q_inuse		Queue usage bitmask
304
+ * @v qn_offset		Queue number offset
305
+ */
306
+static void arbel_free_qn_offset ( arbel_bitmask_t *q_inuse, int qn_offset ) {
307
+	arbel_bitmask_t mask;
308
+
309
+	mask = ( 1 << ( qn_offset % ( 8 * sizeof ( mask ) ) ) );
310
+	q_inuse += ( qn_offset / ( 8 * sizeof ( mask ) ) );
311
+	*q_inuse &= ~mask;
312
+}
313
+
269 314
 /***************************************************************************
270 315
  *
271 316
  * HCA commands
@@ -412,22 +457,78 @@ arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
412 457
  * @v ibdev		Infiniband device
413 458
  * @v 
414 459
  */
415
-static int arbel_create_cq ( struct ib_device *ibdev,
460
+static int arbel_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
416 461
 			     struct ib_completion_queue **new_cq ) {
417 462
 	struct arbel *arbel = ibdev->priv;
463
+	struct arbel_completion_queue *arbel_cq;
418 464
 	struct arbelprm_completion_queue_context cqctx;
419
-	struct ib_completion_queue *cq;
465
+	int cqn_offset;
466
+	unsigned int cqn;
467
+	size_t cqe_size;
468
+	unsigned int i;
469
+	int rc;
420 470
 
421
-	cq = zalloc ( sizeof ( *cq ) );
422
-	if ( ! cq )
423
-		return -ENOMEM;
471
+	/* Find a free completion queue number */
472
+	cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
473
+	if ( cqn_offset < 0 ) {
474
+		rc = cqn_offset;
475
+		goto err_cqn_offset;
476
+	}
477
+	cqn = ( arbel->limits.reserved_cqs + cqn_offset );
424 478
 
425
-	
479
+	/* Allocate control structures */
480
+	arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
481
+	if ( ! arbel_cq ) {
482
+		rc = -ENOMEM;
483
+		goto err_arbel_cq;
484
+	}
485
+	arbel_cq->cq.cqn = cqn;
486
+	arbel_cq->cq.num_cqes = num_cqes;
487
+	INIT_LIST_HEAD ( &arbel_cq->cq.work_queues );
488
+	arbel_cq->doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
489
+
490
+	/* Allocate completion queue itself */
491
+	cqe_size = ( num_cqes * sizeof ( arbel_cq->cqe[0] ) );
492
+	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
493
+	if ( ! arbel_cq->cqe ) {
494
+		rc = -ENOMEM;
495
+		goto err_cqe;
496
+	}
497
+	memset ( arbel_cq->cqe, 0, cqe_size );
498
+	for ( i = 0 ; i < num_cqes ; i++ ) {
499
+		MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
500
+	}
501
+	barrier();
502
+
503
+	/* Initialise doorbell records */
504
+	// ...
426 505
 
506
+	/* Hand queue over to hardware */
427 507
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
428
-	
508
+	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
509
+	MLX_FILL_1 ( &cqctx, 2, start_address_l,
510
+		     virt_to_bus ( arbel_cq->cqe ) );
511
+	///	....
512
+
513
+	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cqn, &cqctx ) ) != 0 ) {
514
+		// ...
515
+	}
429 516
 
430
-	return arbel_cmd_sw2hw_cq ( arbel, 0, &cqctx );
517
+
518
+	// completion queue number
519
+	// doorbell index
520
+
521
+	*new_cq = &arbel_cq->cq;
522
+
523
+
524
+	return 0;
525
+
526
+ err_cqe:
527
+	free ( arbel_cq );
528
+ err_arbel_cq:
529
+	arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
530
+ err_cqn_offset:
531
+	return rc;
431 532
 }
432 533
 
433 534
 
@@ -764,6 +865,8 @@ static void arbel_remove ( struct pci_device *pci ) {
764 865
 static int arbel_probe ( struct pci_device *pci,
765 866
 			 const struct pci_device_id *id __unused ) {
766 867
 	struct net_device *netdev;
868
+	struct arbelprm_query_dev_lim dev_lim;
869
+	struct arbel *arbel = &static_arbel;
767 870
 	struct mlx_nic *mlx;
768 871
 	struct ib_mac *mac;
769 872
 	udqp_t qph;
@@ -815,12 +918,14 @@ static int arbel_probe ( struct pci_device *pci,
815 918
 	list_add ( &static_ipoib_qp.qp.recv.list,
816 919
 		   &static_ipoib_recv_cq.cq.work_queues );
817 920
 
818
-	struct arbelprm_query_dev_lim dev_lim;
819
-	memset ( &dev_lim, 0xaa, sizeof ( dev_lim ) );
820
-	if ( ( rc = arbel_cmd_query_dev_lim ( &static_arbel,
821
-					      &dev_lim ) ) != 0 ) {
822
-		DBG ( "QUERY_DEV_LIM failed: %s\n", strerror ( rc ) );
921
+	/* Get device limits */
922
+	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
923
+		DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
924
+		       arbel, strerror ( rc ) );
925
+		goto err_query_dev_lim;
823 926
 	}
927
+	arbel->limits.reserved_cqs =
928
+		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
824 929
 	DBG ( "Device limits:\n ");
825 930
 	DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
826 931
 
@@ -830,6 +935,7 @@ static int arbel_probe ( struct pci_device *pci,
830 935
 
831 936
 	return 0;
832 937
 
938
+ err_query_dev_lim:
833 939
  err_register_netdev:
834 940
  err_ipoib_init:
835 941
 	ib_driver_close ( 0 );

+ 8
- 8
src/drivers/net/mlx_ipoib/mt25218.h View File

@@ -146,10 +146,10 @@
146 146
 
147 147
 /* uar context indexes */
148 148
 enum {
149
-	MADS_RCV_CQ_ARM_DB_IDX,
150 149
 	MADS_SND_CQ_ARM_DB_IDX,
151
-	IPOIB_RCV_CQ_ARM_DB_IDX,
150
+	MADS_RCV_CQ_ARM_DB_IDX,
152 151
 	IPOIB_SND_CQ_ARM_DB_IDX,
152
+	IPOIB_RCV_CQ_ARM_DB_IDX,
153 153
 	MADS_SND_QP_DB_IDX,
154 154
 	IPOIB_SND_QP_DB_IDX,
155 155
 	GROUP_SEP_IDX,
@@ -158,12 +158,12 @@ enum {
158 158
 	   unmapped doorbell records
159 159
 	   -------------------------- */
160 160
 	END_UNMAPPED_DB_IDX = 505,
161
-	MADS_RCV_QP_DB_IDX = 506,
162
-	IPOIB_RCV_QP_DB_IDX = 507,
163
-	MADS_RCV_CQ_CI_DB_IDX = 508,
164
-	MADS_SND_CQ_CI_DB_IDX = 509,
165
-	IPOIB_RCV_CQ_CI_DB_IDX = 510,
166
-	IPOIB_SND_CQ_CI_DB_IDX = 511
161
+	IPOIB_RCV_QP_DB_IDX = 506,
162
+	MADS_RCV_QP_DB_IDX = 507,
163
+	IPOIB_RCV_CQ_CI_DB_IDX = 508,
164
+	IPOIB_SND_CQ_CI_DB_IDX = 509,
165
+	MADS_RCV_CQ_CI_DB_IDX = 510,
166
+	MADS_SND_CQ_CI_DB_IDX = 511,
167 167
 };
168 168
 
169 169
 /* uar resources types */

Loading…
Cancel
Save