aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c117
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c25
-rw-r--r--include/linux/mlx4/device.h1
4 files changed, 141 insertions, 4 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index f0578961190c..e92cfae82e5a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -647,6 +647,99 @@ out:
647 return err ? err : count; 647 return err ? err : count;
648} 648}
649 649
650enum 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
658static 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
670static 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
682static 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
698static 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);
737err_set_port:
738 mutex_unlock(&priv->port_mutex);
739 mlx4_start_sense(mdev);
740 return err ? err : count;
741}
742
650static int mlx4_load_fw(struct mlx4_dev *dev) 743static 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);
@@ -1362,7 +1455,10 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
1362 "ib capabilities (%d). Continuing " 1455 "ib capabilities (%d). Continuing "
1363 "with caps = 0\n", port, err); 1456 "with caps = 0\n", port, err);
1364 dev->caps.ib_port_def_cap[port] = ib_port_default_caps; 1457 dev->caps.ib_port_def_cap[port] = ib_port_default_caps;
1365 1458 if (mlx4_is_mfunc(dev))
1459 dev->caps.port_ib_mtu[port] = IB_MTU_2048;
1460 else
1461 dev->caps.port_ib_mtu[port] = IB_MTU_4096;
1366 err = mlx4_check_ext_port_caps(dev, port); 1462 err = mlx4_check_ext_port_caps(dev, port);
1367 if (err) 1463 if (err)
1368 mlx4_warn(dev, "failed to get port %d extended " 1464 mlx4_warn(dev, "failed to get port %d extended "
@@ -1524,6 +1620,24 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
1524 info->port = -1; 1620 info->port = -1;
1525 } 1621 }
1526 1622
1623 sprintf(info->dev_mtu_name, "mlx4_port%d_mtu", port);
1624 info->port_mtu_attr.attr.name = info->dev_mtu_name;
1625 if (mlx4_is_mfunc(dev))
1626 info->port_mtu_attr.attr.mode = S_IRUGO;
1627 else {
1628 info->port_mtu_attr.attr.mode = S_IRUGO | S_IWUSR;
1629 info->port_mtu_attr.store = set_port_ib_mtu;
1630 }
1631 info->port_mtu_attr.show = show_port_ib_mtu;
1632 sysfs_attr_init(&info->port_mtu_attr.attr);
1633
1634 err = device_create_file(&dev->pdev->dev, &info->port_mtu_attr);
1635 if (err) {
1636 mlx4_err(dev, "Failed to create mtu file for port %d\n", port);
1637 device_remove_file(&info->dev->pdev->dev, &info->port_attr);
1638 info->port = -1;
1639 }
1640
1527 return err; 1641 return err;
1528} 1642}
1529 1643
@@ -1533,6 +1647,7 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info)
1533 return; 1647 return;
1534 1648
1535 device_remove_file(&info->dev->pdev->dev, &info->port_attr); 1649 device_remove_file(&info->dev->pdev->dev, &info->port_attr);
1650 device_remove_file(&info->dev->pdev->dev, &info->port_mtu_attr);
1536} 1651}
1537 1652
1538static int mlx4_init_steering(struct mlx4_dev *dev) 1653static 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 ac2d6061268d..1aa362181a09 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -686,6 +686,8 @@ struct mlx4_port_info {
686 char dev_name[16]; 686 char dev_name[16];
687 struct device_attribute port_attr; 687 struct device_attribute port_attr;
688 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;
689 struct mlx4_mac_table mac_table; 691 struct mlx4_mac_table mac_table;
690 struct radix_tree_root mac_tree; 692 struct radix_tree_root mac_tree;
691 struct mlx4_vlan_table vlan_table; 693 struct mlx4_vlan_table vlan_table;
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index f44ae555bf43..a6fd56451d7e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -766,10 +766,18 @@ int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
766 vhcr->op_modifier, inbox); 766 vhcr->op_modifier, inbox);
767} 767}
768 768
769/* bit locations for set port command with zero op modifier */
770enum {
771 MLX4_SET_PORT_VL_CAP = 4, /* bits 7:4 */
772 MLX4_SET_PORT_MTU_CAP = 12, /* bits 15:12 */
773 MLX4_CHANGE_PORT_VL_CAP = 21,
774 MLX4_CHANGE_PORT_MTU_CAP = 22,
775};
776
769int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) 777int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
770{ 778{
771 struct mlx4_cmd_mailbox *mailbox; 779 struct mlx4_cmd_mailbox *mailbox;
772 int err; 780 int err, vl_cap;
773 781
774 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) 782 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
775 return 0; 783 return 0;
@@ -781,8 +789,19 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
781 memset(mailbox->buf, 0, 256); 789 memset(mailbox->buf, 0, 256);
782 790
783 ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; 791 ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
784 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, 792
785 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 793 /* IB VL CAP enum isn't used by the firmware, just numerical values */
794 for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) {
795 ((__be32 *) mailbox->buf)[0] = cpu_to_be32(
796 (1 << MLX4_CHANGE_PORT_MTU_CAP) |
797 (1 << MLX4_CHANGE_PORT_VL_CAP) |
798 (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) |
799 (vl_cap << MLX4_SET_PORT_VL_CAP));
800 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
801 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
802 if (err != -ENOMEM)
803 break;
804 }
786 805
787 mlx4_free_cmd_mailbox(dev, mailbox); 806 mlx4_free_cmd_mailbox(dev, mailbox);
788 return err; 807 return err;
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 4b3fbf122533..b19fb9b901a2 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -315,6 +315,7 @@ struct mlx4_caps {
315 enum mlx4_port_type possible_type[MLX4_MAX_PORTS + 1]; 315 enum mlx4_port_type possible_type[MLX4_MAX_PORTS + 1];
316 u32 max_counters; 316 u32 max_counters;
317 u8 ext_port_cap[MLX4_MAX_PORTS + 1]; 317 u8 ext_port_cap[MLX4_MAX_PORTS + 1];
318 u8 port_ib_mtu[MLX4_MAX_PORTS + 1];
318}; 319};
319 320
320struct mlx4_buf_list { 321struct mlx4_buf_list {