diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/main.c')
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 1b6dbe156a37..199c7896f081 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -48,6 +48,7 @@ | |||
48 | 48 | ||
49 | #include <linux/mlx4/driver.h> | 49 | #include <linux/mlx4/driver.h> |
50 | #include <linux/mlx4/cmd.h> | 50 | #include <linux/mlx4/cmd.h> |
51 | #include <linux/mlx4/qp.h> | ||
51 | 52 | ||
52 | #include "mlx4_ib.h" | 53 | #include "mlx4_ib.h" |
53 | #include "user.h" | 54 | #include "user.h" |
@@ -1614,6 +1615,53 @@ static int mlx4_ib_inet6_event(struct notifier_block *this, unsigned long event, | |||
1614 | } | 1615 | } |
1615 | #endif | 1616 | #endif |
1616 | 1617 | ||
1618 | #define MLX4_IB_INVALID_MAC ((u64)-1) | ||
1619 | static void mlx4_ib_update_qps(struct mlx4_ib_dev *ibdev, | ||
1620 | struct net_device *dev, | ||
1621 | int port) | ||
1622 | { | ||
1623 | u64 new_smac = 0; | ||
1624 | u64 release_mac = MLX4_IB_INVALID_MAC; | ||
1625 | struct mlx4_ib_qp *qp; | ||
1626 | |||
1627 | read_lock(&dev_base_lock); | ||
1628 | new_smac = mlx4_mac_to_u64(dev->dev_addr); | ||
1629 | read_unlock(&dev_base_lock); | ||
1630 | |||
1631 | mutex_lock(&ibdev->qp1_proxy_lock[port - 1]); | ||
1632 | qp = ibdev->qp1_proxy[port - 1]; | ||
1633 | if (qp) { | ||
1634 | int new_smac_index; | ||
1635 | u64 old_smac = qp->pri.smac; | ||
1636 | struct mlx4_update_qp_params update_params; | ||
1637 | |||
1638 | if (new_smac == old_smac) | ||
1639 | goto unlock; | ||
1640 | |||
1641 | new_smac_index = mlx4_register_mac(ibdev->dev, port, new_smac); | ||
1642 | |||
1643 | if (new_smac_index < 0) | ||
1644 | goto unlock; | ||
1645 | |||
1646 | update_params.smac_index = new_smac_index; | ||
1647 | if (mlx4_update_qp(ibdev->dev, &qp->mqp, MLX4_UPDATE_QP_SMAC, | ||
1648 | &update_params)) { | ||
1649 | release_mac = new_smac; | ||
1650 | goto unlock; | ||
1651 | } | ||
1652 | |||
1653 | qp->pri.smac = new_smac; | ||
1654 | qp->pri.smac_index = new_smac_index; | ||
1655 | |||
1656 | release_mac = old_smac; | ||
1657 | } | ||
1658 | |||
1659 | unlock: | ||
1660 | mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]); | ||
1661 | if (release_mac != MLX4_IB_INVALID_MAC) | ||
1662 | mlx4_unregister_mac(ibdev->dev, port, release_mac); | ||
1663 | } | ||
1664 | |||
1617 | static void mlx4_ib_get_dev_addr(struct net_device *dev, | 1665 | static void mlx4_ib_get_dev_addr(struct net_device *dev, |
1618 | struct mlx4_ib_dev *ibdev, u8 port) | 1666 | struct mlx4_ib_dev *ibdev, u8 port) |
1619 | { | 1667 | { |
@@ -1689,9 +1737,13 @@ static int mlx4_ib_init_gid_table(struct mlx4_ib_dev *ibdev) | |||
1689 | return 0; | 1737 | return 0; |
1690 | } | 1738 | } |
1691 | 1739 | ||
1692 | static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev) | 1740 | static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev, |
1741 | struct net_device *dev, | ||
1742 | unsigned long event) | ||
1743 | |||
1693 | { | 1744 | { |
1694 | struct mlx4_ib_iboe *iboe; | 1745 | struct mlx4_ib_iboe *iboe; |
1746 | int update_qps_port = -1; | ||
1695 | int port; | 1747 | int port; |
1696 | 1748 | ||
1697 | iboe = &ibdev->iboe; | 1749 | iboe = &ibdev->iboe; |
@@ -1719,6 +1771,11 @@ static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev) | |||
1719 | } | 1771 | } |
1720 | curr_master = iboe->masters[port - 1]; | 1772 | curr_master = iboe->masters[port - 1]; |
1721 | 1773 | ||
1774 | if (dev == iboe->netdevs[port - 1] && | ||
1775 | (event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER || | ||
1776 | event == NETDEV_UP || event == NETDEV_CHANGE)) | ||
1777 | update_qps_port = port; | ||
1778 | |||
1722 | if (curr_netdev) { | 1779 | if (curr_netdev) { |
1723 | port_state = (netif_running(curr_netdev) && netif_carrier_ok(curr_netdev)) ? | 1780 | port_state = (netif_running(curr_netdev) && netif_carrier_ok(curr_netdev)) ? |
1724 | IB_PORT_ACTIVE : IB_PORT_DOWN; | 1781 | IB_PORT_ACTIVE : IB_PORT_DOWN; |
@@ -1752,6 +1809,9 @@ static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev) | |||
1752 | } | 1809 | } |
1753 | 1810 | ||
1754 | spin_unlock(&iboe->lock); | 1811 | spin_unlock(&iboe->lock); |
1812 | |||
1813 | if (update_qps_port > 0) | ||
1814 | mlx4_ib_update_qps(ibdev, dev, update_qps_port); | ||
1755 | } | 1815 | } |
1756 | 1816 | ||
1757 | static int mlx4_ib_netdev_event(struct notifier_block *this, | 1817 | static int mlx4_ib_netdev_event(struct notifier_block *this, |
@@ -1764,7 +1824,7 @@ static int mlx4_ib_netdev_event(struct notifier_block *this, | |||
1764 | return NOTIFY_DONE; | 1824 | return NOTIFY_DONE; |
1765 | 1825 | ||
1766 | ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb); | 1826 | ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb); |
1767 | mlx4_ib_scan_netdevs(ibdev); | 1827 | mlx4_ib_scan_netdevs(ibdev, dev, event); |
1768 | 1828 | ||
1769 | return NOTIFY_DONE; | 1829 | return NOTIFY_DONE; |
1770 | } | 1830 | } |
@@ -2043,6 +2103,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2043 | goto err_map; | 2103 | goto err_map; |
2044 | 2104 | ||
2045 | for (i = 0; i < ibdev->num_ports; ++i) { | 2105 | for (i = 0; i < ibdev->num_ports; ++i) { |
2106 | mutex_init(&ibdev->qp1_proxy_lock[i]); | ||
2046 | if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) == | 2107 | if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) == |
2047 | IB_LINK_LAYER_ETHERNET) { | 2108 | IB_LINK_LAYER_ETHERNET) { |
2048 | err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]); | 2109 | err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]); |
@@ -2126,7 +2187,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2126 | for (i = 1 ; i <= ibdev->num_ports ; ++i) | 2187 | for (i = 1 ; i <= ibdev->num_ports ; ++i) |
2127 | reset_gid_table(ibdev, i); | 2188 | reset_gid_table(ibdev, i); |
2128 | rtnl_lock(); | 2189 | rtnl_lock(); |
2129 | mlx4_ib_scan_netdevs(ibdev); | 2190 | mlx4_ib_scan_netdevs(ibdev, NULL, 0); |
2130 | rtnl_unlock(); | 2191 | rtnl_unlock(); |
2131 | mlx4_ib_init_gid_table(ibdev); | 2192 | mlx4_ib_init_gid_table(ibdev); |
2132 | } | 2193 | } |