Browse Source

create_cq() implemented (but not tested).

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
18edcf6634
2 changed files with 78 additions and 30 deletions
  1. 23
    4
      src/drivers/net/mlx_ipoib/arbel.h
  2. 55
    26
      src/drivers/net/mlx_ipoib/mt25218.c

+ 23
- 4
src/drivers/net/mlx_ipoib/arbel.h View File

12
  *
12
  *
13
  */
13
  */
14
 
14
 
15
+/* UAR context table (UCE) resource types */
16
+#define ARBEL_UAR_RES_NONE		0x00
17
+#define ARBEL_UAR_RES_CQ_CI		0x01
18
+#define ARBEL_UAR_RES_CQ_ARM		0x02
19
+#define ARBEL_UAR_RES_SQ		0x03
20
+#define ARBEL_UAR_RES_RQ		0x04
21
+#define ARBEL_UAR_RES_GROUP_SEP		0x07
22
+
23
+/* Work queue entry and completion queue entry opcodes */
15
 #define ARBEL_OPCODE_SEND		0x0a
24
 #define ARBEL_OPCODE_SEND		0x0a
16
 #define ARBEL_OPCODE_RECV_ERROR		0xfe
25
 #define ARBEL_OPCODE_RECV_ERROR		0xfe
17
 #define ARBEL_OPCODE_SEND_ERROR		0xff
26
 #define ARBEL_OPCODE_SEND_ERROR		0xff
18
 
27
 
28
+/* HCA command register opcodes */
29
+#define ARBEL_HCR_QUERY_DEV_LIM		0x0003
30
+#define ARBEL_HCR_SW2HW_CQ		0x0016
31
+
19
 /*
32
 /*
20
  * Wrapper structures for hardware datatypes
33
  * Wrapper structures for hardware datatypes
21
  *
34
  *
24
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_context );
37
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_context );
25
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
38
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
26
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
39
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
40
+struct MLX_DECLARE_STRUCT ( arbelprm_cq_arm_db_record );
27
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
41
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
28
 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
42
 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
29
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
43
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
71
 } __attribute__ (( packed ));
85
 } __attribute__ (( packed ));
72
 
86
 
73
 union arbelprm_doorbell_record {
87
 union arbelprm_doorbell_record {
88
+	struct arbelprm_cq_arm_db_record cq_arm;
74
 	struct arbelprm_cq_ci_db_record cq_ci;
89
 	struct arbelprm_cq_ci_db_record cq_ci;
75
 	struct arbelprm_qp_db_record qp;
90
 	struct arbelprm_qp_db_record qp;
76
 } __attribute__ (( packed ));
91
 } __attribute__ (( packed ));
87
 
102
 
88
 /** Arbel device limits */
103
 /** Arbel device limits */
89
 struct arbel_dev_limits {
104
 struct arbel_dev_limits {
105
+	/** Number of reserver UARs */
106
+	unsigned long reserved_uars;
90
 	/** Number of reserved CQs */
107
 	/** Number of reserved CQs */
91
 	unsigned long reserved_cqs;
108
 	unsigned long reserved_cqs;
92
 };
109
 };
177
 	 * Used to get unrestricted memory access.
194
 	 * Used to get unrestricted memory access.
178
 	 */
195
 	 */
179
 	unsigned long reserved_lkey;
196
 	unsigned long reserved_lkey;
197
+	/** Event queue number */
198
+	unsigned long eqn;
180
 
199
 
181
 	/** Completion queue in-use bitmask */
200
 	/** Completion queue in-use bitmask */
182
 	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
201
 	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
185
 	struct arbel_dev_limits limits;
204
 	struct arbel_dev_limits limits;
186
 };
205
 };
187
 
206
 
207
+/** Global protection domain */
208
+#define ARBEL_GLOBAL_PD			0x123456
209
+
188
 /*
210
 /*
189
  * HCA commands
211
  * HCA commands
190
  *
212
  *
191
  */
213
  */
192
 
214
 
193
-#define ARBEL_HCR_QUERY_DEV_LIM		0x0003
194
-#define ARBEL_HCR_SW2HW_CQ		0x0016
195
-
196
 #define ARBEL_HCR_BASE			0x80680
215
 #define ARBEL_HCR_BASE			0x80680
197
 #define ARBEL_HCR_REG(x)		( ARBEL_HCR_BASE + 4 * (x) )
216
 #define ARBEL_HCR_REG(x)		( ARBEL_HCR_BASE + 4 * (x) )
198
 #define ARBEL_HCR_MAX_WAIT_MS		2000
217
 #define ARBEL_HCR_MAX_WAIT_MS		2000
251
  * @ret doorbell_idx	Doorbell index
270
  * @ret doorbell_idx	Doorbell index
252
  */
271
  */
253
 static inline unsigned int
272
 static inline unsigned int
254
-arbel_arm_cq_doorbell_idx ( unsigned int cqn_offset ) {
273
+arbel_cq_arm_doorbell_idx ( unsigned int cqn_offset ) {
255
 	return cqn_offset;
274
 	return cqn_offset;
256
 }
275
 }
257
 
276
 

+ 55
- 26
src/drivers/net/mlx_ipoib/mt25218.c View File

455
  * Create completion queue
455
  * Create completion queue
456
  *
456
  *
457
  * @v ibdev		Infiniband device
457
  * @v ibdev		Infiniband device
458
- * @v 
458
+ * @v log2_num_cqes	Log2 of the number of completion queue entries
459
+ * @ret new_cq		New completion queue
460
+ * @ret rc		Return status code
459
  */
461
  */
460
-static int arbel_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
462
+static int arbel_create_cq ( struct ib_device *ibdev,
463
+			     unsigned int log2_num_cqes,
461
 			     struct ib_completion_queue **new_cq ) {
464
 			     struct ib_completion_queue **new_cq ) {
462
 	struct arbel *arbel = ibdev->priv;
465
 	struct arbel *arbel = ibdev->priv;
463
 	struct arbel_completion_queue *arbel_cq;
466
 	struct arbel_completion_queue *arbel_cq;
464
 	struct arbelprm_completion_queue_context cqctx;
467
 	struct arbelprm_completion_queue_context cqctx;
468
+	struct arbelprm_cq_ci_db_record *ci_db_rec;
469
+	struct arbelprm_cq_arm_db_record *arm_db_rec;
465
 	int cqn_offset;
470
 	int cqn_offset;
466
 	unsigned int cqn;
471
 	unsigned int cqn;
472
+	unsigned int num_cqes;
467
 	size_t cqe_size;
473
 	size_t cqe_size;
474
+	unsigned int ci_doorbell_idx;
475
+	unsigned int arm_doorbell_idx;
468
 	unsigned int i;
476
 	unsigned int i;
469
 	int rc;
477
 	int rc;
470
 
478
 
471
 	/* Find a free completion queue number */
479
 	/* Find a free completion queue number */
472
 	cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
480
 	cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
473
 	if ( cqn_offset < 0 ) {
481
 	if ( cqn_offset < 0 ) {
482
+		DBGC ( arbel, "Arbel %p out of completion queues\n", arbel );
474
 		rc = cqn_offset;
483
 		rc = cqn_offset;
475
 		goto err_cqn_offset;
484
 		goto err_cqn_offset;
476
 	}
485
 	}
477
 	cqn = ( arbel->limits.reserved_cqs + cqn_offset );
486
 	cqn = ( arbel->limits.reserved_cqs + cqn_offset );
487
+	ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
488
+	arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
478
 
489
 
479
 	/* Allocate control structures */
490
 	/* Allocate control structures */
480
 	arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
491
 	arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
485
 	arbel_cq->cq.cqn = cqn;
496
 	arbel_cq->cq.cqn = cqn;
486
 	arbel_cq->cq.num_cqes = num_cqes;
497
 	arbel_cq->cq.num_cqes = num_cqes;
487
 	INIT_LIST_HEAD ( &arbel_cq->cq.work_queues );
498
 	INIT_LIST_HEAD ( &arbel_cq->cq.work_queues );
488
-	arbel_cq->doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
499
+	arbel_cq->doorbell_idx = ci_doorbell_idx;
489
 
500
 
490
 	/* Allocate completion queue itself */
501
 	/* Allocate completion queue itself */
502
+	num_cqes = ( 1 << log2_num_cqes );
491
 	cqe_size = ( num_cqes * sizeof ( arbel_cq->cqe[0] ) );
503
 	cqe_size = ( num_cqes * sizeof ( arbel_cq->cqe[0] ) );
492
 	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
504
 	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
493
 	if ( ! arbel_cq->cqe ) {
505
 	if ( ! arbel_cq->cqe ) {
501
 	barrier();
513
 	barrier();
502
 
514
 
503
 	/* Initialise doorbell records */
515
 	/* Initialise doorbell records */
504
-	// ...
516
+	ci_db_rec = &arbel->db_rec[ci_doorbell_idx].cq_ci;
517
+	MLX_FILL_1 ( ci_db_rec, 0, counter, 0 );
518
+	MLX_FILL_2 ( ci_db_rec, 1,
519
+		     res, ARBEL_UAR_RES_CQ_CI,
520
+		     cq_number, cqn );
521
+	arm_db_rec = &arbel->db_rec[arm_doorbell_idx].cq_arm;
522
+	MLX_FILL_1 ( arm_db_rec, 0, counter, 0 );
523
+	MLX_FILL_2 ( arm_db_rec, 1,
524
+		     res, ARBEL_UAR_RES_CQ_ARM,
525
+		     cq_number, cqn );
505
 
526
 
506
 	/* Hand queue over to hardware */
527
 	/* Hand queue over to hardware */
507
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
528
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
508
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
529
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
509
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
530
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
510
 		     virt_to_bus ( arbel_cq->cqe ) );
531
 		     virt_to_bus ( arbel_cq->cqe ) );
511
-	///	....
512
-
532
+	MLX_FILL_2 ( &cqctx, 3,
533
+		     usr_page, arbel->limits.reserved_uars,
534
+		     log_cq_size, log2_num_cqes );
535
+	MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
536
+	MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
537
+	MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
538
+	MLX_FILL_1 ( &cqctx, 12, cqn, cqn );
539
+	MLX_FILL_1 ( &cqctx, 13, cq_ci_db_record, ci_doorbell_idx );
540
+	MLX_FILL_1 ( &cqctx, 14, cq_state_db_record, arm_doorbell_idx );
513
 	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cqn, &cqctx ) ) != 0 ) {
541
 	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cqn, &cqctx ) ) != 0 ) {
514
-		// ...
542
+		DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
543
+		       arbel, strerror ( rc ) );
544
+		goto err_sw2hw;
515
 	}
545
 	}
516
 
546
 
517
-
518
-	// completion queue number
519
-	// doorbell index
520
-
521
 	*new_cq = &arbel_cq->cq;
547
 	*new_cq = &arbel_cq->cq;
522
-
523
-
524
 	return 0;
548
 	return 0;
525
 
549
 
550
+ err_sw2hw:
551
+	memset ( ci_db_rec, 0, sizeof ( *ci_db_rec ) );
552
+	memset ( arm_db_rec, 0, sizeof ( *arm_db_rec ) );
526
  err_cqe:
553
  err_cqe:
527
 	free ( arbel_cq );
554
 	free ( arbel_cq );
528
  err_arbel_cq:
555
  err_arbel_cq:
580
 	struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
607
 	struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
581
 	struct arbelprm_ud_send_wqe *prev_wqe;
608
 	struct arbelprm_ud_send_wqe *prev_wqe;
582
 	struct arbelprm_ud_send_wqe *wqe;
609
 	struct arbelprm_ud_send_wqe *wqe;
583
-	union arbelprm_doorbell_record *db_rec;
610
+	struct arbelprm_qp_db_record *qp_db_rec;
584
 	union arbelprm_doorbell_register db_reg;
611
 	union arbelprm_doorbell_register db_reg;
585
 	const struct ib_gid *gid;
612
 	const struct ib_gid *gid;
586
 	unsigned int wqe_idx_mask;
613
 	unsigned int wqe_idx_mask;
602
 	MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
629
 	MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
603
 	memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
630
 	memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
604
 	MLX_FILL_2 ( &wqe->ud, 0,
631
 	MLX_FILL_2 ( &wqe->ud, 0,
605
-		     ud_address_vector.pd, GLOBAL_PD,
632
+		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
606
 		     ud_address_vector.port_number, PXE_IB_PORT );
633
 		     ud_address_vector.port_number, PXE_IB_PORT );
607
 	MLX_FILL_2 ( &wqe->ud, 1,
634
 	MLX_FILL_2 ( &wqe->ud, 1,
608
 		     ud_address_vector.rlid, av->dlid,
635
 		     ud_address_vector.rlid, av->dlid,
631
 
658
 
632
 	/* Update doorbell record */
659
 	/* Update doorbell record */
633
 	barrier();
660
 	barrier();
634
-	db_rec = &arbel->db_rec[arbel_send_wq->doorbell_idx];
635
-	MLX_FILL_1 ( &db_rec->qp, 0,
661
+	qp_db_rec = &arbel->db_rec[arbel_send_wq->doorbell_idx].qp;
662
+	MLX_FILL_1 ( qp_db_rec, 0,
636
 		     counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
663
 		     counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
637
 
664
 
638
 	/* Ring doorbell register */
665
 	/* Ring doorbell register */
800
 	struct arbel *arbel = ibdev->priv;
827
 	struct arbel *arbel = ibdev->priv;
801
 	struct arbel_completion_queue *arbel_cq
828
 	struct arbel_completion_queue *arbel_cq
802
 		= container_of ( cq, struct arbel_completion_queue, cq );
829
 		= container_of ( cq, struct arbel_completion_queue, cq );
803
-	union arbelprm_doorbell_record *db_rec;
830
+	struct arbelprm_cq_ci_db_record *ci_db_rec;
804
 	union arbelprm_completion_entry *cqe;
831
 	union arbelprm_completion_entry *cqe;
805
 	unsigned int cqe_idx_mask;
832
 	unsigned int cqe_idx_mask;
806
 	int rc;
833
 	int rc;
828
 		/* Update completion queue's index */
855
 		/* Update completion queue's index */
829
 		cq->next_idx++;
856
 		cq->next_idx++;
830
 		/* Update doorbell record */
857
 		/* Update doorbell record */
831
-		db_rec = &arbel->db_rec[arbel_cq->doorbell_idx];
832
-		MLX_FILL_1 ( &db_rec->cq_ci, 0,
858
+		ci_db_rec = &arbel->db_rec[arbel_cq->doorbell_idx].cq_ci;
859
+		MLX_FILL_1 ( ci_db_rec, 0,
833
 			     counter, ( cq->next_idx & 0xffffffffUL ) );
860
 			     counter, ( cq->next_idx & 0xffffffffUL ) );
834
 	}
861
 	}
835
 }
862
 }
897
 	memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
924
 	memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
898
 
925
 
899
 	/* Hack up IB structures */
926
 	/* Hack up IB structures */
900
-	static_arbel.config = memfree_pci_dev.cr_space;
901
-	static_arbel.mailbox_in = dev_buffers_p->inprm_buf;
902
-	static_arbel.mailbox_out = dev_buffers_p->outprm_buf;
903
-	static_arbel.uar = memfree_pci_dev.uar;
904
-	static_arbel.db_rec = dev_ib_data.uar_context_base;
905
-	static_arbel.reserved_lkey = dev_ib_data.mkey;
927
+	arbel->config = memfree_pci_dev.cr_space;
928
+	arbel->mailbox_in = dev_buffers_p->inprm_buf;
929
+	arbel->mailbox_out = dev_buffers_p->outprm_buf;
930
+	arbel->uar = memfree_pci_dev.uar;
931
+	arbel->db_rec = dev_ib_data.uar_context_base;
932
+	arbel->reserved_lkey = dev_ib_data.mkey;
933
+	arbel->eqn = dev_ib_data.eq.eqn;
906
 	static_ipoib_qp.send.wqe =
934
 	static_ipoib_qp.send.wqe =
907
 		( ( struct udqp_st * ) qph )->snd_wq;
935
 		( ( struct udqp_st * ) qph )->snd_wq;
908
 	static_ipoib_qp.recv.wqe =
936
 	static_ipoib_qp.recv.wqe =
924
 		       arbel, strerror ( rc ) );
952
 		       arbel, strerror ( rc ) );
925
 		goto err_query_dev_lim;
953
 		goto err_query_dev_lim;
926
 	}
954
 	}
955
+	arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
927
 	arbel->limits.reserved_cqs =
956
 	arbel->limits.reserved_cqs =
928
 		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
957
 		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
929
 	DBG ( "Device limits:\n ");
958
 	DBG ( "Device limits:\n ");

Loading…
Cancel
Save