diff options
author | Roland Dreier <roland@purestorage.com> | 2012-03-12 19:25:28 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-03-12 19:25:28 -0400 |
commit | 42872c7a5ed8d3ed49f51cb783978ca50369c564 (patch) | |
tree | 0deea7b61c163e6997a4634ab4ee310014984688 /drivers/net/ethernet | |
parent | d927d505c59a0c7353343174e6225c43c61fba6d (diff) | |
parent | db5a7a65c05867cb6ff5cb6d556a0edfce631d2d (diff) |
Merge branches 'misc' and 'mlx4' into for-next
Conflicts:
drivers/infiniband/hw/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/main.c
include/linux/mlx4/device.h
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 121 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mr.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/profile.c | 19 |
6 files changed, 202 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 8fa41f3082cf..780b5adf8e7d 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 2f94d30ab12b..a6ee22b319f8 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; |
@@ -647,6 +647,99 @@ out: | |||
647 | return err ? err : count; | 647 | return err ? err : count; |
648 | } | 648 | } |
649 | 649 | ||
650 | enum ibta_mtu { | ||
651 | IB_MTU_256 = 1, | ||
652 | IB_MTU_512 = 2, | ||
653 | IB_MTU_1024 = 3, | ||
654 | IB_MTU_2048 = 4, | ||
655 | IB_MTU_4096 = 5 | ||
656 | }; | ||
657 | |||
658 | static inline int int_to_ibta_mtu(int mtu) | ||
659 | { | ||
660 | switch (mtu) { | ||
661 | case 256: return IB_MTU_256; | ||
662 | case 512: return IB_MTU_512; | ||
663 | case 1024: return IB_MTU_1024; | ||
664 | case 2048: return IB_MTU_2048; | ||
665 | case 4096: return IB_MTU_4096; | ||
666 | default: return -1; | ||
667 | } | ||
668 | } | ||
669 | |||
670 | static inline int ibta_mtu_to_int(enum ibta_mtu mtu) | ||
671 | { | ||
672 | switch (mtu) { | ||
673 | case IB_MTU_256: return 256; | ||
674 | case IB_MTU_512: return 512; | ||
675 | case IB_MTU_1024: return 1024; | ||
676 | case IB_MTU_2048: return 2048; | ||
677 | case IB_MTU_4096: return 4096; | ||
678 | default: return -1; | ||
679 | } | ||
680 | } | ||
681 | |||
682 | static ssize_t show_port_ib_mtu(struct device *dev, | ||
683 | struct device_attribute *attr, | ||
684 | char *buf) | ||
685 | { | ||
686 | struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info, | ||
687 | port_mtu_attr); | ||
688 | struct mlx4_dev *mdev = info->dev; | ||
689 | |||
690 | if (mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_ETH) | ||
691 | mlx4_warn(mdev, "port level mtu is only used for IB ports\n"); | ||
692 | |||
693 | sprintf(buf, "%d\n", | ||
694 | ibta_mtu_to_int(mdev->caps.port_ib_mtu[info->port])); | ||
695 | return strlen(buf); | ||
696 | } | ||
697 | |||
698 | static ssize_t set_port_ib_mtu(struct device *dev, | ||
699 | struct device_attribute *attr, | ||
700 | const char *buf, size_t count) | ||
701 | { | ||
702 | struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info, | ||
703 | port_mtu_attr); | ||
704 | struct mlx4_dev *mdev = info->dev; | ||
705 | struct mlx4_priv *priv = mlx4_priv(mdev); | ||
706 | int err, port, mtu, ibta_mtu = -1; | ||
707 | |||
708 | if (mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_ETH) { | ||
709 | mlx4_warn(mdev, "port level mtu is only used for IB ports\n"); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | |||
713 | err = sscanf(buf, "%d", &mtu); | ||
714 | if (err > 0) | ||
715 | ibta_mtu = int_to_ibta_mtu(mtu); | ||
716 | |||
717 | if (err <= 0 || ibta_mtu < 0) { | ||
718 | mlx4_err(mdev, "%s is invalid IBTA mtu\n", buf); | ||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
722 | mdev->caps.port_ib_mtu[info->port] = ibta_mtu; | ||
723 | |||
724 | mlx4_stop_sense(mdev); | ||
725 | mutex_lock(&priv->port_mutex); | ||
726 | mlx4_unregister_device(mdev); | ||
727 | for (port = 1; port <= mdev->caps.num_ports; port++) { | ||
728 | mlx4_CLOSE_PORT(mdev, port); | ||
729 | err = mlx4_SET_PORT(mdev, port); | ||
730 | if (err) { | ||
731 | mlx4_err(mdev, "Failed to set port %d, " | ||
732 | "aborting\n", port); | ||
733 | goto err_set_port; | ||
734 | } | ||
735 | } | ||
736 | err = mlx4_register_device(mdev); | ||
737 | err_set_port: | ||
738 | mutex_unlock(&priv->port_mutex); | ||
739 | mlx4_start_sense(mdev); | ||
740 | return err ? err : count; | ||
741 | } | ||
742 | |||
650 | static int mlx4_load_fw(struct mlx4_dev *dev) | 743 | static int mlx4_load_fw(struct mlx4_dev *dev) |
651 | { | 744 | { |
652 | struct mlx4_priv *priv = mlx4_priv(dev); | 745 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -1131,6 +1224,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1131 | goto err_stop_fw; | 1224 | goto err_stop_fw; |
1132 | } | 1225 | } |
1133 | 1226 | ||
1227 | dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; | ||
1228 | |||
1134 | init_hca.log_uar_sz = ilog2(dev->caps.num_uars); | 1229 | init_hca.log_uar_sz = ilog2(dev->caps.num_uars); |
1135 | init_hca.uar_page_sz = PAGE_SHIFT - 12; | 1230 | init_hca.uar_page_sz = PAGE_SHIFT - 12; |
1136 | 1231 | ||
@@ -1361,6 +1456,11 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
1361 | "with caps = 0\n", port, err); | 1456 | "with caps = 0\n", port, err); |
1362 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; | 1457 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; |
1363 | 1458 | ||
1459 | if (mlx4_is_mfunc(dev)) | ||
1460 | dev->caps.port_ib_mtu[port] = IB_MTU_2048; | ||
1461 | else | ||
1462 | dev->caps.port_ib_mtu[port] = IB_MTU_4096; | ||
1463 | |||
1364 | err = mlx4_SET_PORT(dev, port); | 1464 | err = mlx4_SET_PORT(dev, port); |
1365 | if (err) { | 1465 | if (err) { |
1366 | mlx4_err(dev, "Failed to set port %d, aborting\n", | 1466 | mlx4_err(dev, "Failed to set port %d, aborting\n", |
@@ -1515,6 +1615,24 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
1515 | info->port = -1; | 1615 | info->port = -1; |
1516 | } | 1616 | } |
1517 | 1617 | ||
1618 | sprintf(info->dev_mtu_name, "mlx4_port%d_mtu", port); | ||
1619 | info->port_mtu_attr.attr.name = info->dev_mtu_name; | ||
1620 | if (mlx4_is_mfunc(dev)) | ||
1621 | info->port_mtu_attr.attr.mode = S_IRUGO; | ||
1622 | else { | ||
1623 | info->port_mtu_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
1624 | info->port_mtu_attr.store = set_port_ib_mtu; | ||
1625 | } | ||
1626 | info->port_mtu_attr.show = show_port_ib_mtu; | ||
1627 | sysfs_attr_init(&info->port_mtu_attr.attr); | ||
1628 | |||
1629 | err = device_create_file(&dev->pdev->dev, &info->port_mtu_attr); | ||
1630 | if (err) { | ||
1631 | mlx4_err(dev, "Failed to create mtu file for port %d\n", port); | ||
1632 | device_remove_file(&info->dev->pdev->dev, &info->port_attr); | ||
1633 | info->port = -1; | ||
1634 | } | ||
1635 | |||
1518 | return err; | 1636 | return err; |
1519 | } | 1637 | } |
1520 | 1638 | ||
@@ -1524,6 +1642,7 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info) | |||
1524 | return; | 1642 | return; |
1525 | 1643 | ||
1526 | device_remove_file(&info->dev->pdev->dev, &info->port_attr); | 1644 | device_remove_file(&info->dev->pdev->dev, &info->port_attr); |
1645 | device_remove_file(&info->dev->pdev->dev, &info->port_mtu_attr); | ||
1527 | } | 1646 | } |
1528 | 1647 | ||
1529 | static int mlx4_init_steering(struct mlx4_dev *dev) | 1648 | 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 c34d30a5d77b..a99a13e9e695 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; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 25a80d71fb2a..5b7c06e0cd05 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -816,6 +816,9 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, | |||
816 | u64 mtt_offset; | 816 | u64 mtt_offset; |
817 | int err = -ENOMEM; | 817 | int err = -ENOMEM; |
818 | 818 | ||
819 | if (max_maps > dev->caps.max_fmr_maps) | ||
820 | return -EINVAL; | ||
821 | |||
819 | if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) | 822 | if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) |
820 | return -EINVAL; | 823 | return -EINVAL; |
821 | 824 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 51708dd7c8b0..409d444c4df5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -723,10 +723,18 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, | |||
723 | vhcr->op_modifier, inbox); | 723 | vhcr->op_modifier, inbox); |
724 | } | 724 | } |
725 | 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 | |||
726 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | 734 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) |
727 | { | 735 | { |
728 | struct mlx4_cmd_mailbox *mailbox; | 736 | struct mlx4_cmd_mailbox *mailbox; |
729 | int err; | 737 | int err, vl_cap; |
730 | 738 | ||
731 | if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) | 739 | if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) |
732 | return 0; | 740 | return 0; |
@@ -738,8 +746,19 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | |||
738 | memset(mailbox->buf, 0, 256); | 746 | memset(mailbox->buf, 0, 256); |
739 | 747 | ||
740 | ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; | 748 | ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; |
741 | err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, | 749 | |
742 | 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 | } | ||
743 | 762 | ||
744 | mlx4_free_cmd_mailbox(dev, mailbox); | 763 | mlx4_free_cmd_mailbox(dev, mailbox); |
745 | 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; |