Browse Source

Started implementing create_qp() and destroy_qp().

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

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

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

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

464
 			   1, NULL, cqn, NULL );
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
  * Completion queue operations
503
  * Completion queue operations
486
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
520
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
487
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
521
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
488
 	int cqn_offset;
522
 	int cqn_offset;
489
-	size_t cqe_size;
490
 	unsigned int i;
523
 	unsigned int i;
491
 	int rc;
524
 	int rc;
492
 
525
 
509
 	arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
542
 	arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
510
 
543
 
511
 	/* Allocate completion queue itself */
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
 	if ( ! arbel_cq->cqe ) {
548
 	if ( ! arbel_cq->cqe ) {
515
 		rc = -ENOMEM;
549
 		rc = -ENOMEM;
516
 		goto err_cqe;
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
 	for ( i = 0 ; i < cq->num_cqes ; i++ ) {
553
 	for ( i = 0 ; i < cq->num_cqes ; i++ ) {
520
 		MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
554
 		MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
521
 	}
555
 	}
538
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
572
 	MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
539
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
573
 	MLX_FILL_1 ( &cqctx, 2, start_address_l,
540
 		     virt_to_bus ( arbel_cq->cqe ) );
574
 		     virt_to_bus ( arbel_cq->cqe ) );
541
-#if 0
542
 	MLX_FILL_2 ( &cqctx, 3,
575
 	MLX_FILL_2 ( &cqctx, 3,
543
 		     usr_page, arbel->limits.reserved_uars,
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
 	MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
578
 	MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
547
 	MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
579
 	MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
548
 	MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
580
 	MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
554
 	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
586
 	if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
555
 		DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
587
 		DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
556
 		       arbel, strerror ( rc ) );
588
 		       arbel, strerror ( rc ) );
557
-		goto err_sw2hw;
589
+		goto err_sw2hw_cq;
558
 	}
590
 	}
559
 
591
 
560
 	cq->dev_priv = arbel_cq;
592
 	cq->dev_priv = arbel_cq;
561
 	return 0;
593
 	return 0;
562
 
594
 
563
- err_sw2hw:
595
+ err_sw2hw_cq:
564
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
596
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
565
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
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
  err_cqe:
599
  err_cqe:
568
 	free ( arbel_cq );
600
 	free ( arbel_cq );
569
  err_arbel_cq:
601
  err_arbel_cq:
585
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
617
 	struct arbelprm_cq_ci_db_record *ci_db_rec;
586
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
618
 	struct arbelprm_cq_arm_db_record *arm_db_rec;
587
 	int cqn_offset;
619
 	int cqn_offset;
588
-	size_t cqe_size;
589
-	unsigned int ci_doorbell_idx;
590
-	unsigned int arm_doorbell_idx;
591
 	int rc;
620
 	int rc;
592
 
621
 
593
-	assert ( list_empty ( &cq->work_queues ) );
594
-
595
 	/* Take ownership back from hardware */
622
 	/* Take ownership back from hardware */
596
 	if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn ) ) != 0 ) {
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
 		/* Leak memory and return; at least we avoid corruption */
626
 		/* Leak memory and return; at least we avoid corruption */
600
 		return;
627
 		return;
601
 	}
628
 	}
602
 
629
 
603
 	/* Clear doorbell records */
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
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
633
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
610
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
634
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
611
 
635
 
612
 	/* Free memory */
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
 	free ( arbel_cq );
638
 	free ( arbel_cq );
639
+
640
+	/* Mark queue number as free */
641
+	cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
616
 	arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
642
 	arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
643
+
644
+	cq->dev_priv = NULL;
617
 }
645
 }
618
 
646
 
619
 /***************************************************************************
647
 /***************************************************************************
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
 static int arbel_create_qp ( struct ib_device *ibdev,
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
 	struct arbel *arbel = ibdev->dev_priv;
692
 	struct arbel *arbel = ibdev->dev_priv;
633
 	struct arbel_queue_pair *arbel_qp;
693
 	struct arbel_queue_pair *arbel_qp;
694
+	struct arbelprm_queue_pair_ee_context_entry qpctx;
634
 	struct arbelprm_qp_db_record *send_db_rec;
695
 	struct arbelprm_qp_db_record *send_db_rec;
635
 	struct arbelprm_qp_db_record *recv_db_rec;
696
 	struct arbelprm_qp_db_record *recv_db_rec;
636
 	int qpn_offset;
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
 	int rc;
698
 	int rc;
643
 
699
 
644
 	/* Find a free queue pair number */
700
 	/* Find a free queue pair number */
648
 		rc = qpn_offset;
704
 		rc = qpn_offset;
649
 		goto err_qpn_offset;
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
 	/* Allocate control structures */
709
 	/* Allocate control structures */
656
-	num_send_wqes = ( 1 << log2_num_send_wqes );
657
-	num_recv_wqes = ( 1 << log2_num_recv_wqes );
658
 	arbel_qp = zalloc ( sizeof ( *arbel_qp ) );
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
 	return 0;
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
  err_qpn_offset:
773
  err_qpn_offset:
663
 	return rc;
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
  * Work request operations
820
  * Work request operations
966
 static struct ib_device_operations arbel_ib_operations = {
1118
 static struct ib_device_operations arbel_ib_operations = {
967
 	.create_cq	= arbel_create_cq,
1119
 	.create_cq	= arbel_create_cq,
968
 	.destroy_cq	= arbel_destroy_cq,
1120
 	.destroy_cq	= arbel_destroy_cq,
1121
+	.create_qp	= arbel_create_qp,
1122
+	.destroy_qp	= arbel_destroy_qp,
969
 	.post_send	= arbel_post_send,
1123
 	.post_send	= arbel_post_send,
970
 	.post_recv	= arbel_post_recv,
1124
 	.post_recv	= arbel_post_recv,
971
 	.poll_cq	= arbel_poll_cq,
1125
 	.poll_cq	= arbel_poll_cq,
1048
 		   &static_ipoib_send_cq.work_queues );
1202
 		   &static_ipoib_send_cq.work_queues );
1049
 	list_add ( &static_ipoib_qp.recv.list,
1203
 	list_add ( &static_ipoib_qp.recv.list,
1050
 		   &static_ipoib_recv_cq.work_queues );
1204
 		   &static_ipoib_recv_cq.work_queues );
1205
+	static_ibdev.op = &arbel_ib_operations;
1051
 
1206
 
1052
 	/* Get device limits */
1207
 	/* Get device limits */
1053
 	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1208
 	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {

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

174
  * These represent a subset of the Infiniband Verbs.
174
  * These represent a subset of the Infiniband Verbs.
175
  */
175
  */
176
 struct ib_device_operations {
176
 struct ib_device_operations {
177
-	/**
178
-	 * Create completion queue
177
+	/** Create completion queue
179
 	 *
178
 	 *
180
 	 * @v ibdev		Infiniband device
179
 	 * @v ibdev		Infiniband device
181
 	 * @v cq		Completion queue
180
 	 * @v cq		Completion queue
183
 	 */
182
 	 */
184
 	int ( * create_cq ) ( struct ib_device *ibdev,
183
 	int ( * create_cq ) ( struct ib_device *ibdev,
185
 			      struct ib_completion_queue *cq );
184
 			      struct ib_completion_queue *cq );
186
-	/**
187
-	 * Destroy completion queue
185
+	/** Destroy completion queue
188
 	 *
186
 	 *
189
 	 * @v ibdev		Infiniband device
187
 	 * @v ibdev		Infiniband device
190
 	 * @v cq		Completion queue
188
 	 * @v cq		Completion queue
191
 	 */
189
 	 */
192
 	void ( * destroy_cq ) ( struct ib_device *ibdev,
190
 	void ( * destroy_cq ) ( struct ib_device *ibdev,
193
 				struct ib_completion_queue *cq );
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
 	/** Post send work queue entry
207
 	/** Post send work queue entry
195
 	 *
208
 	 *
196
 	 * @v ibdev		Infiniband device
209
 	 * @v ibdev		Infiniband device
247
 	void *dev_priv;
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
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
273
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
252
 					   unsigned long qpn, int is_send );
274
 					   unsigned long qpn, int is_send );
253
 
275
 

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

58
 
58
 
59
 	/* Perform device-specific initialisation and get CQN */
59
 	/* Perform device-specific initialisation and get CQN */
60
 	if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
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
 		free ( cq );
63
 		free ( cq );
64
 		return NULL;
64
 		return NULL;
65
 	}
65
 	}
84
 	free ( cq );
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
  * Find work queue belonging to completion queue
156
  * Find work queue belonging to completion queue
89
  *
157
  *

Loading…
Cancel
Save