diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 126 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mr.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 68 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/profile.c | 19 |
6 files changed, 201 insertions, 56 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 9129ace02560..3b6f8efbf141 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -79,7 +79,8 @@ enum { | |||
79 | (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT) | \ | 79 | (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT) | \ |
80 | (1ull << MLX4_EVENT_TYPE_CMD) | \ | 80 | (1ull << MLX4_EVENT_TYPE_CMD) | \ |
81 | (1ull << MLX4_EVENT_TYPE_COMM_CHANNEL) | \ | 81 | (1ull << MLX4_EVENT_TYPE_COMM_CHANNEL) | \ |
82 | (1ull << MLX4_EVENT_TYPE_FLR_EVENT)) | 82 | (1ull << MLX4_EVENT_TYPE_FLR_EVENT) | \ |
83 | (1ull << MLX4_EVENT_TYPE_FATAL_WARNING)) | ||
83 | 84 | ||
84 | static void eq_set_ci(struct mlx4_eq *eq, int req_not) | 85 | static void eq_set_ci(struct mlx4_eq *eq, int req_not) |
85 | { | 86 | { |
@@ -443,6 +444,35 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
443 | queue_work(priv->mfunc.master.comm_wq, | 444 | queue_work(priv->mfunc.master.comm_wq, |
444 | &priv->mfunc.master.slave_flr_event_work); | 445 | &priv->mfunc.master.slave_flr_event_work); |
445 | break; | 446 | break; |
447 | |||
448 | case MLX4_EVENT_TYPE_FATAL_WARNING: | ||
449 | if (eqe->subtype == MLX4_FATAL_WARNING_SUBTYPE_WARMING) { | ||
450 | if (mlx4_is_master(dev)) | ||
451 | for (i = 0; i < dev->num_slaves; i++) { | ||
452 | mlx4_dbg(dev, "%s: Sending " | ||
453 | "MLX4_FATAL_WARNING_SUBTYPE_WARMING" | ||
454 | " to slave: %d\n", __func__, i); | ||
455 | if (i == dev->caps.function) | ||
456 | continue; | ||
457 | mlx4_slave_event(dev, i, eqe); | ||
458 | } | ||
459 | mlx4_err(dev, "Temperature Threshold was reached! " | ||
460 | "Threshold: %d celsius degrees; " | ||
461 | "Current Temperature: %d\n", | ||
462 | be16_to_cpu(eqe->event.warming.warning_threshold), | ||
463 | be16_to_cpu(eqe->event.warming.current_temperature)); | ||
464 | } else | ||
465 | mlx4_warn(dev, "Unhandled event FATAL WARNING (%02x), " | ||
466 | "subtype %02x on EQ %d at index %u. owner=%x, " | ||
467 | "nent=0x%x, slave=%x, ownership=%s\n", | ||
468 | eqe->type, eqe->subtype, eq->eqn, | ||
469 | eq->cons_index, eqe->owner, eq->nent, | ||
470 | eqe->slave_id, | ||
471 | !!(eqe->owner & 0x80) ^ | ||
472 | !!(eq->cons_index & eq->nent) ? "HW" : "SW"); | ||
473 | |||
474 | break; | ||
475 | |||
446 | case MLX4_EVENT_TYPE_EEC_CATAS_ERROR: | 476 | case MLX4_EVENT_TYPE_EEC_CATAS_ERROR: |
447 | case MLX4_EVENT_TYPE_ECC_DETECT: | 477 | case MLX4_EVENT_TYPE_ECC_DETECT: |
448 | default: | 478 | default: |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 5f15014713bc..8bb05b46db86 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -394,7 +394,7 @@ static int mlx4_how_many_lives_vf(struct mlx4_dev *dev) | |||
394 | return ret; | 394 | return ret; |
395 | } | 395 | } |
396 | 396 | ||
397 | static int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) | 397 | int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) |
398 | { | 398 | { |
399 | struct mlx4_priv *priv = mlx4_priv(dev); | 399 | struct mlx4_priv *priv = mlx4_priv(dev); |
400 | struct mlx4_slave_state *s_slave; | 400 | struct mlx4_slave_state *s_slave; |
@@ -646,6 +646,99 @@ out: | |||
646 | return err ? err : count; | 646 | return err ? err : count; |
647 | } | 647 | } |
648 | 648 | ||
649 | enum ibta_mtu { | ||
650 | IB_MTU_256 = 1, | ||
651 | IB_MTU_512 = 2, | ||
652 | IB_MTU_1024 = 3, | ||
653 | IB_MTU_2048 = 4, | ||
654 | IB_MTU_4096 = 5 | ||
655 | }; | ||
656 | |||
657 | static inline int int_to_ibta_mtu(int mtu) | ||
658 | { | ||
659 | switch (mtu) { | ||
660 | case 256: return IB_MTU_256; | ||
661 | case 512: return IB_MTU_512; | ||
662 | case 1024: return IB_MTU_1024; | ||
663 | case 2048: return IB_MTU_2048; | ||
664 | case 4096: return IB_MTU_4096; | ||
665 | default: return -1; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | static inline int ibta_mtu_to_int(enum ibta_mtu mtu) | ||
670 | { | ||
671 | switch (mtu) { | ||
672 | case IB_MTU_256: return 256; | ||
673 | case IB_MTU_512: return 512; | ||
674 | case IB_MTU_1024: return 1024; | ||
675 | case IB_MTU_2048: return 2048; | ||
676 | case IB_MTU_4096: return 4096; | ||
677 | default: return -1; | ||
678 | } | ||
679 | } | ||
680 | |||
681 | static ssize_t show_port_ib_mtu(struct device *dev, | ||
682 | struct device_attribute *attr, | ||
683 | char *buf) | ||
684 | { | ||
685 | struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info, | ||
686 | port_mtu_attr); | ||
687 | struct mlx4_dev *mdev = info->dev; | ||
688 | |||
689 | if (mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_ETH) | ||
690 | mlx4_warn(mdev, "port level mtu is only used for IB ports\n"); | ||
691 | |||
692 | sprintf(buf, "%d\n", | ||
693 | ibta_mtu_to_int(mdev->caps.port_ib_mtu[info->port])); | ||
694 | return strlen(buf); | ||
695 | } | ||
696 | |||
697 | static ssize_t set_port_ib_mtu(struct device *dev, | ||
698 | struct device_attribute *attr, | ||
699 | const char *buf, size_t count) | ||
700 | { | ||
701 | struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info, | ||
702 | port_mtu_attr); | ||
703 | struct mlx4_dev *mdev = info->dev; | ||
704 | struct mlx4_priv *priv = mlx4_priv(mdev); | ||
705 | int err, port, mtu, ibta_mtu = -1; | ||
706 | |||
707 | if (mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_ETH) { | ||
708 | mlx4_warn(mdev, "port level mtu is only used for IB ports\n"); | ||
709 | return -EINVAL; | ||
710 | } | ||
711 | |||
712 | err = sscanf(buf, "%d", &mtu); | ||
713 | if (err > 0) | ||
714 | ibta_mtu = int_to_ibta_mtu(mtu); | ||
715 | |||
716 | if (err <= 0 || ibta_mtu < 0) { | ||
717 | mlx4_err(mdev, "%s is invalid IBTA mtu\n", buf); | ||
718 | return -EINVAL; | ||
719 | } | ||
720 | |||
721 | mdev->caps.port_ib_mtu[info->port] = ibta_mtu; | ||
722 | |||
723 | mlx4_stop_sense(mdev); | ||
724 | mutex_lock(&priv->port_mutex); | ||
725 | mlx4_unregister_device(mdev); | ||
726 | for (port = 1; port <= mdev->caps.num_ports; port++) { | ||
727 | mlx4_CLOSE_PORT(mdev, port); | ||
728 | err = mlx4_SET_PORT(mdev, port); | ||
729 | if (err) { | ||
730 | mlx4_err(mdev, "Failed to set port %d, " | ||
731 | "aborting\n", port); | ||
732 | goto err_set_port; | ||
733 | } | ||
734 | } | ||
735 | err = mlx4_register_device(mdev); | ||
736 | err_set_port: | ||
737 | mutex_unlock(&priv->port_mutex); | ||
738 | mlx4_start_sense(mdev); | ||
739 | return err ? err : count; | ||
740 | } | ||
741 | |||
649 | static int mlx4_load_fw(struct mlx4_dev *dev) | 742 | static int mlx4_load_fw(struct mlx4_dev *dev) |
650 | { | 743 | { |
651 | struct mlx4_priv *priv = mlx4_priv(dev); | 744 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -1133,6 +1226,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1133 | goto err_stop_fw; | 1226 | goto err_stop_fw; |
1134 | } | 1227 | } |
1135 | 1228 | ||
1229 | dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; | ||
1230 | |||
1136 | init_hca.log_uar_sz = ilog2(dev->caps.num_uars); | 1231 | init_hca.log_uar_sz = ilog2(dev->caps.num_uars); |
1137 | init_hca.uar_page_sz = PAGE_SHIFT - 12; | 1232 | init_hca.uar_page_sz = PAGE_SHIFT - 12; |
1138 | 1233 | ||
@@ -1363,12 +1458,10 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
1363 | "with caps = 0\n", port, err); | 1458 | "with caps = 0\n", port, err); |
1364 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; | 1459 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; |
1365 | 1460 | ||
1366 | err = mlx4_check_ext_port_caps(dev, port); | 1461 | if (mlx4_is_mfunc(dev)) |
1367 | if (err) | 1462 | dev->caps.port_ib_mtu[port] = IB_MTU_2048; |
1368 | mlx4_warn(dev, "failed to get port %d extended " | 1463 | else |
1369 | "port capabilities support info (%d)." | 1464 | dev->caps.port_ib_mtu[port] = IB_MTU_4096; |
1370 | " Assuming not supported\n", | ||
1371 | port, err); | ||
1372 | 1465 | ||
1373 | err = mlx4_SET_PORT(dev, port); | 1466 | err = mlx4_SET_PORT(dev, port); |
1374 | if (err) { | 1467 | if (err) { |
@@ -1524,6 +1617,24 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
1524 | info->port = -1; | 1617 | info->port = -1; |
1525 | } | 1618 | } |
1526 | 1619 | ||
1620 | sprintf(info->dev_mtu_name, "mlx4_port%d_mtu", port); | ||
1621 | info->port_mtu_attr.attr.name = info->dev_mtu_name; | ||
1622 | if (mlx4_is_mfunc(dev)) | ||
1623 | info->port_mtu_attr.attr.mode = S_IRUGO; | ||
1624 | else { | ||
1625 | info->port_mtu_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
1626 | info->port_mtu_attr.store = set_port_ib_mtu; | ||
1627 | } | ||
1628 | info->port_mtu_attr.show = show_port_ib_mtu; | ||
1629 | sysfs_attr_init(&info->port_mtu_attr.attr); | ||
1630 | |||
1631 | err = device_create_file(&dev->pdev->dev, &info->port_mtu_attr); | ||
1632 | if (err) { | ||
1633 | mlx4_err(dev, "Failed to create mtu file for port %d\n", port); | ||
1634 | device_remove_file(&info->dev->pdev->dev, &info->port_attr); | ||
1635 | info->port = -1; | ||
1636 | } | ||
1637 | |||
1527 | return err; | 1638 | return err; |
1528 | } | 1639 | } |
1529 | 1640 | ||
@@ -1533,6 +1644,7 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info) | |||
1533 | return; | 1644 | return; |
1534 | 1645 | ||
1535 | device_remove_file(&info->dev->pdev->dev, &info->port_attr); | 1646 | device_remove_file(&info->dev->pdev->dev, &info->port_attr); |
1647 | device_remove_file(&info->dev->pdev->dev, &info->port_mtu_attr); | ||
1536 | } | 1648 | } |
1537 | 1649 | ||
1538 | static int mlx4_init_steering(struct mlx4_dev *dev) | 1650 | static int mlx4_init_steering(struct mlx4_dev *dev) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 5da51b99dbb8..2a0ff2cc7182 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -363,6 +363,10 @@ struct mlx4_eqe { | |||
363 | struct { | 363 | struct { |
364 | __be32 slave_id; | 364 | __be32 slave_id; |
365 | } __packed flr_event; | 365 | } __packed flr_event; |
366 | struct { | ||
367 | __be16 current_temperature; | ||
368 | __be16 warning_threshold; | ||
369 | } __packed warming; | ||
366 | } event; | 370 | } event; |
367 | u8 slave_id; | 371 | u8 slave_id; |
368 | u8 reserved3[2]; | 372 | u8 reserved3[2]; |
@@ -399,7 +403,7 @@ struct mlx4_profile { | |||
399 | int num_cq; | 403 | int num_cq; |
400 | int num_mcg; | 404 | int num_mcg; |
401 | int num_mpt; | 405 | int num_mpt; |
402 | int num_mtt; | 406 | unsigned num_mtt; |
403 | }; | 407 | }; |
404 | 408 | ||
405 | struct mlx4_fw { | 409 | struct mlx4_fw { |
@@ -682,6 +686,8 @@ struct mlx4_port_info { | |||
682 | char dev_name[16]; | 686 | char dev_name[16]; |
683 | struct device_attribute port_attr; | 687 | struct device_attribute port_attr; |
684 | enum mlx4_port_type tmp_type; | 688 | enum mlx4_port_type tmp_type; |
689 | char dev_mtu_name[16]; | ||
690 | struct device_attribute port_mtu_attr; | ||
685 | struct mlx4_mac_table mac_table; | 691 | struct mlx4_mac_table mac_table; |
686 | struct radix_tree_root mac_tree; | 692 | struct radix_tree_root mac_tree; |
687 | struct mlx4_vlan_table vlan_table; | 693 | struct mlx4_vlan_table vlan_table; |
@@ -1024,7 +1030,6 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
1024 | struct mlx4_cmd_mailbox *outbox, | 1030 | struct mlx4_cmd_mailbox *outbox, |
1025 | struct mlx4_cmd_info *cmd); | 1031 | struct mlx4_cmd_info *cmd); |
1026 | int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); | 1032 | int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); |
1027 | int mlx4_check_ext_port_caps(struct mlx4_dev *dev, u8 port); | ||
1028 | 1033 | ||
1029 | 1034 | ||
1030 | int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 1035 | int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 32e2b6616f3d..fe2ac8449c19 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -791,6 +791,9 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, | |||
791 | u64 mtt_offset; | 791 | u64 mtt_offset; |
792 | int err = -ENOMEM; | 792 | int err = -ENOMEM; |
793 | 793 | ||
794 | if (max_maps > dev->caps.max_fmr_maps) | ||
795 | return -EINVAL; | ||
796 | |||
794 | if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) | 797 | if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) |
795 | return -EINVAL; | 798 | return -EINVAL; |
796 | 799 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 98e776261ead..77535ff18f1b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -590,49 +590,6 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) | |||
590 | return err; | 590 | return err; |
591 | } | 591 | } |
592 | 592 | ||
593 | int mlx4_check_ext_port_caps(struct mlx4_dev *dev, u8 port) | ||
594 | { | ||
595 | struct mlx4_cmd_mailbox *inmailbox, *outmailbox; | ||
596 | u8 *inbuf, *outbuf; | ||
597 | int err, packet_error; | ||
598 | |||
599 | inmailbox = mlx4_alloc_cmd_mailbox(dev); | ||
600 | if (IS_ERR(inmailbox)) | ||
601 | return PTR_ERR(inmailbox); | ||
602 | |||
603 | outmailbox = mlx4_alloc_cmd_mailbox(dev); | ||
604 | if (IS_ERR(outmailbox)) { | ||
605 | mlx4_free_cmd_mailbox(dev, inmailbox); | ||
606 | return PTR_ERR(outmailbox); | ||
607 | } | ||
608 | |||
609 | inbuf = inmailbox->buf; | ||
610 | outbuf = outmailbox->buf; | ||
611 | memset(inbuf, 0, 256); | ||
612 | memset(outbuf, 0, 256); | ||
613 | inbuf[0] = 1; | ||
614 | inbuf[1] = 1; | ||
615 | inbuf[2] = 1; | ||
616 | inbuf[3] = 1; | ||
617 | |||
618 | *(__be16 *) (&inbuf[16]) = MLX4_ATTR_EXTENDED_PORT_INFO; | ||
619 | *(__be32 *) (&inbuf[20]) = cpu_to_be32(port); | ||
620 | |||
621 | err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3, | ||
622 | MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, | ||
623 | MLX4_CMD_NATIVE); | ||
624 | |||
625 | packet_error = be16_to_cpu(*(__be16 *) (outbuf + 4)); | ||
626 | |||
627 | dev->caps.ext_port_cap[port] = (!err && !packet_error) ? | ||
628 | MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO | ||
629 | : 0; | ||
630 | |||
631 | mlx4_free_cmd_mailbox(dev, inmailbox); | ||
632 | mlx4_free_cmd_mailbox(dev, outmailbox); | ||
633 | return err; | ||
634 | } | ||
635 | |||
636 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | 593 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, |
637 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) | 594 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) |
638 | { | 595 | { |
@@ -766,10 +723,18 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
766 | vhcr->op_modifier, inbox); | 723 | vhcr->op_modifier, inbox); |
767 | } | 724 | } |
768 | 725 | ||
726 | /* bit locations for set port command with zero op modifier */ | ||
727 | enum { | ||
728 | MLX4_SET_PORT_VL_CAP = 4, /* bits 7:4 */ | ||
729 | MLX4_SET_PORT_MTU_CAP = 12, /* bits 15:12 */ | ||
730 | MLX4_CHANGE_PORT_VL_CAP = 21, | ||
731 | MLX4_CHANGE_PORT_MTU_CAP = 22, | ||
732 | }; | ||
733 | |||
769 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | 734 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) |
770 | { | 735 | { |
771 | struct mlx4_cmd_mailbox *mailbox; | 736 | struct mlx4_cmd_mailbox *mailbox; |
772 | int err; | 737 | int err, vl_cap; |
773 | 738 | ||
774 | if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) | 739 | if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) |
775 | return 0; | 740 | return 0; |
@@ -781,8 +746,19 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | |||
781 | memset(mailbox->buf, 0, 256); | 746 | memset(mailbox->buf, 0, 256); |
782 | 747 | ||
783 | ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; | 748 | ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; |
784 | err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, | 749 | |
785 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); | 750 | /* IB VL CAP enum isn't used by the firmware, just numerical values */ |
751 | for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) { | ||
752 | ((__be32 *) mailbox->buf)[0] = cpu_to_be32( | ||
753 | (1 << MLX4_CHANGE_PORT_MTU_CAP) | | ||
754 | (1 << MLX4_CHANGE_PORT_VL_CAP) | | ||
755 | (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) | | ||
756 | (vl_cap << MLX4_SET_PORT_VL_CAP)); | ||
757 | err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, | ||
758 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); | ||
759 | if (err != -ENOMEM) | ||
760 | break; | ||
761 | } | ||
786 | 762 | ||
787 | mlx4_free_cmd_mailbox(dev, mailbox); | 763 | mlx4_free_cmd_mailbox(dev, mailbox); |
788 | return err; | 764 | return err; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 1129677daa62..06e5adeb76f7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c | |||
@@ -83,12 +83,31 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
83 | u64 total_size = 0; | 83 | u64 total_size = 0; |
84 | struct mlx4_resource *profile; | 84 | struct mlx4_resource *profile; |
85 | struct mlx4_resource tmp; | 85 | struct mlx4_resource tmp; |
86 | struct sysinfo si; | ||
86 | int i, j; | 87 | int i, j; |
87 | 88 | ||
88 | profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL); | 89 | profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL); |
89 | if (!profile) | 90 | if (!profile) |
90 | return -ENOMEM; | 91 | return -ENOMEM; |
91 | 92 | ||
93 | /* | ||
94 | * We want to scale the number of MTTs with the size of the | ||
95 | * system memory, since it makes sense to register a lot of | ||
96 | * memory on a system with a lot of memory. As a heuristic, | ||
97 | * make sure we have enough MTTs to cover twice the system | ||
98 | * memory (with PAGE_SIZE entries). | ||
99 | * | ||
100 | * This number has to be a power of two and fit into 32 bits | ||
101 | * due to device limitations, so cap this at 2^31 as well. | ||
102 | * That limits us to 8TB of memory registration per HCA with | ||
103 | * 4KB pages, which is probably OK for the next few months. | ||
104 | */ | ||
105 | si_meminfo(&si); | ||
106 | request->num_mtt = | ||
107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, | ||
108 | min(1UL << 31, | ||
109 | si.totalram >> (log_mtts_per_seg - 1)))); | ||
110 | |||
92 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; | 111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; |
93 | profile[MLX4_RES_RDMARC].size = dev_cap->rdmarc_entry_sz; | 112 | profile[MLX4_RES_RDMARC].size = dev_cap->rdmarc_entry_sz; |
94 | profile[MLX4_RES_ALTC].size = dev_cap->altc_entry_sz; | 113 | profile[MLX4_RES_ALTC].size = dev_cap->altc_entry_sz; |