|
@@ -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 ");
|