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 678558b502fc..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,12 +1456,10 @@ 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 | ||
1364 | err = mlx4_check_ext_port_caps(dev, port); | 1459 | if (mlx4_is_mfunc(dev)) |
1365 | if (err) | 1460 | dev->caps.port_ib_mtu[port] = IB_MTU_2048; |
1366 | mlx4_warn(dev, "failed to get port %d extended " | 1461 | else |
1367 | "port capabilities support info (%d)." | 1462 | dev->caps.port_ib_mtu[port] = IB_MTU_4096; |
1368 | " Assuming not supported\n", | ||
1369 | port, err); | ||
1370 | 1463 | ||
1371 | err = mlx4_SET_PORT(dev, port); | 1464 | err = mlx4_SET_PORT(dev, port); |
1372 | if (err) { | 1465 | if (err) { |
@@ -1522,6 +1615,24 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
1522 | info->port = -1; | 1615 | info->port = -1; |
1523 | } | 1616 | } |
1524 | 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 | |||
1525 | return err; | 1636 | return err; |
1526 | } | 1637 | } |
1527 | 1638 | ||
@@ -1531,6 +1642,7 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info) | |||
1531 | return; | 1642 | return; |
1532 | 1643 | ||
1533 | 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); | ||
1534 | } | 1646 | } |
1535 | 1647 | ||
1536 | static int mlx4_init_steering(struct mlx4_dev *dev) | 1648 | static int mlx4_init_steering(struct mlx4_dev *dev) |