aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2015-10-14 10:43:48 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-14 22:14:44 -0400
commit2b3ddf27f48c8061f0676c5a8796008099945280 (patch)
treef5dbb21663ed267c5c32606fa4a9ba9a328bed3f
parente3297246c2c8cf8548ba722da3e3a8104cdcd035 (diff)
net/mlx4_core: Replace VF zero mac with random mac in mlx4_core
By design, when no default MAC addresses are set in the Hypervisor for VFs, the VFs are passed zero-macs. When such a MAC is received by the VF, it generates a random MAC address and registers that MAC address with the Hypervisor. This random mac generation is currently done in the mlx4_en module. There is a problem, though, if the mlx4_ib module is loaded by a VF before the mlx4_en module. In this case, for RoCE, mlx4_ib will see the un-replaced zero-mac and register that zero-mac as part of QP1 initialization. Having a zero-mac in the port's MAC table creates problems for a Baseboard Management Console. The BMC occasionally sends packets with a zero-mac destination MAC. If there is a zero-mac present in the port's MAC table, the FW will send such BMC packets to the host driver rather than to the wire, and BMC will stop working. To address this problem, we move the replacement of zero-mac addresses with random-mac addresses to procedure mlx4_slave_cap(), which is part of the driver startup for VFs, and is before activation of mlx4_ib and mlx4_en. As a result, zero-mac addresses will never be registered in the port MAC table by the driver. In addition, when mlx4_en does initialize the net device, it needs to set the NET_ADDR_RANDOM flag in the netdev structure if the address was randomly generated. This is done so that udev on the VM does not create a new device name after each VF probe (VM boot and such). To accomplish this, we add a per-port flag in mlx4_dev which gets set whenever mlx4_core replaces a zero-mac with a randomly-generated mac. This flag is examined when mlx4_en initializes the net-device. Fix was suggested by Matan Barak <matanb@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c23
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--include/linux/mlx4/device.h1
5 files changed, 32 insertions, 12 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 597d8923c8e1..886e1bc86374 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2816,7 +2816,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2816 struct mlx4_en_priv *priv; 2816 struct mlx4_en_priv *priv;
2817 int i; 2817 int i;
2818 int err; 2818 int err;
2819 u64 mac_u64;
2820 2819
2821 dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), 2820 dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv),
2822 MAX_TX_RINGS, MAX_RX_RINGS); 2821 MAX_TX_RINGS, MAX_RX_RINGS);
@@ -2908,17 +2907,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2908 dev->addr_len = ETH_ALEN; 2907 dev->addr_len = ETH_ALEN;
2909 mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]); 2908 mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]);
2910 if (!is_valid_ether_addr(dev->dev_addr)) { 2909 if (!is_valid_ether_addr(dev->dev_addr)) {
2911 if (mlx4_is_slave(priv->mdev->dev)) { 2910 en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n",
2912 eth_hw_addr_random(dev); 2911 priv->port, dev->dev_addr);
2913 en_warn(priv, "Assigned random MAC address %pM\n", dev->dev_addr); 2912 err = -EINVAL;
2914 mac_u64 = mlx4_mac_to_u64(dev->dev_addr); 2913 goto out;
2915 mdev->dev->caps.def_mac[priv->port] = mac_u64; 2914 } else if (mlx4_is_slave(priv->mdev->dev) &&
2916 } else { 2915 (priv->mdev->dev->port_random_macs & 1 << priv->port)) {
2917 en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n", 2916 /* Random MAC was assigned in mlx4_slave_cap
2918 priv->port, dev->dev_addr); 2917 * in mlx4_core module
2919 err = -EINVAL; 2918 */
2920 goto out; 2919 dev->addr_assign_type |= NET_ADDR_RANDOM;
2921 } 2920 en_warn(priv, "Assigned random MAC address %pM\n", dev->dev_addr);
2922 } 2921 }
2923 2922
2924 memcpy(priv->current_mac, dev->dev_addr, sizeof(priv->current_mac)); 2923 memcpy(priv->current_mac, dev->dev_addr, sizeof(priv->current_mac));
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index e8ec1dec5789..f13a4d7bbf95 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -2840,3 +2840,19 @@ int set_phv_bit(struct mlx4_dev *dev, u8 port, int new_val)
2840 return -EOPNOTSUPP; 2840 return -EOPNOTSUPP;
2841} 2841}
2842EXPORT_SYMBOL(set_phv_bit); 2842EXPORT_SYMBOL(set_phv_bit);
2843
2844void mlx4_replace_zero_macs(struct mlx4_dev *dev)
2845{
2846 int i;
2847 u8 mac_addr[ETH_ALEN];
2848
2849 dev->port_random_macs = 0;
2850 for (i = 1; i <= dev->caps.num_ports; ++i)
2851 if (!dev->caps.def_mac[i] &&
2852 dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) {
2853 eth_random_addr(mac_addr);
2854 dev->port_random_macs |= 1 << i;
2855 dev->caps.def_mac[i] = mlx4_mac_to_u64(mac_addr);
2856 }
2857}
2858EXPORT_SYMBOL_GPL(mlx4_replace_zero_macs);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 006757f80988..bcbdfab1fe19 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -863,6 +863,8 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
863 return -ENODEV; 863 return -ENODEV;
864 } 864 }
865 865
866 mlx4_replace_zero_macs(dev);
867
866 dev->caps.qp0_qkey = kcalloc(dev->caps.num_ports, sizeof(u32), GFP_KERNEL); 868 dev->caps.qp0_qkey = kcalloc(dev->caps.num_ports, sizeof(u32), GFP_KERNEL);
867 dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); 869 dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
868 dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL); 870 dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 232b2b55f23b..e1cf9036af22 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1378,6 +1378,8 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work);
1378 1378
1379void mlx4_init_quotas(struct mlx4_dev *dev); 1379void mlx4_init_quotas(struct mlx4_dev *dev);
1380 1380
1381/* for VFs, replace zero MACs with randomly-generated MACs at driver start */
1382void mlx4_replace_zero_macs(struct mlx4_dev *dev);
1381int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port); 1383int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port);
1382/* Returns the VF index of slave */ 1384/* Returns the VF index of slave */
1383int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); 1385int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave);
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index baad4cb8e9b0..5a8677bafe04 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -833,6 +833,7 @@ struct mlx4_dev {
833 struct mlx4_quotas quotas; 833 struct mlx4_quotas quotas;
834 struct radix_tree_root qp_table_tree; 834 struct radix_tree_root qp_table_tree;
835 u8 rev_id; 835 u8 rev_id;
836 u8 port_random_macs;
836 char board_id[MLX4_BOARD_ID_LEN]; 837 char board_id[MLX4_BOARD_ID_LEN];
837 int numa_node; 838 int numa_node;
838 int oper_log_mgm_entry_size; 839 int oper_log_mgm_entry_size;