Browse Source

Started implementing create_qp() and destroy_qp().

tags/v0.9.3
Michael Brown 16 years ago
parent
commit
251cc84ed6

+ 11
- 2
src/drivers/net/mlx_ipoib/arbel.h View File

@@ -29,6 +29,10 @@
29 29
 #define ARBEL_HCR_QUERY_DEV_LIM		0x0003
30 30
 #define ARBEL_HCR_SW2HW_CQ		0x0016
31 31
 #define ARBEL_HCR_HW2SW_CQ		0x0017
32
+#define ARBEL_HCR_RST2INIT_QPEE		0x0019
33
+#define ARBEL_HCR_INIT2RTR_QPEE		0x001a
34
+#define ARBEL_HCR_RTR2RTS_QPEE		0x001b
35
+#define ARBEL_HCR_2RST_QPEE		0x0021
32 36
 
33 37
 /*
34 38
  * Wrapper structures for hardware datatypes
@@ -43,6 +47,7 @@ struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
43 47
 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
44 48
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
45 49
 struct MLX_DECLARE_STRUCT ( arbelprm_query_dev_lim );
50
+struct MLX_DECLARE_STRUCT ( arbelprm_queue_pair_ee_context_entry );
46 51
 struct MLX_DECLARE_STRUCT ( arbelprm_recv_wqe_segment_next );
47 52
 struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
48 53
 struct MLX_DECLARE_STRUCT ( arbelprm_ud_address_vector );
@@ -126,6 +131,8 @@ struct arbel_send_work_queue {
126 131
 	unsigned int doorbell_idx;
127 132
 	/** Work queue entries */
128 133
 	union arbel_send_wqe *wqe;
134
+	/** Size of work queue */
135
+	size_t wqe_size;
129 136
 };
130 137
 
131 138
 /** Alignment of Arbel receive work queue entries */
@@ -143,6 +150,8 @@ struct arbel_recv_work_queue {
143 150
 	unsigned int doorbell_idx;
144 151
 	/** Work queue entries */
145 152
 	union arbel_recv_wqe *wqe;
153
+	/** Size of work queue */
154
+	size_t wqe_size;
146 155
 };
147 156
 
148 157
 /** Maximum number of allocatable queue pairs
@@ -156,8 +165,6 @@ struct arbel_recv_work_queue {
156 165
 
157 166
 /** An Arbel queue pair */
158 167
 struct arbel_queue_pair {
159
-	/** Infiniband queue pair */
160
-	struct ib_queue_pair qp;
161 168
 	/** Send work queue */
162 169
 	struct arbel_send_work_queue send;
163 170
 	/** Receive work queue */
@@ -178,6 +185,8 @@ struct arbel_completion_queue {
178 185
 	unsigned int arm_doorbell_idx;
179 186
 	/** Completion queue entries */
180 187
 	union arbelprm_completion_entry *cqe;
188
+	/** Size of completion queue */
189
+	size_t cqe_size;
181 190
 };
182 191
 
183 192
 /** An Arbel resource bitmask */

+ 194
- 39
src/drivers/net/mlx_ipoib/mt25218.c View File

@@ -464,6 +464,40 @@ arbel_cmd_hw2sw_cq ( struct arbel *arbel, unsigned long cqn ) {
464 464
 			   1, NULL, cqn, NULL );
465 465
 }
466 466
 
467
+static inline int
468
+arbel_cmd_rst2init_qpee ( struct arbel *arbel, unsigned long qpn,
469
+			  struct arbelprm_queue_pair_ee_context_entry *ctx ) {
470
+	return arbel_cmd ( arbel,
471
+			   ARBEL_HCR_IN_CMD ( ARBEL_HCR_RST2INIT_QPEE,
472
+					      1, sizeof ( *ctx ) ),
473
+			   0, ctx, qpn, NULL );
474
+}
475
+
476
+static inline int
477
+arbel_cmd_init2rtr_qpee ( struct arbel *arbel, unsigned long qpn,
478
+			  struct arbelprm_queue_pair_ee_context_entry *ctx ) {
479
+	return arbel_cmd ( arbel,
480
+			   ARBEL_HCR_IN_CMD ( ARBEL_HCR_INIT2RTR_QPEE,
481
+					      1, sizeof ( *ctx ) ),
482
+			   0, ctx, qpn, NULL );
483
+}
484
+
485
+static inline int
486
+arbel_cmd_rtr2rts_qpee ( struct arbel *arbel, unsigned long qpn,
487
+			 struct arbelprm_queue_pair_ee_context_entry *ctx ) {
488
+	return arbel_cmd ( arbel,
489
+			   ARBEL_HCR_IN_CMD ( ARBEL_HCR_RTR2RTS_QPEE,
490
+					      1, sizeof ( *ctx ) ),
491
+			   0, ctx, qpn, NULL );
492
+}
493
+
494
+static inline int
495
+arbel_cmd_2rst_qpee ( struct arbel *arbel, unsigned long qpn ) {
496
+	return arbel_cmd ( arbel,
497
+			   ARBEL_HCR_VOID_CMD ( ARBEL_HCR_2RST_QPEE ),
498
+			   0x03, NULL, qpn, NULL );
499
+}
500
+
467 501
 /***************************************************************************
468 502
  *
469 503
  * Completion queue operations
@@ -486,7 +520,6 @@ static int arbel_create_cq ( struct ib_device *ibdev,
486 520
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
487 521
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
488 522
 	int cqn_offset;
489
-	size_t cqe_size;
490 523
 	unsigned int i;
491 524
 	int rc;
492 525
 
@@ -509,13 +542,14 @@ static int arbel_create_cq ( struct ib_device *ibdev,
509 542
 	arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
510 543
 
511 544
 	/* Allocate completion queue itself */
512
-	cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
513
-	arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
545
+	arbel_cq->cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
546
+	arbel_cq->cqe = malloc_dma ( arbel_cq->cqe_size,
547
+				     sizeof ( arbel_cq->cqe[0] ) );
514 548
 	if ( ! arbel_cq->cqe ) {
515 549
 		rc = -ENOMEM;
516 550
 		goto err_cqe;
517 551
 	}
518
-	memset ( arbel_cq->cqe, 0, cqe_size );
552
+	memset ( arbel_cq->cqe, 0, arbel_cq->cqe_size );
519 553
 	for ( i = 0 ; i < cq->num_cqes ; i++ ) {
520 554
 		MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
521 555
 	}
@@ -538,11 +572,9 @@ static int arbel_create_cq ( struct ib_device *ibdev,
538 572
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
539 573
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
540 574
 		     virt_to_bus ( arbel_cq->cqe ) );
541
-#if 0
542 575
 	MLX_FILL_2 ( &cqctx, 3,
543 576
 		     usr_page, arbel->limits.reserved_uars,
544
-		     log_cq_size, log2_num_cqes );
545
-#endif
577
+		     log_cq_size, ( fls ( cq->num_cqes ) - 1 ) );
546 578
 	MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
547 579
 	MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
548 580
 	MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
@@ -554,16 +586,16 @@ static int arbel_create_cq ( struct ib_device *ibdev,
554 586
 	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
555 587
 		DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
556 588
 		       arbel, strerror ( rc ) );
557
-		goto err_sw2hw;
589
+		goto err_sw2hw_cq;
558 590
 	}
559 591
 
560 592
 	cq->dev_priv = arbel_cq;
561 593
 	return 0;
562 594
 
563
- err_sw2hw:
595
+ err_sw2hw_cq:
564 596
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
565 597
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
566
-	free_dma ( arbel_cq->cqe, cqe_size );
598
+	free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
567 599
  err_cqe:
568 600
 	free ( arbel_cq );
569 601
  err_arbel_cq:
@@ -585,35 +617,31 @@ static void arbel_destroy_cq ( struct ib_device *ibdev,
585 617
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
586 618
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
587 619
 	int cqn_offset;
588
-	size_t cqe_size;
589
-	unsigned int ci_doorbell_idx;
590
-	unsigned int arm_doorbell_idx;
591 620
 	int rc;
592 621
 
593
-	assert ( list_empty ( &cq->work_queues ) );
594
-
595 622
 	/* Take ownership back from hardware */
596 623
 	if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn ) ) != 0 ) {
597
-		DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed: %s\n",
598
-		       arbel, strerror ( rc ) );
624
+		DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed on CQN %#lx: "
625
+		       "%s\n", arbel, cq->cqn, strerror ( rc ) );
599 626
 		/* Leak memory and return; at least we avoid corruption */
600 627
 		return;
601 628
 	}
602 629
 
603 630
 	/* Clear doorbell records */
604
-	cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
605
-	ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
606
-	arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
607
-	ci_db_rec = &arbel->db_rec[ci_doorbell_idx].cq_ci;
608
-	arm_db_rec = &arbel->db_rec[arm_doorbell_idx].cq_arm;
631
+	ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
632
+	arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
609 633
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
610 634
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
611 635
 
612 636
 	/* Free memory */
613
-	cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
614
-	free_dma ( arbel_cq->cqe, cqe_size );
637
+	free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
615 638
 	free ( arbel_cq );
639
+
640
+	/* Mark queue number as free */
641
+	cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
616 642
 	arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
643
+
644
+	cq->dev_priv = NULL;
617 645
 }
618 646
 
619 647
 /***************************************************************************
@@ -623,22 +651,50 @@ static void arbel_destroy_cq ( struct ib_device *ibdev,
623 651
  ***************************************************************************
624 652
  */
625 653
 
654
+static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
655
+				  unsigned int num_wqes ) {
656
+
657
+	arbel_send_wq->wqe_size = ( num_wqes *
658
+				    sizeof ( arbel_send_wq->wqe[0] ) );
659
+	arbel_send_wq->wqe = malloc_dma ( arbel_send_wq->wqe_size,
660
+					  sizeof ( arbel_send_wq->wqe[0] ) );
661
+	if ( ! arbel_send_wq->wqe )
662
+		return -ENOMEM;
663
+
664
+	// initialise (prelink?)
665
+}
666
+
667
+static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
668
+				  unsigned int num_wqes ) {
669
+
670
+	arbel_recv_wq->wqe_size = ( num_wqes *
671
+				    sizeof ( arbel_recv_wq->wqe[0] ) );
672
+	arbel_recv_wq->wqe = malloc_dma ( arbel_recv_wq->wqe_size,
673
+					  sizeof ( arbel_recv_wq->wqe[0] ) );
674
+	if ( ! arbel_recv_wq->wqe )
675
+		return -ENOMEM;
676
+
677
+	// initialise (prelink?)
678
+}
679
+
680
+
681
+
682
+
683
+/**
684
+ * Create queue pair
685
+ *
686
+ * @v ibdev		Infiniband device
687
+ * @v qp		Queue pair
688
+ * @ret rc		Return status code
689
+ */
626 690
 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 ) {
691
+			     struct ib_queue_pair *qp ) {
632 692
 	struct arbel *arbel = ibdev->dev_priv;
633 693
 	struct arbel_queue_pair *arbel_qp;
694
+	struct arbelprm_queue_pair_ee_context_entry qpctx;
634 695
 	struct arbelprm_qp_db_record *send_db_rec;
635 696
 	struct arbelprm_qp_db_record *recv_db_rec;
636 697
 	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 698
 	int rc;
643 699
 
644 700
 	/* Find a free queue pair number */
@@ -648,21 +704,117 @@ static int arbel_create_qp ( struct ib_device *ibdev,
648 704
 		rc = qpn_offset;
649 705
 		goto err_qpn_offset;
650 706
 	}
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 );
707
+	qp->qpn = ( ARBEL_QPN_BASE + arbel->limits.reserved_qps + qpn_offset );
654 708
 
655 709
 	/* Allocate control structures */
656
-	num_send_wqes = ( 1 << log2_num_send_wqes );
657
-	num_recv_wqes = ( 1 << log2_num_recv_wqes );
658 710
 	arbel_qp = zalloc ( sizeof ( *arbel_qp ) );
711
+	if ( ! arbel_qp ) {
712
+		rc = -ENOMEM;
713
+		goto err_arbel_qp;
714
+	}
715
+	arbel_qp->send.doorbell_idx = arbel_send_doorbell_idx ( qpn_offset );
716
+	arbel_qp->recv.doorbell_idx = arbel_recv_doorbell_idx ( qpn_offset );
717
+
718
+	/* Create send and receive work queues */
719
+	if ( ( rc = arbel_create_send_wq ( &arbel_qp->send,
720
+					   qp->send.num_wqes ) ) != 0 )
721
+		goto err_create_send_wq;
722
+	if ( ( rc = arbel_create_recv_wq ( &arbel_qp->recv,
723
+					   qp->recv.num_wqes ) ) != 0 )
724
+		goto err_create_recv_wq;
725
+
726
+	/* Initialise doorbell records */
727
+	send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
728
+	MLX_FILL_1 ( send_db_rec, 0, counter, 0 );
729
+	MLX_FILL_2 ( send_db_rec, 1,
730
+		     res, ARBEL_UAR_RES_SQ,
731
+		     qp_number, qp->qpn );
732
+	recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
733
+	MLX_FILL_1 ( recv_db_rec, 0, counter, 0 );
734
+	MLX_FILL_2 ( recv_db_rec, 1,
735
+		     res, ARBEL_UAR_RES_RQ,
736
+		     qp_number, qp->qpn );
737
+
738
+	/* Hand queue over to hardware */
739
+	memset ( &qpctx, 0, sizeof ( qpctx ) );
740
+	// ...  fill in context
741
+	if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
742
+		DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
743
+		       arbel, strerror ( rc ) );
744
+		goto err_rst2init_qpee;
745
+	}
746
+	if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
747
+		DBGC ( arbel, "Arbel %p INIT2RTR_QPEE failed: %s\n",
748
+		       arbel, strerror ( rc ) );
749
+		goto err_init2rtr_qpee;
750
+	}
751
+	if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ){
752
+		DBGC ( arbel, "Arbel %p RTR2RTS_QPEE failed: %s\n",
753
+		       arbel, strerror ( rc ) );
754
+		goto err_rtr2rts_qpee;
755
+	}
659 756
 
757
+	qp->dev_priv = arbel_qp;
660 758
 	return 0;
661 759
 
760
+ err_rtr2rts_qpee:
761
+ err_init2rtr_qpee:
762
+	arbel_cmd_2rst_qpee ( arbel, qp->qpn );
763
+ err_rst2init_qpee:
764
+	MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
765
+	MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
766
+	free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
767
+ err_create_recv_wq:
768
+	free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
769
+ err_create_send_wq:
770
+	free ( arbel_qp );
771
+ err_arbel_qp:
772
+	arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
662 773
  err_qpn_offset:
663 774
 	return rc;
664 775
 }
665 776
 
777
+/**
778
+ * Destroy queue pair
779
+ *
780
+ * @v ibdev		Infiniband device
781
+ * @v qp		Queue pair
782
+ */
783
+static void arbel_destroy_qp ( struct ib_device *ibdev,
784
+			       struct ib_queue_pair *qp ) {
785
+	struct arbel *arbel = ibdev->dev_priv;
786
+	struct arbel_queue_pair *arbel_qp = qp->dev_priv;
787
+	struct arbelprm_qp_db_record *send_db_rec;
788
+	struct arbelprm_qp_db_record *recv_db_rec;
789
+	int qpn_offset;
790
+	int rc;
791
+
792
+	/* Take ownership back from hardware */
793
+	if ( ( rc = arbel_cmd_2rst_qpee ( arbel, qp->qpn ) ) != 0 ) {
794
+		DBGC ( arbel, "Arbel %p FATAL 2RST_QPEE failed on QPN %#lx: "
795
+		       "%s\n", arbel, qp->qpn, strerror ( rc ) );
796
+		/* Leak memory and return; at least we avoid corruption */
797
+		return;
798
+	}
799
+
800
+	/* Clear doorbell records */
801
+	send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
802
+	recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
803
+	MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
804
+	MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
805
+
806
+	/* Free memory */
807
+	free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
808
+	free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
809
+	free ( arbel_qp );
810
+
811
+	/* Mark queue number as free */
812
+	qpn_offset = ( qp->qpn - ARBEL_QPN_BASE - arbel->limits.reserved_qps );
813
+	arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
814
+
815
+	qp->dev_priv = NULL;
816
+}
817
+
666 818
 /***************************************************************************
667 819
  *
668 820
  * Work request operations
@@ -966,6 +1118,8 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
966 1118
 static struct ib_device_operations arbel_ib_operations = {
967 1119
 	.create_cq	= arbel_create_cq,
968 1120
 	.destroy_cq	= arbel_destroy_cq,
1121
+	.create_qp	= arbel_create_qp,
1122
+	.destroy_qp	= arbel_destroy_qp,
969 1123
 	.post_send	= arbel_post_send,
970 1124
 	.post_recv	= arbel_post_recv,
971 1125
 	.poll_cq	= arbel_poll_cq,
@@ -1048,6 +1202,7 @@ static int arbel_probe ( struct pci_device *pci,
1048 1202
 		   &static_ipoib_send_cq.work_queues );
1049 1203
 	list_add ( &static_ipoib_qp.recv.list,
1050 1204
 		   &static_ipoib_recv_cq.work_queues );
1205
+	static_ibdev.op = &arbel_ib_operations;
1051 1206
 
1052 1207
 	/* Get device limits */
1053 1208
 	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {

+ 27
- 5
src/include/gpxe/infiniband.h View File

@@ -174,8 +174,7 @@ struct ib_address_vector {
174 174
  * These represent a subset of the Infiniband Verbs.
175 175
  */
176 176
 struct ib_device_operations {
177
-	/**
178
-	 * Create completion queue
177
+	/** Create completion queue
179 178
 	 *
180 179
 	 * @v ibdev		Infiniband device
181 180
 	 * @v cq		Completion queue
@@ -183,14 +182,28 @@ struct ib_device_operations {
183 182
 	 */
184 183
 	int ( * create_cq ) ( struct ib_device *ibdev,
185 184
 			      struct ib_completion_queue *cq );
186
-	/**
187
-	 * Destroy completion queue
185
+	/** Destroy completion queue
188 186
 	 *
189 187
 	 * @v ibdev		Infiniband device
190 188
 	 * @v cq		Completion queue
191 189
 	 */
192 190
 	void ( * destroy_cq ) ( struct ib_device *ibdev,
193 191
 				struct ib_completion_queue *cq );
192
+	/** Create queue pair
193
+	 *
194
+	 * @v ibdev		Infiniband device
195
+	 * @v qp		Queue pair
196
+	 * @ret rc		Return status code
197
+	 */
198
+	int ( * create_qp ) ( struct ib_device *ibdev,
199
+			      struct ib_queue_pair *qp );
200
+	/** Destroy queue pair
201
+	 *
202
+	 * @v ibdev		Infiniband device
203
+	 * @v qp		Queue pair
204
+	 */
205
+	void ( * destroy_qp ) ( struct ib_device *ibdev,
206
+				struct ib_queue_pair *qp );
194 207
 	/** Post send work queue entry
195 208
 	 *
196 209
 	 * @v ibdev		Infiniband device
@@ -247,7 +260,16 @@ struct ib_device {
247 260
 	void *dev_priv;
248 261
 };
249 262
 
250
-
263
+extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
264
+						   unsigned int num_cqes );
265
+extern void ib_destroy_cq ( struct ib_device *ibdev,
266
+			    struct ib_completion_queue *cq );
267
+extern struct ib_queue_pair *
268
+ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
269
+	       struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
270
+	       struct ib_completion_queue *recv_cq );
271
+extern void ib_destroy_qp ( struct ib_device *ibdev,
272
+			    struct ib_queue_pair *qp );
251 273
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
252 274
 					   unsigned long qpn, int is_send );
253 275
 

+ 70
- 2
src/net/infiniband.c View File

@@ -58,8 +58,8 @@ struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
58 58
 
59 59
 	/* Perform device-specific initialisation and get CQN */
60 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 ) );
61
+		DBGC ( ibdev, "IBDEV %p could not initialise completion "
62
+		       "queue: %s\n", ibdev, strerror ( rc ) );
63 63
 		free ( cq );
64 64
 		return NULL;
65 65
 	}
@@ -84,6 +84,74 @@ void ib_destroy_cq ( struct ib_device *ibdev,
84 84
 	free ( cq );
85 85
 }
86 86
 
87
+/**
88
+ * Create queue pair
89
+ *
90
+ * @v ibdev		Infiniband device
91
+ * @v num_send_wqes	Number of send work queue entries
92
+ * @v send_cq		Send completion queue
93
+ * @v num_recv_wqes	Number of receive work queue entries
94
+ * @v recv_cq		Receive completion queue
95
+ * @ret qp		Queue pair
96
+ */
97
+struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
98
+				      unsigned int num_send_wqes,
99
+				      struct ib_completion_queue *send_cq,
100
+				      unsigned int num_recv_wqes,
101
+				      struct ib_completion_queue *recv_cq ) {
102
+	struct ib_queue_pair *qp;
103
+	int rc;
104
+
105
+	DBGC ( ibdev, "IBDEV %p creating queue pair\n", ibdev );
106
+
107
+	/* Allocate and initialise data structure */
108
+	qp = zalloc ( sizeof ( *qp ) +
109
+		      ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ) +
110
+		      ( num_recv_wqes * sizeof ( qp->recv.iobufs[0] ) ) );
111
+	if ( ! qp )
112
+		return NULL;
113
+	qp->send.qp = qp;
114
+	qp->send.is_send = 1;
115
+	qp->send.cq = send_cq;
116
+	list_add ( &qp->send.list, &send_cq->work_queues );
117
+	qp->send.num_wqes = num_send_wqes;
118
+	qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
119
+	qp->recv.qp = qp;
120
+	qp->recv.cq = recv_cq;
121
+	list_add ( &qp->recv.list, &recv_cq->work_queues );
122
+	qp->recv.num_wqes = num_recv_wqes;
123
+	qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
124
+			    ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
125
+
126
+	/* Perform device-specific initialisation and get QPN */
127
+	if ( ( rc = ibdev->op->create_qp ( ibdev, qp ) ) != 0 ) {
128
+		DBGC ( ibdev, "IBDEV %p could not initialise queue pair: "
129
+		       "%s\n", ibdev, strerror ( rc ) );
130
+		free ( qp );
131
+		return NULL;
132
+	}
133
+
134
+	DBGC ( ibdev, "IBDEV %p created queue pair %#lx\n",
135
+	       ibdev, qp->qpn );
136
+	return qp;
137
+}
138
+
139
+/**
140
+ * Destroy queue pair
141
+ *
142
+ * @v ibdev		Infiniband device
143
+ * @v qp		Queue pair
144
+ */
145
+void ib_destroy_qp ( struct ib_device *ibdev,
146
+		     struct ib_queue_pair *qp ) {
147
+	DBGC ( ibdev, "IBDEV %p destroying queue pair %#lx\n",
148
+	       ibdev, qp->qpn );
149
+	ibdev->op->destroy_qp ( ibdev, qp );
150
+	free ( qp );
151
+}
152
+
153
+
154
+
87 155
 /**
88 156
  * Find work queue belonging to completion queue
89 157
  *

Loading…
Cancel
Save