RDMA/hns: Move SRQ code to the reasonable place
Just move the SRQ related code to more reasonable place, and unify format of some prints. Link: https://lore.kernel.org/r/1588071823-40200-5-git-send-email-liweihang@huawei.com Signed-off-by: Yixian Liu <liuyixian@huawei.com> Signed-off-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Родитель
54d6638765
Коммит
ffb1308b88
|
@ -694,6 +694,129 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *get_srq_wqe(struct hns_roce_srq *srq, int n)
|
||||||
|
{
|
||||||
|
return hns_roce_buf_offset(srq->buf_mtr.kmem, n << srq->wqe_shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hns_roce_free_srq_wqe(struct hns_roce_srq *srq, int wqe_index)
|
||||||
|
{
|
||||||
|
/* always called with interrupts disabled. */
|
||||||
|
spin_lock(&srq->lock);
|
||||||
|
|
||||||
|
bitmap_clear(srq->idx_que.bitmap, wqe_index, 1);
|
||||||
|
srq->tail++;
|
||||||
|
|
||||||
|
spin_unlock(&srq->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int find_empty_entry(struct hns_roce_idx_que *idx_que,
|
||||||
|
unsigned long size)
|
||||||
|
{
|
||||||
|
int wqe_idx;
|
||||||
|
|
||||||
|
if (unlikely(bitmap_full(idx_que->bitmap, size)))
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
wqe_idx = find_first_zero_bit(idx_que->bitmap, size);
|
||||||
|
|
||||||
|
bitmap_set(idx_que->bitmap, wqe_idx, 1);
|
||||||
|
|
||||||
|
return wqe_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_idx_queue(struct hns_roce_idx_que *idx_que,
|
||||||
|
int cur_idx, int wqe_idx)
|
||||||
|
{
|
||||||
|
unsigned int *addr;
|
||||||
|
|
||||||
|
addr = (unsigned int *)hns_roce_buf_offset(idx_que->mtr.kmem,
|
||||||
|
cur_idx * idx_que->entry_sz);
|
||||||
|
*addr = wqe_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_wqe_data_seg *dseg;
|
||||||
|
struct hns_roce_v2_db srq_db;
|
||||||
|
unsigned long flags;
|
||||||
|
int ret = 0;
|
||||||
|
int wqe_idx;
|
||||||
|
void *wqe;
|
||||||
|
int nreq;
|
||||||
|
int ind;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&srq->lock, flags);
|
||||||
|
|
||||||
|
ind = srq->head & (srq->wqe_cnt - 1);
|
||||||
|
|
||||||
|
for (nreq = 0; wr; ++nreq, wr = wr->next) {
|
||||||
|
if (unlikely(wr->num_sge >= srq->max_gs)) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
*bad_wr = wr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(srq->head == srq->tail)) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
*bad_wr = wr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wqe_idx = find_empty_entry(&srq->idx_que, srq->wqe_cnt);
|
||||||
|
if (wqe_idx < 0) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
*bad_wr = wr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_idx_queue(&srq->idx_que, ind, wqe_idx);
|
||||||
|
wqe = get_srq_wqe(srq, wqe_idx);
|
||||||
|
dseg = (struct hns_roce_v2_wqe_data_seg *)wqe;
|
||||||
|
|
||||||
|
for (i = 0; i < wr->num_sge; ++i) {
|
||||||
|
dseg[i].len = cpu_to_le32(wr->sg_list[i].length);
|
||||||
|
dseg[i].lkey = cpu_to_le32(wr->sg_list[i].lkey);
|
||||||
|
dseg[i].addr = cpu_to_le64(wr->sg_list[i].addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < srq->max_gs) {
|
||||||
|
dseg[i].len = 0;
|
||||||
|
dseg[i].lkey = cpu_to_le32(0x100);
|
||||||
|
dseg[i].addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
srq->wrid[wqe_idx] = wr->wr_id;
|
||||||
|
ind = (ind + 1) & (srq->wqe_cnt - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(nreq)) {
|
||||||
|
srq->head += nreq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that descriptors are written before
|
||||||
|
* doorbell record.
|
||||||
|
*/
|
||||||
|
wmb();
|
||||||
|
|
||||||
|
srq_db.byte_4 =
|
||||||
|
cpu_to_le32(HNS_ROCE_V2_SRQ_DB << V2_DB_BYTE_4_CMD_S |
|
||||||
|
(srq->srqn & V2_DB_BYTE_4_TAG_M));
|
||||||
|
srq_db.parameter = cpu_to_le32(srq->head);
|
||||||
|
|
||||||
|
hns_roce_write64(hr_dev, (__le32 *)&srq_db, srq->db_reg_l);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&srq->lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int hns_roce_v2_cmd_hw_reseted(struct hns_roce_dev *hr_dev,
|
static int hns_roce_v2_cmd_hw_reseted(struct hns_roce_dev *hr_dev,
|
||||||
unsigned long instance_stage,
|
unsigned long instance_stage,
|
||||||
unsigned long reset_stage)
|
unsigned long reset_stage)
|
||||||
|
@ -2667,22 +2790,6 @@ static struct hns_roce_v2_cqe *next_cqe_sw_v2(struct hns_roce_cq *hr_cq)
|
||||||
return get_sw_cqe_v2(hr_cq, hr_cq->cons_index);
|
return get_sw_cqe_v2(hr_cq, hr_cq->cons_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *get_srq_wqe(struct hns_roce_srq *srq, int n)
|
|
||||||
{
|
|
||||||
return hns_roce_buf_offset(srq->buf_mtr.kmem, n << srq->wqe_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hns_roce_free_srq_wqe(struct hns_roce_srq *srq, int wqe_index)
|
|
||||||
{
|
|
||||||
/* always called with interrupts disabled. */
|
|
||||||
spin_lock(&srq->lock);
|
|
||||||
|
|
||||||
bitmap_clear(srq->idx_que.bitmap, wqe_index, 1);
|
|
||||||
srq->tail++;
|
|
||||||
|
|
||||||
spin_unlock(&srq->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hns_roce_v2_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index)
|
static void hns_roce_v2_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index)
|
||||||
{
|
{
|
||||||
*hr_cq->set_ci_db = cons_index & V2_CQ_DB_PARAMETER_CONS_IDX_M;
|
*hr_cq->set_ci_db = cons_index & V2_CQ_DB_PARAMETER_CONS_IDX_M;
|
||||||
|
@ -4777,6 +4884,186 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hns_roce_v2_write_srqc(struct hns_roce_dev *hr_dev,
|
||||||
|
struct hns_roce_srq *srq, u32 pdn, u16 xrcd,
|
||||||
|
u32 cqn, void *mb_buf, u64 *mtts_wqe,
|
||||||
|
u64 *mtts_idx, dma_addr_t dma_handle_wqe,
|
||||||
|
dma_addr_t dma_handle_idx)
|
||||||
|
{
|
||||||
|
struct hns_roce_srq_context *srq_context;
|
||||||
|
|
||||||
|
srq_context = mb_buf;
|
||||||
|
memset(srq_context, 0, sizeof(*srq_context));
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_4_srqn_srqst, SRQC_BYTE_4_SRQ_ST_M,
|
||||||
|
SRQC_BYTE_4_SRQ_ST_S, 1);
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_4_srqn_srqst,
|
||||||
|
SRQC_BYTE_4_SRQ_WQE_HOP_NUM_M,
|
||||||
|
SRQC_BYTE_4_SRQ_WQE_HOP_NUM_S,
|
||||||
|
(hr_dev->caps.srqwqe_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 :
|
||||||
|
hr_dev->caps.srqwqe_hop_num));
|
||||||
|
roce_set_field(srq_context->byte_4_srqn_srqst,
|
||||||
|
SRQC_BYTE_4_SRQ_SHIFT_M, SRQC_BYTE_4_SRQ_SHIFT_S,
|
||||||
|
ilog2(srq->wqe_cnt));
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_4_srqn_srqst, SRQC_BYTE_4_SRQN_M,
|
||||||
|
SRQC_BYTE_4_SRQN_S, srq->srqn);
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_8_limit_wl, SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_S, 0);
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_12_xrcd, SRQC_BYTE_12_SRQ_XRCD_M,
|
||||||
|
SRQC_BYTE_12_SRQ_XRCD_S, xrcd);
|
||||||
|
|
||||||
|
srq_context->wqe_bt_ba = cpu_to_le32((u32)(dma_handle_wqe >> 3));
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_24_wqe_bt_ba,
|
||||||
|
SRQC_BYTE_24_SRQ_WQE_BT_BA_M,
|
||||||
|
SRQC_BYTE_24_SRQ_WQE_BT_BA_S,
|
||||||
|
dma_handle_wqe >> 35);
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_28_rqws_pd, SRQC_BYTE_28_PD_M,
|
||||||
|
SRQC_BYTE_28_PD_S, pdn);
|
||||||
|
roce_set_field(srq_context->byte_28_rqws_pd, SRQC_BYTE_28_RQWS_M,
|
||||||
|
SRQC_BYTE_28_RQWS_S, srq->max_gs <= 0 ? 0 :
|
||||||
|
fls(srq->max_gs - 1));
|
||||||
|
|
||||||
|
srq_context->idx_bt_ba = cpu_to_le32(dma_handle_idx >> 3);
|
||||||
|
roce_set_field(srq_context->rsv_idx_bt_ba,
|
||||||
|
SRQC_BYTE_36_SRQ_IDX_BT_BA_M,
|
||||||
|
SRQC_BYTE_36_SRQ_IDX_BT_BA_S,
|
||||||
|
dma_handle_idx >> 35);
|
||||||
|
|
||||||
|
srq_context->idx_cur_blk_addr =
|
||||||
|
cpu_to_le32(to_hr_hw_page_addr(mtts_idx[0]));
|
||||||
|
roce_set_field(srq_context->byte_44_idxbufpgsz_addr,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_CUR_BLK_ADDR_M,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_CUR_BLK_ADDR_S,
|
||||||
|
upper_32_bits(to_hr_hw_page_addr(mtts_idx[0])));
|
||||||
|
roce_set_field(srq_context->byte_44_idxbufpgsz_addr,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_HOP_NUM_M,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_HOP_NUM_S,
|
||||||
|
hr_dev->caps.idx_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 :
|
||||||
|
hr_dev->caps.idx_hop_num);
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_44_idxbufpgsz_addr,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_BA_PG_SZ_M,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_BA_PG_SZ_S,
|
||||||
|
to_hr_hw_page_shift(srq->idx_que.mtr.hem_cfg.ba_pg_shift));
|
||||||
|
roce_set_field(srq_context->byte_44_idxbufpgsz_addr,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_BUF_PG_SZ_M,
|
||||||
|
SRQC_BYTE_44_SRQ_IDX_BUF_PG_SZ_S,
|
||||||
|
to_hr_hw_page_shift(srq->idx_que.mtr.hem_cfg.buf_pg_shift));
|
||||||
|
|
||||||
|
srq_context->idx_nxt_blk_addr =
|
||||||
|
cpu_to_le32(to_hr_hw_page_addr(mtts_idx[1]));
|
||||||
|
roce_set_field(srq_context->rsv_idxnxtblkaddr,
|
||||||
|
SRQC_BYTE_52_SRQ_IDX_NXT_BLK_ADDR_M,
|
||||||
|
SRQC_BYTE_52_SRQ_IDX_NXT_BLK_ADDR_S,
|
||||||
|
upper_32_bits(to_hr_hw_page_addr(mtts_idx[1])));
|
||||||
|
roce_set_field(srq_context->byte_56_xrc_cqn,
|
||||||
|
SRQC_BYTE_56_SRQ_XRC_CQN_M, SRQC_BYTE_56_SRQ_XRC_CQN_S,
|
||||||
|
cqn);
|
||||||
|
roce_set_field(srq_context->byte_56_xrc_cqn,
|
||||||
|
SRQC_BYTE_56_SRQ_WQE_BA_PG_SZ_M,
|
||||||
|
SRQC_BYTE_56_SRQ_WQE_BA_PG_SZ_S,
|
||||||
|
to_hr_hw_page_shift(srq->buf_mtr.hem_cfg.ba_pg_shift));
|
||||||
|
roce_set_field(srq_context->byte_56_xrc_cqn,
|
||||||
|
SRQC_BYTE_56_SRQ_WQE_BUF_PG_SZ_M,
|
||||||
|
SRQC_BYTE_56_SRQ_WQE_BUF_PG_SZ_S,
|
||||||
|
to_hr_hw_page_shift(srq->buf_mtr.hem_cfg.buf_pg_shift));
|
||||||
|
|
||||||
|
roce_set_bit(srq_context->db_record_addr_record_en,
|
||||||
|
SRQC_BYTE_60_SRQ_RECORD_EN_S, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq,
|
||||||
|
struct ib_srq_attr *srq_attr,
|
||||||
|
enum ib_srq_attr_mask srq_attr_mask,
|
||||||
|
struct ib_udata *udata)
|
||||||
|
{
|
||||||
|
struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
|
||||||
|
struct hns_roce_srq *srq = to_hr_srq(ibsrq);
|
||||||
|
struct hns_roce_srq_context *srq_context;
|
||||||
|
struct hns_roce_srq_context *srqc_mask;
|
||||||
|
struct hns_roce_cmd_mailbox *mailbox;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (srq_attr_mask & IB_SRQ_LIMIT) {
|
||||||
|
if (srq_attr->srq_limit >= srq->wqe_cnt)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
|
||||||
|
if (IS_ERR(mailbox))
|
||||||
|
return PTR_ERR(mailbox);
|
||||||
|
|
||||||
|
srq_context = mailbox->buf;
|
||||||
|
srqc_mask = (struct hns_roce_srq_context *)mailbox->buf + 1;
|
||||||
|
|
||||||
|
memset(srqc_mask, 0xff, sizeof(*srqc_mask));
|
||||||
|
|
||||||
|
roce_set_field(srq_context->byte_8_limit_wl,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_S, srq_attr->srq_limit);
|
||||||
|
roce_set_field(srqc_mask->byte_8_limit_wl,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_S, 0);
|
||||||
|
|
||||||
|
ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, srq->srqn, 0,
|
||||||
|
HNS_ROCE_CMD_MODIFY_SRQC,
|
||||||
|
HNS_ROCE_CMD_TIMEOUT_MSECS);
|
||||||
|
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
|
||||||
|
if (ret) {
|
||||||
|
ibdev_err(&hr_dev->ib_dev,
|
||||||
|
"failed to handle cmd of modifying SRQ, ret = %d.\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hns_roce_v2_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
|
||||||
|
{
|
||||||
|
struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
|
||||||
|
struct hns_roce_srq *srq = to_hr_srq(ibsrq);
|
||||||
|
struct hns_roce_srq_context *srq_context;
|
||||||
|
struct hns_roce_cmd_mailbox *mailbox;
|
||||||
|
int limit_wl;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
|
||||||
|
if (IS_ERR(mailbox))
|
||||||
|
return PTR_ERR(mailbox);
|
||||||
|
|
||||||
|
srq_context = mailbox->buf;
|
||||||
|
ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, srq->srqn, 0,
|
||||||
|
HNS_ROCE_CMD_QUERY_SRQC,
|
||||||
|
HNS_ROCE_CMD_TIMEOUT_MSECS);
|
||||||
|
if (ret) {
|
||||||
|
ibdev_err(&hr_dev->ib_dev,
|
||||||
|
"failed to process cmd of querying SRQ, ret = %d.\n",
|
||||||
|
ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit_wl = roce_get_field(srq_context->byte_8_limit_wl,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
||||||
|
SRQC_BYTE_8_SRQ_LIMIT_WL_S);
|
||||||
|
|
||||||
|
attr->srq_limit = limit_wl;
|
||||||
|
attr->max_wr = srq->wqe_cnt;
|
||||||
|
attr->max_sge = srq->max_gs;
|
||||||
|
|
||||||
|
memcpy(srq_context, mailbox->buf, sizeof(*srq_context));
|
||||||
|
|
||||||
|
out:
|
||||||
|
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
|
static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
|
||||||
{
|
{
|
||||||
struct hns_roce_dev *hr_dev = to_hr_dev(cq->device);
|
struct hns_roce_dev *hr_dev = to_hr_dev(cq->device);
|
||||||
|
@ -5588,296 +5875,6 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
|
||||||
destroy_workqueue(hr_dev->irq_workq);
|
destroy_workqueue(hr_dev->irq_workq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hns_roce_v2_write_srqc(struct hns_roce_dev *hr_dev,
|
|
||||||
struct hns_roce_srq *srq, u32 pdn, u16 xrcd,
|
|
||||||
u32 cqn, void *mb_buf, u64 *mtts_wqe,
|
|
||||||
u64 *mtts_idx, dma_addr_t dma_handle_wqe,
|
|
||||||
dma_addr_t dma_handle_idx)
|
|
||||||
{
|
|
||||||
struct hns_roce_srq_context *srq_context;
|
|
||||||
|
|
||||||
srq_context = mb_buf;
|
|
||||||
memset(srq_context, 0, sizeof(*srq_context));
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_4_srqn_srqst, SRQC_BYTE_4_SRQ_ST_M,
|
|
||||||
SRQC_BYTE_4_SRQ_ST_S, 1);
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_4_srqn_srqst,
|
|
||||||
SRQC_BYTE_4_SRQ_WQE_HOP_NUM_M,
|
|
||||||
SRQC_BYTE_4_SRQ_WQE_HOP_NUM_S,
|
|
||||||
(hr_dev->caps.srqwqe_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 :
|
|
||||||
hr_dev->caps.srqwqe_hop_num));
|
|
||||||
roce_set_field(srq_context->byte_4_srqn_srqst,
|
|
||||||
SRQC_BYTE_4_SRQ_SHIFT_M, SRQC_BYTE_4_SRQ_SHIFT_S,
|
|
||||||
ilog2(srq->wqe_cnt));
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_4_srqn_srqst, SRQC_BYTE_4_SRQN_M,
|
|
||||||
SRQC_BYTE_4_SRQN_S, srq->srqn);
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_8_limit_wl, SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_S, 0);
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_12_xrcd, SRQC_BYTE_12_SRQ_XRCD_M,
|
|
||||||
SRQC_BYTE_12_SRQ_XRCD_S, xrcd);
|
|
||||||
|
|
||||||
srq_context->wqe_bt_ba = cpu_to_le32((u32)(dma_handle_wqe >> 3));
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_24_wqe_bt_ba,
|
|
||||||
SRQC_BYTE_24_SRQ_WQE_BT_BA_M,
|
|
||||||
SRQC_BYTE_24_SRQ_WQE_BT_BA_S,
|
|
||||||
dma_handle_wqe >> 35);
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_28_rqws_pd, SRQC_BYTE_28_PD_M,
|
|
||||||
SRQC_BYTE_28_PD_S, pdn);
|
|
||||||
roce_set_field(srq_context->byte_28_rqws_pd, SRQC_BYTE_28_RQWS_M,
|
|
||||||
SRQC_BYTE_28_RQWS_S, srq->max_gs <= 0 ? 0 :
|
|
||||||
fls(srq->max_gs - 1));
|
|
||||||
|
|
||||||
srq_context->idx_bt_ba = cpu_to_le32(dma_handle_idx >> 3);
|
|
||||||
roce_set_field(srq_context->rsv_idx_bt_ba,
|
|
||||||
SRQC_BYTE_36_SRQ_IDX_BT_BA_M,
|
|
||||||
SRQC_BYTE_36_SRQ_IDX_BT_BA_S,
|
|
||||||
dma_handle_idx >> 35);
|
|
||||||
|
|
||||||
srq_context->idx_cur_blk_addr =
|
|
||||||
cpu_to_le32(to_hr_hw_page_addr(mtts_idx[0]));
|
|
||||||
roce_set_field(srq_context->byte_44_idxbufpgsz_addr,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_CUR_BLK_ADDR_M,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_CUR_BLK_ADDR_S,
|
|
||||||
upper_32_bits(to_hr_hw_page_addr(mtts_idx[0])));
|
|
||||||
roce_set_field(srq_context->byte_44_idxbufpgsz_addr,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_HOP_NUM_M,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_HOP_NUM_S,
|
|
||||||
hr_dev->caps.idx_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 :
|
|
||||||
hr_dev->caps.idx_hop_num);
|
|
||||||
|
|
||||||
roce_set_field(
|
|
||||||
srq_context->byte_44_idxbufpgsz_addr,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_BA_PG_SZ_M,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_BA_PG_SZ_S,
|
|
||||||
to_hr_hw_page_shift(srq->idx_que.mtr.hem_cfg.ba_pg_shift));
|
|
||||||
roce_set_field(
|
|
||||||
srq_context->byte_44_idxbufpgsz_addr,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_BUF_PG_SZ_M,
|
|
||||||
SRQC_BYTE_44_SRQ_IDX_BUF_PG_SZ_S,
|
|
||||||
to_hr_hw_page_shift(srq->idx_que.mtr.hem_cfg.buf_pg_shift));
|
|
||||||
|
|
||||||
srq_context->idx_nxt_blk_addr =
|
|
||||||
cpu_to_le32(to_hr_hw_page_addr(mtts_idx[1]));
|
|
||||||
roce_set_field(srq_context->rsv_idxnxtblkaddr,
|
|
||||||
SRQC_BYTE_52_SRQ_IDX_NXT_BLK_ADDR_M,
|
|
||||||
SRQC_BYTE_52_SRQ_IDX_NXT_BLK_ADDR_S,
|
|
||||||
upper_32_bits(to_hr_hw_page_addr(mtts_idx[1])));
|
|
||||||
roce_set_field(srq_context->byte_56_xrc_cqn,
|
|
||||||
SRQC_BYTE_56_SRQ_XRC_CQN_M, SRQC_BYTE_56_SRQ_XRC_CQN_S,
|
|
||||||
cqn);
|
|
||||||
roce_set_field(srq_context->byte_56_xrc_cqn,
|
|
||||||
SRQC_BYTE_56_SRQ_WQE_BA_PG_SZ_M,
|
|
||||||
SRQC_BYTE_56_SRQ_WQE_BA_PG_SZ_S,
|
|
||||||
to_hr_hw_page_shift(srq->buf_mtr.hem_cfg.ba_pg_shift));
|
|
||||||
roce_set_field(srq_context->byte_56_xrc_cqn,
|
|
||||||
SRQC_BYTE_56_SRQ_WQE_BUF_PG_SZ_M,
|
|
||||||
SRQC_BYTE_56_SRQ_WQE_BUF_PG_SZ_S,
|
|
||||||
to_hr_hw_page_shift(srq->buf_mtr.hem_cfg.buf_pg_shift));
|
|
||||||
|
|
||||||
roce_set_bit(srq_context->db_record_addr_record_en,
|
|
||||||
SRQC_BYTE_60_SRQ_RECORD_EN_S, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq,
|
|
||||||
struct ib_srq_attr *srq_attr,
|
|
||||||
enum ib_srq_attr_mask srq_attr_mask,
|
|
||||||
struct ib_udata *udata)
|
|
||||||
{
|
|
||||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
|
|
||||||
struct hns_roce_srq *srq = to_hr_srq(ibsrq);
|
|
||||||
struct hns_roce_srq_context *srq_context;
|
|
||||||
struct hns_roce_srq_context *srqc_mask;
|
|
||||||
struct hns_roce_cmd_mailbox *mailbox;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (srq_attr_mask & IB_SRQ_LIMIT) {
|
|
||||||
if (srq_attr->srq_limit >= srq->wqe_cnt)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
|
|
||||||
if (IS_ERR(mailbox))
|
|
||||||
return PTR_ERR(mailbox);
|
|
||||||
|
|
||||||
srq_context = mailbox->buf;
|
|
||||||
srqc_mask = (struct hns_roce_srq_context *)mailbox->buf + 1;
|
|
||||||
|
|
||||||
memset(srqc_mask, 0xff, sizeof(*srqc_mask));
|
|
||||||
|
|
||||||
roce_set_field(srq_context->byte_8_limit_wl,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_S, srq_attr->srq_limit);
|
|
||||||
roce_set_field(srqc_mask->byte_8_limit_wl,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_S, 0);
|
|
||||||
|
|
||||||
ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, srq->srqn, 0,
|
|
||||||
HNS_ROCE_CMD_MODIFY_SRQC,
|
|
||||||
HNS_ROCE_CMD_TIMEOUT_MSECS);
|
|
||||||
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
|
|
||||||
if (ret) {
|
|
||||||
ibdev_err(&hr_dev->ib_dev,
|
|
||||||
"failed to process cmd when modifying SRQ, ret = %d\n",
|
|
||||||
ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hns_roce_v2_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
|
|
||||||
{
|
|
||||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
|
|
||||||
struct hns_roce_srq *srq = to_hr_srq(ibsrq);
|
|
||||||
struct hns_roce_srq_context *srq_context;
|
|
||||||
struct hns_roce_cmd_mailbox *mailbox;
|
|
||||||
int limit_wl;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
|
|
||||||
if (IS_ERR(mailbox))
|
|
||||||
return PTR_ERR(mailbox);
|
|
||||||
|
|
||||||
srq_context = mailbox->buf;
|
|
||||||
ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, srq->srqn, 0,
|
|
||||||
HNS_ROCE_CMD_QUERY_SRQC,
|
|
||||||
HNS_ROCE_CMD_TIMEOUT_MSECS);
|
|
||||||
if (ret) {
|
|
||||||
ibdev_err(&hr_dev->ib_dev,
|
|
||||||
"failed to process cmd when querying SRQ, ret = %d\n",
|
|
||||||
ret);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
limit_wl = roce_get_field(srq_context->byte_8_limit_wl,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_M,
|
|
||||||
SRQC_BYTE_8_SRQ_LIMIT_WL_S);
|
|
||||||
|
|
||||||
attr->srq_limit = limit_wl;
|
|
||||||
attr->max_wr = srq->wqe_cnt - 1;
|
|
||||||
attr->max_sge = srq->max_gs;
|
|
||||||
|
|
||||||
memcpy(srq_context, mailbox->buf, sizeof(*srq_context));
|
|
||||||
|
|
||||||
out:
|
|
||||||
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_empty_entry(struct hns_roce_idx_que *idx_que,
|
|
||||||
unsigned long size)
|
|
||||||
{
|
|
||||||
int wqe_idx;
|
|
||||||
|
|
||||||
if (unlikely(bitmap_full(idx_que->bitmap, size)))
|
|
||||||
return -ENOSPC;
|
|
||||||
|
|
||||||
wqe_idx = find_first_zero_bit(idx_que->bitmap, size);
|
|
||||||
|
|
||||||
bitmap_set(idx_que->bitmap, wqe_idx, 1);
|
|
||||||
|
|
||||||
return wqe_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fill_idx_queue(struct hns_roce_idx_que *idx_que,
|
|
||||||
int cur_idx, int wqe_idx)
|
|
||||||
{
|
|
||||||
unsigned int *addr;
|
|
||||||
|
|
||||||
addr = (unsigned int *)hns_roce_buf_offset(idx_que->mtr.kmem,
|
|
||||||
cur_idx * idx_que->entry_sz);
|
|
||||||
*addr = wqe_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_wqe_data_seg *dseg;
|
|
||||||
struct hns_roce_v2_db srq_db;
|
|
||||||
unsigned long flags;
|
|
||||||
int ret = 0;
|
|
||||||
int wqe_idx;
|
|
||||||
void *wqe;
|
|
||||||
int nreq;
|
|
||||||
int ind;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&srq->lock, flags);
|
|
||||||
|
|
||||||
ind = srq->head & (srq->wqe_cnt - 1);
|
|
||||||
|
|
||||||
for (nreq = 0; wr; ++nreq, wr = wr->next) {
|
|
||||||
if (unlikely(wr->num_sge > srq->max_gs)) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
*bad_wr = wr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(srq->head == srq->tail)) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
*bad_wr = wr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
wqe_idx = find_empty_entry(&srq->idx_que, srq->wqe_cnt);
|
|
||||||
if (wqe_idx < 0) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
*bad_wr = wr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fill_idx_queue(&srq->idx_que, ind, wqe_idx);
|
|
||||||
wqe = get_srq_wqe(srq, wqe_idx);
|
|
||||||
dseg = (struct hns_roce_v2_wqe_data_seg *)wqe;
|
|
||||||
|
|
||||||
for (i = 0; i < wr->num_sge; ++i) {
|
|
||||||
dseg[i].len = cpu_to_le32(wr->sg_list[i].length);
|
|
||||||
dseg[i].lkey = cpu_to_le32(wr->sg_list[i].lkey);
|
|
||||||
dseg[i].addr = cpu_to_le64(wr->sg_list[i].addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < srq->max_gs) {
|
|
||||||
dseg[i].len = 0;
|
|
||||||
dseg[i].lkey = cpu_to_le32(0x100);
|
|
||||||
dseg[i].addr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
srq->wrid[wqe_idx] = wr->wr_id;
|
|
||||||
ind = (ind + 1) & (srq->wqe_cnt - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (likely(nreq)) {
|
|
||||||
srq->head += nreq;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure that descriptors are written before
|
|
||||||
* doorbell record.
|
|
||||||
*/
|
|
||||||
wmb();
|
|
||||||
|
|
||||||
srq_db.byte_4 =
|
|
||||||
cpu_to_le32(HNS_ROCE_V2_SRQ_DB << V2_DB_BYTE_4_CMD_S |
|
|
||||||
(srq->srqn & V2_DB_BYTE_4_TAG_M));
|
|
||||||
srq_db.parameter = cpu_to_le32(srq->head);
|
|
||||||
|
|
||||||
hns_roce_write64(hr_dev, (__le32 *)&srq_db, srq->db_reg_l);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&srq->lock, flags);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct hns_roce_dfx_hw hns_roce_dfx_hw_v2 = {
|
static const struct hns_roce_dfx_hw hns_roce_dfx_hw_v2 = {
|
||||||
.query_cqc_info = hns_roce_v2_query_cqc_info,
|
.query_cqc_info = hns_roce_v2_query_cqc_info,
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче