aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4/mr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/mr.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c186
1 files changed, 141 insertions, 45 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index c202d3ad2a0e..602ca9bf78e4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -44,20 +44,6 @@
44#include "mlx4.h" 44#include "mlx4.h"
45#include "icm.h" 45#include "icm.h"
46 46
47#define MLX4_MPT_FLAG_SW_OWNS (0xfUL << 28)
48#define MLX4_MPT_FLAG_FREE (0x3UL << 28)
49#define MLX4_MPT_FLAG_MIO (1 << 17)
50#define MLX4_MPT_FLAG_BIND_ENABLE (1 << 15)
51#define MLX4_MPT_FLAG_PHYSICAL (1 << 9)
52#define MLX4_MPT_FLAG_REGION (1 << 8)
53
54#define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27)
55#define MLX4_MPT_PD_FLAG_RAE (1 << 28)
56#define MLX4_MPT_PD_FLAG_EN_INV (3 << 24)
57
58#define MLX4_MPT_STATUS_SW 0xF0
59#define MLX4_MPT_STATUS_HW 0x00
60
61static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order) 47static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order)
62{ 48{
63 int o; 49 int o;
@@ -321,7 +307,7 @@ static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
321 mr->size = size; 307 mr->size = size;
322 mr->pd = pd; 308 mr->pd = pd;
323 mr->access = access; 309 mr->access = access;
324 mr->enabled = MLX4_MR_DISABLED; 310 mr->enabled = MLX4_MPT_DISABLED;
325 mr->key = hw_index_to_key(mridx); 311 mr->key = hw_index_to_key(mridx);
326 312
327 return mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); 313 return mlx4_mtt_init(dev, npages, page_shift, &mr->mtt);
@@ -335,14 +321,14 @@ static int mlx4_WRITE_MTT(struct mlx4_dev *dev,
335 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 321 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
336} 322}
337 323
338int __mlx4_mr_reserve(struct mlx4_dev *dev) 324int __mlx4_mpt_reserve(struct mlx4_dev *dev)
339{ 325{
340 struct mlx4_priv *priv = mlx4_priv(dev); 326 struct mlx4_priv *priv = mlx4_priv(dev);
341 327
342 return mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap); 328 return mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap);
343} 329}
344 330
345static int mlx4_mr_reserve(struct mlx4_dev *dev) 331static int mlx4_mpt_reserve(struct mlx4_dev *dev)
346{ 332{
347 u64 out_param; 333 u64 out_param;
348 334
@@ -353,17 +339,17 @@ static int mlx4_mr_reserve(struct mlx4_dev *dev)
353 return -1; 339 return -1;
354 return get_param_l(&out_param); 340 return get_param_l(&out_param);
355 } 341 }
356 return __mlx4_mr_reserve(dev); 342 return __mlx4_mpt_reserve(dev);
357} 343}
358 344
359void __mlx4_mr_release(struct mlx4_dev *dev, u32 index) 345void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
360{ 346{
361 struct mlx4_priv *priv = mlx4_priv(dev); 347 struct mlx4_priv *priv = mlx4_priv(dev);
362 348
363 mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index); 349 mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index);
364} 350}
365 351
366static void mlx4_mr_release(struct mlx4_dev *dev, u32 index) 352static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
367{ 353{
368 u64 in_param; 354 u64 in_param;
369 355
@@ -376,17 +362,17 @@ static void mlx4_mr_release(struct mlx4_dev *dev, u32 index)
376 index); 362 index);
377 return; 363 return;
378 } 364 }
379 __mlx4_mr_release(dev, index); 365 __mlx4_mpt_release(dev, index);
380} 366}
381 367
382int __mlx4_mr_alloc_icm(struct mlx4_dev *dev, u32 index) 368int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
383{ 369{
384 struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table; 370 struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;
385 371
386 return mlx4_table_get(dev, &mr_table->dmpt_table, index); 372 return mlx4_table_get(dev, &mr_table->dmpt_table, index);
387} 373}
388 374
389static int mlx4_mr_alloc_icm(struct mlx4_dev *dev, u32 index) 375static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
390{ 376{
391 u64 param; 377 u64 param;
392 378
@@ -397,17 +383,17 @@ static int mlx4_mr_alloc_icm(struct mlx4_dev *dev, u32 index)
397 MLX4_CMD_TIME_CLASS_A, 383 MLX4_CMD_TIME_CLASS_A,
398 MLX4_CMD_WRAPPED); 384 MLX4_CMD_WRAPPED);
399 } 385 }
400 return __mlx4_mr_alloc_icm(dev, index); 386 return __mlx4_mpt_alloc_icm(dev, index);
401} 387}
402 388
403void __mlx4_mr_free_icm(struct mlx4_dev *dev, u32 index) 389void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
404{ 390{
405 struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table; 391 struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;
406 392
407 mlx4_table_put(dev, &mr_table->dmpt_table, index); 393 mlx4_table_put(dev, &mr_table->dmpt_table, index);
408} 394}
409 395
410static void mlx4_mr_free_icm(struct mlx4_dev *dev, u32 index) 396static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
411{ 397{
412 u64 in_param; 398 u64 in_param;
413 399
@@ -420,7 +406,7 @@ static void mlx4_mr_free_icm(struct mlx4_dev *dev, u32 index)
420 index); 406 index);
421 return; 407 return;
422 } 408 }
423 return __mlx4_mr_free_icm(dev, index); 409 return __mlx4_mpt_free_icm(dev, index);
424} 410}
425 411
426int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, 412int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
@@ -429,41 +415,52 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
429 u32 index; 415 u32 index;
430 int err; 416 int err;
431 417
432 index = mlx4_mr_reserve(dev); 418 index = mlx4_mpt_reserve(dev);
433 if (index == -1) 419 if (index == -1)
434 return -ENOMEM; 420 return -ENOMEM;
435 421
436 err = mlx4_mr_alloc_reserved(dev, index, pd, iova, size, 422 err = mlx4_mr_alloc_reserved(dev, index, pd, iova, size,
437 access, npages, page_shift, mr); 423 access, npages, page_shift, mr);
438 if (err) 424 if (err)
439 mlx4_mr_release(dev, index); 425 mlx4_mpt_release(dev, index);
440 426
441 return err; 427 return err;
442} 428}
443EXPORT_SYMBOL_GPL(mlx4_mr_alloc); 429EXPORT_SYMBOL_GPL(mlx4_mr_alloc);
444 430
445static void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr) 431static int mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
446{ 432{
447 int err; 433 int err;
448 434
449 if (mr->enabled == MLX4_MR_EN_HW) { 435 if (mr->enabled == MLX4_MPT_EN_HW) {
450 err = mlx4_HW2SW_MPT(dev, NULL, 436 err = mlx4_HW2SW_MPT(dev, NULL,
451 key_to_hw_index(mr->key) & 437 key_to_hw_index(mr->key) &
452 (dev->caps.num_mpts - 1)); 438 (dev->caps.num_mpts - 1));
453 if (err) 439 if (err) {
454 mlx4_warn(dev, "xxx HW2SW_MPT failed (%d)\n", err); 440 mlx4_warn(dev, "HW2SW_MPT failed (%d),", err);
441 mlx4_warn(dev, "MR has MWs bound to it.\n");
442 return err;
443 }
455 444
456 mr->enabled = MLX4_MR_EN_SW; 445 mr->enabled = MLX4_MPT_EN_SW;
457 } 446 }
458 mlx4_mtt_cleanup(dev, &mr->mtt); 447 mlx4_mtt_cleanup(dev, &mr->mtt);
448
449 return 0;
459} 450}
460 451
461void mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr) 452int mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr)
462{ 453{
463 mlx4_mr_free_reserved(dev, mr); 454 int ret;
455
456 ret = mlx4_mr_free_reserved(dev, mr);
457 if (ret)
458 return ret;
464 if (mr->enabled) 459 if (mr->enabled)
465 mlx4_mr_free_icm(dev, key_to_hw_index(mr->key)); 460 mlx4_mpt_free_icm(dev, key_to_hw_index(mr->key));
466 mlx4_mr_release(dev, key_to_hw_index(mr->key)); 461 mlx4_mpt_release(dev, key_to_hw_index(mr->key));
462
463 return 0;
467} 464}
468EXPORT_SYMBOL_GPL(mlx4_mr_free); 465EXPORT_SYMBOL_GPL(mlx4_mr_free);
469 466
@@ -473,7 +470,7 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
473 struct mlx4_mpt_entry *mpt_entry; 470 struct mlx4_mpt_entry *mpt_entry;
474 int err; 471 int err;
475 472
476 err = mlx4_mr_alloc_icm(dev, key_to_hw_index(mr->key)); 473 err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mr->key));
477 if (err) 474 if (err)
478 return err; 475 return err;
479 476
@@ -520,7 +517,7 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
520 mlx4_warn(dev, "SW2HW_MPT failed (%d)\n", err); 517 mlx4_warn(dev, "SW2HW_MPT failed (%d)\n", err);
521 goto err_cmd; 518 goto err_cmd;
522 } 519 }
523 mr->enabled = MLX4_MR_EN_HW; 520 mr->enabled = MLX4_MPT_EN_HW;
524 521
525 mlx4_free_cmd_mailbox(dev, mailbox); 522 mlx4_free_cmd_mailbox(dev, mailbox);
526 523
@@ -530,7 +527,7 @@ err_cmd:
530 mlx4_free_cmd_mailbox(dev, mailbox); 527 mlx4_free_cmd_mailbox(dev, mailbox);
531 528
532err_table: 529err_table:
533 mlx4_mr_free_icm(dev, key_to_hw_index(mr->key)); 530 mlx4_mpt_free_icm(dev, key_to_hw_index(mr->key));
534 return err; 531 return err;
535} 532}
536EXPORT_SYMBOL_GPL(mlx4_mr_enable); 533EXPORT_SYMBOL_GPL(mlx4_mr_enable);
@@ -657,6 +654,101 @@ int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
657} 654}
658EXPORT_SYMBOL_GPL(mlx4_buf_write_mtt); 655EXPORT_SYMBOL_GPL(mlx4_buf_write_mtt);
659 656
657int mlx4_mw_alloc(struct mlx4_dev *dev, u32 pd, enum mlx4_mw_type type,
658 struct mlx4_mw *mw)
659{
660 u32 index;
661
662 if ((type == MLX4_MW_TYPE_1 &&
663 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW)) ||
664 (type == MLX4_MW_TYPE_2 &&
665 !(dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN)))
666 return -ENOTSUPP;
667
668 index = mlx4_mpt_reserve(dev);
669 if (index == -1)
670 return -ENOMEM;
671
672 mw->key = hw_index_to_key(index);
673 mw->pd = pd;
674 mw->type = type;
675 mw->enabled = MLX4_MPT_DISABLED;
676
677 return 0;
678}
679EXPORT_SYMBOL_GPL(mlx4_mw_alloc);
680
681int mlx4_mw_enable(struct mlx4_dev *dev, struct mlx4_mw *mw)
682{
683 struct mlx4_cmd_mailbox *mailbox;
684 struct mlx4_mpt_entry *mpt_entry;
685 int err;
686
687 err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mw->key));
688 if (err)
689 return err;
690
691 mailbox = mlx4_alloc_cmd_mailbox(dev);
692 if (IS_ERR(mailbox)) {
693 err = PTR_ERR(mailbox);
694 goto err_table;
695 }
696 mpt_entry = mailbox->buf;
697
698 memset(mpt_entry, 0, sizeof(*mpt_entry));
699
700 /* Note that the MLX4_MPT_FLAG_REGION bit in mpt_entry->flags is turned
701 * off, thus creating a memory window and not a memory region.
702 */
703 mpt_entry->key = cpu_to_be32(key_to_hw_index(mw->key));
704 mpt_entry->pd_flags = cpu_to_be32(mw->pd);
705 if (mw->type == MLX4_MW_TYPE_2) {
706 mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_FREE);
707 mpt_entry->qpn = cpu_to_be32(MLX4_MPT_QP_FLAG_BOUND_QP);
708 mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_EN_INV);
709 }
710
711 err = mlx4_SW2HW_MPT(dev, mailbox,
712 key_to_hw_index(mw->key) &
713 (dev->caps.num_mpts - 1));
714 if (err) {
715 mlx4_warn(dev, "SW2HW_MPT failed (%d)\n", err);
716 goto err_cmd;
717 }
718 mw->enabled = MLX4_MPT_EN_HW;
719
720 mlx4_free_cmd_mailbox(dev, mailbox);
721
722 return 0;
723
724err_cmd:
725 mlx4_free_cmd_mailbox(dev, mailbox);
726
727err_table:
728 mlx4_mpt_free_icm(dev, key_to_hw_index(mw->key));
729 return err;
730}
731EXPORT_SYMBOL_GPL(mlx4_mw_enable);
732
733void mlx4_mw_free(struct mlx4_dev *dev, struct mlx4_mw *mw)
734{
735 int err;
736
737 if (mw->enabled == MLX4_MPT_EN_HW) {
738 err = mlx4_HW2SW_MPT(dev, NULL,
739 key_to_hw_index(mw->key) &
740 (dev->caps.num_mpts - 1));
741 if (err)
742 mlx4_warn(dev, "xxx HW2SW_MPT failed (%d)\n", err);
743
744 mw->enabled = MLX4_MPT_EN_SW;
745 }
746 if (mw->enabled)
747 mlx4_mpt_free_icm(dev, key_to_hw_index(mw->key));
748 mlx4_mpt_release(dev, key_to_hw_index(mw->key));
749}
750EXPORT_SYMBOL_GPL(mlx4_mw_free);
751
660int mlx4_init_mr_table(struct mlx4_dev *dev) 752int mlx4_init_mr_table(struct mlx4_dev *dev)
661{ 753{
662 struct mlx4_priv *priv = mlx4_priv(dev); 754 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -831,7 +923,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
831 return 0; 923 return 0;
832 924
833err_free: 925err_free:
834 mlx4_mr_free(dev, &fmr->mr); 926 (void) mlx4_mr_free(dev, &fmr->mr);
835 return err; 927 return err;
836} 928}
837EXPORT_SYMBOL_GPL(mlx4_fmr_alloc); 929EXPORT_SYMBOL_GPL(mlx4_fmr_alloc);
@@ -882,17 +974,21 @@ void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr,
882 err); 974 err);
883 return; 975 return;
884 } 976 }
885 fmr->mr.enabled = MLX4_MR_EN_SW; 977 fmr->mr.enabled = MLX4_MPT_EN_SW;
886} 978}
887EXPORT_SYMBOL_GPL(mlx4_fmr_unmap); 979EXPORT_SYMBOL_GPL(mlx4_fmr_unmap);
888 980
889int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr) 981int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
890{ 982{
983 int ret;
984
891 if (fmr->maps) 985 if (fmr->maps)
892 return -EBUSY; 986 return -EBUSY;
893 987
894 mlx4_mr_free(dev, &fmr->mr); 988 ret = mlx4_mr_free(dev, &fmr->mr);
895 fmr->mr.enabled = MLX4_MR_DISABLED; 989 if (ret)
990 return ret;
991 fmr->mr.enabled = MLX4_MPT_DISABLED;
896 992
897 return 0; 993 return 0;
898} 994}