diff options
Diffstat (limited to 'drivers/infiniband/hw/hns/hns_roce_hw_v2.c')
-rw-r--r-- | drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 594d4cef31b3..5b9953105752 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1248,8 +1248,7 @@ static void hns_roce_cmq_setup_basic_desc(struct hns_roce_cmq_desc *desc, { memset((void *)desc, 0, sizeof(struct hns_roce_cmq_desc)); desc->opcode = cpu_to_le16(opcode); - desc->flag = - cpu_to_le16(HNS_ROCE_CMD_FLAG_NO_INTR | HNS_ROCE_CMD_FLAG_IN); + desc->flag = cpu_to_le16(HNS_ROCE_CMD_FLAG_IN); if (is_read) desc->flag |= cpu_to_le16(HNS_ROCE_CMD_FLAG_WR); else @@ -1288,16 +1287,11 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, /* Write to hardware */ roce_write(hr_dev, ROCEE_TX_CMQ_PI_REG, csq->head); - /* If the command is sync, wait for the firmware to write back, - * if multi descriptors to be sent, use the first one to check - */ - if (le16_to_cpu(desc->flag) & HNS_ROCE_CMD_FLAG_NO_INTR) { - do { - if (hns_roce_cmq_csq_done(hr_dev)) - break; - udelay(1); - } while (++timeout < priv->cmq.tx_timeout); - } + do { + if (hns_roce_cmq_csq_done(hr_dev)) + break; + udelay(1); + } while (++timeout < priv->cmq.tx_timeout); if (hns_roce_cmq_csq_done(hr_dev)) { for (ret = 0, i = 0; i < num; i++) { @@ -1761,8 +1755,7 @@ static int __hns_roce_set_vf_switch_param(struct hns_roce_dev *hr_dev, if (ret) return ret; - desc.flag = - cpu_to_le16(HNS_ROCE_CMD_FLAG_NO_INTR | HNS_ROCE_CMD_FLAG_IN); + desc.flag = cpu_to_le16(HNS_ROCE_CMD_FLAG_IN); desc.flag &= cpu_to_le16(~HNS_ROCE_CMD_FLAG_WR); roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_LPBK_S, 1); roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_LCL_LPBK_S, 0); @@ -2004,6 +1997,7 @@ static void set_default_caps(struct hns_roce_dev *hr_dev) caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM; if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) { + caps->flags |= HNS_ROCE_CAP_FLAG_STASH; caps->max_sq_inline = HNS_ROCE_V3_MAX_SQ_INLINE; } else { caps->max_sq_inline = HNS_ROCE_V2_MAX_SQ_INLINE; @@ -4114,6 +4108,9 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp, if (hr_qp->en_flags & HNS_ROCE_QP_CAP_RQ_RECORD_DB) hr_reg_enable(context, QPC_RQ_RECORD_EN); + if (hr_qp->en_flags & HNS_ROCE_QP_CAP_OWNER_DB) + hr_reg_enable(context, QPC_OWNER_MODE); + hr_reg_write(context, QPC_RQ_DB_RECORD_ADDR_L, lower_32_bits(hr_qp->rdb.dma) >> 1); hr_reg_write(context, QPC_RQ_DB_RECORD_ADDR_H, @@ -4146,8 +4143,6 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, struct hns_roce_v2_qp_context *context, struct hns_roce_v2_qp_context *qpc_mask) { - struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); - /* * In v2 engine, software pass context and context mask to hardware * when modifying qp. If software need modify some fields in context, @@ -4172,11 +4167,6 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, hr_reg_write(context, QPC_SRQN, to_hr_srq(ibqp->srq)->srqn); hr_reg_clear(qpc_mask, QPC_SRQN); } - - if (attr_mask & IB_QP_DEST_QPN) { - hr_reg_write(context, QPC_DQPN, hr_qp->qpn); - hr_reg_clear(qpc_mask, QPC_DQPN); - } } static int config_qp_rq_buf(struct hns_roce_dev *hr_dev, @@ -4486,9 +4476,6 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, hr_reg_clear(qpc_mask, QPC_CHECK_FLG); - hr_reg_write(context, QPC_LSN, 0x100); - hr_reg_clear(qpc_mask, QPC_LSN); - hr_reg_clear(qpc_mask, QPC_V2_IRRL_HEAD); return 0; @@ -4507,15 +4494,23 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, { const struct ib_global_route *grh = rdma_ah_read_grh(&attr->ah_attr); struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); + u32 *spare_idx = hr_dev->qp_table.idx_table.spare_idx; + u32 *head = &hr_dev->qp_table.idx_table.head; + u32 *tail = &hr_dev->qp_table.idx_table.tail; struct hns_roce_dip *hr_dip; unsigned long flags; int ret = 0; spin_lock_irqsave(&hr_dev->dip_list_lock, flags); + spare_idx[*tail] = ibqp->qp_num; + *tail = (*tail == hr_dev->caps.num_qps - 1) ? 0 : (*tail + 1); + list_for_each_entry(hr_dip, &hr_dev->dip_list, node) { - if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) + if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) { + *dip_idx = hr_dip->dip_idx; goto out; + } } /* If no dgid is found, a new dip and a mapping between dgid and @@ -4528,7 +4523,8 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr, } memcpy(hr_dip->dgid, grh->dgid.raw, sizeof(grh->dgid.raw)); - hr_dip->dip_idx = *dip_idx = ibqp->qp_num; + hr_dip->dip_idx = *dip_idx = spare_idx[*head]; + *head = (*head == hr_dev->caps.num_qps - 1) ? 0 : (*head + 1); list_add_tail(&hr_dip->node, &hr_dev->dip_list); out: @@ -5127,7 +5123,7 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, qp_attr->rq_psn = hr_reg_read(&context, QPC_RX_REQ_EPSN); qp_attr->sq_psn = (u32)hr_reg_read(&context, QPC_SQ_CUR_PSN); - qp_attr->dest_qp_num = (u8)hr_reg_read(&context, QPC_DQPN); + qp_attr->dest_qp_num = hr_reg_read(&context, QPC_DQPN); qp_attr->qp_access_flags = ((hr_reg_read(&context, QPC_RRE)) << V2_QP_RRE_S) | ((hr_reg_read(&context, QPC_RWE)) << V2_QP_RWE_S) | @@ -5224,7 +5220,6 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev, if (send_cq && send_cq != recv_cq) __hns_roce_v2_cq_clean(send_cq, hr_qp->qpn, NULL); - } hns_roce_qp_remove(hr_dev, hr_qp); @@ -6118,35 +6113,32 @@ static int hns_roce_v2_init_eq_table(struct hns_roce_dev *hr_dev) ret = hns_roce_v2_create_eq(hr_dev, eq, eq_cmd); if (ret) { - dev_err(dev, "eq create failed.\n"); + dev_err(dev, "failed to create eq.\n"); goto err_create_eq_fail; } } - /* enable irq */ - hns_roce_v2_int_mask_enable(hr_dev, eq_num, EQ_ENABLE); + hr_dev->irq_workq = alloc_ordered_workqueue("hns_roce_irq_workq", 0); + if (!hr_dev->irq_workq) { + dev_err(dev, "failed to create irq workqueue.\n"); + ret = -ENOMEM; + goto err_create_eq_fail; + } - ret = __hns_roce_request_irq(hr_dev, irq_num, comp_num, - aeq_num, other_num); + ret = __hns_roce_request_irq(hr_dev, irq_num, comp_num, aeq_num, + other_num); if (ret) { - dev_err(dev, "Request irq failed.\n"); + dev_err(dev, "failed to request irq.\n"); goto err_request_irq_fail; } - hr_dev->irq_workq = alloc_ordered_workqueue("hns_roce_irq_workq", 0); - if (!hr_dev->irq_workq) { - dev_err(dev, "Create irq workqueue failed!\n"); - ret = -ENOMEM; - goto err_create_wq_fail; - } + /* enable irq */ + hns_roce_v2_int_mask_enable(hr_dev, eq_num, EQ_ENABLE); return 0; -err_create_wq_fail: - __hns_roce_free_irq(hr_dev); - err_request_irq_fail: - hns_roce_v2_int_mask_enable(hr_dev, eq_num, EQ_DISABLE); + destroy_workqueue(hr_dev->irq_workq); err_create_eq_fail: for (i -= 1; i >= 0; i--) @@ -6367,7 +6359,6 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) handle->rinfo.instance_state = HNS_ROCE_STATE_INITED; - return 0; reset_chk_err: |