|
@@ -270,6 +270,13 @@ static struct net_device_operations mlx_operations = {
|
270
|
270
|
|
271
|
271
|
|
272
|
272
|
|
|
273
|
+/***************************************************************************
|
|
274
|
+ *
|
|
275
|
+ * Queue number allocation
|
|
276
|
+ *
|
|
277
|
+ ***************************************************************************
|
|
278
|
+ */
|
|
279
|
+
|
273
|
280
|
/**
|
274
|
281
|
* Allocate queue number
|
275
|
282
|
*
|
|
@@ -444,6 +451,13 @@ arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
|
444
|
451
|
0, cqctx, cqn, NULL );
|
445
|
452
|
}
|
446
|
453
|
|
|
454
|
+static inline int
|
|
455
|
+arbel_cmd_hw2sw_cq ( struct arbel *arbel, unsigned long cqn ) {
|
|
456
|
+ return arbel_cmd ( arbel,
|
|
457
|
+ ARBEL_HCR_VOID_CMD ( ARBEL_HCR_HW2SW_CQ ),
|
|
458
|
+ 1, NULL, cqn, NULL );
|
|
459
|
+}
|
|
460
|
+
|
447
|
461
|
/***************************************************************************
|
448
|
462
|
*
|
449
|
463
|
* Completion queue operations
|
|
@@ -548,8 +562,9 @@ static int arbel_create_cq ( struct ib_device *ibdev,
|
548
|
562
|
return 0;
|
549
|
563
|
|
550
|
564
|
err_sw2hw:
|
551
|
|
- memset ( ci_db_rec, 0, sizeof ( *ci_db_rec ) );
|
552
|
|
- memset ( arm_db_rec, 0, sizeof ( *arm_db_rec ) );
|
|
565
|
+ MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
|
|
566
|
+ MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
|
|
567
|
+ free_dma ( arbel_cq->cqe, cqe_size );
|
553
|
568
|
err_cqe:
|
554
|
569
|
free ( arbel_cq );
|
555
|
570
|
err_arbel_cq:
|
|
@@ -558,6 +573,50 @@ static int arbel_create_cq ( struct ib_device *ibdev,
|
558
|
573
|
return rc;
|
559
|
574
|
}
|
560
|
575
|
|
|
576
|
+/**
|
|
577
|
+ * Destroy completion queue
|
|
578
|
+ *
|
|
579
|
+ * @v ibdev Infiniband device
|
|
580
|
+ * @v cq Completion queue
|
|
581
|
+ */
|
|
582
|
+static void arbel_destroy_cq ( struct ib_device *ibdev,
|
|
583
|
+ struct ib_completion_queue *cq ) {
|
|
584
|
+ struct arbel *arbel = ibdev->priv;
|
|
585
|
+ struct arbel_completion_queue *arbel_cq =
|
|
586
|
+ container_of ( cq, struct arbel_completion_queue, cq );
|
|
587
|
+ struct arbelprm_cq_ci_db_record *ci_db_rec;
|
|
588
|
+ struct arbelprm_cq_arm_db_record *arm_db_rec;
|
|
589
|
+ int cqn_offset;
|
|
590
|
+ size_t cqe_size;
|
|
591
|
+ unsigned int ci_doorbell_idx;
|
|
592
|
+ unsigned int arm_doorbell_idx;
|
|
593
|
+ int rc;
|
|
594
|
+
|
|
595
|
+ assert ( list_empty ( &cq->work_queues ) );
|
|
596
|
+
|
|
597
|
+ /* Take ownership back from hardware */
|
|
598
|
+ if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn ) ) != 0 ) {
|
|
599
|
+ DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed: %s\n",
|
|
600
|
+ arbel, strerror ( rc ) );
|
|
601
|
+ /* Leak memory and return; at least we avoid corruption */
|
|
602
|
+ return;
|
|
603
|
+ }
|
|
604
|
+
|
|
605
|
+ /* Clear doorbell records */
|
|
606
|
+ cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
|
|
607
|
+ ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
|
|
608
|
+ arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
|
|
609
|
+ ci_db_rec = &arbel->db_rec[ci_doorbell_idx].cq_ci;
|
|
610
|
+ arm_db_rec = &arbel->db_rec[arm_doorbell_idx].cq_arm;
|
|
611
|
+ MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
|
|
612
|
+ MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
|
|
613
|
+
|
|
614
|
+ /* Free memory */
|
|
615
|
+ cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
|
|
616
|
+ free_dma ( arbel_cq->cqe, cqe_size );
|
|
617
|
+ free ( arbel_cq );
|
|
618
|
+ arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
|
|
619
|
+}
|
561
|
620
|
|
562
|
621
|
/***************************************************************************
|
563
|
622
|
*
|
|
@@ -863,6 +922,8 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
|
863
|
922
|
|
864
|
923
|
/** Arbel Infiniband operations */
|
865
|
924
|
static struct ib_device_operations arbel_ib_operations = {
|
|
925
|
+ .create_cq = arbel_create_cq,
|
|
926
|
+ .destroy_cq = arbel_destroy_cq,
|
866
|
927
|
.post_send = arbel_post_send,
|
867
|
928
|
.post_recv = arbel_post_recv,
|
868
|
929
|
.poll_cq = arbel_poll_cq,
|