diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/main.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 126 |
1 files changed, 119 insertions, 7 deletions
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) |