Browse Source

create_cq() implemented (but not tested).

tags/v0.9.3
Michael Brown 16 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,10 +12,23 @@
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 24
 #define ARBEL_OPCODE_SEND		0x0a
16 25
 #define ARBEL_OPCODE_RECV_ERROR		0xfe
17 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 33
  * Wrapper structures for hardware datatypes
21 34
  *
@@ -24,6 +37,7 @@
24 37
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_context );
25 38
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
26 39
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
40
+struct MLX_DECLARE_STRUCT ( arbelprm_cq_arm_db_record );
27 41
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
28 42
 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
29 43
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
@@ -71,6 +85,7 @@ union arbelprm_completion_entry {
71 85
 } __attribute__ (( packed ));
72 86
 
73 87
 union arbelprm_doorbell_record {
88
+	struct arbelprm_cq_arm_db_record cq_arm;
74 89
 	struct arbelprm_cq_ci_db_record cq_ci;
75 90
 	struct arbelprm_qp_db_record qp;
76 91
 } __attribute__ (( packed ));
@@ -87,6 +102,8 @@ union arbelprm_doorbell_register {
87 102
 
88 103
 /** Arbel device limits */
89 104
 struct arbel_dev_limits {
105
+	/** Number of reserver UARs */
106
+	unsigned long reserved_uars;
90 107
 	/** Number of reserved CQs */
91 108
 	unsigned long reserved_cqs;
92 109
 };
@@ -177,6 +194,8 @@ struct arbel {
177 194
 	 * Used to get unrestricted memory access.
178 195
 	 */
179 196
 	unsigned long reserved_lkey;
197
+	/** Event queue number */
198
+	unsigned long eqn;
180 199
 
181 200
 	/** Completion queue in-use bitmask */
182 201
 	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
@@ -185,14 +204,14 @@ struct arbel {
185 204
 	struct arbel_dev_limits limits;
186 205
 };
187 206
 
207
+/** Global protection domain */
208
+#define ARBEL_GLOBAL_PD			0x123456
209
+
188 210
 /*
189 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 215
 #define ARBEL_HCR_BASE			0x80680
197 216
 #define ARBEL_HCR_REG(x)		( ARBEL_HCR_BASE + 4 * (x) )
198 217
 #define ARBEL_HCR_MAX_WAIT_MS		2000
@@ -251,7 +270,7 @@ struct arbel {
251 270
  * @ret doorbell_idx	Doorbell index
252 271
  */
253 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 274
 	return cqn_offset;
256 275
 }
257 276
 

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

@@ -455,26 +455,37 @@ arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
455 455
  * Create completion queue
456 456
  *
457 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 464
 			     struct ib_completion_queue **new_cq ) {
462 465
 	struct arbel *arbel = ibdev->priv;
463 466
 	struct arbel_completion_queue *arbel_cq;
464 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 470
 	int cqn_offset;
466 471
 	unsigned int cqn;
472
+	unsigned int num_cqes;
467 473
 	size_t cqe_size;
474
+	unsigned int ci_doorbell_idx;
475
+	unsigned int arm_doorbell_idx;
468 476
 	unsigned int i;
469 477
 	int rc;
470 478
 
471 479
 	/* Find a free completion queue number */
472 480
 	cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
473 481
 	if ( cqn_offset < 0 ) {
482
+		DBGC ( arbel, "Arbel %p out of completion queues\n", arbel );
474 483
 		rc = cqn_offset;
475 484
 		goto err_cqn_offset;
476 485
 	}
477 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 490
 	/* Allocate control structures */
480 491
 	arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
@@ -485,9 +496,10 @@ static int arbel_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
485 496
 	arbel_cq->cq.cqn = cqn;
486 497
 	arbel_cq->cq.num_cqes = num_cqes;
487 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 501
 	/* Allocate completion queue itself */
502
+	num_cqes = ( 1 << log2_num_cqes );
491 503
 	cqe_size = ( num_cqes * sizeof ( arbel_cq->cqe[0] ) );
492 504
 	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
493 505
 	if ( ! arbel_cq->cqe ) {
@@ -501,28 +513,43 @@ static int arbel_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
501 513
 	barrier();
502 514
 
503 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 527
 	/* Hand queue over to hardware */
507 528
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
508 529
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
509 530
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
510 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 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 547
 	*new_cq = &arbel_cq->cq;
522
-
523
-
524 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 553
  err_cqe:
527 554
 	free ( arbel_cq );
528 555
  err_arbel_cq:
@@ -580,7 +607,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
580 607
 	struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
581 608
 	struct arbelprm_ud_send_wqe *prev_wqe;
582 609
 	struct arbelprm_ud_send_wqe *wqe;
583
-	union arbelprm_doorbell_record *db_rec;
610
+	struct arbelprm_qp_db_record *qp_db_rec;
584 611
 	union arbelprm_doorbell_register db_reg;
585 612
 	const struct ib_gid *gid;
586 613
 	unsigned int wqe_idx_mask;
@@ -602,7 +629,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
602 629
 	MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
603 630
 	memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
604 631
 	MLX_FILL_2 ( &wqe->ud, 0,
605
-		     ud_address_vector.pd, GLOBAL_PD,
632
+		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
606 633
 		     ud_address_vector.port_number, PXE_IB_PORT );
607 634
 	MLX_FILL_2 ( &wqe->ud, 1,
608 635
 		     ud_address_vector.rlid, av->dlid,
@@ -631,8 +658,8 @@ static int arbel_post_send ( struct ib_device *ibdev,
631 658
 
632 659
 	/* Update doorbell record */
633 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 663
 		     counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
637 664
 
638 665
 	/* Ring doorbell register */
@@ -800,7 +827,7 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
800 827
 	struct arbel *arbel = ibdev->priv;
801 828
 	struct arbel_completion_queue *arbel_cq
802 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 831
 	union arbelprm_completion_entry *cqe;
805 832
 	unsigned int cqe_idx_mask;
806 833
 	int rc;
@@ -828,8 +855,8 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
828 855
 		/* Update completion queue's index */
829 856
 		cq->next_idx++;
830 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 860
 			     counter, ( cq->next_idx & 0xffffffffUL ) );
834 861
 	}
835 862
 }
@@ -897,12 +924,13 @@ static int arbel_probe ( struct pci_device *pci,
897 924
 	memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
898 925
 
899 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 934
 	static_ipoib_qp.send.wqe =
907 935
 		( ( struct udqp_st * ) qph )->snd_wq;
908 936
 	static_ipoib_qp.recv.wqe =
@@ -924,6 +952,7 @@ static int arbel_probe ( struct pci_device *pci,
924 952
 		       arbel, strerror ( rc ) );
925 953
 		goto err_query_dev_lim;
926 954
 	}
955
+	arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
927 956
 	arbel->limits.reserved_cqs =
928 957
 		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
929 958
 	DBG ( "Device limits:\n ");

Loading…
Cancel
Save