RDMA/hns: Support SRQ record doorbell
[sfrench/cifs-2.6.git] / drivers / infiniband / hw / hns / hns_roce_hw_v2.c
index b48f2c7b2fb0d102c472f6e436bf72fa8d676b30..a17bbf29b64be9d8277c05051daa999b7d0c646e 100644 (file)
@@ -941,20 +941,23 @@ static void fill_wqe_idx(struct hns_roce_srq *srq, unsigned int wqe_idx)
        idx_que->head++;
 }
 
-static void update_srq_db(struct hns_roce_v2_db *db, struct hns_roce_srq *srq)
+static void update_srq_db(struct hns_roce_srq *srq)
 {
-       hr_reg_write(db, DB_TAG, srq->srqn);
-       hr_reg_write(db, DB_CMD, HNS_ROCE_V2_SRQ_DB);
-       hr_reg_write(db, DB_PI, srq->idx_que.head);
+       struct hns_roce_dev *hr_dev = to_hr_dev(srq->ibsrq.device);
+       struct hns_roce_v2_db db;
+
+       hr_reg_write(&db, DB_TAG, srq->srqn);
+       hr_reg_write(&db, DB_CMD, HNS_ROCE_V2_SRQ_DB);
+       hr_reg_write(&db, DB_PI, srq->idx_que.head);
+
+       hns_roce_write64(hr_dev, (__le32 *)&db, srq->db_reg);
 }
 
 static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
                                     const struct ib_recv_wr *wr,
                                     const struct ib_recv_wr **bad_wr)
 {
-       struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
        struct hns_roce_srq *srq = to_hr_srq(ibsrq);
-       struct hns_roce_v2_db srq_db;
        unsigned long flags;
        int ret = 0;
        u32 max_sge;
@@ -985,9 +988,11 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
        }
 
        if (likely(nreq)) {
-               update_srq_db(&srq_db, srq);
-
-               hns_roce_write64(hr_dev, (__le32 *)&srq_db, srq->db_reg);
+               if (srq->cap_flags & HNS_ROCE_SRQ_CAP_RECORD_DB)
+                       *srq->rdb.db_record = srq->idx_que.head &
+                                             V2_DB_PRODUCER_IDX_M;
+               else
+                       update_srq_db(srq);
        }
 
        spin_unlock_irqrestore(&srq->lock, flags);
@@ -5630,6 +5635,14 @@ static int hns_roce_v2_write_srqc(struct hns_roce_srq *srq, void *mb_buf)
        hr_reg_write(ctx, SRQC_WQE_BUF_PG_SZ,
                     to_hr_hw_page_shift(srq->buf_mtr.hem_cfg.buf_pg_shift));
 
+       if (srq->cap_flags & HNS_ROCE_SRQ_CAP_RECORD_DB) {
+               hr_reg_enable(ctx, SRQC_DB_RECORD_EN);
+               hr_reg_write(ctx, SRQC_DB_RECORD_ADDR_L,
+                            lower_32_bits(srq->rdb.dma) >> 1);
+               hr_reg_write(ctx, SRQC_DB_RECORD_ADDR_H,
+                            upper_32_bits(srq->rdb.dma));
+       }
+
        return hns_roce_v2_write_srqc_index_queue(srq, ctx);
 }