aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4/mr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mlx4/mr.c')
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c87
1 files changed, 82 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index bbaf6176f207..e471f089ff00 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -41,9 +41,19 @@ static u32 convert_access(int acc)
41 (acc & IB_ACCESS_REMOTE_WRITE ? MLX4_PERM_REMOTE_WRITE : 0) | 41 (acc & IB_ACCESS_REMOTE_WRITE ? MLX4_PERM_REMOTE_WRITE : 0) |
42 (acc & IB_ACCESS_REMOTE_READ ? MLX4_PERM_REMOTE_READ : 0) | 42 (acc & IB_ACCESS_REMOTE_READ ? MLX4_PERM_REMOTE_READ : 0) |
43 (acc & IB_ACCESS_LOCAL_WRITE ? MLX4_PERM_LOCAL_WRITE : 0) | 43 (acc & IB_ACCESS_LOCAL_WRITE ? MLX4_PERM_LOCAL_WRITE : 0) |
44 (acc & IB_ACCESS_MW_BIND ? MLX4_PERM_BIND_MW : 0) |
44 MLX4_PERM_LOCAL_READ; 45 MLX4_PERM_LOCAL_READ;
45} 46}
46 47
48static enum mlx4_mw_type to_mlx4_type(enum ib_mw_type type)
49{
50 switch (type) {
51 case IB_MW_TYPE_1: return MLX4_MW_TYPE_1;
52 case IB_MW_TYPE_2: return MLX4_MW_TYPE_2;
53 default: return -1;
54 }
55}
56
47struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc) 57struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc)
48{ 58{
49 struct mlx4_ib_mr *mr; 59 struct mlx4_ib_mr *mr;
@@ -68,7 +78,7 @@ struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc)
68 return &mr->ibmr; 78 return &mr->ibmr;
69 79
70err_mr: 80err_mr:
71 mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); 81 (void) mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr);
72 82
73err_free: 83err_free:
74 kfree(mr); 84 kfree(mr);
@@ -163,7 +173,7 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
163 return &mr->ibmr; 173 return &mr->ibmr;
164 174
165err_mr: 175err_mr:
166 mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); 176 (void) mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr);
167 177
168err_umem: 178err_umem:
169 ib_umem_release(mr->umem); 179 ib_umem_release(mr->umem);
@@ -177,8 +187,11 @@ err_free:
177int mlx4_ib_dereg_mr(struct ib_mr *ibmr) 187int mlx4_ib_dereg_mr(struct ib_mr *ibmr)
178{ 188{
179 struct mlx4_ib_mr *mr = to_mmr(ibmr); 189 struct mlx4_ib_mr *mr = to_mmr(ibmr);
190 int ret;
180 191
181 mlx4_mr_free(to_mdev(ibmr->device)->dev, &mr->mmr); 192 ret = mlx4_mr_free(to_mdev(ibmr->device)->dev, &mr->mmr);
193 if (ret)
194 return ret;
182 if (mr->umem) 195 if (mr->umem)
183 ib_umem_release(mr->umem); 196 ib_umem_release(mr->umem);
184 kfree(mr); 197 kfree(mr);
@@ -186,6 +199,70 @@ int mlx4_ib_dereg_mr(struct ib_mr *ibmr)
186 return 0; 199 return 0;
187} 200}
188 201
202struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type)
203{
204 struct mlx4_ib_dev *dev = to_mdev(pd->device);
205 struct mlx4_ib_mw *mw;
206 int err;
207
208 mw = kmalloc(sizeof(*mw), GFP_KERNEL);
209 if (!mw)
210 return ERR_PTR(-ENOMEM);
211
212 err = mlx4_mw_alloc(dev->dev, to_mpd(pd)->pdn,
213 to_mlx4_type(type), &mw->mmw);
214 if (err)
215 goto err_free;
216
217 err = mlx4_mw_enable(dev->dev, &mw->mmw);
218 if (err)
219 goto err_mw;
220
221 mw->ibmw.rkey = mw->mmw.key;
222
223 return &mw->ibmw;
224
225err_mw:
226 mlx4_mw_free(dev->dev, &mw->mmw);
227
228err_free:
229 kfree(mw);
230
231 return ERR_PTR(err);
232}
233
234int mlx4_ib_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
235 struct ib_mw_bind *mw_bind)
236{
237 struct ib_send_wr wr;
238 struct ib_send_wr *bad_wr;
239 int ret;
240
241 memset(&wr, 0, sizeof(wr));
242 wr.opcode = IB_WR_BIND_MW;
243 wr.wr_id = mw_bind->wr_id;
244 wr.send_flags = mw_bind->send_flags;
245 wr.wr.bind_mw.mw = mw;
246 wr.wr.bind_mw.bind_info = mw_bind->bind_info;
247 wr.wr.bind_mw.rkey = ib_inc_rkey(mw->rkey);
248
249 ret = mlx4_ib_post_send(qp, &wr, &bad_wr);
250 if (!ret)
251 mw->rkey = wr.wr.bind_mw.rkey;
252
253 return ret;
254}
255
256int mlx4_ib_dealloc_mw(struct ib_mw *ibmw)
257{
258 struct mlx4_ib_mw *mw = to_mmw(ibmw);
259
260 mlx4_mw_free(to_mdev(ibmw->device)->dev, &mw->mmw);
261 kfree(mw);
262
263 return 0;
264}
265
189struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, 266struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd,
190 int max_page_list_len) 267 int max_page_list_len)
191{ 268{
@@ -212,7 +289,7 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd,
212 return &mr->ibmr; 289 return &mr->ibmr;
213 290
214err_mr: 291err_mr:
215 mlx4_mr_free(dev->dev, &mr->mmr); 292 (void) mlx4_mr_free(dev->dev, &mr->mmr);
216 293
217err_free: 294err_free:
218 kfree(mr); 295 kfree(mr);
@@ -291,7 +368,7 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc,
291 return &fmr->ibfmr; 368 return &fmr->ibfmr;
292 369
293err_mr: 370err_mr:
294 mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr); 371 (void) mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr);
295 372
296err_free: 373err_free:
297 kfree(fmr); 374 kfree(fmr);