Browse Source

Started to add code for CQ creation

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

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

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
 /** Alignment of Arbel send work queue entries */
94
 /** Alignment of Arbel send work queue entries */
89
 #define ARBEL_SEND_WQE_ALIGN 128
95
 #define ARBEL_SEND_WQE_ALIGN 128
90
 
96
 
129
 	struct arbel_recv_work_queue recv;
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
 /** An Arbel completion queue */
144
 /** An Arbel completion queue */
133
 struct arbel_completion_queue {
145
 struct arbel_completion_queue {
134
 	/** Infiniband completion queue */
146
 	/** Infiniband completion queue */
139
 	union arbelprm_completion_entry *cqe;
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
 /** An Arbel device */
162
 /** An Arbel device */
143
 struct arbel {
163
 struct arbel {
144
 	/** Configuration registers */
164
 	/** Configuration registers */
157
 	 * Used to get unrestricted memory access.
177
 	 * Used to get unrestricted memory access.
158
 	 */
178
 	 */
159
 	unsigned long reserved_lkey;
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
 #define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len )		     \
228
 #define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len )		     \
204
 	ARBEL_HCR_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
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
 #endif /* _ARBEL_H */
291
 #endif /* _ARBEL_H */

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

12
 
12
 
13
 #include <errno.h>
13
 #include <errno.h>
14
 #include <gpxe/pci.h>
14
 #include <gpxe/pci.h>
15
+#include <gpxe/malloc.h>
15
 #include <gpxe/iobuf.h>
16
 #include <gpxe/iobuf.h>
16
 #include <gpxe/netdevice.h>
17
 #include <gpxe/netdevice.h>
17
 #include <gpxe/infiniband.h>
18
 #include <gpxe/infiniband.h>
266
 	.irq		= mlx_irq,
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
  * HCA commands
316
  * HCA commands
412
  * @v ibdev		Infiniband device
457
  * @v ibdev		Infiniband device
413
  * @v 
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
 			     struct ib_completion_queue **new_cq ) {
461
 			     struct ib_completion_queue **new_cq ) {
417
 	struct arbel *arbel = ibdev->priv;
462
 	struct arbel *arbel = ibdev->priv;
463
+	struct arbel_completion_queue *arbel_cq;
418
 	struct arbelprm_completion_queue_context cqctx;
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
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
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
 static int arbel_probe ( struct pci_device *pci,
865
 static int arbel_probe ( struct pci_device *pci,
765
 			 const struct pci_device_id *id __unused ) {
866
 			 const struct pci_device_id *id __unused ) {
766
 	struct net_device *netdev;
867
 	struct net_device *netdev;
868
+	struct arbelprm_query_dev_lim dev_lim;
869
+	struct arbel *arbel = &static_arbel;
767
 	struct mlx_nic *mlx;
870
 	struct mlx_nic *mlx;
768
 	struct ib_mac *mac;
871
 	struct ib_mac *mac;
769
 	udqp_t qph;
872
 	udqp_t qph;
815
 	list_add ( &static_ipoib_qp.qp.recv.list,
918
 	list_add ( &static_ipoib_qp.qp.recv.list,
816
 		   &static_ipoib_recv_cq.cq.work_queues );
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
 	DBG ( "Device limits:\n ");
929
 	DBG ( "Device limits:\n ");
825
 	DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
930
 	DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
826
 
931
 
830
 
935
 
831
 	return 0;
936
 	return 0;
832
 
937
 
938
+ err_query_dev_lim:
833
  err_register_netdev:
939
  err_register_netdev:
834
  err_ipoib_init:
940
  err_ipoib_init:
835
 	ib_driver_close ( 0 );
941
 	ib_driver_close ( 0 );

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

146
 
146
 
147
 /* uar context indexes */
147
 /* uar context indexes */
148
 enum {
148
 enum {
149
-	MADS_RCV_CQ_ARM_DB_IDX,
150
 	MADS_SND_CQ_ARM_DB_IDX,
149
 	MADS_SND_CQ_ARM_DB_IDX,
151
-	IPOIB_RCV_CQ_ARM_DB_IDX,
150
+	MADS_RCV_CQ_ARM_DB_IDX,
152
 	IPOIB_SND_CQ_ARM_DB_IDX,
151
 	IPOIB_SND_CQ_ARM_DB_IDX,
152
+	IPOIB_RCV_CQ_ARM_DB_IDX,
153
 	MADS_SND_QP_DB_IDX,
153
 	MADS_SND_QP_DB_IDX,
154
 	IPOIB_SND_QP_DB_IDX,
154
 	IPOIB_SND_QP_DB_IDX,
155
 	GROUP_SEP_IDX,
155
 	GROUP_SEP_IDX,
158
 	   unmapped doorbell records
158
 	   unmapped doorbell records
159
 	   -------------------------- */
159
 	   -------------------------- */
160
 	END_UNMAPPED_DB_IDX = 505,
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
 /* uar resources types */
169
 /* uar resources types */

Loading…
Cancel
Save