aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugenia Emantayev <eugenia@mellanox.com>2017-02-23 05:02:42 -0500
committerDavid S. Miller <davem@davemloft.net>2017-02-23 10:57:56 -0500
commit745d8ae4622c6808b22e33a944c7decb30074be4 (patch)
tree56b55f8e44f2678025ad8551d0e8d8e983f31ab1
parent423b3aecf29085a52530d4f9167c56a84b081042 (diff)
net/mlx4: Spoofcheck and zero MAC can't coexist
Spoofcheck can't be enabled if VF MAC is zero. Vice versa, can't zero MAC if spoofcheck is on. Fixes: 8f7ba3ca12f6 ('net/mlx4: Add set VF mac address support') Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c6
-rw-r--r--include/linux/mlx4/cmd.h2
-rw-r--r--include/linux/mlx4/driver.h10
4 files changed, 32 insertions, 8 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index a49072b4fa52..e8c105164931 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -43,6 +43,7 @@
43#include <linux/semaphore.h> 43#include <linux/semaphore.h>
44#include <rdma/ib_smi.h> 44#include <rdma/ib_smi.h>
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/etherdevice.h>
46 47
47#include <asm/io.h> 48#include <asm/io.h>
48 49
@@ -2955,7 +2956,7 @@ static bool mlx4_valid_vf_state_change(struct mlx4_dev *dev, int port,
2955 return false; 2956 return false;
2956} 2957}
2957 2958
2958int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac) 2959int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac)
2959{ 2960{
2960 struct mlx4_priv *priv = mlx4_priv(dev); 2961 struct mlx4_priv *priv = mlx4_priv(dev);
2961 struct mlx4_vport_state *s_info; 2962 struct mlx4_vport_state *s_info;
@@ -2964,13 +2965,22 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
2964 if (!mlx4_is_master(dev)) 2965 if (!mlx4_is_master(dev))
2965 return -EPROTONOSUPPORT; 2966 return -EPROTONOSUPPORT;
2966 2967
2968 if (is_multicast_ether_addr(mac))
2969 return -EINVAL;
2970
2967 slave = mlx4_get_slave_indx(dev, vf); 2971 slave = mlx4_get_slave_indx(dev, vf);
2968 if (slave < 0) 2972 if (slave < 0)
2969 return -EINVAL; 2973 return -EINVAL;
2970 2974
2971 port = mlx4_slaves_closest_port(dev, slave, port); 2975 port = mlx4_slaves_closest_port(dev, slave, port);
2972 s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; 2976 s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
2973 s_info->mac = mac; 2977
2978 if (s_info->spoofchk && is_zero_ether_addr(mac)) {
2979 mlx4_info(dev, "MAC invalidation is not allowed when spoofchk is on\n");
2980 return -EPERM;
2981 }
2982
2983 s_info->mac = mlx4_mac_to_u64(mac);
2974 mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n", 2984 mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n",
2975 vf, port, s_info->mac); 2985 vf, port, s_info->mac);
2976 return 0; 2986 return 0;
@@ -3143,6 +3153,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
3143 struct mlx4_priv *priv = mlx4_priv(dev); 3153 struct mlx4_priv *priv = mlx4_priv(dev);
3144 struct mlx4_vport_state *s_info; 3154 struct mlx4_vport_state *s_info;
3145 int slave; 3155 int slave;
3156 u8 mac[ETH_ALEN];
3146 3157
3147 if ((!mlx4_is_master(dev)) || 3158 if ((!mlx4_is_master(dev)) ||
3148 !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM)) 3159 !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM))
@@ -3154,6 +3165,13 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
3154 3165
3155 port = mlx4_slaves_closest_port(dev, slave, port); 3166 port = mlx4_slaves_closest_port(dev, slave, port);
3156 s_info = &priv->mfunc.master.vf_admin[slave].vport[port]; 3167 s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
3168
3169 mlx4_u64_to_mac(mac, s_info->mac);
3170 if (setting && !is_valid_ether_addr(mac)) {
3171 mlx4_info(dev, "Illegal MAC with spoofchk\n");
3172 return -EPERM;
3173 }
3174
3157 s_info->spoofchk = setting; 3175 s_info->spoofchk = setting;
3158 3176
3159 return 0; 3177 return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index afe4444e5434..61420473fe5f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2485,12 +2485,8 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
2485{ 2485{
2486 struct mlx4_en_priv *en_priv = netdev_priv(dev); 2486 struct mlx4_en_priv *en_priv = netdev_priv(dev);
2487 struct mlx4_en_dev *mdev = en_priv->mdev; 2487 struct mlx4_en_dev *mdev = en_priv->mdev;
2488 u64 mac_u64 = mlx4_mac_to_u64(mac);
2489 2488
2490 if (is_multicast_ether_addr(mac)) 2489 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac);
2491 return -EINVAL;
2492
2493 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
2494} 2490}
2495 2491
2496static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos, 2492static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 1f3568694a57..7b74afcbbab2 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -308,7 +308,7 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
308int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx, 308int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
309 struct ifla_vf_stats *vf_stats); 309 struct ifla_vf_stats *vf_stats);
310u32 mlx4_comm_get_version(void); 310u32 mlx4_comm_get_version(void);
311int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); 311int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac);
312int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, 312int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan,
313 u8 qos, __be16 proto); 313 u8 qos, __be16 proto);
314int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate, 314int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate,
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h
index bd0e7075ea6d..e965e5090d96 100644
--- a/include/linux/mlx4/driver.h
+++ b/include/linux/mlx4/driver.h
@@ -104,4 +104,14 @@ static inline u64 mlx4_mac_to_u64(u8 *addr)
104 return mac; 104 return mac;
105} 105}
106 106
107static inline void mlx4_u64_to_mac(u8 *addr, u64 mac)
108{
109 int i;
110
111 for (i = ETH_ALEN; i > 0; i--) {
112 addr[i - 1] = mac && 0xFF;
113 mac >>= 8;
114 }
115}
116
107#endif /* MLX4_DRIVER_H */ 117#endif /* MLX4_DRIVER_H */