|
@@ -609,10 +609,42 @@ static int build_rdma_recv(struct c4iw_qp *qhp, union t4_recv_wr *wqe,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void build_tpte_memreg(struct fw_ri_fr_nsmr_tpte_wr *fr,
|
|
|
|
+ struct ib_reg_wr *wr, struct c4iw_mr *mhp,
|
|
|
|
+ u8 *len16)
|
|
|
|
+{
|
|
|
|
+ __be64 *p = (__be64 *)fr->pbl;
|
|
|
|
+
|
|
|
|
+ fr->r2 = cpu_to_be32(0);
|
|
|
|
+ fr->stag = cpu_to_be32(mhp->ibmr.rkey);
|
|
|
|
+
|
|
|
|
+ fr->tpte.valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
|
|
|
|
+ FW_RI_TPTE_STAGKEY_V((mhp->ibmr.rkey & FW_RI_TPTE_STAGKEY_M)) |
|
|
|
|
+ FW_RI_TPTE_STAGSTATE_V(1) |
|
|
|
|
+ FW_RI_TPTE_STAGTYPE_V(FW_RI_STAG_NSMR) |
|
|
|
|
+ FW_RI_TPTE_PDID_V(mhp->attr.pdid));
|
|
|
|
+ fr->tpte.locread_to_qpid = cpu_to_be32(
|
|
|
|
+ FW_RI_TPTE_PERM_V(c4iw_ib_to_tpt_access(wr->access)) |
|
|
|
|
+ FW_RI_TPTE_ADDRTYPE_V(FW_RI_VA_BASED_TO) |
|
|
|
|
+ FW_RI_TPTE_PS_V(ilog2(wr->mr->page_size) - 12));
|
|
|
|
+ fr->tpte.nosnoop_pbladdr = cpu_to_be32(FW_RI_TPTE_PBLADDR_V(
|
|
|
|
+ PBL_OFF(&mhp->rhp->rdev, mhp->attr.pbl_addr)>>3));
|
|
|
|
+ fr->tpte.dca_mwbcnt_pstag = cpu_to_be32(0);
|
|
|
|
+ fr->tpte.len_hi = cpu_to_be32(0);
|
|
|
|
+ fr->tpte.len_lo = cpu_to_be32(mhp->ibmr.length);
|
|
|
|
+ fr->tpte.va_hi = cpu_to_be32(mhp->ibmr.iova >> 32);
|
|
|
|
+ fr->tpte.va_lo_fbo = cpu_to_be32(mhp->ibmr.iova & 0xffffffff);
|
|
|
|
+
|
|
|
|
+ p[0] = cpu_to_be64((u64)mhp->mpl[0]);
|
|
|
|
+ p[1] = cpu_to_be64((u64)mhp->mpl[1]);
|
|
|
|
+
|
|
|
|
+ *len16 = DIV_ROUND_UP(sizeof(*fr), 16);
|
|
|
|
+}
|
|
|
|
+
|
|
static int build_memreg(struct t4_sq *sq, union t4_wr *wqe,
|
|
static int build_memreg(struct t4_sq *sq, union t4_wr *wqe,
|
|
- struct ib_reg_wr *wr, u8 *len16, bool dsgl_supported)
|
|
|
|
|
|
+ struct ib_reg_wr *wr, struct c4iw_mr *mhp, u8 *len16,
|
|
|
|
+ bool dsgl_supported)
|
|
{
|
|
{
|
|
- struct c4iw_mr *mhp = to_c4iw_mr(wr->mr);
|
|
|
|
struct fw_ri_immd *imdp;
|
|
struct fw_ri_immd *imdp;
|
|
__be64 *p;
|
|
__be64 *p;
|
|
int i;
|
|
int i;
|
|
@@ -674,9 +706,12 @@ static int build_memreg(struct t4_sq *sq, union t4_wr *wqe,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int build_inv_stag(union t4_wr *wqe, struct ib_send_wr *wr,
|
|
|
|
- u8 *len16)
|
|
|
|
|
|
+static int build_inv_stag(struct c4iw_dev *dev, union t4_wr *wqe,
|
|
|
|
+ struct ib_send_wr *wr, u8 *len16)
|
|
{
|
|
{
|
|
|
|
+ struct c4iw_mr *mhp = get_mhp(dev, wr->ex.invalidate_rkey >> 8);
|
|
|
|
+
|
|
|
|
+ mhp->attr.state = 0;
|
|
wqe->inv.stag_inv = cpu_to_be32(wr->ex.invalidate_rkey);
|
|
wqe->inv.stag_inv = cpu_to_be32(wr->ex.invalidate_rkey);
|
|
wqe->inv.r2 = 0;
|
|
wqe->inv.r2 = 0;
|
|
*len16 = DIV_ROUND_UP(sizeof wqe->inv, 16);
|
|
*len16 = DIV_ROUND_UP(sizeof wqe->inv, 16);
|
|
@@ -816,18 +851,32 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
|
|
if (!qhp->wq.sq.oldest_read)
|
|
if (!qhp->wq.sq.oldest_read)
|
|
qhp->wq.sq.oldest_read = swsqe;
|
|
qhp->wq.sq.oldest_read = swsqe;
|
|
break;
|
|
break;
|
|
- case IB_WR_REG_MR:
|
|
|
|
- fw_opcode = FW_RI_FR_NSMR_WR;
|
|
|
|
|
|
+ case IB_WR_REG_MR: {
|
|
|
|
+ struct c4iw_mr *mhp = to_c4iw_mr(reg_wr(wr)->mr);
|
|
|
|
+
|
|
swsqe->opcode = FW_RI_FAST_REGISTER;
|
|
swsqe->opcode = FW_RI_FAST_REGISTER;
|
|
- err = build_memreg(&qhp->wq.sq, wqe, reg_wr(wr), &len16,
|
|
|
|
- qhp->rhp->rdev.lldi.ulptx_memwrite_dsgl);
|
|
|
|
|
|
+ if (qhp->rhp->rdev.lldi.fr_nsmr_tpte_wr_support &&
|
|
|
|
+ !mhp->attr.state && mhp->mpl_len <= 2) {
|
|
|
|
+ fw_opcode = FW_RI_FR_NSMR_TPTE_WR;
|
|
|
|
+ build_tpte_memreg(&wqe->fr_tpte, reg_wr(wr),
|
|
|
|
+ mhp, &len16);
|
|
|
|
+ } else {
|
|
|
|
+ fw_opcode = FW_RI_FR_NSMR_WR;
|
|
|
|
+ err = build_memreg(&qhp->wq.sq, wqe, reg_wr(wr),
|
|
|
|
+ mhp, &len16,
|
|
|
|
+ qhp->rhp->rdev.lldi.ulptx_memwrite_dsgl);
|
|
|
|
+ if (err)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ mhp->attr.state = 1;
|
|
break;
|
|
break;
|
|
|
|
+ }
|
|
case IB_WR_LOCAL_INV:
|
|
case IB_WR_LOCAL_INV:
|
|
if (wr->send_flags & IB_SEND_FENCE)
|
|
if (wr->send_flags & IB_SEND_FENCE)
|
|
fw_flags |= FW_RI_LOCAL_FENCE_FLAG;
|
|
fw_flags |= FW_RI_LOCAL_FENCE_FLAG;
|
|
fw_opcode = FW_RI_INV_LSTAG_WR;
|
|
fw_opcode = FW_RI_INV_LSTAG_WR;
|
|
swsqe->opcode = FW_RI_LOCAL_INV;
|
|
swsqe->opcode = FW_RI_LOCAL_INV;
|
|
- err = build_inv_stag(wqe, wr, &len16);
|
|
|
|
|
|
+ err = build_inv_stag(qhp->rhp, wqe, wr, &len16);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
PDBG("%s post of type=%d TBD!\n", __func__,
|
|
PDBG("%s post of type=%d TBD!\n", __func__,
|