0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/module.h>
0034 #include <linux/moduleparam.h>
0035 #include <rdma/ib_umem.h>
0036 #include <linux/atomic.h>
0037 #include <rdma/ib_user_verbs.h>
0038
0039 #include "iw_cxgb4.h"
0040
0041 int use_dsgl = 1;
0042 module_param(use_dsgl, int, 0644);
0043 MODULE_PARM_DESC(use_dsgl, "Use DSGL for PBL/FastReg (default=1) (DEPRECATED)");
0044
0045 #define T4_ULPTX_MIN_IO 32
0046 #define C4IW_MAX_INLINE_SIZE 96
0047 #define T4_ULPTX_MAX_DMA 1024
0048 #define C4IW_INLINE_THRESHOLD 128
0049
0050 static int inline_threshold = C4IW_INLINE_THRESHOLD;
0051 module_param(inline_threshold, int, 0644);
0052 MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)");
0053
0054 static int mr_exceeds_hw_limits(struct c4iw_dev *dev, u64 length)
0055 {
0056 return (is_t4(dev->rdev.lldi.adapter_type) ||
0057 is_t5(dev->rdev.lldi.adapter_type)) &&
0058 length >= 8*1024*1024*1024ULL;
0059 }
0060
0061 static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
0062 u32 len, dma_addr_t data,
0063 struct sk_buff *skb,
0064 struct c4iw_wr_wait *wr_waitp)
0065 {
0066 struct ulp_mem_io *req;
0067 struct ulptx_sgl *sgl;
0068 u8 wr_len;
0069 int ret = 0;
0070
0071 addr &= 0x7FFFFFF;
0072
0073 if (wr_waitp)
0074 c4iw_init_wr_wait(wr_waitp);
0075 wr_len = roundup(sizeof(*req) + sizeof(*sgl), 16);
0076
0077 if (!skb) {
0078 skb = alloc_skb(wr_len, GFP_KERNEL | __GFP_NOFAIL);
0079 if (!skb)
0080 return -ENOMEM;
0081 }
0082 set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
0083
0084 req = __skb_put_zero(skb, wr_len);
0085 INIT_ULPTX_WR(req, wr_len, 0, 0);
0086 req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) |
0087 (wr_waitp ? FW_WR_COMPL_F : 0));
0088 req->wr.wr_lo = wr_waitp ? (__force __be64)(unsigned long)wr_waitp : 0L;
0089 req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16)));
0090 req->cmd = cpu_to_be32(ULPTX_CMD_V(ULP_TX_MEM_WRITE) |
0091 T5_ULP_MEMIO_ORDER_V(1) |
0092 T5_ULP_MEMIO_FID_V(rdev->lldi.rxq_ids[0]));
0093 req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V(len>>5));
0094 req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr), 16));
0095 req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(addr));
0096
0097 sgl = (struct ulptx_sgl *)(req + 1);
0098 sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_DSGL) |
0099 ULPTX_NSGE_V(1));
0100 sgl->len0 = cpu_to_be32(len);
0101 sgl->addr0 = cpu_to_be64(data);
0102
0103 if (wr_waitp)
0104 ret = c4iw_ref_send_wait(rdev, skb, wr_waitp, 0, 0, __func__);
0105 else
0106 ret = c4iw_ofld_send(rdev, skb);
0107 return ret;
0108 }
0109
0110 static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len,
0111 void *data, struct sk_buff *skb,
0112 struct c4iw_wr_wait *wr_waitp)
0113 {
0114 struct ulp_mem_io *req;
0115 struct ulptx_idata *sc;
0116 u8 wr_len, *to_dp, *from_dp;
0117 int copy_len, num_wqe, i, ret = 0;
0118 __be32 cmd = cpu_to_be32(ULPTX_CMD_V(ULP_TX_MEM_WRITE));
0119
0120 if (is_t4(rdev->lldi.adapter_type))
0121 cmd |= cpu_to_be32(ULP_MEMIO_ORDER_F);
0122 else
0123 cmd |= cpu_to_be32(T5_ULP_MEMIO_IMM_F);
0124
0125 addr &= 0x7FFFFFF;
0126 pr_debug("addr 0x%x len %u\n", addr, len);
0127 num_wqe = DIV_ROUND_UP(len, C4IW_MAX_INLINE_SIZE);
0128 c4iw_init_wr_wait(wr_waitp);
0129 for (i = 0; i < num_wqe; i++) {
0130
0131 copy_len = len > C4IW_MAX_INLINE_SIZE ? C4IW_MAX_INLINE_SIZE :
0132 len;
0133 wr_len = roundup(sizeof(*req) + sizeof(*sc) +
0134 roundup(copy_len, T4_ULPTX_MIN_IO),
0135 16);
0136
0137 if (!skb) {
0138 skb = alloc_skb(wr_len, GFP_KERNEL | __GFP_NOFAIL);
0139 if (!skb)
0140 return -ENOMEM;
0141 }
0142 set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
0143
0144 req = __skb_put_zero(skb, wr_len);
0145 INIT_ULPTX_WR(req, wr_len, 0, 0);
0146
0147 if (i == (num_wqe-1)) {
0148 req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) |
0149 FW_WR_COMPL_F);
0150 req->wr.wr_lo = (__force __be64)(unsigned long)wr_waitp;
0151 } else
0152 req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR));
0153 req->wr.wr_mid = cpu_to_be32(
0154 FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16)));
0155
0156 req->cmd = cmd;
0157 req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V(
0158 DIV_ROUND_UP(copy_len, T4_ULPTX_MIN_IO)));
0159 req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr),
0160 16));
0161 req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(addr + i * 3));
0162
0163 sc = (struct ulptx_idata *)(req + 1);
0164 sc->cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM));
0165 sc->len = cpu_to_be32(roundup(copy_len, T4_ULPTX_MIN_IO));
0166
0167 to_dp = (u8 *)(sc + 1);
0168 from_dp = (u8 *)data + i * C4IW_MAX_INLINE_SIZE;
0169 if (data)
0170 memcpy(to_dp, from_dp, copy_len);
0171 else
0172 memset(to_dp, 0, copy_len);
0173 if (copy_len % T4_ULPTX_MIN_IO)
0174 memset(to_dp + copy_len, 0, T4_ULPTX_MIN_IO -
0175 (copy_len % T4_ULPTX_MIN_IO));
0176 if (i == (num_wqe-1))
0177 ret = c4iw_ref_send_wait(rdev, skb, wr_waitp, 0, 0,
0178 __func__);
0179 else
0180 ret = c4iw_ofld_send(rdev, skb);
0181 if (ret)
0182 break;
0183 skb = NULL;
0184 len -= C4IW_MAX_INLINE_SIZE;
0185 }
0186
0187 return ret;
0188 }
0189
0190 static int _c4iw_write_mem_dma(struct c4iw_rdev *rdev, u32 addr, u32 len,
0191 void *data, struct sk_buff *skb,
0192 struct c4iw_wr_wait *wr_waitp)
0193 {
0194 u32 remain = len;
0195 u32 dmalen;
0196 int ret = 0;
0197 dma_addr_t daddr;
0198 dma_addr_t save;
0199
0200 daddr = dma_map_single(&rdev->lldi.pdev->dev, data, len, DMA_TO_DEVICE);
0201 if (dma_mapping_error(&rdev->lldi.pdev->dev, daddr))
0202 return -1;
0203 save = daddr;
0204
0205 while (remain > inline_threshold) {
0206 if (remain < T4_ULPTX_MAX_DMA) {
0207 if (remain & ~T4_ULPTX_MIN_IO)
0208 dmalen = remain & ~(T4_ULPTX_MIN_IO-1);
0209 else
0210 dmalen = remain;
0211 } else
0212 dmalen = T4_ULPTX_MAX_DMA;
0213 remain -= dmalen;
0214 ret = _c4iw_write_mem_dma_aligned(rdev, addr, dmalen, daddr,
0215 skb, remain ? NULL : wr_waitp);
0216 if (ret)
0217 goto out;
0218 addr += dmalen >> 5;
0219 data += dmalen;
0220 daddr += dmalen;
0221 }
0222 if (remain)
0223 ret = _c4iw_write_mem_inline(rdev, addr, remain, data, skb,
0224 wr_waitp);
0225 out:
0226 dma_unmap_single(&rdev->lldi.pdev->dev, save, len, DMA_TO_DEVICE);
0227 return ret;
0228 }
0229
0230
0231
0232
0233
0234 static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len,
0235 void *data, struct sk_buff *skb,
0236 struct c4iw_wr_wait *wr_waitp)
0237 {
0238 int ret;
0239
0240 if (!rdev->lldi.ulptx_memwrite_dsgl || !use_dsgl) {
0241 ret = _c4iw_write_mem_inline(rdev, addr, len, data, skb,
0242 wr_waitp);
0243 goto out;
0244 }
0245
0246 if (len <= inline_threshold) {
0247 ret = _c4iw_write_mem_inline(rdev, addr, len, data, skb,
0248 wr_waitp);
0249 goto out;
0250 }
0251
0252 ret = _c4iw_write_mem_dma(rdev, addr, len, data, skb, wr_waitp);
0253 if (ret) {
0254 pr_warn_ratelimited("%s: dma map failure (non fatal)\n",
0255 pci_name(rdev->lldi.pdev));
0256 ret = _c4iw_write_mem_inline(rdev, addr, len, data, skb,
0257 wr_waitp);
0258 }
0259 out:
0260 return ret;
0261
0262 }
0263
0264
0265
0266
0267
0268
0269
0270 static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
0271 u32 *stag, u8 stag_state, u32 pdid,
0272 enum fw_ri_stag_type type, enum fw_ri_mem_perms perm,
0273 int bind_enabled, u32 zbva, u64 to,
0274 u64 len, u8 page_size, u32 pbl_size, u32 pbl_addr,
0275 struct sk_buff *skb, struct c4iw_wr_wait *wr_waitp)
0276 {
0277 int err;
0278 struct fw_ri_tpte *tpt;
0279 u32 stag_idx;
0280 static atomic_t key;
0281
0282 if (c4iw_fatal_error(rdev))
0283 return -EIO;
0284
0285 tpt = kmalloc(sizeof(*tpt), GFP_KERNEL);
0286 if (!tpt)
0287 return -ENOMEM;
0288
0289 stag_state = stag_state > 0;
0290 stag_idx = (*stag) >> 8;
0291
0292 if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) {
0293 stag_idx = c4iw_get_resource(&rdev->resource.tpt_table);
0294 if (!stag_idx) {
0295 mutex_lock(&rdev->stats.lock);
0296 rdev->stats.stag.fail++;
0297 mutex_unlock(&rdev->stats.lock);
0298 kfree(tpt);
0299 return -ENOMEM;
0300 }
0301 mutex_lock(&rdev->stats.lock);
0302 rdev->stats.stag.cur += 32;
0303 if (rdev->stats.stag.cur > rdev->stats.stag.max)
0304 rdev->stats.stag.max = rdev->stats.stag.cur;
0305 mutex_unlock(&rdev->stats.lock);
0306 *stag = (stag_idx << 8) | (atomic_inc_return(&key) & 0xff);
0307 }
0308 pr_debug("stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n",
0309 stag_state, type, pdid, stag_idx);
0310
0311
0312 if (reset_tpt_entry)
0313 memset(tpt, 0, sizeof(*tpt));
0314 else {
0315 tpt->valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
0316 FW_RI_TPTE_STAGKEY_V((*stag & FW_RI_TPTE_STAGKEY_M)) |
0317 FW_RI_TPTE_STAGSTATE_V(stag_state) |
0318 FW_RI_TPTE_STAGTYPE_V(type) | FW_RI_TPTE_PDID_V(pdid));
0319 tpt->locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
0320 (bind_enabled ? FW_RI_TPTE_MWBINDEN_F : 0) |
0321 FW_RI_TPTE_ADDRTYPE_V((zbva ? FW_RI_ZERO_BASED_TO :
0322 FW_RI_VA_BASED_TO))|
0323 FW_RI_TPTE_PS_V(page_size));
0324 tpt->nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
0325 FW_RI_TPTE_PBLADDR_V(PBL_OFF(rdev, pbl_addr)>>3));
0326 tpt->len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
0327 tpt->va_hi = cpu_to_be32((u32)(to >> 32));
0328 tpt->va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
0329 tpt->dca_mwbcnt_pstag = cpu_to_be32(0);
0330 tpt->len_hi = cpu_to_be32((u32)(len >> 32));
0331 }
0332 err = write_adapter_mem(rdev, stag_idx +
0333 (rdev->lldi.vr->stag.start >> 5),
0334 sizeof(*tpt), tpt, skb, wr_waitp);
0335
0336 if (reset_tpt_entry) {
0337 c4iw_put_resource(&rdev->resource.tpt_table, stag_idx);
0338 mutex_lock(&rdev->stats.lock);
0339 rdev->stats.stag.cur -= 32;
0340 mutex_unlock(&rdev->stats.lock);
0341 }
0342 kfree(tpt);
0343 return err;
0344 }
0345
0346 static int write_pbl(struct c4iw_rdev *rdev, __be64 *pbl,
0347 u32 pbl_addr, u32 pbl_size, struct c4iw_wr_wait *wr_waitp)
0348 {
0349 int err;
0350
0351 pr_debug("*pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n",
0352 pbl_addr, rdev->lldi.vr->pbl.start,
0353 pbl_size);
0354
0355 err = write_adapter_mem(rdev, pbl_addr >> 5, pbl_size << 3, pbl, NULL,
0356 wr_waitp);
0357 return err;
0358 }
0359
0360 static int dereg_mem(struct c4iw_rdev *rdev, u32 stag, u32 pbl_size,
0361 u32 pbl_addr, struct sk_buff *skb,
0362 struct c4iw_wr_wait *wr_waitp)
0363 {
0364 return write_tpt_entry(rdev, 1, &stag, 0, 0, 0, 0, 0, 0, 0UL, 0, 0,
0365 pbl_size, pbl_addr, skb, wr_waitp);
0366 }
0367
0368 static int allocate_stag(struct c4iw_rdev *rdev, u32 *stag, u32 pdid,
0369 u32 pbl_size, u32 pbl_addr,
0370 struct c4iw_wr_wait *wr_waitp)
0371 {
0372 *stag = T4_STAG_UNSET;
0373 return write_tpt_entry(rdev, 0, stag, 0, pdid, FW_RI_STAG_NSMR, 0, 0, 0,
0374 0UL, 0, 0, pbl_size, pbl_addr, NULL, wr_waitp);
0375 }
0376
0377 static int finish_mem_reg(struct c4iw_mr *mhp, u32 stag)
0378 {
0379 u32 mmid;
0380
0381 mhp->attr.state = 1;
0382 mhp->attr.stag = stag;
0383 mmid = stag >> 8;
0384 mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
0385 mhp->ibmr.length = mhp->attr.len;
0386 mhp->ibmr.page_size = 1U << (mhp->attr.page_size + 12);
0387 pr_debug("mmid 0x%x mhp %p\n", mmid, mhp);
0388 return xa_insert_irq(&mhp->rhp->mrs, mmid, mhp, GFP_KERNEL);
0389 }
0390
0391 static int register_mem(struct c4iw_dev *rhp, struct c4iw_pd *php,
0392 struct c4iw_mr *mhp, int shift)
0393 {
0394 u32 stag = T4_STAG_UNSET;
0395 int ret;
0396
0397 ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid,
0398 FW_RI_STAG_NSMR, mhp->attr.len ?
0399 mhp->attr.perms : 0,
0400 mhp->attr.mw_bind_enable, mhp->attr.zbva,
0401 mhp->attr.va_fbo, mhp->attr.len ?
0402 mhp->attr.len : -1, shift - 12,
0403 mhp->attr.pbl_size, mhp->attr.pbl_addr, NULL,
0404 mhp->wr_waitp);
0405 if (ret)
0406 return ret;
0407
0408 ret = finish_mem_reg(mhp, stag);
0409 if (ret) {
0410 dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
0411 mhp->attr.pbl_addr, mhp->dereg_skb, mhp->wr_waitp);
0412 mhp->dereg_skb = NULL;
0413 }
0414 return ret;
0415 }
0416
0417 static int alloc_pbl(struct c4iw_mr *mhp, int npages)
0418 {
0419 mhp->attr.pbl_addr = c4iw_pblpool_alloc(&mhp->rhp->rdev,
0420 npages << 3);
0421
0422 if (!mhp->attr.pbl_addr)
0423 return -ENOMEM;
0424
0425 mhp->attr.pbl_size = npages;
0426
0427 return 0;
0428 }
0429
0430 struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc)
0431 {
0432 struct c4iw_dev *rhp;
0433 struct c4iw_pd *php;
0434 struct c4iw_mr *mhp;
0435 int ret;
0436 u32 stag = T4_STAG_UNSET;
0437
0438 pr_debug("ib_pd %p\n", pd);
0439 php = to_c4iw_pd(pd);
0440 rhp = php->rhp;
0441
0442 mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
0443 if (!mhp)
0444 return ERR_PTR(-ENOMEM);
0445 mhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL);
0446 if (!mhp->wr_waitp) {
0447 ret = -ENOMEM;
0448 goto err_free_mhp;
0449 }
0450 c4iw_init_wr_wait(mhp->wr_waitp);
0451
0452 mhp->dereg_skb = alloc_skb(SGE_MAX_WR_LEN, GFP_KERNEL);
0453 if (!mhp->dereg_skb) {
0454 ret = -ENOMEM;
0455 goto err_free_wr_wait;
0456 }
0457
0458 mhp->rhp = rhp;
0459 mhp->attr.pdid = php->pdid;
0460 mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
0461 mhp->attr.mw_bind_enable = (acc&IB_ACCESS_MW_BIND) == IB_ACCESS_MW_BIND;
0462 mhp->attr.zbva = 0;
0463 mhp->attr.va_fbo = 0;
0464 mhp->attr.page_size = 0;
0465 mhp->attr.len = ~0ULL;
0466 mhp->attr.pbl_size = 0;
0467
0468 ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, php->pdid,
0469 FW_RI_STAG_NSMR, mhp->attr.perms,
0470 mhp->attr.mw_bind_enable, 0, 0, ~0ULL, 0, 0, 0,
0471 NULL, mhp->wr_waitp);
0472 if (ret)
0473 goto err_free_skb;
0474
0475 ret = finish_mem_reg(mhp, stag);
0476 if (ret)
0477 goto err_dereg_mem;
0478 return &mhp->ibmr;
0479 err_dereg_mem:
0480 dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
0481 mhp->attr.pbl_addr, mhp->dereg_skb, mhp->wr_waitp);
0482 err_free_skb:
0483 kfree_skb(mhp->dereg_skb);
0484 err_free_wr_wait:
0485 c4iw_put_wr_wait(mhp->wr_waitp);
0486 err_free_mhp:
0487 kfree(mhp);
0488 return ERR_PTR(ret);
0489 }
0490
0491 struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
0492 u64 virt, int acc, struct ib_udata *udata)
0493 {
0494 __be64 *pages;
0495 int shift, n, i;
0496 int err = -ENOMEM;
0497 struct ib_block_iter biter;
0498 struct c4iw_dev *rhp;
0499 struct c4iw_pd *php;
0500 struct c4iw_mr *mhp;
0501
0502 pr_debug("ib_pd %p\n", pd);
0503
0504 if (length == ~0ULL)
0505 return ERR_PTR(-EINVAL);
0506
0507 if ((length + start) < start)
0508 return ERR_PTR(-EINVAL);
0509
0510 php = to_c4iw_pd(pd);
0511 rhp = php->rhp;
0512
0513 if (mr_exceeds_hw_limits(rhp, length))
0514 return ERR_PTR(-EINVAL);
0515
0516 mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
0517 if (!mhp)
0518 return ERR_PTR(-ENOMEM);
0519 mhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL);
0520 if (!mhp->wr_waitp)
0521 goto err_free_mhp;
0522
0523 mhp->dereg_skb = alloc_skb(SGE_MAX_WR_LEN, GFP_KERNEL);
0524 if (!mhp->dereg_skb)
0525 goto err_free_wr_wait;
0526
0527 mhp->rhp = rhp;
0528
0529 mhp->umem = ib_umem_get(pd->device, start, length, acc);
0530 if (IS_ERR(mhp->umem))
0531 goto err_free_skb;
0532
0533 shift = PAGE_SHIFT;
0534
0535 n = ib_umem_num_dma_blocks(mhp->umem, 1 << shift);
0536 err = alloc_pbl(mhp, n);
0537 if (err)
0538 goto err_umem_release;
0539
0540 pages = (__be64 *) __get_free_page(GFP_KERNEL);
0541 if (!pages) {
0542 err = -ENOMEM;
0543 goto err_pbl_free;
0544 }
0545
0546 i = n = 0;
0547
0548 rdma_umem_for_each_dma_block(mhp->umem, &biter, 1 << shift) {
0549 pages[i++] = cpu_to_be64(rdma_block_iter_dma_address(&biter));
0550 if (i == PAGE_SIZE / sizeof(*pages)) {
0551 err = write_pbl(&mhp->rhp->rdev, pages,
0552 mhp->attr.pbl_addr + (n << 3), i,
0553 mhp->wr_waitp);
0554 if (err)
0555 goto pbl_done;
0556 n += i;
0557 i = 0;
0558 }
0559 }
0560
0561 if (i)
0562 err = write_pbl(&mhp->rhp->rdev, pages,
0563 mhp->attr.pbl_addr + (n << 3), i,
0564 mhp->wr_waitp);
0565
0566 pbl_done:
0567 free_page((unsigned long) pages);
0568 if (err)
0569 goto err_pbl_free;
0570
0571 mhp->attr.pdid = php->pdid;
0572 mhp->attr.zbva = 0;
0573 mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
0574 mhp->attr.va_fbo = virt;
0575 mhp->attr.page_size = shift - 12;
0576 mhp->attr.len = length;
0577
0578 err = register_mem(rhp, php, mhp, shift);
0579 if (err)
0580 goto err_pbl_free;
0581
0582 return &mhp->ibmr;
0583
0584 err_pbl_free:
0585 c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
0586 mhp->attr.pbl_size << 3);
0587 err_umem_release:
0588 ib_umem_release(mhp->umem);
0589 err_free_skb:
0590 kfree_skb(mhp->dereg_skb);
0591 err_free_wr_wait:
0592 c4iw_put_wr_wait(mhp->wr_waitp);
0593 err_free_mhp:
0594 kfree(mhp);
0595 return ERR_PTR(err);
0596 }
0597
0598 struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
0599 u32 max_num_sg)
0600 {
0601 struct c4iw_dev *rhp;
0602 struct c4iw_pd *php;
0603 struct c4iw_mr *mhp;
0604 u32 mmid;
0605 u32 stag = 0;
0606 int ret = 0;
0607 int length = roundup(max_num_sg * sizeof(u64), 32);
0608
0609 php = to_c4iw_pd(pd);
0610 rhp = php->rhp;
0611
0612 if (mr_type != IB_MR_TYPE_MEM_REG ||
0613 max_num_sg > t4_max_fr_depth(rhp->rdev.lldi.ulptx_memwrite_dsgl &&
0614 use_dsgl))
0615 return ERR_PTR(-EINVAL);
0616
0617 mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
0618 if (!mhp) {
0619 ret = -ENOMEM;
0620 goto err;
0621 }
0622
0623 mhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL);
0624 if (!mhp->wr_waitp) {
0625 ret = -ENOMEM;
0626 goto err_free_mhp;
0627 }
0628 c4iw_init_wr_wait(mhp->wr_waitp);
0629
0630 mhp->mpl = dma_alloc_coherent(&rhp->rdev.lldi.pdev->dev,
0631 length, &mhp->mpl_addr, GFP_KERNEL);
0632 if (!mhp->mpl) {
0633 ret = -ENOMEM;
0634 goto err_free_wr_wait;
0635 }
0636 mhp->max_mpl_len = length;
0637
0638 mhp->rhp = rhp;
0639 ret = alloc_pbl(mhp, max_num_sg);
0640 if (ret)
0641 goto err_free_dma;
0642 mhp->attr.pbl_size = max_num_sg;
0643 ret = allocate_stag(&rhp->rdev, &stag, php->pdid,
0644 mhp->attr.pbl_size, mhp->attr.pbl_addr,
0645 mhp->wr_waitp);
0646 if (ret)
0647 goto err_free_pbl;
0648 mhp->attr.pdid = php->pdid;
0649 mhp->attr.type = FW_RI_STAG_NSMR;
0650 mhp->attr.stag = stag;
0651 mhp->attr.state = 0;
0652 mmid = (stag) >> 8;
0653 mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
0654 if (xa_insert_irq(&rhp->mrs, mmid, mhp, GFP_KERNEL)) {
0655 ret = -ENOMEM;
0656 goto err_dereg;
0657 }
0658
0659 pr_debug("mmid 0x%x mhp %p stag 0x%x\n", mmid, mhp, stag);
0660 return &(mhp->ibmr);
0661 err_dereg:
0662 dereg_mem(&rhp->rdev, stag, mhp->attr.pbl_size,
0663 mhp->attr.pbl_addr, mhp->dereg_skb, mhp->wr_waitp);
0664 err_free_pbl:
0665 c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
0666 mhp->attr.pbl_size << 3);
0667 err_free_dma:
0668 dma_free_coherent(&mhp->rhp->rdev.lldi.pdev->dev,
0669 mhp->max_mpl_len, mhp->mpl, mhp->mpl_addr);
0670 err_free_wr_wait:
0671 c4iw_put_wr_wait(mhp->wr_waitp);
0672 err_free_mhp:
0673 kfree(mhp);
0674 err:
0675 return ERR_PTR(ret);
0676 }
0677
0678 static int c4iw_set_page(struct ib_mr *ibmr, u64 addr)
0679 {
0680 struct c4iw_mr *mhp = to_c4iw_mr(ibmr);
0681
0682 if (unlikely(mhp->mpl_len == mhp->attr.pbl_size))
0683 return -ENOMEM;
0684
0685 mhp->mpl[mhp->mpl_len++] = addr;
0686
0687 return 0;
0688 }
0689
0690 int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
0691 unsigned int *sg_offset)
0692 {
0693 struct c4iw_mr *mhp = to_c4iw_mr(ibmr);
0694
0695 mhp->mpl_len = 0;
0696
0697 return ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, c4iw_set_page);
0698 }
0699
0700 int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata)
0701 {
0702 struct c4iw_dev *rhp;
0703 struct c4iw_mr *mhp;
0704 u32 mmid;
0705
0706 pr_debug("ib_mr %p\n", ib_mr);
0707
0708 mhp = to_c4iw_mr(ib_mr);
0709 rhp = mhp->rhp;
0710 mmid = mhp->attr.stag >> 8;
0711 xa_erase_irq(&rhp->mrs, mmid);
0712 if (mhp->mpl)
0713 dma_free_coherent(&mhp->rhp->rdev.lldi.pdev->dev,
0714 mhp->max_mpl_len, mhp->mpl, mhp->mpl_addr);
0715 dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
0716 mhp->attr.pbl_addr, mhp->dereg_skb, mhp->wr_waitp);
0717 if (mhp->attr.pbl_size)
0718 c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
0719 mhp->attr.pbl_size << 3);
0720 if (mhp->kva)
0721 kfree((void *) (unsigned long) mhp->kva);
0722 ib_umem_release(mhp->umem);
0723 pr_debug("mmid 0x%x ptr %p\n", mmid, mhp);
0724 c4iw_put_wr_wait(mhp->wr_waitp);
0725 kfree(mhp);
0726 return 0;
0727 }
0728
0729 void c4iw_invalidate_mr(struct c4iw_dev *rhp, u32 rkey)
0730 {
0731 struct c4iw_mr *mhp;
0732 unsigned long flags;
0733
0734 xa_lock_irqsave(&rhp->mrs, flags);
0735 mhp = xa_load(&rhp->mrs, rkey >> 8);
0736 if (mhp)
0737 mhp->attr.state = 0;
0738 xa_unlock_irqrestore(&rhp->mrs, flags);
0739 }